diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1999-01-21 00:55:32 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1999-01-21 00:55:32 +0000 |
commit | 76b5366091f76c9bc73570149ef5055648fc2c39 (patch) | |
tree | 590d020e0f2a5bea6e09d66d951a674443b21d67 /sys/pci/ide_pci.c | |
parent | 4b4d01da6f07f7754ff6a6e4f5223e9f0984d1a6 (diff) |
Notes
Diffstat (limited to 'sys/pci/ide_pci.c')
-rw-r--r-- | sys/pci/ide_pci.c | 339 |
1 files changed, 31 insertions, 308 deletions
diff --git a/sys/pci/ide_pci.c b/sys/pci/ide_pci.c index 39c53a562b32c..68df969ff56bd 100644 --- a/sys/pci/ide_pci.c +++ b/sys/pci/ide_pci.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ide_pci.c,v 1.27 1999/01/17 05:18:54 bde Exp $ + * $Id: ide_pci.c,v 1.13 1998/07/11 07:45:52 bde Exp $ */ #include "pci.h" @@ -120,15 +120,6 @@ via_571_dmainit(struct ide_pci_cookie *cookie, void *wdinfo); static void -acer_status(struct ide_pci_cookie *cookie); - -static int -acer_dmainit(struct ide_pci_cookie *cookie, - struct wdparams *wp, - int (*wdcmd)(int, void *), - void *wdinfo); - -static void intel_piix_dump_drive(char *ctlr, int sitre, int is_piix4, @@ -159,7 +150,7 @@ mkcookie(int iobase_wd, static void ide_pci_attach(pcici_t tag, int unit); -static void *ide_pci_candma(int, int, int); +static void *ide_pci_candma(int, int); static int ide_pci_dmainit(void *, struct wdparams *, int (*)(int, void *), @@ -276,14 +267,8 @@ generic_dmainit(struct ide_pci_cookie *cookie, printf("ide_pci: generic_dmainit %04x:%d: warning, IDE controller timing not set\n", cookie->iobase_wd, cookie->unit); - /* If we're here, then this controller is most likely not set - for UDMA, even if the drive may be. Make the drive wise - up. */ - - if(!wdcmd(WDDMA_MDMA2, wdinfo)) - printf("generic_dmainit: could not set multiword DMA mode!\n"); return 1; - } + } #ifdef IDE_PCI_DEBUG printf("pio_mode: %d, mwdma_mode(wp): %d, udma_mode(wp): %d\n", pio_mode(wp), mwdma_mode(wp), udma_mode(wp)); @@ -404,7 +389,7 @@ via_571_dmainit(struct ide_pci_cookie *cookie, /* UDMA enable by SET FEATURES, DMA cycles, cycle time 2T */ mask = 0xe3000000 >> (unitno * 8); - new = 0x40000000 >> (unitno * 8); + new = 0x80000000 >> (unitno * 8); word50 &= ~mask; word50 |= new; @@ -418,10 +403,10 @@ via_571_dmainit(struct ide_pci_cookie *cookie, */ /* Set UDMA mode 2 on drive */ if (bootverbose) - printf("via_571_dmainit: setting ultra DMA mode 2\n"); + printf("intel_piix_dmainit: setting ultra DMA mode 2\n"); r = wdcmd(WDDMA_UDMA2, wdinfo); if (!r) { - printf("via_571_dmainit: setting DMA mode failed\n"); + printf("intel_piix_dmainit: setting DMA mode failed\n"); return 0; } @@ -437,10 +422,10 @@ via_571_dmainit(struct ide_pci_cookie *cookie, /* Set multiword DMA mode 2 on drive */ if (bootverbose) - printf("via_571_dmainit: setting multiword DMA mode 2\n"); + printf("intel_piix_dmainit: setting multiword DMA mode 2\n"); r = wdcmd(WDDMA_MDMA2, wdinfo); if (!r) { - printf("via_571_dmainit: setting DMA mode failed\n"); + printf("intel_piix_dmainit: setting DMA mode failed\n"); return 0; } @@ -452,7 +437,8 @@ via_571_dmainit(struct ide_pci_cookie *cookie, * enable prefetch/postwrite-- XXX may cause problems * with CD-ROMs? */ - workword |= 0xc000 >> (cookie->ctlr * 2); + workword &= ~(3 << (cookie->ctlr * 2 + 12)); + workword |= 3 << (cookie->ctlr * 2 + 12); /* FIFO configurations-- equal split, threshold 1/2 */ workword &= 0x90ffffff; @@ -495,175 +481,6 @@ static struct vendor_fns vs_via_571 = via_571_status }; -/* Cyrix Cx5530 Courtesy of Whistle Communications */ - -/* - * Verify that controller can handle a dma request for cp. Should - * not affect any hardware or driver state. - * Special version for 5530 that allows only transfers on 16 byte boundaries.(!) - * (Yes the Cyrix 5530 can only UDMA to cache-line boundaries.(bleh!)) - * Luckily nearly all disk IO is to kernel bufers which are page alligned. - * They may fix this in some other version of the chip, but it's in the latest - * at this time (Jan 1999). - */ -static int -cyrix_5530_dmaverify(void *xcp, char *vaddr, u_long count, int dir) -{ - int badfu; - - /* - * check for nonaligned or odd-length Stuff - */ - badfu = ((unsigned int)vaddr & 0xf) || (count & 0xf); -#ifdef DIAGNOSTIC - if (badfu) { - printf("ide_pci: dmaverify odd vaddr or length, "); - printf("vaddr = %p length = %08lx\n", (void *)vaddr, count); - } -#endif - return (!badfu); -} - -/* - * XXX Unit number handling may be broken in the Cx5530 modules. - * It has only been checked with a single drive. - * 12MByte/Sec transfer rates were seen with Quantum Fireball drives - * with negligable CPU usage. - */ -static void -cyrix_5530_status(struct ide_pci_cookie *cookie) -{ - int iobase_wd; - int ctlr, unit; - int iobase_bm; - pcici_t tag; - pcidi_t type; - u_long PIO_config; - u_long DMA_config; - int unitno; - - iobase_wd = cookie->iobase_wd; - unit = cookie->unit; - ctlr = cookie->ctlr; - iobase_bm = cookie->iobase_bm; - tag = cookie->tag; - type = cookie->type; - - unitno = ctlr * 2 + unit; - - /* set some values the BIOS should have set */ - printf("Using 0x%x\n", cookie->iobase_bm); - outl(iobase_bm + (unit * 0x10) + 0x20, 0x00040010); - outl(iobase_bm + (unit * 0x10) + 0x24, 0x00911030); - /* if ((ctlr == 0) && (unit == 0)) */ /* XXX */ - /* outb(iobase_bm + (unit * 0x10) + BMISTA_PORT, 0xe6);*/ - - PIO_config = inl(iobase_bm + (unit * 0x10) + 0x20); - DMA_config = inl(iobase_bm + (unit * 0x10) + 0x24); - - - printf("cyrix_5530_status: %s:%u IDE PIO cfg: 0x%08lx\n", - (ctlr ? "Secondary" : "Primary"), unit, PIO_config); - printf("cyrix_5530_status: %s:%u IDE DMA cfg: 0x%08lx\n", - (ctlr ? "Secondary" : "Primary"), unit, DMA_config); -} - -/* - * XXX timing values set here are only good for 30/33MHz buses; should deal - * with slower ones too (BTW: you overclock-- you lose) - */ - -static int -cyrix_5530_dmainit(struct ide_pci_cookie *cookie, - struct wdparams *wp, - int(*wdcmd)(int, void *), - void *wdinfo) -{ - int r; - u_long pci_revision; - int unitno; - int iobase_bm; - int unit; - - /*cookie->unit = 0; */ /* XXX */ - unit = cookie->unit; - pci_revision = pci_conf_read(cookie->tag, PCI_CLASS_REG) & - PCI_REVISION_MASK; - - unitno = cookie->ctlr * 2 + unit; - iobase_bm = cookie->iobase_bm; - - printf("Setting using 0x%x\n", iobase_bm); - if ((cookie->ctlr == 0) && (unit == 0)) /* XXX */ - outb(iobase_bm + (unit * 0x10) + BMISTA_PORT, 0xe6); - outl(iobase_bm + (unit * 0x10) + 0x20, 0x00040010); - outl(iobase_bm + (unit * 0x10) + 0x24, 0x00911030); - /* If it's a UDMA drive on a '5530, set it up */ - /* - * depending on what the drive can do, - * set the correct modes, - */ - printf("wd%d: mw=0x%x, pio=0x%x, pcirev=0x%lx, udma=0x%x\n", - unitno, - mwdma_mode(wp), pio_mode(wp), - pci_revision, udma_mode(wp)); - if (/* pci_revision >= 1 && */ udma_mode(wp) >= 2) { - /*outl(iobase_bm + 0x20 + (cookie->unit * 16), 0x00100010);*/ - outl(iobase_bm + 0x24 + (cookie->unit * 16), 0x00911030); - - /* - * With the Cx5530, drive configuration should come *after* the - * controller configuration, to make sure the controller sees - * the command and does the right thing. - */ - /* Set UDMA mode 2 on drive */ - if (bootverbose) - printf("cyrix_5530_dmainit: setting ultra DMA mode 2\n"); - r = wdcmd(WDDMA_UDMA2, wdinfo); - if (!r) { - printf("cyrix_5530_dmainit: setting DMA mode failed\n"); - return 0; - } - - if (bootverbose) - cyrix_5530_status(cookie); - return 1; - - } - - /* otherwise, try and program it for MW DMA mode 2 */ - else if (mwdma_mode(wp) >= 2 && pio_mode(wp) >= 4) { - - /* Set multiword DMA mode 2 on drive */ - if (bootverbose) - printf("cyrix_5530_dmainit: setting multiword DMA mode 2\n"); - r = wdcmd(WDDMA_MDMA2, wdinfo); - if (!r) { - printf("cyrix_5530_dmainit: setting DMA mode failed\n"); - return 0; - } - - /* Configure the controller appropriately for MWDMA mode 2 */ - - /*outl(iobase_bm + 0x20 + (cookie->unit * 16), 0x00100010);*/ - outl(iobase_bm + 0x24 + (cookie->unit * 16), 0x00002020); - - if (bootverbose) - cyrix_5530_status(cookie); - - return 1; - - } - return 0; -} - - -static struct vendor_fns vs_cyrix_5530 = -{ - cyrix_5530_dmainit, - cyrix_5530_status -}; - static void promise_status(struct ide_pci_cookie *cookie) @@ -879,8 +696,8 @@ intel_piix_dmainit(struct ide_pci_cookie *cookie, unitno = cookie->ctlr * 2 + cookie->unit; - mask = (1 << unitno) + (3 << (16 + unitno * 4)); - new = (1 << unitno) + (2 << (16 + unitno * 4)); + mask = 1 << unitno + 3 << (16 + unitno * 4); + new = 1 << unitno + 2 << (16 + unitno * 4); pci_conf_write(cookie->tag, 0x48, (pci_conf_read(cookie->tag, 0x48) & ~mask) | new); @@ -1019,70 +836,6 @@ static struct vendor_fns vs_intel_piix = intel_piix_status }; - -static void -acer_status(struct ide_pci_cookie *cookie) { - /* XXX does not do anything right now */ -} - -static int -acer_dmainit(struct ide_pci_cookie *cookie, - struct wdparams *wp, - int(*wdcmd)(int, void *), - void *wdinfo) -{ - /* Acer Aladdin DMA setup code. UDMA looks to be sinfully easy to set - on this thing - just one register. */ - - u_long word54 = pci_conf_read(cookie->tag, 0x54); - - /* Set the default Acer FIFO settings (0x55 = 13-word depth and - slave operation mode 1) */ - - word54 |= 0x5555; - - /* Is this drive UDMA? Set it up if so... */ - if(udma_mode(wp) >= 2) { - /* This is really easy to do. Just write 0xa (enable - UDMA mode with 2T timing) into the word at the right - places. */ - word54 |= (0xA << (16 + (cookie->ctlr * 8) + (cookie->unit * 4))); - - /* Now set the drive for UDMA2. */ - if(!wdcmd(WDDMA_UDMA2, wdinfo)) { - printf("acer_dmainit: could not set UDMA2 mode on wdc%d:%d!\n", cookie->ctlr, cookie->unit); - return 0; - } - - /* Write the new config into the registers. I'm not - sure if I'm doing this in the right order. */ - - pci_conf_write(cookie->tag, 0x54, word54); - - } else if(mwdma_mode(wp) >= 2 && pio_mode(wp) >=4) { - - - /* Otherwise, we're already set for regular DMA. */ - - if(!wdcmd(WDDMA_MDMA2, wdinfo)) { - printf("acer_dmainit: could not set MWDMA2 mode on wdc%d:%d!\n", - cookie->ctlr, cookie->unit); - return 0; - } - return 1; - } - - return 0; -} - -static struct vendor_fns vs_acer = -{ - acer_dmainit, - acer_status -}; - - - /* Generic SFF-8038i code-- all code below here, except for PCI probes, * more or less conforms to the SFF-8038i spec as extended for PCI. * There should be no code that goes beyond that feature set below. @@ -1145,7 +898,7 @@ mkcookie(int iobase_wd, return cp; } -static const char * +static char * ide_pci_probe(pcici_t tag, pcidi_t type) { u_long data; @@ -1164,11 +917,7 @@ ide_pci_probe(pcici_t tag, pcidi_t type) if (type == PROMISE_ULTRA33) return ("Promise Ultra/33 IDE controller"); if (type == 0x05711106) - return ("VIA 82C586x (Apollo) Bus-master IDE controller"); - if (type == 0x01021078) - return ("Cyrix 5530 Bus-master IDE controller"); - if (type == 0x522910b9) - return ("Acer Aladdin IV/V (M5229) Bus-master IDE controller"); + return ("VIA 82C586x (Apollo) Bus-master IDE controller"); if (data & 0x8000) return ("PCI IDE controller (busmaster capable)"); #ifndef CMD640 @@ -1186,7 +935,7 @@ ide_pci_probe(pcici_t tag, pcidi_t type) static void ide_pci_attach(pcici_t tag, int unit) { - u_long class = 0, cmd; + u_long class, cmd; int bmista_1, bmista_2; int iobase_wd_1, iobase_wd_2, iobase_bm_1, iobase_bm_2; int altiobase_wd_1, altiobase_wd_2; @@ -1232,13 +981,6 @@ ide_pci_attach(pcici_t tag, int unit) vp = &vs_promise; break; - case 0x01021078: /* cyrix 5530 */ - printf("cyrix 5530\n"); - vp = &vs_cyrix_5530; - break; - case 0x522910B9: /* Acer Aladdin IV/V (M5229) */ - vp = &vs_acer; - break; default: /* everybody else */ vp = &vs_generic; @@ -1269,19 +1011,16 @@ ide_pci_attach(pcici_t tag, int unit) } iobase_bm_1 = pci_conf_read(tag, 0x20) & 0xfffc; + iobase_bm_2 = iobase_bm_1 + SFF8038_CTLR_1; if (iobase_bm_1 == 0) { - printf("ide_pci: BIOS has not configured busmaster" - "I/O address,\n ide_pci: giving up\n"); + printf("ide_pci: BIOS has not configured busmaster I/O address,\n\ +ide_pci: giving up\n"); return; } - iobase_bm_2 = iobase_bm_1 + SFF8038_CTLR_1; wddma[unit].wdd_candma = ide_pci_candma; wddma[unit].wdd_dmainit = ide_pci_dmainit; - if (type == 0x01021078 /*CYRIX_5530*/) - wddma[unit].wdd_dmaverify = cyrix_5530_dmaverify; - else - wddma[unit].wdd_dmaverify = ide_pci_dmaverify; + wddma[unit].wdd_dmaverify = ide_pci_dmaverify; wddma[unit].wdd_dmaprep = ide_pci_dmasetup; wddma[unit].wdd_dmastart = ide_pci_dmastart; wddma[unit].wdd_dmadone = ide_pci_dmadone; @@ -1331,7 +1070,7 @@ ide_pci_attach(pcici_t tag, int unit) if (dvup->id_id == 0) { iobase_wd_2 = 0; break; - } + } } if (dvup->id_unit == biotabunit + 2) { @@ -1389,8 +1128,6 @@ ide_pci_attach(pcici_t tag, int unit) if (bootverbose) { vp->vendor_status(cookie); - bmista_1 = inb(iobase_bm_1 + BMISTA_PORT); - bmista_2 = inb(iobase_bm_2 + BMISTA_PORT); printf("ide_pci: busmaster 0 status: %02x from port: %08x\n", bmista_1, iobase_bm_1+BMISTA_PORT); @@ -1401,7 +1138,9 @@ ide_pci_attach(pcici_t tag, int unit) } } - if (iobase_wd_2 != 0) { + if (bmista_1 & BMISTA_SIMPLEX || bmista_2 & BMISTA_SIMPLEX) { + printf("ide_pci: controller is simplex, no DMA on secondary channel\n"); + } else if (iobase_wd_2 != 0) { cookie = mkcookie(iobase_wd_2, ctlridx + 1, 0, @@ -1423,8 +1162,6 @@ ide_pci_attach(pcici_t tag, int unit) if (bootverbose) { vp->vendor_status(cookie); - bmista_1 = inb(iobase_bm_1 + BMISTA_PORT); - bmista_2 = inb(iobase_bm_2 + BMISTA_PORT); printf("ide_pci: busmaster 1 status: %02x from port: %08x\n", bmista_2, iobase_bm_2+BMISTA_PORT); @@ -1449,17 +1186,16 @@ static struct pci_device ide_pci_device = { DATA_SET(pcidevice_set, ide_pci_device); /* - * Return a cookie if we may be able to do DMA on the specified - * (iobase_wd, ctlr, unit). + * 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) +ide_pci_candma(int iobase_wd, int unit) { struct ide_pci_cookie *cp; cp = softc.cookies.lh_first; while(cp) { - if (cp->ctlr == ctlr && cp->unit == unit && + if (cp->ctlr == unit && ((iobase_wd == 0) || (cp->iobase_wd == iobase_wd))) break; cp = cp->le.le_next; @@ -1529,10 +1265,7 @@ ide_pci_dmasetup(void *xcp, char *vaddr, u_long vcount, int dir) u_long prd_base, prd_count; u_long nbase, ncount, nend; int iobase_bm; - u_long count; -#ifdef DIAGNOSTIC - u_long checkcount; -#endif + u_long count, checkcount; prd = cp->prd; @@ -1568,22 +1301,10 @@ ide_pci_dmasetup(void *xcp, char *vaddr, u_long vcount, int dir) * Coalesce if physically contiguous and not crossing * 64k boundary. */ -#if 0 - /* - * Aggregation is NOT an optimisation worth doing, - * and the Cyrix UDMA controller screws itself - * in some aggregated situations. - * We might as well just assign each 4K page a DMA entry - * as this doesn't really gain us anything to aggregate them. - * This was basically copied from my agregation code in the aha - * driver, but I doubt it helped much there either. [JRE] - */ if ((prd_base + prd_count == nbase) && ((((nend - 1) ^ prd_base) & ~0xffff) == 0)) { prd_count += ncount; - } else -#endif - { + } else { prd[i].prd_base = prd_base; prd[i].prd_count = (prd_count & 0xffff); i++; @@ -1670,10 +1391,11 @@ ide_pci_dmadone(void *xcp) static int ide_pci_status(void *xcp) { + struct ide_pci_cookie *cp = xcp; int iobase_bm, status, bmista; status = 0; - iobase_bm = ((struct ide_pci_cookie *)xcp)->iobase_bm; + iobase_bm = cp->iobase_bm; bmista = inb(iobase_bm + BMISTA_PORT); @@ -1683,6 +1405,7 @@ ide_pci_status(void *xcp) status |= WDDS_ERROR; if (bmista & BMISTA_DMA_ACTIVE) status |= WDDS_ACTIVE; + return status; } |