diff options
| author | bouyer <bouyer@NetBSD.org> | 2000-07-06 15:08:11 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2000-07-06 15:08:11 +0000 |
| commit | e2aaf9ef7ff47ca9d0e0454eccda033cd0d37ca1 (patch) | |
| tree | 8115d0ee639f8fcda689d77f0cffe9917813b8cd /sys | |
| parent | b23b64b8cea40832a0009b4926371ea07042853f (diff) | |
Work around a bug in AMD756 rev D2, from patches provided by David Sainty:
disable multiword DMA for these chips. multiword DMA can be forced with
options PCIIDE_AMD756_ENABLEDMA on rev D2 chips, but use at your own risk !
While I'm there remove a duplicate allocation of sc_wdcdev.nchannels in HPT
code.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/pci/pciide.c | 24 | ||||
| -rw-r--r-- | sys/dev/pci/pciide_amd_reg.h | 17 |
2 files changed, 37 insertions, 4 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index afd22d9b9c3..5da832e1134 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $NetBSD: pciide.c,v 1.77 2000/07/05 19:05:31 bouyer Exp $ */ +/* $NetBSD: pciide.c,v 1.78 2000/07/06 15:08:11 bouyer Exp $ */ /* @@ -1777,6 +1777,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); @@ -1809,8 +1811,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; @@ -2826,7 +2845,6 @@ hpt_chip_map(sc, pa) sc->sc_wdcdev.set_modes = hpt_setup_channel; sc->sc_wdcdev.channels = sc->wdc_chanarray; - sc->sc_wdcdev.nchannels = (revision == HPT366_REV) ? 1 : 2; if (revision == HPT366_REV) { /* * The 366 has 2 PCI IDE functions, one for primary and one diff --git a/sys/dev/pci/pciide_amd_reg.h b/sys/dev/pci/pciide_amd_reg.h index fcd026d512b..b85f4fe38bf 100644 --- a/sys/dev/pci/pciide_amd_reg.h +++ b/sys/dev/pci/pciide_amd_reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: pciide_amd_reg.h,v 1.1 2000/03/06 18:02:27 bouyer Exp $ */ +/* $NetBSD: pciide_amd_reg.h,v 1.2 2000/07/06 15:08:11 bouyer Exp $ */ /* * Copyright (c) 2000 David Sainty. @@ -38,6 +38,21 @@ * 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))) |
