mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 00:02:44 +00:00
Fix a bug in the selection timeout handler that was introduced when the
selection loop was merged with the poll_for_work loop. We cannot assume that the SCB for the selection timeout is the current SCB. Instead we must look at the SCB at the head of the waiting for selection list. This fixes part of a problem reported by David Malone, but does not explain why he was getting selection timeouts in the first place.
This commit is contained in:
parent
583f1729d1
commit
844b7c2d86
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24660
@ -32,7 +32,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: aic7xxx.c,v 1.111 1997/04/04 04:21:43 gibbs Exp $
|
* $Id: aic7xxx.c,v 1.112 1997/04/04 19:36:04 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
@ -1663,6 +1663,57 @@ ahc_handle_scsiint(ahc, intstat)
|
|||||||
ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
|
ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
|
||||||
restart_sequencer(ahc);
|
restart_sequencer(ahc);
|
||||||
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
||||||
|
} else if ((status & SELTO) != 0) {
|
||||||
|
struct scsi_xfer *xs;
|
||||||
|
u_int8_t scbptr;
|
||||||
|
u_int8_t nextscb;
|
||||||
|
|
||||||
|
scbptr = ahc_inb(ahc, WAITING_SCBH);
|
||||||
|
ahc_outb(ahc, SCBPTR, scbptr);
|
||||||
|
scb_index = ahc_inb(ahc, SCB_TAG);
|
||||||
|
|
||||||
|
if (scb_index < ahc->scb_data->numscbs) {
|
||||||
|
scb = ahc->scb_data->scbarray[scb_index];
|
||||||
|
if ((scb->flags & SCB_ACTIVE) == 0)
|
||||||
|
scb = NULL;
|
||||||
|
} else
|
||||||
|
scb = NULL;
|
||||||
|
|
||||||
|
if (scb == NULL) {
|
||||||
|
printf("%s: ahc_intr - referenced scb not "
|
||||||
|
"valid during SELTO scb(%d)\n",
|
||||||
|
ahc_name(ahc), scb_index);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* XXX If we queued an abort tag, go clean up the
|
||||||
|
* disconnected list.
|
||||||
|
*/
|
||||||
|
xs = scb->xs;
|
||||||
|
xs->error = XS_SELTIMEOUT;
|
||||||
|
/*
|
||||||
|
* Clear any pending messages for the timed out
|
||||||
|
* target, and mark the target as free
|
||||||
|
*/
|
||||||
|
ahc_outb(ahc, MSG_LEN, 0);
|
||||||
|
ahc_index_busy_target(ahc, xs->sc_link->target,
|
||||||
|
IS_SCSIBUS_B(ahc, xs->sc_link) ? 'B' : 'A',
|
||||||
|
/*unbusy*/TRUE);
|
||||||
|
|
||||||
|
ahc_outb(ahc, SCB_CONTROL, 0);
|
||||||
|
/* Shift the waiting Q forward. */
|
||||||
|
nextscb = ahc_inb(ahc, SCB_NEXT);
|
||||||
|
ahc_outb(ahc, WAITING_SCBH, nextscb);
|
||||||
|
|
||||||
|
ahc_add_curscb_to_free_list(ahc);
|
||||||
|
}
|
||||||
|
/* Stop the selection */
|
||||||
|
ahc_outb(ahc, SCSISEQ, 0);
|
||||||
|
|
||||||
|
ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE);
|
||||||
|
|
||||||
|
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
||||||
|
|
||||||
|
restart_sequencer(ahc);
|
||||||
} else if (scb == NULL) {
|
} else if (scb == NULL) {
|
||||||
printf("%s: ahc_intr - referenced scb not "
|
printf("%s: ahc_intr - referenced scb not "
|
||||||
"valid during scsiint 0x%x scb(%d)\n"
|
"valid during scsiint 0x%x scb(%d)\n"
|
||||||
@ -1741,43 +1792,6 @@ ahc_handle_scsiint(ahc, intstat)
|
|||||||
ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
|
ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
|
||||||
unpause_sequencer(ahc, /*unpause_always*/TRUE);
|
unpause_sequencer(ahc, /*unpause_always*/TRUE);
|
||||||
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
||||||
} else if ((status & SELTO) != 0) {
|
|
||||||
struct scsi_xfer *xs;
|
|
||||||
u_int8_t scbptr;
|
|
||||||
u_int8_t nextscb;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX If we queued an abort tag, go clean up the
|
|
||||||
* disconnected list.
|
|
||||||
*/
|
|
||||||
xs = scb->xs;
|
|
||||||
xs->error = XS_SELTIMEOUT;
|
|
||||||
/*
|
|
||||||
* Clear any pending messages for the timed out
|
|
||||||
* target, and mark the target as free
|
|
||||||
*/
|
|
||||||
ahc_outb(ahc, MSG_LEN, 0);
|
|
||||||
ahc_index_busy_target(ahc, xs->sc_link->target,
|
|
||||||
IS_SCSIBUS_B(ahc, xs->sc_link) ? 'B' : 'A',
|
|
||||||
/*unbusy*/TRUE);
|
|
||||||
/* Stop the selection */
|
|
||||||
ahc_outb(ahc, SCSISEQ, 0);
|
|
||||||
|
|
||||||
ahc_outb(ahc, SCB_CONTROL, 0);
|
|
||||||
|
|
||||||
ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE);
|
|
||||||
|
|
||||||
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
|
||||||
|
|
||||||
/* Shift the waiting Q forward. */
|
|
||||||
scbptr = ahc_inb(ahc, WAITING_SCBH);
|
|
||||||
ahc_outb(ahc, SCBPTR, scbptr);
|
|
||||||
nextscb = ahc_inb(ahc, SCB_NEXT);
|
|
||||||
ahc_outb(ahc, WAITING_SCBH, nextscb);
|
|
||||||
|
|
||||||
ahc_add_curscb_to_free_list(ahc);
|
|
||||||
|
|
||||||
restart_sequencer(ahc);
|
|
||||||
} else {
|
} else {
|
||||||
sc_print_addr(scb->xs->sc_link);
|
sc_print_addr(scb->xs->sc_link);
|
||||||
printf("Unknown SCSIINT. Status = 0x%x\n", status);
|
printf("Unknown SCSIINT. Status = 0x%x\n", status);
|
||||||
|
Loading…
Reference in New Issue
Block a user