diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2004-06-02 18:55:09 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2004-06-02 18:55:09 +0000 |
commit | 5a39fe414db9196464fc4176ea67c2fd7c2701d6 (patch) | |
tree | bc673bfa57f489b486a05c89aa0b6c848eefd187 | |
parent | 12fd1578a303513cd03b772c5e909bb6020d7f8f (diff) |
Add quirks field to the wdc softc and implement the first one:
WDC_QUIRK_NOSHORTDMA which disables DMA for the one-sector
transfers. Use this quirk for the Geode SC1100 IDE to fix
hanging during fdisk reported in PR 3729.
Thanks to Alexandre Belloni <abelloni@nerim.net> for testing.
ok costa@
-rw-r--r-- | sys/dev/ata/ata_wdc.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/wdcvar.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/pciide.c | 8 |
3 files changed, 14 insertions, 4 deletions
diff --git a/sys/dev/ata/ata_wdc.c b/sys/dev/ata/ata_wdc.c index c6ef07b91a4..304bcc09973 100644 --- a/sys/dev/ata/ata_wdc.c +++ b/sys/dev/ata/ata_wdc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ata_wdc.c,v 1.26 2004/01/23 20:48:33 grange Exp $ */ +/* $OpenBSD: ata_wdc.c,v 1.27 2004/06/02 18:55:08 grange Exp $ */ /* $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $ */ /* @@ -144,7 +144,9 @@ wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) xfer->c_flags |= C_POLL; if (!(ata_bio->flags & ATA_POLL) && (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && - (ata_bio->flags & ATA_SINGLE) == 0) + (ata_bio->flags & ATA_SINGLE) == 0 && + (ata_bio->bcount > 512 || + (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA) == 0)) xfer->c_flags |= C_DMA; xfer->drive = drvp->drive; xfer->cmd = ata_bio; diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h index 87fbb305cf6..a3c9cea2e10 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wdcvar.h,v 1.32 2003/10/21 18:58:50 jmc Exp $ */ +/* $OpenBSD: wdcvar.h,v 1.33 2004/06/02 18:55:08 grange Exp $ */ /* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */ /*- @@ -163,6 +163,8 @@ struct wdc_softc { /* Per controller state */ u_int8_t UDMA_cap; /* highest UDMA mode supported */ int nchannels; /* Number of channels on this controller */ struct channel_softc **channels; /* channels-specific datas (array) */ + u_int16_t quirks; /* per-device oddities */ +#define WDC_QUIRK_NOSHORTDMA 0x0001 /* can't do short DMA transfers */ #if 0 /* diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index e9b13ca3435..8ca47e1a3ef 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.167 2004/05/24 22:52:52 mickey Exp $ */ +/* $OpenBSD: pciide.c,v 1.168 2004/06/02 18:55:08 grange Exp $ */ /* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */ /* @@ -4215,6 +4215,12 @@ ns_scx200_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_MAX - PAGE_SIZE; } + /* + * This chip seems to be unable to do one-sector transfers + * using DMA. + */ + sc->sc_wdcdev.quirks = WDC_QUIRK_NOSHORTDMA; + pciide_print_channels(sc->sc_wdcdev.nchannels, interface); for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { |