1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-17 15:27:36 +00:00

Keep track of when we actually are awaiting a reply to an SDTR or WDTR

message instead of relying on the fact that we are scheduled to send them.
The old method worked 99.9% of the time, but someone reported some periferals
that did MSG_REJECT at odd times (sometimes before we could send an SDTR
or WDTR) that we would construe as the response to an SDTR or WDTR message.
This also removes a possible race condition where after a bus reset (the
result of a command time out not during intial probe time), we might queue
two commands both requesting SDTR, WDTR or both.
This commit is contained in:
Justin T. Gibbs 1995-02-03 17:15:12 +00:00
parent 4e259174eb
commit cfa2e9e703
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6155
2 changed files with 31 additions and 10 deletions

View File

@ -24,7 +24,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
* $Id: aic7xxx.c,v 1.12 1995/01/22 00:48:39 gibbs Exp $
* $Id: aic7xxx.c,v 1.13 1995/01/27 17:37:05 gibbs Exp $
*/
/*
* TODO:
@ -849,13 +849,14 @@ ahcintr(unit)
outb(HA_TARG_SCRATCH + iobase + scsi_id, rate);
outb(SCSIRATE + iobase, rate);
/* See if we initiated Sync Negotiation */
if(ahc->needsdtr & (0x01 << scsi_id))
if(ahc->sdtrpending & (0x01 << scsi_id))
{
/*
* Negate the flag and don't send
* an SDTR back to the target
*/
ahc->needsdtr &= ~(0x01 << scsi_id);
ahc->sdtrpending &= ~(0x01 << scsi_id);
outb(HA_RETURN_1 + iobase, 0);
}
@ -883,7 +884,7 @@ ahcintr(unit)
scratch = inb(HA_TARG_SCRATCH + iobase
+ scsi_id);
if(ahc->needwdtr & (0x01 << scsi_id))
if(ahc->wdtrpending & (0x01 << scsi_id))
{
/*
* Negate the flag and don't
@ -891,6 +892,7 @@ ahcintr(unit)
* target, since we asked first.
*/
ahc->needwdtr &= ~(0x01 << scsi_id);
ahc->wdtrpending &= ~(0x01 << scsi_id);
outb(HA_RETURN_1 + iobase, 0);
switch(bus_width)
{
@ -957,7 +959,7 @@ ahcintr(unit)
+ scsi_id);
mask = (0x01 << scsi_id);
if(ahc->needwdtr & mask){
if(ahc->wdtrpending & mask){
/* note 8bit xfers and clear flag */
targ_scratch &= 0x7f;
ahc->needwdtr &= ~mask;
@ -966,7 +968,7 @@ ahcintr(unit)
"8bit transfers\n",
unit, scsi_id);
}
else if(ahc->needsdtr & mask){
else if(ahc->sdtrpending & mask){
/* note asynch xfers and clear flag */
targ_scratch &= 0xf0;
ahc->needsdtr &= ~mask;
@ -1443,6 +1445,8 @@ ahc_init(unit)
}
ahc->needsdtr = ahc->needsdtr_orig;
ahc->needwdtr = ahc->needwdtr_orig;
ahc->sdtrpending = 0;
ahc->wdtrpending = 0;
/*
* Set the number of availible SCBs
*/
@ -1452,6 +1456,11 @@ ahc_init(unit)
outb( HA_ACTIVE0 + iobase, 0 );
outb( HA_ACTIVE1 + iobase, 0 );
/* Reset the bus */
outb(SCSISEQ + iobase, SCSIRSTO);
DELAY(500);
outb(SCSISEQ + iobase, 0);
UNPAUSE_SEQUENCER(ahc);
/*
@ -1540,10 +1549,16 @@ ahc_scsi_cmd(xs)
* Put all the arguments for the xfer in the scb
*/
if(ahc->needsdtr & mask)
if((ahc->needsdtr & mask) && !(ahc->sdtrpending & mask))
{
scb->control |= SCB_NEEDSDTR;
if(ahc->needwdtr & mask)
ahc->sdtrpending |= mask;
}
if((ahc->needwdtr & mask) && !(ahc->wdtrpending & mask))
{
scb->control |= SCB_NEEDWDTR;
ahc->wdtrpending |= mask;
}
scb->target_channel_lun = ((xs->sc_link->target << 4) & 0xF0) |
((u_long)xs->sc_link->fordriver & 0x08) |
xs->sc_link->lun & 0x07;
@ -1888,23 +1903,27 @@ ahc_abort_scb( unit, ahc, scb )
u_char flags;
if(scb->target_channel_lun & 0x08){
ahc->needsdtr |= (ahc->needsdtr_orig & 0xff00);
ahc->sdtrpending &= 0x00ff;
outb(HA_ACTIVE1, 0);
}
else if (ahc->type == AHC_274W || ahc->type == AHC_284W
|| ahc->type == AHC_294W){
ahc->needsdtr = ahc->needsdtr_orig;
ahc->needwdtr = ahc->needwdtr_orig;
ahc->sdtrpending = 0;
ahc->wdtrpending = 0;
outb(HA_ACTIVE0, 0);
outb(HA_ACTIVE1, 0);
}
else{
ahc->needsdtr = ahc->needsdtr_orig;
ahc->needsdtr |= (ahc->needsdtr_orig & 0x00ff);
ahc->sdtrpending &= 0xff00;
outb(HA_ACTIVE0, 0);
}
/* Reset the bus */
outb(SCSISEQ + iobase, SCSIRSTO);
DELAY(50);
DELAY(100);
outb(SCSISEQ + iobase, 0);
goto done;
}

View File

@ -20,7 +20,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
* $Id$
* $Id: aic7xxx.h,v 1.2 1995/01/16 16:33:47 gibbs Exp $
*/
#ifndef _AIC7XXX_H_
@ -136,6 +136,8 @@ struct ahc_data {
u_short needwdtr_orig; /* Targets we initiate wide neg with */
u_short needsdtr; /* Current list of negotiated targets */
u_short needwdtr; /* Current list of negotiated targets */
u_short sdtrpending; /* Pending SDTR to these targets */
u_short wdtrpending; /* Pending WDTR to these targets */
int numscbs;
u_char maxscbs;
int unpause;