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