Make it possible for (*dma_finish)() to abort quietly a DMA op. Use this

in wdc_reset_channel().
This commit is contained in:
bouyer 2004-08-02 22:20:54 +00:00
parent 495631e4d6
commit 73203a8277
3 changed files with 20 additions and 14 deletions

View File

@ -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;
}
/*

View File

@ -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 */

View File

@ -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;
}