Author: mav
Date: Mon Apr 24 11:19:47 2017
New Revision: 317363
URL: https://svnweb.freebsd.org/changeset/base/317363

Log:
  MFC r315708: Cleanup response queue processing.

Modified:
  stable/10/sys/dev/isp/isp.c
  stable/10/sys/dev/isp/isp_freebsd.c
  stable/10/sys/dev/isp/isp_freebsd.h
  stable/10/sys/dev/isp/ispvar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c Mon Apr 24 11:12:03 2017        (r317362)
+++ stable/10/sys/dev/isp/isp.c Mon Apr 24 11:19:47 2017        (r317363)
@@ -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/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c Mon Apr 24 11:12:03 2017        
(r317362)
+++ stable/10/sys/dev/isp/isp_freebsd.c Mon Apr 24 11:19:47 2017        
(r317363)
@@ -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/10/sys/dev/isp/isp_freebsd.h
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.h Mon Apr 24 11:12:03 2017        
(r317362)
+++ stable/10/sys/dev/isp/isp_freebsd.h Mon Apr 24 11:19:47 2017        
(r317363)
@@ -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/10/sys/dev/isp/ispvar.h
==============================================================================
--- stable/10/sys/dev/isp/ispvar.h      Mon Apr 24 11:12:03 2017        
(r317362)
+++ stable/10/sys/dev/isp/ispvar.h      Mon Apr 24 11:19:47 2017        
(r317363)
@@ -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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to