From cfd36b1a9735334adbe6de6400b3dd85ed6e9f61 Mon Sep 17 00:00:00 2001 From: gibbs Date: Sun, 6 Oct 1996 19:43:36 +0000 Subject: [PATCH] If, during an SDTR negotiation, the target comes back with a response that is too low for the aic7xxx chip to handle with sync transfers, negotiate async transfers. --- sys/i386/scsi/aic7xxx.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c index e4c648a4b977..227e3d037674 100644 --- a/sys/i386/scsi/aic7xxx.c +++ b/sys/i386/scsi/aic7xxx.c @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx.c,v 1.76 1996/10/01 03:01:06 pst Exp $ + * $Id: aic7xxx.c,v 1.77 1996/10/06 16:38:25 gibbs Exp $ */ /* * TODO: @@ -1361,6 +1361,7 @@ ahc_handle_seqint(ahc, intstat) { u_int8_t period; u_int8_t offset; + u_int8_t saved_offset; u_int8_t targ_scratch; u_int8_t maxoffset; u_int8_t rate; @@ -1371,14 +1372,14 @@ ahc_handle_seqint(ahc, intstat) break; } period = AHC_INB(ahc, MSGIN_EXT_BYTE0); - offset = AHC_INB(ahc, MSGIN_EXT_BYTE1); + saved_offset = AHC_INB(ahc, MSGIN_EXT_BYTE1); targ_scratch = AHC_INB(ahc, TARG_SCRATCH + scratch_offset); if (targ_scratch & WIDEXFER) maxoffset = MAX_OFFSET_16BIT; else maxoffset = MAX_OFFSET_8BIT; - offset = MIN(offset, maxoffset); + offset = MIN(saved_offset, maxoffset); ahc_scsirate(ahc, &rate, &period, &offset, channel, target); /* Preserve the WideXfer flag */ @@ -1392,13 +1393,20 @@ ahc_handle_seqint(ahc, intstat) targ_scratch); AHC_OUTB(ahc, SCSIRATE, targ_scratch); - /* See if we initiated Sync Negotiation */ - if (ahc->sdtrpending & targ_mask) { + /* + * See if we initiated Sync Negotiation + * and didn't have to fall down to async + * transfers. + */ + if ((ahc->sdtrpending & targ_mask) != 0 + && (saved_offset == offset)) { /* * Don't send an SDTR back to * the target */ AHC_OUTB(ahc, RETURN_1, 0); + ahc->needsdtr &= ~targ_mask; + ahc->sdtrpending &= ~targ_mask; } else { /* * Send our own SDTR in reply @@ -1410,12 +1418,18 @@ ahc_handle_seqint(ahc, intstat) ahc_construct_sdtr(ahc, /*start_byte*/0, period, offset); AHC_OUTB(ahc, RETURN_1, SEND_MSG); + + /* + * If we aren't starting a re-negotiation + * because we had to go async in response + * to a "too low" response from the target + * clear the needsdtr flag for this target. + */ + if ((ahc->sdtrpending & targ_mask) == 0) + ahc->needsdtr &= ~targ_mask; + else + ahc->sdtrpending |= targ_mask; } - /* - * Negate the flags - */ - ahc->needsdtr &= ~targ_mask; - ahc->sdtrpending &= ~targ_mask; break; } case MSG_EXT_WDTR: