diff options
author | gibbs <gibbs@FreeBSD.org> | 1995-04-01 19:53:04 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1995-04-01 19:53:04 +0000 |
commit | 6f307fa4969845b9cf410a96812226f30224442e (patch) | |
tree | e4cdd778e098971355b448d6eae2f0eb3f64964c /sys/i386/scsi | |
parent | 084bd6c7a2f6aee212a35c1363a402551a8e03cd (diff) | |
download | FreeBSD-src-6f307fa4969845b9cf410a96812226f30224442e.zip FreeBSD-src-6f307fa4969845b9cf410a96812226f30224442e.tar.gz |
Log ABORT_TAG messages to the console.
When attempting to abort a command, don't assume that just because the
sequecer happens to have SCBPTR pointing at the scb we want that it is
an active command.
Diffstat (limited to 'sys/i386/scsi')
-rw-r--r-- | sys/i386/scsi/aic7xxx.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c index dc6bba04..8119e98 100644 --- a/sys/i386/scsi/aic7xxx.c +++ b/sys/i386/scsi/aic7xxx.c @@ -24,7 +24,7 @@ * * commenced: Sun Sep 27 18:14:01 PDT 1992 * - * $Id: aic7xxx.c,v 1.17 1995/03/17 23:58:27 gibbs Exp $ + * $Id: aic7xxx.c,v 1.18 1995/03/31 13:54:40 gibbs Exp $ */ /* * TODO: @@ -355,6 +355,7 @@ struct scsi_device ahc_dev = #define MSG_REJECT 0x60 #define BAD_STATUS 0x70 #define RESIDUAL 0x80 +#define ABORT_TAG 0x90 #define BRKADRINT 0x08 #define SCSIINT 0x04 #define CMDCMPLT 0x02 @@ -1131,6 +1132,26 @@ ahcintr(unit) inb(iobase+SCBARRAY+15); break; } + case ABORT_TAG: + { + int scb_index; + scb_index = inb(SCBPTR + iobase); + scb = ahc->scbarray[scb_index]; + /* + * We didn't recieve a valid tag back from + * the target on a reconnect. + */ + printf("ahc%d: invalid tag recieved on channel %c " + "target %d, lun %d -- sending ABORT_TAG\n", + unit, + ((u_long)xs->sc_link->fordriver & 0x08)? 'B':'A', + xs->sc_link->target, + xs->sc_link->lun); + scb->xs->error = XS_DRIVER_STUFFUP; + untimeout(ahc_timeout, (caddr_t)scb); + ahc_done(unit, scb); + break; + } default: printf("ahc: seqint, " "intstat == 0x%x, scsisigi = 0x%x\n", @@ -1956,6 +1977,7 @@ ahc_abort_scb( unit, ahc, scb ) int found = 0; int active_scb; u_char flags; + u_char scb_control; PAUSE_SEQUENCER(ahc); /* @@ -1993,7 +2015,6 @@ ahc_abort_scb( unit, ahc, scb ) * the driver will then abort the command * and notify us of the abort. */ - int scb_control; outb(SCBPTR + iobase, scb->position); scb_control = inb(SCBARRAY + iobase); scb_control &= ~SCB_DIS; @@ -2001,6 +2022,13 @@ ahc_abort_scb( unit, ahc, scb ) outb(SCBPTR + iobase, active_scb); goto done; } + scb_control = inb(SCBARRAY + iobase); + scb_control &= ~SCB_DIS; + if( scb_control & SCB_DIS ) { + scb_control &= ~SCB_DIS; + outb(SCBARRAY + iobase, scb_control); + goto done; + } /* * Case 3: Currently active command */ @@ -2078,7 +2106,7 @@ ahc_timeout(void *arg1) #endif /*AHC_DEBUG */ /* - * If it's immediate, don't try abort it + * If it's immediate, don't try to abort it */ if (scb->flags & SCB_IMMED) { scb->xs->retries = 0; /* I MEAN IT ! */ |