Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Fix wrong test for (software) queue blocked condi...



details:   https://anonhg.NetBSD.org/src/rev/4743adc157dd
branches:  trunk
changeset: 487207:4743adc157dd
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sun Jun 04 11:42:55 2000 +0000

description:
Fix wrong test for (software) queue blocked condition.

diffstat:

 sys/dev/ic/aic7xxx.c |  50 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 47 insertions(+), 3 deletions(-)

diffs (106 lines):

diff -r 044484ea3612 -r 4743adc157dd sys/dev/ic/aic7xxx.c
--- a/sys/dev/ic/aic7xxx.c      Sun Jun 04 09:55:53 2000 +0000
+++ b/sys/dev/ic/aic7xxx.c      Sun Jun 04 11:42:55 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aic7xxx.c,v 1.54 2000/05/29 20:13:53 fvdl Exp $        */
+/*     $NetBSD: aic7xxx.c,v 1.55 2000/06/04 11:42:55 fvdl Exp $        */
 
 /*
  * Generic driver for the aic7xxx based adaptec SCSI controllers
@@ -115,6 +115,8 @@
 #include <dev/microcode/aic7xxx/aic7xxx_reg.h>
 #include <dev/microcode/aic7xxx/aic7xxx_seq.h>
 
+#define XS_STS_DEBUG   0x00000002
+
 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #define ALL_CHANNELS '\0'
@@ -358,7 +360,7 @@
        while (xs != NULL) {
                target = xs->sc_link->scsipi_scsi.target;
                if (ahc->devqueue_blocked[target] == 0 &&
-                   (!ahc_istagged_device(ahc, xs, 0) &&
+                   (ahc_istagged_device(ahc, xs, 0) ||
                     ahc_index_busy_tcl(ahc, XS_TCL(ahc, xs), FALSE) ==
                    SCB_LIST_NULL))
                        break;
@@ -1722,6 +1724,8 @@
                u_int  scb_index;
                struct hardware_scb *hscb;
                struct scsipi_xfer *xs;
+               struct scb *scbp;
+               int todo, inqueue;
                /*
                 * The sequencer will notify us when a command
                 * has an error that would be of interest to
@@ -1890,10 +1894,34 @@
                case SCSI_STATUS_BUSY:
                        /*
                         * XXX middle layer doesn't handle XS_BUSY well.
-                        * So, requeue this ourselves internally.
+                        * So, requeue this ourselves internally. It will
+                        * get its turn once all outstanding (tagged)
+                        * commands have finished.
                         */
                        xs->error = XS_BUSY;
+                       xs->xs_status |= XS_STS_DEBUG;
                        scb->flags |= SCB_REQUEUE;
+
+                       /*
+                        * Walk through all pending SCBs for this target,
+                        * incrementing the freeze count for the queue.
+                        * When all of these have been completed, the
+                        * queue will be available again.
+                        */
+                       inqueue = todo = 0;
+                       scbp = ahc->pending_ccbs.lh_first;
+                       while (scbp != NULL) {
+                               inqueue++;
+                               if (ahc_match_scb(scbp, SCB_TARGET(scb),
+                                   SCB_CHANNEL(scb), SCB_LUN(scb), 
+                                   SCB_LIST_NULL, ROLE_INITIATOR)) {
+                                       ahc_freeze_ccb(scbp);
+                                       todo++;
+                               }
+                               scbp = scbp->plinks.le_next;
+                       }
+                       scsi_print_addr(xs->sc_link);
+                       printf("%d SCBs pending, %d to drain\n", inqueue, todo);
                        break;
                }
                break;
@@ -3427,10 +3455,21 @@
                 */
                int s;
 
+               if (xs->xs_status & XS_STS_DEBUG) {
+                       scsi_print_addr(xs->sc_link);
+                       printf("putting SCB that caused queue full back"
+                              " in queue\n");
+               }
+
                s = splbio();
                TAILQ_INSERT_HEAD(&ahc->sc_q, xs, adapter_q);
                splx(s);
        } else {
+               if (xs->xs_status & XS_STS_DEBUG) {
+                       xs->xs_status &= ~XS_STS_DEBUG;
+                       scsi_print_addr(xs->sc_link);
+                       printf("completed SCB that caused queue full\n");
+               }
                xs->xs_status |= XS_STS_DONE;
                ahc_check_tags(ahc, xs);
                scsipi_done(xs);
@@ -4059,6 +4098,11 @@
        if ((tstate->discenable & mask) != 0)
                hscb->control |= DISCENB;
 
+       if (xs->xs_status & XS_STS_DEBUG) {
+               scsi_print_addr(xs->sc_link);
+               printf("redoing command that caused queue full\n");
+       }
+
        if (xs->xs_control & XS_CTL_RESET) {
                hscb->cmdpointer = 0;
                scb->flags |= SCB_DEVICE_RESET;



Home | Main Index | Thread Index | Old Index