Make it possible for (*dma_finish)() to abort quietly a DMA op. Use this
in wdc_reset_channel().
This commit is contained in:
parent
495631e4d6
commit
73203a8277
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdc.c,v 1.184 2004/08/02 22:02:35 bouyer Exp $ */
|
||||
/* $NetBSD: wdc.c,v 1.185 2004/08/02 22:20:54 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
|
||||
|
@ -70,7 +70,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.184 2004/08/02 22:02:35 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.185 2004/08/02 22:20:54 bouyer Exp $");
|
||||
|
||||
#ifndef WDCDEBUG
|
||||
#define WDCDEBUG
|
||||
|
@ -948,7 +948,7 @@ wdcintr(void *arg)
|
|||
if (chp->ch_flags & WDCF_DMA_WAIT) {
|
||||
wdc->dma_status =
|
||||
(*wdc->dma_finish)(wdc->dma_arg, chp->ch_channel,
|
||||
xfer->c_drive, 0);
|
||||
xfer->c_drive, WDC_DMAEND_END);
|
||||
if (wdc->dma_status & WDC_DMAST_NOIRQ) {
|
||||
/* IRQ not for us, not detected by DMA engine */
|
||||
return 0;
|
||||
|
@ -1035,7 +1035,7 @@ wdc_reset_channel(struct wdc_channel *chp, int flags)
|
|||
chp->ch_wdc->dma_arg,
|
||||
chp->ch_channel,
|
||||
xfer->c_drive,
|
||||
1);
|
||||
WDC_DMAEND_ABRT_QUIET);
|
||||
chp->ch_flags &= WDCF_DMA_WAIT;
|
||||
}
|
||||
}
|
||||
|
@ -1327,14 +1327,14 @@ wdc_dmawait(struct wdc_channel *chp, struct ata_xfer *xfer, int timeout)
|
|||
for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
|
||||
wdc->dma_status =
|
||||
(*wdc->dma_finish)(wdc->dma_arg,
|
||||
chp->ch_channel, xfer->c_drive, 0);
|
||||
chp->ch_channel, xfer->c_drive, WDC_DMAEND_END);
|
||||
if ((wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
|
||||
return 0;
|
||||
delay(WDCDELAY);
|
||||
}
|
||||
/* timeout, force a DMA halt */
|
||||
wdc->dma_status = (*wdc->dma_finish)(wdc->dma_arg,
|
||||
chp->ch_channel, xfer->c_drive, 1);
|
||||
chp->ch_channel, xfer->c_drive, WDC_DMAEND_ABRT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1358,7 +1358,8 @@ wdctimeout(void *arg)
|
|||
if (chp->ch_flags & WDCF_DMA_WAIT) {
|
||||
wdc->dma_status =
|
||||
(*wdc->dma_finish)(wdc->dma_arg,
|
||||
chp->ch_channel, xfer->c_drive, 1);
|
||||
chp->ch_channel, xfer->c_drive,
|
||||
WDC_DMAEND_ABRT);
|
||||
chp->ch_flags &= ~WDCF_DMA_WAIT;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdcvar.h,v 1.59 2004/08/02 22:02:35 bouyer Exp $ */
|
||||
/* $NetBSD: wdcvar.h,v 1.60 2004/08/02 22:20:54 bouyer Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -154,6 +154,11 @@ struct wdc_softc {
|
|||
#define WDC_DMA_IRQW 0x02
|
||||
#define WDC_DMA_LBA48 0x04
|
||||
|
||||
/* values passed to dma_finish */
|
||||
#define WDC_DMAEND_END 0 /* check for proper end of a DMA xfer */
|
||||
#define WDC_DMAEND_ABRT 1 /* abort a DMA xfer, verbose */
|
||||
#define WDC_DMAEND_ABRT_QUIET 2 /* abort a DMA xfer, quiet */
|
||||
|
||||
int dma_status; /* status returned from dma_finish() */
|
||||
#define WDC_DMAST_NOIRQ 0x01 /* missing IRQ */
|
||||
#define WDC_DMAST_ERR 0x02 /* DMA error */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pciide_common.c,v 1.13 2004/08/02 19:37:33 bouyer Exp $ */
|
||||
/* $NetBSD: pciide_common.c,v 1.14 2004/08/02 22:20:54 bouyer Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -76,7 +76,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.13 2004/08/02 19:37:33 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.14 2004/08/02 22:20:54 bouyer Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
|
@ -693,7 +693,7 @@ pciide_dma_finish(v, channel, drive, force)
|
|||
WDCDEBUG_PRINT(("pciide_dma_finish: status 0x%x\n", status),
|
||||
DEBUG_XFERS);
|
||||
|
||||
if (force == 0 && (status & IDEDMA_CTL_INTR) == 0)
|
||||
if (force == WDC_DMAEND_END && (status & IDEDMA_CTL_INTR) == 0)
|
||||
return WDC_DMAST_NOIRQ;
|
||||
|
||||
/* stop DMA channel */
|
||||
|
@ -708,20 +708,20 @@ pciide_dma_finish(v, channel, drive, force)
|
|||
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
|
||||
bus_dmamap_unload(sc->sc_dmat, dma_maps->dmamap_xfer);
|
||||
|
||||
if ((status & IDEDMA_CTL_ERR) != 0) {
|
||||
if ((status & IDEDMA_CTL_ERR) != 0 && force != WDC_DMAEND_ABRT_QUIET) {
|
||||
printf("%s:%d:%d: bus-master DMA error: status=0x%x\n",
|
||||
sc->sc_wdcdev.sc_dev.dv_xname, channel, drive, status);
|
||||
error |= WDC_DMAST_ERR;
|
||||
}
|
||||
|
||||
if ((status & IDEDMA_CTL_INTR) == 0) {
|
||||
if ((status & IDEDMA_CTL_INTR) == 0 && force != WDC_DMAEND_ABRT_QUIET) {
|
||||
printf("%s:%d:%d: bus-master DMA error: missing interrupt, "
|
||||
"status=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, channel,
|
||||
drive, status);
|
||||
error |= WDC_DMAST_NOIRQ;
|
||||
}
|
||||
|
||||
if ((status & IDEDMA_CTL_ACT) != 0) {
|
||||
if ((status & IDEDMA_CTL_ACT) != 0 && force != WDC_DMAEND_ABRT_QUIET) {
|
||||
/* data underrun, may be a valid condition for ATAPI */
|
||||
error |= WDC_DMAST_UNDER;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue