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.
This commit is contained in:
gibbs 1997-02-18 04:25:31 +00:00
parent 3f2bb8dbd8
commit 23a89f2e84
2 changed files with 20 additions and 20 deletions

View File

@ -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;
}

View File

@ -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,