summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2010-11-06 16:57:34 +0000
committerkettenis <kettenis@openbsd.org>2010-11-06 16:57:34 +0000
commit2bce368a8e130efbffe6f7a9ca9342e541d2c013 (patch)
tree74d31e5645a4762b4078b3ffd0d134f2b102e2b8
parentIf the dma_init callback function returns with EINVAL, fall back to PIO. (diff)
downloadwireguard-openbsd-2bce368a8e130efbffe6f7a9ca9342e541d2c013.tar.xz
wireguard-openbsd-2bce368a8e130efbffe6f7a9ca9342e541d2c013.zip
Revision 0xc4 and earlier of the Acer Labs M5229 UDMA IDE controller can't do
DMA for LBA48 commands. Work around this issue by (silently) falling back to PIO for LBA48 commands. Access to the tail end of large disks will be much slower, but at least it works. From NetBSD (Takeshi Nakayama). ok jsg@, krw@, deraadt@
-rw-r--r--sys/dev/pci/pciide.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index be172ec0cd2..d9223f2e67c 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.321 2010/08/31 17:13:44 deraadt Exp $ */
+/* $OpenBSD: pciide.c,v 1.322 2010/11/06 16:57:34 kettenis Exp $ */
/* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */
/*
@@ -215,6 +215,7 @@ void ns_scx200_setup_channel(struct channel_softc *);
void acer_chip_map(struct pciide_softc *, struct pci_attach_args *);
void acer_setup_channel(struct channel_softc *);
int acer_pci_intr(void *);
+int acer_dma_init(void *, int, int, void *, size_t, int);
void pdc202xx_chip_map(struct pciide_softc *, struct pci_attach_args *);
void pdc202xx_setup_channel(struct channel_softc *);
@@ -5629,6 +5630,8 @@ acer_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
}
sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
sc->sc_wdcdev.irqack = pciide_irqack;
+ if (rev <= 0xC4)
+ sc->sc_wdcdev.dma_init = acer_dma_init;
}
sc->sc_wdcdev.PIO_cap = 4;
@@ -5823,6 +5826,17 @@ acer_pci_intr(void *arg)
return (rv);
}
+int
+acer_dma_init(void *v, int channel, int drive, void *databuf,
+ size_t datalen, int flags)
+{
+ /* Use PIO for LBA48 transfers. */
+ if (flags & WDC_DMA_LBA48)
+ return (EINVAL);
+
+ return (pciide_dma_init(v, channel, drive, databuf, datalen, flags));
+}
+
void
hpt_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{