Date: Thu, 9 Apr 1998 15:42:54 -0700 From: Parag Patel <parag@cgt.com> To: <freebsd-current@FreeBSD.ORG> Cc: "Thomas J. Merritt" <tjm@codegen.com> Subject: Re: Questions for PCI-IDE driver owner Message-ID: <199804092241.PAA17868@mail1.sirius.com>
next in thread | raw e-mail | index | archive | help
Well, since I haven't gotten any responses, I went ahead and changed some
IDE files the way I thought they should have been done. Anyone feel like
trying them out to see if I broke anything, and then hopefully merging
them into the main sources? Thanks in advance.
The three files changed are pci/ide_pci.c, i386/isa/wdreg.h, and
i386/isa/wd.c. The changes are small but necessary for the CMD646
controller to work in DMA mode. The diffs are relative to the current
release, ie the latest checked-in code. If there's a preferred format
for the diffs, please let me know - I just ran "cvs diff -c <file>".
-- Parag Patel <parag@cgt.com>
Index: ide_pci.c
===================================================================
RCS file: /src/freebsd/src/sys/pci/ide_pci.c,v
retrieving revision 1.9
diff -c -r1.9 ide_pci.c
*** ide_pci.c 1998/02/06 12:14:06 1.9
--- ide_pci.c 1998/04/09 22:19:37
***************
*** 61,66 ****
--- 61,67 ----
#endif
#define PROMISE_ULTRA33 0x4d33105a
+ #define CMD_PCI646U2_ID 0x06461095
struct ide_pci_cookie; /* structs vendor_fns, ide_pci_cookie are
recursive */
***************
*** 150,156 ****
static void ide_pci_attach(pcici_t tag, int unit);
! static void *ide_pci_candma(int, int);
static int ide_pci_dmainit(void *,
struct wdparams *,
int (*)(int, void *),
--- 151,157 ----
static void ide_pci_attach(pcici_t tag, int unit);
! static void *ide_pci_candma(int, int, int);
static int ide_pci_dmainit(void *,
struct wdparams *,
int (*)(int, void *),
***************
*** 537,542 ****
--- 538,632 ----
promise_status
};
+ static void
+ cmd646_status(struct ide_pci_cookie *cookie)
+ {
+ int iobase_bm = cookie->iobase_bm;
+ pcici_t tag = cookie->tag;
+ int i;
+
+ printf("cmd646_status: %d:%d register dump:\n",
+ cookie->ctlr, cookie->unit);
+
+ for (i = 0; i < 0x80; i += 16)
+ {
+ printf(" %2x:%8x %8x %8x %8x\n",
+ i, pci_conf_read(tag, i), pci_conf_read(tag, i + 4),
+ pci_conf_read(tag, i + 8), pci_conf_read(tag, i + 12));
+ }
+ }
+
+ static int
+ cmd646_dmainit(struct ide_pci_cookie *cookie,
+ struct wdparams *wp,
+ int(*wdcmd)(int, void *),
+ void *wdinfo)
+ {
+ int iobase_bm = cookie->iobase_bm;
+ int ctlr = cookie->ctlr;
+ int unit = cookie->unit;
+ int mrdmode, bmista, udidetcr, r;
+ #define BMRDMODE 1
+ #define BUDIDETCR 3
+
+ if (udma_mode(wp) >= 2)
+ {
+ mrdmode = inb(iobase_bm + BMRDMODE);
+ udidetcr = inb(iobase_bm + BUDIDETCR);
+ bmista = inb(iobase_bm + BMISTA_PORT);
+
+ outb(iobase_bm + BMRDMODE, mrdmode | 0x08C);
+ outb(iobase_bm + BUDIDETCR, udidetcr | (unit ? 0x2 : 0x1));
+ outb(iobase_bm + BMISTA_PORT,
+ bmista | (unit ? BMISTA_DMA1CAP : BMISTA_DMA0CAP) |
+ BMISTA_DMA_ERROR);
+
+ if (bootverbose)
+ cmd646_status(cookie);
+
+ /* set the drive to Ultra-DMA mode */
+ r = wdcmd(WDDMA_UDMA2, wdinfo);
+
+ if (!r)
+ {
+ printf("cmd646_dmainit: setting DMA mode failed\n");
+ return 0;
+ }
+
+ return 1;
+ }
+
+ if (pio_mode(wp) >= 4 && mwdma_mode(wp) >= 2)
+ {
+ bmista = inb(iobase_bm + BMISTA_PORT);
+ outb(iobase_bm + BMISTA_PORT,
+ bmista | (unit ? BMISTA_DMA1CAP : BMISTA_DMA0CAP) |
+ BMISTA_DMA_ERROR);
+
+ if (bootverbose)
+ cmd646_status(cookie);
+
+ /* set the drive to DMA mode */
+ r = wdcmd(WDDMA_MDMA2, wdinfo);
+
+ if (!r)
+ {
+ printf("cmd646_dmainit: setting DMA mode failed\n");
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ static struct vendor_fns vs_cmd646 =
+ {
+ cmd646_dmainit,
+ cmd646_status
+ };
+
/* Intel PIIX, PIIX3, and PIIX4 IDE controller subfunctions */
static void
intel_piix_dump_drive(char *ctlr,
***************
*** 916,921 ****
--- 1006,1013 ----
return ("Promise Ultra/33 IDE controller");
if (type == 0x05711106)
return ("VIA 82C586x (Apollo) Bus-master IDE controller");
+ if (type == CMD_PCI646U2_ID)
+ return "CMD PCI646U2 Ultra/33 IDE controller";
if (data & 0x8000)
return ("PCI IDE controller (busmaster capable)");
#ifndef CMD640
***************
*** 947,953 ****
/* set up vendor-specific stuff */
type = pci_conf_read(tag, PCI_ID_REG);
! if (type != PROMISE_ULTRA33) {
/* is it busmaster capable? bail if not */
class = pci_conf_read(tag, PCI_CLASS_REG);
if (!(class & 0x8000)) {
--- 1039,1045 ----
/* set up vendor-specific stuff */
type = pci_conf_read(tag, PCI_ID_REG);
! if (type != PROMISE_ULTRA33 && type != CMD_PCI646U2_ID) {
/* is it busmaster capable? bail if not */
class = pci_conf_read(tag, PCI_CLASS_REG);
if (!(class & 0x8000)) {
***************
*** 979,991 ****
vp = &vs_promise;
break;
default:
/* everybody else */
vp = &vs_generic;
break;
}
! if (type != PROMISE_ULTRA33) {
if ((class & 0x100) == 0) {
iobase_wd_1 = IO_WD1;
altiobase_wd_1 = iobase_wd_1 + wd_altsts;
--- 1071,1088 ----
vp = &vs_promise;
break;
+ case CMD_PCI646U2_ID:
+ /* CMD PCI646U2-based controllers */
+ vp = &vs_cmd646;
+ break;
+
default:
/* everybody else */
vp = &vs_generic;
break;
}
! if (type != PROMISE_ULTRA33 && type != CMD_PCI646U2_ID) {
if ((class & 0x100) == 0) {
iobase_wd_1 = IO_WD1;
altiobase_wd_1 = iobase_wd_1 + wd_altsts;
***************
*** 1187,1199 ****
* Return a cookie if we can do DMA on the specified (iobase_wd, unit).
*/
static void *
! ide_pci_candma(int iobase_wd, int unit)
{
struct ide_pci_cookie *cp;
cp = softc.cookies.lh_first;
while(cp) {
! if (cp->ctlr == unit &&
((iobase_wd == 0) || (cp->iobase_wd == iobase_wd)))
break;
cp = cp->le.le_next;
--- 1284,1296 ----
* Return a cookie if we can do DMA on the specified (iobase_wd, unit).
*/
static void *
! ide_pci_candma(int iobase_wd, int ctlr, int unit)
{
struct ide_pci_cookie *cp;
cp = softc.cookies.lh_first;
while(cp) {
! if (cp->ctlr == ctlr && cp->unit == unit &&
((iobase_wd == 0) || (cp->iobase_wd == iobase_wd)))
break;
cp = cp->le.le_next;
***************
*** 1214,1225 ****
void *wdinfo)
{
struct ide_pci_cookie *cp = cookie;
/*
* If the controller status indicates that DMA is configured already,
* we flounce happily away
*/
! if (inb(cp->iobase_bm + BMISTA_PORT) &
! ((cp->unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))
return 1;
/* We take a stab at it with device-dependent code */
--- 1311,1325 ----
void *wdinfo)
{
struct ide_pci_cookie *cp = cookie;
+
/*
* If the controller status indicates that DMA is configured already,
* we flounce happily away
+ * [CMD 646 part should always be initialized]
*/
! if (cp->type != CMD_PCI646U2_ID &&
! inb(cp->iobase_bm + BMISTA_PORT) &
! ((cp->unit == 0) ? BMISTA_DMA0CAP : BMISTA_DMA1CAP))
return 1;
/* We take a stab at it with device-dependent code */
Index: wdreg.h
===================================================================
RCS file: /src/freebsd/src/sys/i386/isa/wdreg.h,v
retrieving revision 1.21
diff -c -r1.21 wdreg.h
*** wdreg.h 1998/01/14 08:08:42 1.21
--- wdreg.h 1998/04/09 22:18:29
***************
*** 261,267 ****
*/
struct wddma {
void *(*wdd_candma) /* returns a cookie if PCI */
! __P((int ctlr, int drive));
int (*wdd_dmaverify) /* verify that request is DMA-able */
__P((void *cookie, char *vaddr, u_long len, int direction));
int (*wdd_dmaprep) /* prepare DMA hardware */
--- 261,267 ----
*/
struct wddma {
void *(*wdd_candma) /* returns a cookie if PCI */
! __P((int iobase, int ctlr, int drive));
int (*wdd_dmaverify) /* verify that request is DMA-able */
__P((void *cookie, char *vaddr, u_long len, int direction));
int (*wdd_dmaprep) /* prepare DMA hardware */
Index: wd.c
===================================================================
RCS file: /src/freebsd/src/sys/i386/isa/wd.c,v
retrieving revision 1.152
diff -c -r1.152 wd.c
*** wd.c 1998/04/02 02:10:47 1.152
--- wd.c 1998/04/09 22:18:52
***************
*** 297,303 ****
du->dk_interface = interface;
#if !defined(DISABLE_PCI_IDE) && (NPCI > 0)
if (wddma[interface].wdd_candma) {
! du->dk_dmacookie = wddma[interface].wdd_candma(dvp->id_iobase,
du->dk_ctrlr);
du->dk_port = dvp->id_iobase;
du->dk_altport = wddma[interface].wdd_altiobase(du->dk_dmacookie);
} else {
--- 297,304 ----
du->dk_interface = interface;
#if !defined(DISABLE_PCI_IDE) && (NPCI > 0)
if (wddma[interface].wdd_candma) {
! du->dk_dmacookie = wddma[interface].wdd_candma(dvp->id_iobase,
! du->dk_ctrlr, unit);
du->dk_port = dvp->id_iobase;
du->dk_altport = wddma[interface].wdd_altiobase(du->dk_dmacookie);
} else {
***************
*** 1070,1076 ****
du = wddrives[dkunit(bp->b_dev)];
/* finish off DMA */
! if (du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) {
/* XXX SMP boxes sometimes generate an early intr. Why? */
if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) &
WDDS_INTERRUPT)
== 0)
--- 1071,1077 ----
du = wddrives[dkunit(bp->b_dev)];
/* finish off DMA */
! if (du->dk_flags & DKFL_DMA) {
/* XXX SMP boxes sometimes generate an early intr. Why? */
if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) &
WDDS_INTERRUPT)
== 0)
***************
*** 1861,1867 ****
* check drive's DMA capability
*/
if (wddma[du->dk_interface].wdd_candma) {
! du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(du->dk_port,
du->dk_ctrlr);
/* does user want this? */
if ((du->cfg_flags & WDOPT_DMA) &&
/* have we got a DMA controller? */
--- 1862,1869 ----
* check drive's DMA capability
*/
if (wddma[du->dk_interface].wdd_candma) {
! du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(du->dk_port,
! du->dk_ctrlr, du->dk_unit);
/* does user want this? */
if ((du->cfg_flags & WDOPT_DMA) &&
/* have we got a DMA controller? */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804092241.PAA17868>
