summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordufault <dufault@FreeBSD.org>1995-01-08 13:41:28 +0000
committerdufault <dufault@FreeBSD.org>1995-01-08 13:41:28 +0000
commit01d7a8c613070df9d41e6216af8233cbcda8cec9 (patch)
treeeb9ae488dee60af04db197b19d219c297a1a414d
parentcb06d663a26438b386b770a277879a540e31e0a9 (diff)
downloadFreeBSD-src-01d7a8c613070df9d41e6216af8233cbcda8cec9.zip
FreeBSD-src-01d7a8c613070df9d41e6216af8233cbcda8cec9.tar.gz
Added residual length for 1542C only
-rw-r--r--sys/i386/isa/aha1542.c69
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 */
OpenPOWER on IntegriCloud