From owner-svn-src-stable-11@freebsd.org Mon Apr 24 10:19:27 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E26D8D4D342; Mon, 24 Apr 2017 10:19:27 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AAAB7ABA; Mon, 24 Apr 2017 10:19:27 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3OAJQmA001744; Mon, 24 Apr 2017 10:19:26 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3OAJQAF001739; Mon, 24 Apr 2017 10:19:26 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201704241019.v3OAJQAF001739@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Mon, 24 Apr 2017 10:19:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r317357 - stable/11/sys/dev/isp X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Apr 2017 10:19:28 -0000 Author: mav Date: Mon Apr 24 10:19:26 2017 New Revision: 317357 URL: https://svnweb.freebsd.org/changeset/base/317357 Log: MFC r315708: Cleanup response queue processing. Modified: stable/11/sys/dev/isp/isp.c stable/11/sys/dev/isp/isp_freebsd.c stable/11/sys/dev/isp/isp_freebsd.h stable/11/sys/dev/isp/ispvar.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/isp/isp.c ============================================================================== --- stable/11/sys/dev/isp/isp.c Mon Apr 24 10:16:12 2017 (r317356) +++ stable/11/sys/dev/isp/isp.c Mon Apr 24 10:19:26 2017 (r317357) @@ -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 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) { - 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) { @@ -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 *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: @@ -6345,7 +6198,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: stable/11/sys/dev/isp/isp_freebsd.c ============================================================================== --- stable/11/sys/dev/isp/isp_freebsd.c Mon Apr 24 10:16:12 2017 (r317356) +++ stable/11/sys/dev/isp/isp_freebsd.c Mon Apr 24 10:19:26 2017 (r317357) @@ -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: stable/11/sys/dev/isp/isp_freebsd.h ============================================================================== --- stable/11/sys/dev/isp/isp_freebsd.h Mon Apr 24 10:16:12 2017 (r317356) +++ stable/11/sys/dev/isp/isp_freebsd.h Mon Apr 24 10:19:26 2017 (r317357) @@ -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: stable/11/sys/dev/isp/ispvar.h ============================================================================== --- stable/11/sys/dev/isp/ispvar.h Mon Apr 24 10:16:12 2017 (r317356) +++ stable/11/sys/dev/isp/ispvar.h Mon Apr 24 10:19:26 2017 (r317357) @@ -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