From owner-freebsd-current Thu Apr 9 15:42:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id PAA27225 for freebsd-current-outgoing; Thu, 9 Apr 1998 15:42:02 -0700 (PDT) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from mail1.sirius.com (mail1.sirius.com [205.134.253.131]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id PAA27189 for ; Thu, 9 Apr 1998 15:41:52 -0700 (PDT) (envelope-from parag@mail.codegen.com) Received: from [192.168.100.101] (ppp-asok08--166.sirius.net [205.134.245.166]) by mail1.sirius.com (8.8.7/Sirius-8.8.7-97.08.12) with SMTP id PAA17868; Thu, 9 Apr 1998 15:41:26 -0700 (PDT) Message-Id: <199804092241.PAA17868@mail1.sirius.com> Subject: Re: Questions for PCI-IDE driver owner Date: Thu, 9 Apr 1998 15:42:54 -0700 x-sender: parag@mail.codegen.com x-mailer: Claris Emailer 2.0v3, January 22, 1998 From: Parag Patel To: cc: "Thomas J. Merritt" Mime-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 ". -- Parag Patel 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