summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorChris Cappuccio <chris@cvs.openbsd.org>2000-07-07 18:42:18 +0000
committerChris Cappuccio <chris@cvs.openbsd.org>2000-07-07 18:42:18 +0000
commit025de15d15bfbc089e2c174c993641fe05d99f97 (patch)
tree6b9ee652b8f346080482b7b893cb885dd8ece1be /sys/dev/pci
parent1d419d20183a0f020426a726e32ea535ada648ed (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/dev/pci')
-rw-r--r--sys/dev/pci/pciide.c27
-rw-r--r--sys/dev/pci/pciide_amd_reg.h16
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)))