summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-04-24 10:19:26 +0000
committermav <mav@FreeBSD.org>2017-04-24 10:19:26 +0000
commit61bb50f29c391954c63bc5394acc7a63fe4cd816 (patch)
tree8c429085c0d4f47e7cfc2d6a15b593f0d75cf49f
parentf36a0be961e835af2feb682ac43d13f1d081b964 (diff)
downloadFreeBSD-src-61bb50f29c391954c63bc5394acc7a63fe4cd816.zip
FreeBSD-src-61bb50f29c391954c63bc5394acc7a63fe4cd816.tar.gz
MFC r315708: Cleanup response queue processing.
-rw-r--r--sys/dev/isp/isp.c429
-rw-r--r--sys/dev/isp/isp_freebsd.c3
-rw-r--r--sys/dev/isp/isp_freebsd.h31
-rw-r--r--sys/dev/isp/ispvar.h8
4 files changed, 153 insertions, 318 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 4435d53..f46656b 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
/*
* Local static data
*/
-static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
+static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
static const char lipd[] = "Chan %d LIP destroyed %d active commands";
static const char sacq[] = "unable to acquire scratch area";
@@ -98,8 +98,8 @@ static const uint8_t alpa_map[] = {
static void isp_parse_async(ispsoftc_t *, uint16_t);
static void isp_parse_async_fc(ispsoftc_t *, uint16_t);
static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
-static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
-static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
+static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, uint32_t *);
+static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, uint32_t *);
static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
static void isp_scsi_init(ispsoftc_t *);
static void isp_scsi_channel_init(ispsoftc_t *, int);
@@ -4971,21 +4971,18 @@ isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
MBOX_NOTIFY_COMPLETE(isp);
}
-/*
- * Limit our stack depth by sticking with the max likely number
- * of completions on a request queue at any one time.
- */
-#ifndef MAX_REQUESTQ_COMPLETIONS
-#define MAX_REQUESTQ_COMPLETIONS 32
-#endif
-
void
isp_intr_respq(ispsoftc_t *isp)
{
- XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
- uint32_t iptr, optr, junk;
- int i, nlooked = 0, ndone = 0, continuations_expected = 0;
- int etype, last_etype = 0;
+ XS_T *xs, *cont_xs;
+ uint8_t qe[QENTRY_LEN];
+ ispstatusreq_t *sp = (ispstatusreq_t *)qe;
+ isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
+ isphdr_t *hp;
+ uint8_t *resp, *snsp;
+ int buddaboom, completion_status, cont = 0, etype, i;
+ int req_status_flags, req_state_flags, scsi_status;
+ uint32_t iptr, junk, cptr, optr, rlen, slen, sptr, totslen, resid;
/*
* We can't be getting this now.
@@ -5007,38 +5004,30 @@ isp_intr_respq(ispsoftc_t *isp)
optr = isp->isp_resodx;
while (optr != iptr) {
- uint8_t qe[QENTRY_LEN];
- ispstatusreq_t *sp = (ispstatusreq_t *) qe;
- isphdr_t *hp;
- int buddaboom, scsi_status, completion_status;
- int req_status_flags, req_state_flags;
- uint8_t *snsp, *resp;
- uint32_t rlen, slen, totslen;
- long resid;
- uint16_t oop;
-
- hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
- oop = optr;
+ sptr = cptr = optr;
+ hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
- nlooked++;
- read_again:
- buddaboom = req_status_flags = req_state_flags = 0;
- resid = 0L;
/*
* Synchronize our view of this response queue entry.
*/
- MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
+ MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
if (isp->isp_dblev & ISP_LOGDEBUG1)
- isp_print_qentry(isp, "Response Queue Entry", oop, hp);
+ isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
isp_get_hdr(isp, hp, &sp->req_header);
etype = sp->req_header.rqs_entry_type;
+ /* We expected Status Continuation, but got different IOCB. */
+ if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
+ cont = 0;
+ isp_done(cont_xs);
+ }
+
if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
- isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
scsi_status = sp2->req_scsi_status;
completion_status = sp2->req_completion_status;
+ req_status_flags = 0;
if ((scsi_status & 0xff) != 0)
req_state_flags = RQSF_GOT_STATUS;
else
@@ -5058,79 +5047,52 @@ isp_intr_respq(ispsoftc_t *isp)
isp_fastpost_complete(isp, rio->req_handles[i]);
}
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
continue;
} else if (etype == RQSTYPE_RIO2) {
isp_prt(isp, ISP_LOGERR, "dropping RIO2 response");
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
continue;
} else if (etype == RQSTYPE_STATUS_CONT) {
- isp_get_cont_response(isp, (ispstatus_cont_t *) hp, (ispstatus_cont_t *) sp);
- if (last_etype == RQSTYPE_RESPONSE && continuations_expected && ndone > 0 && (xs = complist[ndone-1]) != NULL) {
- ispstatus_cont_t *scp = (ispstatus_cont_t *) sp;
- XS_SENSE_APPEND(xs, scp->req_sense_data, sizeof (scp->req_sense_data));
- isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, "%d more Status Continuations expected", --continuations_expected);
+ ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
+ isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
+ if (cont > 0) {
+ i = min(cont, sizeof(scp->req_sense_data));
+ XS_SENSE_APPEND(cont_xs, scp->req_sense_data, i);
+ cont -= i;
+ if (cont == 0) {
+ isp_done(cont_xs);
+ } else {
+ isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
+ "Expecting Status Continuations for %u bytes",
+ cont);
+ }
} else {
isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
}
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
continue;
- } else {
- /*
- * Somebody reachable via isp_handle_other_response
- * may have updated the response queue pointers for
- * us, so we reload our goal index.
- */
- int r;
- uint32_t tsto = oop;
- r = isp_handle_other_response(isp, etype, hp, &tsto);
- if (r < 0) {
- goto read_again;
- }
- /*
- * If somebody updated the output pointer, then reset
- * optr to be one more than the updated amount.
- */
- while (tsto != oop) {
- optr = ISP_NXT_QENTRY(tsto, RESULT_QUEUE_LEN(isp));
- }
- if (r > 0) {
+ } else if (isp_handle_other_response(isp, etype, hp, &cptr)) {
+ /* More then one IOCB could be consumed. */
+ while (sptr != cptr) {
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
- continue;
+ sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
+ hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
}
-
- /*
- * After this point, we'll just look at the header as
- * we don't know how to deal with the rest of the
- * response.
- */
-
- /*
- * It really has to be a bounced request just copied
- * from the request queue to the response queue. If
- * not, something bad has happened.
- */
- if (etype != RQSTYPE_REQUEST) {
- isp_prt(isp, ISP_LOGERR, notresp, etype, oop, optr, nlooked);
- ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
- continue;
- }
- buddaboom = 1;
- scsi_status = sp->req_scsi_status;
- completion_status = sp->req_completion_status;
- req_status_flags = sp->req_status_flags;
- req_state_flags = sp->req_state_flags;
- resid = sp->req_resid;
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
+ optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
+ continue;
+ } else {
+ /* We don't know what was this -- log and skip. */
+ isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
+ ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
+ continue;
}
+ buddaboom = 0;
if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
isp_print_qentry(isp, "unexpected continuation segment",
- oop, hp);
- last_etype = etype;
+ cptr, hp);
continue;
}
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
@@ -5141,23 +5103,22 @@ isp_intr_respq(ispsoftc_t *isp)
}
if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
isp_print_qentry(isp, "bad header flag",
- oop, hp);
+ cptr, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
isp_print_qentry(isp, "bad request packet",
- oop, hp);
+ cptr, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
isp_print_qentry(isp, "invalid entry count",
- oop, hp);
+ cptr, hp);
buddaboom++;
}
if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
isp_print_qentry(isp, "invalid IOCB ordering",
- oop, hp);
- last_etype = etype;
+ cptr, hp);
continue;
}
}
@@ -5175,7 +5136,6 @@ isp_intr_respq(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
}
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
continue;
}
if (req_status_flags & RQSTF_BUS_RESET) {
@@ -5190,13 +5150,11 @@ isp_intr_respq(ispsoftc_t *isp)
XS_SETERR(xs, HBA_BOTCH);
}
- resp = NULL;
- rlen = 0;
- snsp = NULL;
- totslen = slen = 0;
+ resp = snsp = NULL;
+ rlen = slen = totslen = 0;
if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
- resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
- rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
+ resp = sp2->req_rsp_sense;
+ rlen = sp2->req_response_len;
} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
resp = sp->req_response;
rlen = sp->req_response_len;
@@ -5209,203 +5167,115 @@ isp_intr_respq(ispsoftc_t *isp)
*/
req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
if (IS_24XX(isp)) {
- snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
+ snsp = sp2->req_rsp_sense;
snsp += rlen;
- totslen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
- slen = (sizeof (((isp24xx_statusreq_t *)sp)->req_rsp_sense)) - rlen;
- if (totslen < slen)
- slen = totslen;
+ totslen = sp2->req_sense_len;
+ slen = sizeof(sp2->req_rsp_sense) - rlen;
} else {
snsp = sp->req_sense_data;
totslen = sp->req_sense_len;
- slen = sizeof (sp->req_sense_data);
- if (totslen < slen)
- slen = totslen;
+ slen = sizeof(sp->req_sense_data);
}
} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
snsp = sp->req_sense_data;
totslen = sp->req_sense_len;
slen = sizeof (sp->req_sense_data);
- if (totslen < slen)
- slen = totslen;
}
- if (req_state_flags & RQSF_GOT_STATUS) {
+ if (slen > totslen)
+ slen = totslen;
+ if (req_state_flags & RQSF_GOT_STATUS)
*XS_STSP(xs) = scsi_status & 0xff;
- }
- switch (etype) {
- case RQSTYPE_RESPONSE:
- if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
- const char *ptr;
- char lb[64];
- const char *rnames[10] = {
- "Task Management function complete",
- "FCP_DATA length different than FCP_BURST_LEN",
- "FCP_CMND fields invalid",
- "FCP_DATA parameter mismatch with FCP_DATA_RO",
- "Task Management function rejected",
- "Task Management function failed",
- NULL,
- NULL,
- "Task Management function succeeded",
- "Task Management function incorrect logical unit number",
- };
- uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
- if (code >= 10 || rnames[code] == NULL) {
- ISP_SNPRINTF(lb, sizeof(lb),
- "Unknown FCP Response Code 0x%x",
- code);
- ptr = lb;
- } else {
- ptr = rnames[code];
- }
- isp_xs_prt(isp, xs, ISP_LOGWARN,
- "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
- rlen, ptr, XS_CDBP(xs)[0] & 0xff);
- if (code != 0 && code != 8)
- XS_SETERR(xs, HBA_BOTCH);
- }
- if (IS_24XX(isp)) {
- isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
+ if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
+ const char *ptr;
+ char lb[64];
+ const char *rnames[10] = {
+ "Task Management function complete",
+ "FCP_DATA length different than FCP_BURST_LEN",
+ "FCP_CMND fields invalid",
+ "FCP_DATA parameter mismatch with FCP_DATA_RO",
+ "Task Management function rejected",
+ "Task Management function failed",
+ NULL,
+ NULL,
+ "Task Management function succeeded",
+ "Task Management function incorrect logical unit number",
+ };
+ uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
+ if (code >= 10 || rnames[code] == NULL) {
+ ISP_SNPRINTF(lb, sizeof(lb),
+ "Unknown FCP Response Code 0x%x", code);
+ ptr = lb;
} else {
- isp_parse_status(isp, (void *)sp, xs, &resid);
+ ptr = rnames[code];
}
- if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
- XS_SETERR(xs, HBA_TGTBSY);
+ isp_xs_prt(isp, xs, ISP_LOGWARN,
+ "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
+ rlen, ptr, XS_CDBP(xs)[0] & 0xff);
+ if (code != 0 && code != 8)
+ XS_SETERR(xs, HBA_BOTCH);
+ }
+ if (IS_24XX(isp))
+ isp_parse_status_24xx(isp, sp2, xs, &resid);
+ else
+ isp_parse_status(isp, sp, xs, &resid);
+ if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
+ (*XS_STSP(xs) == SCSI_BUSY))
+ XS_SETERR(xs, HBA_TGTBSY);
+ if (IS_SCSI(isp)) {
+ XS_SET_RESID(xs, resid);
+ /*
+ * A new synchronous rate was negotiated for
+ * this target. Mark state such that we'll go
+ * look up that which has changed later.
+ */
+ if (req_status_flags & RQSTF_NEGOTIATION) {
+ int t = XS_TGT(xs);
+ sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
+ sdp->isp_devparam[t].dev_refresh = 1;
+ sdp->update = 1;
}
- if (IS_SCSI(isp)) {
+ } else {
+ if (req_status_flags & RQSF_XFER_COMPLETE) {
+ XS_SET_RESID(xs, 0);
+ } else if (scsi_status & RQCS_RESID) {
XS_SET_RESID(xs, resid);
- /*
- * A new synchronous rate was negotiated for
- * this target. Mark state such that we'll go
- * look up that which has changed later.
- */
- if (req_status_flags & RQSTF_NEGOTIATION) {
- int t = XS_TGT(xs);
- sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
- sdp->isp_devparam[t].dev_refresh = 1;
- sdp->update = 1;
- }
} else {
- if (req_status_flags & RQSF_XFER_COMPLETE) {
- XS_SET_RESID(xs, 0);
- } else if (scsi_status & RQCS_RESID) {
- XS_SET_RESID(xs, resid);
- } else {
- XS_SET_RESID(xs, 0);
- }
- }
- if (snsp && slen) {
- if (totslen > slen) {
- continuations_expected += ((totslen - slen + QENTRY_LEN - 5) / (QENTRY_LEN - 4));
- if (ndone > (MAX_REQUESTQ_COMPLETIONS - continuations_expected - 1)) {
- /* we'll lose some stats, but that's a small price to pay */
- for (i = 0; i < ndone; i++) {
- if (complist[i])
- isp_done(complist[i]);
- }
- ndone = 0;
- }
- isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, "Expecting %d more Status Continuations for total sense length of %u",
- continuations_expected, totslen);
- }
- XS_SAVE_SENSE(xs, snsp, totslen, slen);
- } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
- isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
- isp_print_qentry(isp, "CC with no Sense",
- oop, hp);
- }
- isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
- break;
- case RQSTYPE_REQUEST:
- case RQSTYPE_A64:
- case RQSTYPE_T2RQS:
- case RQSTYPE_T3RQS:
- case RQSTYPE_T7RQS:
- if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
- /*
- * Force Queue Full status.
- */
- *XS_STSP(xs) = SCSI_QFULL;
- XS_SETERR(xs, HBA_NOERROR);
- } else if (XS_NOERR(xs)) {
- isp_prt(isp, ISP_LOG_WARN1,
- "%d.%d.%jx badness at %s:%u",
- XS_CHANNEL(xs), XS_TGT(xs),
- (uintmax_t)XS_LUN(xs),
- __func__, __LINE__);
- XS_SETERR(xs, HBA_BOTCH);
+ XS_SET_RESID(xs, 0);
}
- XS_SET_RESID(xs, XS_XFRLEN(xs));
- break;
- default:
- isp_print_qentry(isp, "Unhandled Response Type",
- oop, hp);
- if (XS_NOERR(xs)) {
- XS_SETERR(xs, HBA_BOTCH);
+ }
+ if (slen > 0) {
+ XS_SAVE_SENSE(xs, snsp, slen);
+ if (totslen > slen) {
+ cont = totslen - slen;
+ cont_xs = xs;
+ isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
+ "Expecting Status Continuations for %u bytes",
+ cont);
}
- break;
}
+ isp_prt(isp, ISP_LOGDEBUG2, "asked for %lu got raw resid %lu settled for %lu",
+ (u_long)XS_XFRLEN(xs), (u_long)resid, (u_long)XS_GET_RESID(xs));
- /*
- * Free any DMA resources. As a side effect, this may
- * also do any cache flushing necessary for data coherence.
- */
- if (XS_XFRLEN(xs)) {
+ if (XS_XFRLEN(xs))
ISP_DMAFREE(isp, xs, sp->req_handle);
- }
isp_destroy_handle(isp, sp->req_handle);
- complist[ndone++] = xs; /* defer completion call until later */
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
- last_etype = etype;
- if (ndone == MAX_REQUESTQ_COMPLETIONS) {
- break;
- }
- }
-
- /*
- * If we looked at any commands, then it's valid to find out
- * what the outpointer is. It also is a trigger to update the
- * ISP's notion of what we've seen so far.
- */
- if (nlooked) {
- ISP_WRITE(isp, isp->isp_respoutrp, optr);
- isp->isp_resodx = optr;
- }
- for (i = 0; i < ndone; i++) {
- xs = complist[i];
- if (xs) {
- if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
- ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
- isp_prt_endcmd(isp, xs);
- }
+ /* Complete command if we expect no Status Continuations. */
+ if (cont == 0)
isp_done(xs);
- }
}
-}
-
-/*
- * Support routines.
- */
-void
-isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
-{
- char cdbstr[16 * 5 + 1];
- int i, lim;
+ /* We haven't received all Status Continuations, but that is it. */
+ if (cont > 0)
+ isp_done(cont_xs);
- lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
- ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
- for (i = 1; i < lim; i++) {
- ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
- }
- if (XS_SENSE_VALID(xs)) {
- isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s SenseLength=%u/%u KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x",
- XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_CUR_SNSLEN(xs), XS_TOT_SNSLEN(xs), XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs));
- } else {
- isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s STS 0x%x XS_ERR=0x%x", XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, *XS_STSP(xs), XS_ERR(xs));
+ /* If we processed any IOCBs, let ISP know about it. */
+ if (optr != isp->isp_resodx) {
+ ISP_WRITE(isp, isp->isp_respoutrp, optr);
+ isp->isp_resodx = optr;
}
}
@@ -5990,34 +5860,17 @@ isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *opt
case RQSTYPE_ABTS_RCVD:
case RQSTYPE_ABTS_RSP:
#ifdef ISP_TARGET_MODE
- if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp))
- return (1);
+ return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
#endif
/* FALLTHROUGH */
case RQSTYPE_REQUEST:
default:
- ISP_DELAY(100);
- if (type != isp_get_response_type(isp, hp)) {
- /*
- * This is questionable- we're just papering over
- * something we've seen on SMP linux in target
- * mode- we don't really know what's happening
- * here that causes us to think we've gotten
- * an entry, but that either the entry isn't
- * filled out yet or our CPU read data is stale.
- */
- isp_prt(isp, ISP_LOGINFO,
- "unstable type in response queue");
- return (-1);
- }
- isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
- isp_get_response_type(isp, hp));
return (0);
}
}
static void
-isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
+isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, uint32_t *rp)
{
switch (sp->req_completion_status & 0xff) {
case RQCS_COMPLETE:
@@ -6345,7 +6198,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
}
static void
-isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
+isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, uint32_t *rp)
{
int ru_marked, sv_marked;
int chan = XS_CHANNEL(xs);
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 6368ed9..bbaac2f 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -731,8 +731,6 @@ isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
if (ISP_PCMD(ccb)) {
#ifdef ISP_TARGET_MODE
PISP_PCMD(ccb)->datalen = 0;
- PISP_PCMD(ccb)->totslen = 0;
- PISP_PCMD(ccb)->cumslen = 0;
PISP_PCMD(ccb)->crn = 0;
#endif
PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free;
@@ -2581,7 +2579,6 @@ isp_watchdog(void *arg)
isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle);
xs->ccb_h.status &= ~CAM_STATUS_MASK;
xs->ccb_h.status |= CAM_CMD_TIMEOUT;
- isp_prt_endcmd(isp, xs);
isp_done(xs);
} else {
if (ohandle != ISP_HANDLE_FREE) {
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index 16726bb..6c2466d 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -176,8 +176,6 @@ struct isp_pcmd {
struct ispsoftc * isp; /* containing isp */
struct callout wdog; /* watchdog timer */
uint32_t datalen; /* data length for this command (target mode only) */
- uint8_t totslen; /* sense length on status response */
- uint8_t cumslen; /* sense length on status response */
uint8_t crn; /* command reference number */
};
#define ISP_PCMD(ccb) (ccb)->ccb_h.spriv_ptr1
@@ -569,26 +567,19 @@ default: \
#define XS_INITERR(ccb) XS_SETERR(ccb, CAM_REQ_INPROG), ccb->sense_resid = ccb->sense_len
-#define XS_SAVE_SENSE(xs, sense_ptr, totslen, slen) do { \
- uint32_t tlen = slen; \
- if (tlen > (xs)->sense_len) \
- tlen = (xs)->sense_len; \
- PISP_PCMD(xs)->totslen = imin((xs)->sense_len, totslen); \
- PISP_PCMD(xs)->cumslen = tlen; \
- memcpy(&(xs)->sense_data, sense_ptr, tlen); \
- (xs)->sense_resid = (xs)->sense_len - tlen; \
- (xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \
+#define XS_SAVE_SENSE(xs, sp, len) do { \
+ uint32_t amt = min(len, (xs)->sense_len); \
+ memcpy(&(xs)->sense_data, sp, amt); \
+ (xs)->sense_resid = (xs)->sense_len - amt; \
+ (xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \
} while (0)
-#define XS_SENSE_APPEND(xs, xsnsp, xsnsl) do { \
- uint32_t off = PISP_PCMD(xs)->cumslen; \
- uint8_t *ptr = &((uint8_t *)(&(xs)->sense_data))[off]; \
- uint32_t amt = imin(xsnsl, PISP_PCMD(xs)->totslen - off); \
- if (amt) { \
- memcpy(ptr, xsnsp, amt); \
- (xs)->sense_resid -= amt; \
- PISP_PCMD(xs)->cumslen += amt; \
- } \
+#define XS_SENSE_APPEND(xs, sp, len) do { \
+ uint8_t *ptr = (uint8_t *)(&(xs)->sense_data) + \
+ ((xs)->sense_len - (xs)->sense_resid); \
+ uint32_t amt = min((len), (xs)->sense_resid); \
+ memcpy(ptr, sp, amt); \
+ (xs)->sense_resid -= amt; \
} while (0)
#define XS_SENSE_VALID(xs) (((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index e42133c..179c751 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -914,11 +914,6 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
#define ISPASYNC_CHANGE_OTHER 2
/*
- * Platform Independent Error Prinout
- */
-void isp_prt_endcmd(ispsoftc_t *, XS_T *);
-
-/*
* Platform Dependent Error and Debug Printout
*
* Two required functions for each platform must be provided:
@@ -1039,8 +1034,7 @@ void isp_prt_endcmd(ispsoftc_t *, XS_T *);
* XS_NOERR(xs) there is no error currently set
* XS_INITERR(xs) initialize error state
*
- * XS_SAVE_SENSE(xs, sp, total_len, this_len) save sense data (total and current amount)
- *
+ * XS_SAVE_SENSE(xs, sp, len) save sense data
* XS_APPEND_SENSE(xs, sp, len) append more sense data
*
* XS_SENSE_VALID(xs) indicates whether sense is valid
OpenPOWER on IntegriCloud