Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Mar 2017 08:56:03 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r315708 - head/sys/dev/isp
Message-ID:  <201703220856.v2M8u3VD011080@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Mar 22 08:56:03 2017
New Revision: 315708
URL: https://svnweb.freebsd.org/changeset/base/315708

Log:
  Cleanup response queue processing.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/isp/isp.c
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_freebsd.h
  head/sys/dev/isp/ispvar.h

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c	Wed Mar 22 08:55:32 2017	(r315707)
+++ head/sys/dev/isp/isp.c	Wed Mar 22 08:56:03 2017	(r315708)
@@ -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);
@@ -4970,21 +4970,18 @@ isp_intr_mbox(ispsoftc_t *isp, uint16_t 
 	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.
@@ -5006,38 +5003,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
@@ -5057,79 +5046,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) {
-				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
-				last_etype = etype;
-				continue;
-			}
-
-			/*
-			 * 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);
+		} 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);
 			}
-			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) {
@@ -5140,23 +5102,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;
 			}
 		}
@@ -5174,7 +5135,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) {
@@ -5189,13 +5149,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;
@@ -5208,203 +5166,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;
 	}
 }
 
@@ -5989,34 +5859,17 @@ isp_handle_other_response(ispsoftc_t *is
 	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:
@@ -6344,7 +6197,7 @@ isp_parse_status(ispsoftc_t *isp, ispsta
 }
 
 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);

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Wed Mar 22 08:55:32 2017	(r315707)
+++ head/sys/dev/isp/isp_freebsd.c	Wed Mar 22 08:56:03 2017	(r315708)
@@ -731,8 +731,6 @@ isp_free_pcmd(ispsoftc_t *isp, union 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) {

Modified: head/sys/dev/isp/isp_freebsd.h
==============================================================================
--- head/sys/dev/isp/isp_freebsd.h	Wed Mar 22 08:55:32 2017	(r315707)
+++ head/sys/dev/isp/isp_freebsd.h	Wed Mar 22 08:56:03 2017	(r315708)
@@ -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)

Modified: head/sys/dev/isp/ispvar.h
==============================================================================
--- head/sys/dev/isp/ispvar.h	Wed Mar 22 08:55:32 2017	(r315707)
+++ head/sys/dev/isp/ispvar.h	Wed Mar 22 08:56:03 2017	(r315708)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703220856.v2M8u3VD011080>