Added residual length for 1542C only

This commit is contained in:
dufault 1995-01-08 13:41:28 +00:00
parent cb06d663a2
commit 01d7a8c613

View File

@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* $Id: aha1542.c,v 1.37 1994/10/19 01:58:50 wollman Exp $
* $Id: aha1542.c,v 1.38 1994/10/23 21:27:04 wollman Exp $
*/
/*
@ -193,6 +193,24 @@ struct aha_ccb {
#define AHA_INIT_SCAT_GATH_CCB 0x02 /* SCSI Initiator with scatter gather */
#define AHA_RESET_CCB 0x81 /* SCSI Bus reset */
#define AHA_INIT_RESID_CCB 0x03 /* SCSI Initiator CCB */
#define AHA_INIT_SG_RESID_CCB 0x04 /* SCSI initiator with scatter gather */
/* Which CCBs to use. If you use the "RESID" ones then the
* host adapter will return the DATA OVER/UNDERRUN condition
* on short reads and writes.
*
* This apparently FAILS on old 1542s. Perhaps we can auto configure
* it somehow using an inquiry for a long string?
*/
#if 1
#define INITIATOR_CCB AHA_INIT_RESID_CCB
#define INIT_SCAT_GATH_CCB AHA_INIT_SG_RESID_CCB
#else
#define INITIATOR_CCB AHA_INITIATOR_CCB
#define INIT_SCAT_GATH_CCB AHA_INIT_SCAT_GATH_CCB
#endif
/*
* aha_ccb.host_stat values
*/
@ -800,6 +818,9 @@ aha_done(unit, ccb)
printf("aha%d: exiting but not in use!\n", unit);
Debugger("aha1542");
}
xs->status = ccb->target_stat;
xs->resid = 0;
if (((ccb->host_stat != AHA_OK) || (ccb->target_stat != SCSI_OK))
&& ((xs->flags & SCSI_ERR_OK) == 0)) {
/*
@ -817,6 +838,31 @@ aha_done(unit, ccb)
case AHA_SEL_TIMEOUT: /* No response */
xs->error = XS_TIMEOUT;
break;
case AHA_OVER_UNDER: /* Over run / under run */
switch(ccb->opcode)
{
case AHA_TARGET_CCB:
xs->resid = xs->datalen - _3btol(ccb->data_length);
if (xs->resid <= 0)
xs->error = XS_LENGTH;
break;
case AHA_INIT_RESID_CCB:
case AHA_INIT_SG_RESID_CCB:
xs->resid = _3btol(ccb->data_length);
if (xs->resid <= 0)
xs->error = XS_LENGTH;
printf("aha over under: resid %d error %d.\n",
xs->resid, xs->error);
break;
default:
xs->error = XS_LENGTH;
}
break;
default: /* Other scsi protocol messes */
xs->error = XS_DRIVER_STUFFUP;
printf("aha%d:host_stat%x\n",
@ -840,10 +886,8 @@ aha_done(unit, ccb)
xs->error = XS_DRIVER_STUFFUP;
}
}
} else {
/* All went correctly OR errors expected */
xs->resid = 0;
}
xs->flags |= ITSDONE;
aha_free_ccb(unit, ccb, xs->flags);
scsi_done(xs);
@ -1108,7 +1152,8 @@ aha_scsi_cmd(xs)
return (TRY_AGAIN_LATER);
}
if (ccb->mbx->cmd != AHA_MBO_FREE)
printf("aha%d: MBO not free\n", unit);
printf("aha%d: MBO %02x and not %02x (free)\n",
unit, ccb->mbx->cmd, AHA_MBO_FREE);
/*
* Put all the arguments for the xfer in the ccb
@ -1119,15 +1164,23 @@ aha_scsi_cmd(xs)
} else {
/* can't use S/G if zero length */
ccb->opcode = (xs->datalen ?
AHA_INIT_SCAT_GATH_CCB
: AHA_INITIATOR_CCB);
INIT_SCAT_GATH_CCB
: INITIATOR_CCB);
}
ccb->target = sc_link->target;
ccb->data_out = 0;
ccb->data_in = 0;
ccb->lun = sc_link->lun;
ccb->scsi_cmd_length = xs->cmdlen;
ccb->req_sense_length = sizeof(ccb->scsi_sense);
/* Some devices (e.g, Microtek ScanMaker II)
* fall on the ground if you ask for anything but
* an exact number of sense bytes (wiping out the
* sense data)
*/
ccb->req_sense_length = (xs->req_sense_length)
? xs->req_sense_length
: sizeof(ccb->scsi_sense);
if ((xs->datalen) && (!(flags & SCSI_RESET))) {
/* can use S/G only if not zero length */