Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev - change the interrupt routines to take a 3rd argume...
details: https://anonhg.NetBSD.org/src/rev/722ca8f3841e
branches: trunk
changeset: 468015:722ca8f3841e
user: bouyer <bouyer%NetBSD.org@localhost>
date: Thu Apr 01 21:46:28 1999 +0000
description:
- change the interrupt routines to take a 3rd arguments, set to 1 if we
are called from the interrupt or timeout handler, 0 otherwise.
- use this to know if we can busy-wait for wait_for_unbusy or wait_for_ready
This fixes a bug where CDs withot the DRQ_INTR capability would not busy-wait
for the CMDOUT phase.
While I'm there change 2 delay() to DELAY() for consistency, and
garbage-collect some old code from wdcintr() which has been ifdef'd out
for some time now.
diffstat:
sys/dev/ata/ata_wdc.c | 27 ++++++++++++++-------------
sys/dev/ic/wdc.c | 46 +++++++++-------------------------------------
sys/dev/ic/wdcvar.h | 4 ++--
sys/dev/scsipi/atapi_wdc.c | 41 +++++++++++++++++++++--------------------
4 files changed, 46 insertions(+), 72 deletions(-)
diffs (truncated from 325 to 300 lines):
diff -r ef55323141ef -r 722ca8f3841e sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c Thu Apr 01 21:15:43 1999 +0000
+++ b/sys/dev/ata/ata_wdc.c Thu Apr 01 21:46:28 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_wdc.c,v 1.18 1999/03/25 16:17:36 bouyer Exp $ */
+/* $NetBSD: ata_wdc.c,v 1.19 1999/04/01 21:46:28 bouyer Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -117,9 +117,9 @@
#define ATA_DELAY 10000 /* 10s for a drive I/O */
void wdc_ata_bio_start __P((struct channel_softc *,struct wdc_xfer *));
-int wdc_ata_bio_intr __P((struct channel_softc *, struct wdc_xfer *));
+int wdc_ata_bio_intr __P((struct channel_softc *, struct wdc_xfer *, int));
void wdc_ata_bio_done __P((struct channel_softc *, struct wdc_xfer *));
-int wdc_ata_ctrl_intr __P((struct channel_softc *, struct wdc_xfer *));
+int wdc_ata_ctrl_intr __P((struct channel_softc *, struct wdc_xfer *, int));
int wdc_ata_err __P((struct ata_drive_datas *, struct ata_bio *));
#define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */
#define WDC_ATA_RECOV 0x01 /* There was a recovered error */
@@ -199,8 +199,8 @@
ATA_DELAY / 1000 * hz);
} else {
/* Wait for at last 400ns for status bit to be valid */
- delay(1);
- wdc_ata_ctrl_intr(chp, xfer);
+ DELAY(1);
+ wdc_ata_ctrl_intr(chp, xfer, 0);
}
return;
}
@@ -372,7 +372,7 @@
} else {
/* Wait for at last 400ns for status bit to be valid */
delay(1);
- wdc_ata_bio_intr(chp, xfer);
+ wdc_ata_bio_intr(chp, xfer, 0);
if ((ata_bio->flags & ATA_ITSDONE) == 0)
goto again;
}
@@ -388,9 +388,10 @@
}
int
-wdc_ata_bio_intr(chp, xfer)
+wdc_ata_bio_intr(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
+ int irq;
{
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
@@ -417,9 +418,8 @@
/* Ack interrupt done by wait_for_unbusy */
if (wait_for_unbusy(chp,
- (ata_bio->flags & ATA_POLL) ? ATA_DELAY : 0) < 0) {
- if ((ata_bio->flags & ATA_POLL) == 0 &&
- (xfer->c_flags & C_TIMEOU) == 0)
+ (irq == 0) ? ATA_DELAY : 0) < 0) {
+ if (irq && (xfer->c_flags & C_TIMEOU) == 0)
return 0; /* IRQ was not for us */
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
@@ -585,14 +585,15 @@
* Implement operations needed before read/write.
*/
int
-wdc_ata_ctrl_intr(chp, xfer)
+wdc_ata_ctrl_intr(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
+ int irq;
{
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
char *errstring = NULL;
- int delay = (ata_bio->flags & ATA_POLL) ? ATA_DELAY : 0;
+ int delay = (irq == 0) ? ATA_DELAY : 0;
WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state),
DEBUG_FUNCS);
@@ -708,7 +709,7 @@
return 1;
timeout:
- if ((xfer->c_flags & C_TIMEOU) == 0 && delay == 0) {
+ if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
return 0; /* IRQ was not for us */
}
printf("%s:%d:%d: %s timed out\n",
diff -r ef55323141ef -r 722ca8f3841e sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c Thu Apr 01 21:15:43 1999 +0000
+++ b/sys/dev/ic/wdc.c Thu Apr 01 21:46:28 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdc.c,v 1.65 1999/03/31 11:18:31 bouyer Exp $ */
+/* $NetBSD: wdc.c,v 1.66 1999/04/01 21:46:29 bouyer Exp $ */
/*
@@ -117,7 +117,7 @@
static int __wdcwait_reset __P((struct channel_softc *, int));
void __wdccommand_done __P((struct channel_softc *, struct wdc_xfer *));
void __wdccommand_start __P((struct channel_softc *, struct wdc_xfer *));
-int __wdccommand_intr __P((struct channel_softc *, struct wdc_xfer *));
+int __wdccommand_intr __P((struct channel_softc *, struct wdc_xfer *, int));
int wdprint __P((void *, const char *));
@@ -518,35 +518,7 @@
struct wdc_xfer *xfer;
if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
-#if 0
- /* Clear the pending interrupt and abort. */
- u_int8_t s =
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
-#ifdef WDCDEBUG
- u_int8_t e =
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
- u_int8_t i =
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
-#else
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
-#endif
-
- WDCDEBUG_PRINT(("wdcintr: inactive controller, "
- "punting st=%02x er=%02x irr=%02x\n", s, e, i), DEBUG_INTR);
-
- if (s & WDCS_DRQ) {
- int len;
- len = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
- wd_cyl_lo) + 256 * bus_space_read_1(chp->cmd_iot,
- chp->cmd_ioh, wd_cyl_hi);
- WDCDEBUG_PRINT(("wdcintr: clearing up %d bytes\n",
- len), DEBUG_INTR);
- wdcbit_bucket (chp, len);
- }
-#else
WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
-#endif
return 0;
}
@@ -554,7 +526,7 @@
untimeout(wdctimeout, chp);
chp->ch_flags &= ~WDCF_IRQ_WAIT;
xfer = chp->ch_queue->sc_xfer.tqh_first;
- return xfer->c_intr(chp, xfer);
+ return xfer->c_intr(chp, xfer, 1);
}
/* Put all disk in RESET state */
@@ -738,7 +710,7 @@
*/
xfer->c_flags |= C_TIMEOU;
chp->ch_flags &= ~WDCF_IRQ_WAIT;
- xfer->c_intr(chp, xfer);
+ xfer->c_intr(chp, xfer, 1);
} else
__wdcerror(chp, "missing untimeout");
splx(s);
@@ -1079,13 +1051,14 @@
* Wait for at last 400ns for status bit to be valid.
*/
delay(10);
- __wdccommand_intr(chp, xfer);
+ __wdccommand_intr(chp, xfer, 0);
}
int
-__wdccommand_intr(chp, xfer)
+__wdccommand_intr(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
+ int irq;
{
struct wdc_command *wdc_c = xfer->cmd;
int bcount = wdc_c->bcount;
@@ -1094,9 +1067,8 @@
WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
- (wdc_c->flags & AT_POLL) ? wdc_c->timeout : 0)) {
- if ((xfer->c_flags & C_TIMEOU) == 0 &&
- (wdc_c->flags & AT_POLL) == 0)
+ (irq == 0) ? wdc_c->timeout : 0)) {
+ if (irq && (xfer->c_flags & C_TIMEOU) == 0)
return 0; /* IRQ was not for us */
wdc_c->flags |= AT_TIMEOU;
__wdccommand_done(chp, xfer);
diff -r ef55323141ef -r 722ca8f3841e sys/dev/ic/wdcvar.h
--- a/sys/dev/ic/wdcvar.h Thu Apr 01 21:15:43 1999 +0000
+++ b/sys/dev/ic/wdcvar.h Thu Apr 01 21:46:28 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdcvar.h,v 1.15 1999/02/08 15:22:29 bouyer Exp $ */
+/* $NetBSD: wdcvar.h,v 1.16 1999/04/01 21:46:30 bouyer Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -145,7 +145,7 @@
TAILQ_ENTRY(wdc_xfer) c_xferchain;
LIST_ENTRY(wdc_xfer) free_list;
void (*c_start) __P((struct channel_softc *, struct wdc_xfer *));
- int (*c_intr) __P((struct channel_softc *, struct wdc_xfer *));
+ int (*c_intr) __P((struct channel_softc *, struct wdc_xfer *, int));
};
/*
diff -r ef55323141ef -r 722ca8f3841e sys/dev/scsipi/atapi_wdc.c
--- a/sys/dev/scsipi/atapi_wdc.c Thu Apr 01 21:15:43 1999 +0000
+++ b/sys/dev/scsipi/atapi_wdc.c Thu Apr 01 21:46:28 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atapi_wdc.c,v 1.19 1999/03/25 16:17:37 bouyer Exp $ */
+/* $NetBSD: atapi_wdc.c,v 1.20 1999/04/01 21:46:30 bouyer Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer.
@@ -86,8 +86,8 @@
void wdc_atapi_minphys __P((struct buf *bp));
void wdc_atapi_start __P((struct channel_softc *,struct wdc_xfer *));
-int wdc_atapi_intr __P((struct channel_softc *, struct wdc_xfer *));
-int wdc_atapi_ctrl __P((struct channel_softc *, struct wdc_xfer *));
+int wdc_atapi_intr __P((struct channel_softc *, struct wdc_xfer *, int));
+int wdc_atapi_ctrl __P((struct channel_softc *, struct wdc_xfer *, int));
void wdc_atapi_done __P((struct channel_softc *, struct wdc_xfer *));
void wdc_atapi_reset __P((struct channel_softc *, struct wdc_xfer *));
int wdc_atapi_send_cmd __P((struct scsipi_xfer *sc_xfer));
@@ -246,7 +246,7 @@
xfer->drive, drvp->state);
panic("wdc_atapi_start: bad state");
}
- wdc_atapi_ctrl(chp, xfer);
+ wdc_atapi_ctrl(chp, xfer, 0);
return;
}
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
@@ -281,26 +281,23 @@
if ((sc_xfer->sc_link->scsipi_atapi.cap & 0x0300) != ACAP_DRQ_INTR ||
sc_xfer->flags & SCSI_POLL) {
/* Wait for at last 400ns for status bit to be valid */
- delay(1);
- if (wdc_atapi_intr(chp, xfer) == 0) {
- sc_xfer->error = XS_TIMEOUT;
- wdc_atapi_reset(chp, xfer);
- return;
- }
+ DELAY(1);
+ wdc_atapi_intr(chp, xfer, 0);
}
if (sc_xfer->flags & SCSI_POLL) {
while ((sc_xfer->flags & ITSDONE) == 0) {
/* Wait for at last 400ns for status bit to be valid */
- delay(1);
- wdc_atapi_intr(chp, xfer);
+ DELAY(1);
+ wdc_atapi_intr(chp, xfer, 0);
}
}
}
int
-wdc_atapi_intr(chp, xfer)
+wdc_atapi_intr(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
+ int irq;
{
struct scsipi_xfer *sc_xfer = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
@@ -326,9 +323,8 @@
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wait_for_unbusy(chp,
- (sc_xfer->flags & SCSI_POLL) ? sc_xfer->timeout : 0) != 0) {
- if ((sc_xfer->flags & SCSI_POLL) == 0 &&
- (xfer->c_flags & C_TIMEOU) == 0)
+ (irq == 0) ? sc_xfer->timeout : 0) != 0) {
+ if (irq && (xfer->c_flags & C_TIMEOU) == 0)
return 0; /* IRQ was not for us */
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
@@ -592,7 +588,11 @@
if (xfer->c_flags & C_DMA) {
dma_err = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
chp->channel, xfer->drive, dma_flags);
- xfer->c_bcount -= sc_xfer->datalen;
+ if (xfer->c_flags & C_SENSE)
+ xfer->c_bcount -=
+ sizeof(sc_xfer->sense.scsi_sense);
+ else
+ xfer->c_bcount -= sc_xfer->datalen;
}
if (xfer->c_flags & C_SENSE) {
if ((chp->ch_status & WDCS_ERR) || dma_err < 0) {
@@ -680,14 +680,15 @@
}
Home |
Main Index |
Thread Index |
Old Index