diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-11-06 16:57:35 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-11-06 16:57:35 +0000 |
commit | c27aa45435b3b40f0350bf3b3e32ed20459129fa (patch) | |
tree | 5d0fc9479b1adf19e105f4d49dcce62ac7ea12a5 | |
parent | 45d3e364b6be21e55782f40158b077add47f1e3f (diff) |
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.c | 16 |
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) { |