diff options
author | dufault <dufault@FreeBSD.org> | 1995-01-08 13:41:28 +0000 |
---|---|---|
committer | dufault <dufault@FreeBSD.org> | 1995-01-08 13:41:28 +0000 |
commit | 01d7a8c613070df9d41e6216af8233cbcda8cec9 (patch) | |
tree | eb9ae488dee60af04db197b19d219c297a1a414d | |
parent | cb06d663a26438b386b770a277879a540e31e0a9 (diff) | |
download | FreeBSD-src-01d7a8c613070df9d41e6216af8233cbcda8cec9.zip FreeBSD-src-01d7a8c613070df9d41e6216af8233cbcda8cec9.tar.gz |
Added residual length for 1542C only
-rw-r--r-- | sys/i386/isa/aha1542.c | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/sys/i386/isa/aha1542.c b/sys/i386/isa/aha1542.c index a09b4ee..d907f27 100644 --- a/sys/i386/isa/aha1542.c +++ b/sys/i386/isa/aha1542.c @@ -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 */ |