summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2001-04-04 21:53:59 +0000
committermjacob <mjacob@FreeBSD.org>2001-04-04 21:53:59 +0000
commitacc5f5724452f51201c3b23eeb949ccd8bca5ea2 (patch)
treeab1de478273c089dae243e662837b8c7819d231b /sys/dev/isp
parent233d363dbc6792e53ac4abf96dfcddb5c70dc00d (diff)
downloadFreeBSD-src-acc5f5724452f51201c3b23eeb949ccd8bca5ea2.zip
FreeBSD-src-acc5f5724452f51201c3b23eeb949ccd8bca5ea2.tar.gz
Complete some Ansification. Check to make sure, in tdma_mk, that we won't
overflow the request queue. The reason we want to do this is that we now push out completed CTIOs as we complete them- this gets the QLogic working on them quicker. So we need to know whether we can put the entire burrito out before we start. We now support conjoint status with data for the last CTIO for both Fibre Channel and SCSI. Leave the old code in place in case we need to go back (minor 3 line ifdef). Ultra-ultra important- *don't* set rq->req_seg_count for non-data target mode requests in isp_pci_dmasetup. D'oh- this is actually the tag value area for a CTIO. What *was* I thinking? Boy howdy does both aic7xxx and sym get awfully unhappy when on reconnect you give them a constant '1' for a tag value.
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp_pci.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 0064a1f..d16b111 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1021,8 +1021,10 @@ typedef struct {
* mapped and a pointer to a partially filled in already allocated request
* queue entry. We finish the job.
*/
-static void tdma_mk __P((void *, bus_dma_segment_t *, int, int));
-static void tdma_mkfc __P((void *, bus_dma_segment_t *, int, int));
+static void tdma_mk(void *, bus_dma_segment_t *, int, int);
+static void tdma_mkfc(void *, bus_dma_segment_t *, int, int);
+
+#define STATUS_WITH_DATA 1
static void
tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
@@ -1037,6 +1039,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
u_int32_t totxfr, sflags;
int nctios, send_status;
int32_t resid;
+ int i, j;
mp = (mush_t *) arg;
if (error) {
@@ -1053,12 +1056,12 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
if (nseg == 0) {
cto->ct_header.rqs_seqno = 1;
- ISP_TDQE(mp->isp, "tdma_mk[no data]", *mp->iptrp, cto);
isp_prt(mp->isp, ISP_LOGTDEBUG1,
- "CTIO[%x] lun%d->iid%d flgs 0x%x sts 0x%x ssts 0x%x res %d",
+ "CTIO[%x] lun%d iid%d tag %x flgs %x sts %x ssts %x res %d",
cto->ct_fwhandle, csio->ccb_h.target_lun, cto->ct_iid,
- cto->ct_flags, cto->ct_status, cto->ct_scsi_status,
- cto->ct_resid);
+ cto->ct_tag_val, cto->ct_flags, cto->ct_status,
+ cto->ct_scsi_status, cto->ct_resid);
+ ISP_TDQE(mp->isp, "tdma_mk[no data]", *mp->iptrp, cto);
ISP_SWIZ_CTIO(mp->isp, cto, cto);
return;
}
@@ -1069,6 +1072,19 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
/*
+ * Check to see that we don't overflow.
+ */
+ for (i = 0, j = *mp->iptrp; i < nctios; i++) {
+ j = ISP_NXT_QENTRY(j, RQUEST_QUEUE_LEN(isp));
+ if (j == mp->optr) {
+ isp_prt(mp->isp, ISP_LOGWARN,
+ "Request Queue Overflow [tdma_mk]");
+ mp->error = MUSHERR_NOQENTRIES;
+ return;
+ }
+ }
+
+ /*
* Save syshandle, and potentially any SCSI status, which we'll
* reinsert on the last CTIO we're going to send.
*/
@@ -1090,8 +1106,8 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*/
scsi_status = cto->ct_scsi_status;
-#if 0
- sflags |= CT_NODATA;
+#ifndef STATUS_WITH_DATA
+ sflags |= CT_NO_DATA;
/*
* We can't do a status at the same time as a data CTIO, so
* we need to synthesize an extra CTIO at this level.
@@ -1165,7 +1181,8 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
* this CTIO and save the handle to the CCB such that
* when this CTIO completes we can free dma resources
* and do whatever else we need to do to finish the
- * rest of the command.
+ * rest of the command. We *don't* give this to the
+ * firmware to work on- the caller will do that.
*/
cto->ct_syshandle = handle;
cto->ct_header.rqs_seqno = 1;
@@ -1177,16 +1194,17 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
}
if (send_status) {
isp_prt(mp->isp, ISP_LOGTDEBUG1,
- "CTIO[%x] lun%d for ID %d ct_flags 0x%x "
+ "CTIO[%x] lun%d iid %d tag %x ct_flags %x "
"scsi status %x resid %d",
cto->ct_fwhandle, csio->ccb_h.target_lun,
- cto->ct_iid, cto->ct_flags,
+ cto->ct_iid, cto->ct_tag_val, cto->ct_flags,
cto->ct_scsi_status, cto->ct_resid);
} else {
isp_prt(mp->isp, ISP_LOGTDEBUG1,
- "CTIO[%x] lun%d for ID%d ct_flags 0x%x",
+ "CTIO[%x] lun%d iid%d tag %x ct_flags 0x%x",
cto->ct_fwhandle, csio->ccb_h.target_lun,
- cto->ct_iid, cto->ct_flags);
+ cto->ct_iid, cto->ct_tag_val,
+ cto->ct_flags);
}
ISP_TDQE(mp->isp, "last tdma_mk", *mp->iptrp, cto);
ISP_SWIZ_CTIO(mp->isp, cto, cto);
@@ -1210,6 +1228,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*/
cto = (ct_entry_t *)
ISP_QUEUE_ENTRY(mp->isp->isp_rquest, *mp->iptrp);
+ j = *mp->iptrp;
*mp->iptrp =
ISP_NXT_QENTRY(*mp->iptrp, RQUEST_QUEUE_LEN(isp));
if (*mp->iptrp == mp->optr) {
@@ -1240,10 +1259,12 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
cto->ct_seg_count = 0;
MEMZERO(cto->ct_dataseg, sizeof(cto->ct_dataseg));
/*
- * Now swizzle the old one for the consumption of the
- * chip.
+ * Now swizzle the old one for the consumption
+ * of the chip and give it to the firmware to
+ * work on while we do the next.
*/
ISP_SWIZ_CTIO(mp->isp, octo, octo);
+ ISP_ADD_REQUEST(mp->isp, j);
}
}
}
@@ -1685,11 +1706,10 @@ isp_pci_dmasetup(struct ispsoftc *isp, struct ccb_scsiio *csio, ispreq_t *rq,
}
if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE ||
(csio->dxfer_len == 0)) {
- rq->req_seg_count = 1;
mp = &mush;
mp->isp = isp;
mp->cmd_token = csio;
- mp->rq = rq;
+ mp->rq = rq; /* really a ct_entry_t or ct2_entry_t */
mp->iptrp = iptrp;
mp->optr = optr;
mp->error = 0;
OpenPOWER on IntegriCloud