diff options
author | Chris Cappuccio <chris@cvs.openbsd.org> | 2000-07-07 18:42:18 +0000 |
---|---|---|
committer | Chris Cappuccio <chris@cvs.openbsd.org> | 2000-07-07 18:42:18 +0000 |
commit | 025de15d15bfbc089e2c174c993641fe05d99f97 (patch) | |
tree | 6b9ee652b8f346080482b7b893cb885dd8ece1be /sys | |
parent | 1d419d20183a0f020426a726e32ea535ada648ed (diff) |
From NetBSD:
Match Promise Ultra/100 controller
(Ultra/100 drives will be used as Ultra/66 fow now)
Work-around for a bug in revision D2 AMD controllers
(They do not work correctly with Multiword-DMA mode, workaround is to
disable MW DMA, but this bug does not affect all drives so there is an
option PCIIDE_AMD756_ENABLEDMA to stop this behavior. You know you have
this bug when your system hangs completely with this option.)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/pciide.c | 27 | ||||
-rw-r--r-- | sys/dev/pci/pciide_amd_reg.h | 16 |
2 files changed, 40 insertions, 3 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index dc85a7112ad..ac12b46f54f 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.26 2000/06/26 18:09:11 chris Exp $ */ +/* $OpenBSD: pciide.c,v 1.27 2000/07/07 18:42:16 chris Exp $ */ /* $NetBSD: pciide.c,v 1.48 1999/11/28 20:05:18 bouyer Exp $ */ /* @@ -372,6 +372,10 @@ const struct pciide_product_desc pciide_promise_products[] = { { PCI_PRODUCT_PROMISE_ULTRA66, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, + }, + { PCI_PRODUCT_PROMISE_ULTRA100, + IDE_PCI_CLASS_OVERRIDE, + pdc202xx_chip_map, } }; @@ -1806,6 +1810,8 @@ amd756_setup_channel(chp) struct ata_drive_datas *drvp; struct pciide_channel *cp = (struct pciide_channel*)chp; struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; + int rev = PCI_REVISION( + pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG)); idedma_ctl = 0; datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_DATATIM); @@ -1838,8 +1844,25 @@ amd756_setup_channel(chp) /* can use PIO timings, MW DMA unused */ mode = drvp->PIO_mode; } else { - /* use Multiword DMA */ + /* use Multiword DMA, but only if revision is OK */ drvp->drive_flags &= ~DRIVE_UDMA; +#ifndef PCIIDE_AMD756_ENABLEDMA + /* + * The workaround doesn't seem to be necessary + * with all drives, so it can be disabled by + * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if + * triggered. + */ + if (AMD756_CHIPREV_DISABLEDMA(rev)) { + printf("%s:%d:%d: multi-word DMA disabled due " + "to chip revision\n", + sc->sc_wdcdev.sc_dev.dv_xname, + chp->channel, drive); + mode = drvp->PIO_mode; + drvp->drive_flags &= ~DRIVE_DMA; + goto pio; + } +#endif /* mode = min(pio, dma+2) */ if (drvp->PIO_mode <= (drvp->DMA_mode +2)) mode = drvp->PIO_mode; diff --git a/sys/dev/pci/pciide_amd_reg.h b/sys/dev/pci/pciide_amd_reg.h index f683e173bd7..dda05e3dee5 100644 --- a/sys/dev/pci/pciide_amd_reg.h +++ b/sys/dev/pci/pciide_amd_reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide_amd_reg.h,v 1.1 2000/03/24 17:47:41 chris Exp $ */ +/* $OpenBSD: pciide_amd_reg.h,v 1.2 2000/07/07 18:42:17 chris Exp $ */ /* * Copyright (c) 2000 David Sainty. @@ -38,6 +38,20 @@ * available at: http://www.amd.com/products/cpg/athlon/techdocs/pdf/22548.pdf */ +/* Chip revisions */ +#define AMD756_CHIPREV_D2 3 + +/* Chip revision tests */ + +/* + * The AMD756 chip revision D2 has a bug affecting DMA (but not UDMA) + * modes. The workaround documented by AMD is to not use DMA on any + * drive which does not support UDMA modes. + * + * See: http://www.amd.com/products/cpg/athlon/techdocs/pdf/22591.pdf + */ +#define AMD756_CHIPREV_DISABLEDMA(rev) ((rev) <= AMD756_CHIPREV_D2) + /* Channel enable */ #define AMD756_CHANSTATUS_EN 0x40 #define AMD756_CHAN_EN(chan) (0x01 << (1 - (chan))) |