From 4e605384b5796ed2f4514fba63edc6eedd203358 Mon Sep 17 00:00:00 2001 From: "Justin T. Gibbs" Date: Tue, 18 Feb 1997 04:25:31 +0000 Subject: Don't rely on AAP(Auto Access Pause) when queueing SCBs to the card. This will increase the overhead of queueing a command, but some recent bug reports make me believe that AAP isn't really working and that we are losing some SCBs from the input queue. Hopefully this will cure that problem. Fix some bugs in the error recovery code. Mainly these could cause us to inadvertantly forget to untimeout an SCB that was recovered causing later confusion. --- sys/i386/scsi/aic7xxx.c | 38 +++++++++++++++++++------------------- sys/i386/scsi/aic7xxx.h | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'sys') diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c index e8a64b88a21a..44e61f8193bc 100644 --- a/sys/i386/scsi/aic7xxx.c +++ b/sys/i386/scsi/aic7xxx.c @@ -1530,10 +1530,17 @@ ahc_handle_scsiint(ahc, intstat) scb = NULL; printerror = 0; } else if (scb->flags & SCB_ABORT) { + struct hardware_scb *hscb; + u_int8_t tag; + + hscb = scb->hscb; + tag = SCB_LIST_NULL; + if (hscb->control & TAG_ENB) + tag = scb->hscb->tag; ahc_reset_device(ahc, target, channel, - scb->hscb->tag, + tag, XS_TIMEOUT); ahc_run_done_queue(ahc); scb = NULL; @@ -1553,6 +1560,7 @@ ahc_handle_scsiint(ahc, intstat) if (scb != NULL) { scb->xs->error = XS_DRIVER_STUFFUP; sc_print_addr(scb->xs->sc_link); + untimeout(ahc_timeout, (caddr_t)scb); ahc_done(ahc, scb); scb = NULL; } else @@ -2297,7 +2305,7 @@ ahc_scsi_cmd(xs) if (ahc->discenable & mask) { hscb->control |= DISCENB; if (ahc->tagenable & mask) - hscb->control |= TAG_ENB; + hscb->control |= MSG_SIMPLE_Q_TAG; if (ahc->orderedtag & mask) { /* XXX this should be handled by the upper SCSI layer */ printf("Ordered Tag sent\n"); @@ -2458,12 +2466,7 @@ ahc_run_waiting_queue(ahc) { struct scb *scb; - /* - * On aic78X0 chips, we rely on Auto Access Pause (AAP) - * instead of doing an explicit pause/unpause. - */ - if ((ahc->type & AHC_AIC78X0) == 0) - pause_sequencer(ahc); + pause_sequencer(ahc); while ((scb = ahc->waiting_scbs.stqh_first) != NULL) { @@ -2484,8 +2487,7 @@ ahc_run_waiting_queue(ahc) */ ahc->curqincnt++; } - if ((ahc->type & AHC_AIC78X0) == 0) - unpause_sequencer(ahc, /*Unpause always*/FALSE); + unpause_sequencer(ahc, /*Unpause always*/FALSE); } /* @@ -2724,8 +2726,7 @@ ahc_timeout(arg) */ panic("%s: Timed-out command times out " "again\n", ahc_name(ahc)); - } else if ((scb->flags & (SCB_ABORTED | SCB_DEVICE_RESET - | SCB_SENTORDEREDTAG)) == 0) { + } else if ((scb->flags & SCB_RECOVERY_SCB) == 0) { /* * This is not the SCB that started this timeout * processing. Give this scb another lifetime so @@ -2792,7 +2793,7 @@ ahc_timeout(arg) /* Decide our course of action */ channel = (scb->hscb->tcl & SELBUSB) ? 'B': 'A'; - if (scb->flags & SCB_ABORTED) { + if (scb->flags & SCB_RECOVERY_SCB) { /* * Been down this road before. * Do a full bus reset. @@ -2814,7 +2815,7 @@ ahc_timeout(arg) mask = (0x01 << (scb->xs->sc_link->target | (IS_SCSIBUS_B(ahc, scb->xs->sc_link) ? SELBUSB : 0))); - scb->flags |= SCB_SENTORDEREDTAG; + scb->flags |= SCB_SENTORDEREDTAG|SCB_RECOVERY_SCB; ahc->orderedtag |= mask; timeout(ahc_timeout, (caddr_t)scb, (1 * hz)); unpause_sequencer(ahc, /*unpause_always*/TRUE); @@ -2851,7 +2852,7 @@ ahc_timeout(arg) ahc_outb(ahc, SCSISIGO, bus_state|ATNO); sc_print_addr(active_scb->xs->sc_link); printf("abort message in message buffer\n"); - active_scb->flags |= SCB_ABORTED; + active_scb->flags |= SCB_ABORT|SCB_RECOVERY_SCB; if (active_scb != scb) { untimeout(ahc_timeout, (caddr_t)active_scb); @@ -2860,7 +2861,7 @@ ahc_timeout(arg) (scb->xs->timeout * hz) / 1000); } timeout(ahc_timeout, (caddr_t)active_scb, - (100 * hz) / 1000); + (200 * hz) / 1000); unpause_sequencer(ahc, /*unpause_always*/TRUE); } else { u_int8_t hscb_index; @@ -2876,12 +2877,11 @@ ahc_timeout(arg) disconnected = TRUE; } - scb->flags |= SCB_ABORTED; if (disconnected) { /* Simply set the ABORT_SCB control bit */ scb->hscb->control |= ABORT_SCB|MK_MESSAGE; scb->hscb->control &= ~DISCONNECTED;; - scb->flags |= SCB_ABORT; + scb->flags |= SCB_ABORT|SCB_RECOVERY_SCB; if (hscb_index != SCB_LIST_NULL) { u_int8_t scb_control; @@ -3170,7 +3170,7 @@ ahc_abort_wscb (ahc, scbp, scbpos, prev, xs_error) */ ahc_outb(ahc, SCBPTR, curscb); scbp->flags = SCB_ABORTED|SCB_QUEUED_FOR_DONE; - scbp->xs->error |= xs_error; + scbp->xs->error = xs_error; untimeout(ahc_timeout, (caddr_t)scbp); return next; } diff --git a/sys/i386/scsi/aic7xxx.h b/sys/i386/scsi/aic7xxx.h index c22431bb903c..79d890443c16 100644 --- a/sys/i386/scsi/aic7xxx.h +++ b/sys/i386/scsi/aic7xxx.h @@ -151,7 +151,7 @@ typedef enum { SCB_SENSE = 0x0010, SCB_TIMEDOUT = 0x0020, SCB_QUEUED_FOR_DONE = 0x0040, - SCB_PAGED_OUT = 0x0080, + SCB_RECOVERY_SCB = 0x0080, SCB_WAITINGQ = 0x0100, SCB_ASSIGNEDQ = 0x0200, SCB_SENTORDEREDTAG = 0x0400, -- cgit v1.3