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