Apply patch from David Sainty <David.Sainty@optimation.co.nz>:
Some AMD controllers have a bug which can look up the machine when using DMA, so disable DMA for some revisions (info provided by AMD). "options PCIIDE_AMD756_ENABLEDMA" can be used to force DMA on these chips.
This commit is contained in:
parent
87788b7d50
commit
838676ce64
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pciide.c,v 1.75 2000/07/05 16:11:35 bouyer Exp $ */
|
/* $NetBSD: pciide.c,v 1.76 2000/07/05 18:58:41 bouyer Exp $ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1713,21 +1713,46 @@ amd756_chip_map(sc, pa)
|
||||||
struct pci_attach_args *pa;
|
struct pci_attach_args *pa;
|
||||||
{
|
{
|
||||||
struct pciide_channel *cp;
|
struct pciide_channel *cp;
|
||||||
pcireg_t interface = PCI_INTERFACE(pa->pa_class);
|
pcireg_t classreg, interface;
|
||||||
int channel;
|
int channel, dmacap;
|
||||||
pcireg_t chanenable;
|
pcireg_t chanenable;
|
||||||
bus_size_t cmdsize, ctlsize;
|
bus_size_t cmdsize, ctlsize;
|
||||||
|
|
||||||
if (pciide_chipen(sc, pa) == 0)
|
if (pciide_chipen(sc, pa) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
classreg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG);
|
||||||
|
interface = PCI_INTERFACE(classreg);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PCIIDE_AMD756_ENABLEDMA
|
||||||
|
/*
|
||||||
|
* 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,
|
||||||
|
* but this does not appear to be necessary on all drives.
|
||||||
|
* The bug, if triggered, will cause a total system hang.
|
||||||
|
*
|
||||||
|
* http://www.amd.com/products/cpg/athlon/techdocs/pdf/22591.pdf
|
||||||
|
*/
|
||||||
|
if (AMD756_CHIPREV_DISABLEDMA(PCI_REVISION(classreg))) {
|
||||||
|
printf("%s: multi-word DMA disabled due to chip revision\n",
|
||||||
|
sc->sc_wdcdev.sc_dev.dv_xname);
|
||||||
|
dmacap = 0;
|
||||||
|
} else
|
||||||
|
#endif /* PCIIDE_AMD756_ENABLEDMA */
|
||||||
|
{
|
||||||
|
dmacap = WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
|
||||||
printf("%s: bus-master DMA support present",
|
printf("%s: bus-master DMA support present",
|
||||||
sc->sc_wdcdev.sc_dev.dv_xname);
|
sc->sc_wdcdev.sc_dev.dv_xname);
|
||||||
pciide_mapreg_dma(sc, pa);
|
pciide_mapreg_dma(sc, pa);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
|
sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
|
||||||
WDC_CAPABILITY_MODE;
|
WDC_CAPABILITY_MODE;
|
||||||
if (sc->sc_dma_ok) {
|
if (sc->sc_dma_ok) {
|
||||||
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
|
sc->sc_wdcdev.cap |= dmacap;
|
||||||
sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
|
sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
|
||||||
sc->sc_wdcdev.irqack = pciide_irqack;
|
sc->sc_wdcdev.irqack = pciide_irqack;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue