From owner-svn-src-stable@freebsd.org Mon Mar 6 06:37:48 2017 Return-Path: Delivered-To: svn-src-stable@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 EC15BCF88E0; Mon, 6 Mar 2017 06:37:48 +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 8D7AB1A07; Mon, 6 Mar 2017 06:37:45 +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 v266bi4s000552; Mon, 6 Mar 2017 06:37:44 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v266bi1U000549; Mon, 6 Mar 2017 06:37:44 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201703060637.v266bi1U000549@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Mon, 6 Mar 2017 06:37:44 +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: r314756 - in stable/11/sys: cam/ctl 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@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Mar 2017 06:37:49 -0000 Author: mav Date: Mon Mar 6 06:37:44 2017 New Revision: 314756 URL: https://svnweb.freebsd.org/changeset/base/314756 Log: MFC r314299, r314300: Fix residual length reporting in target mode. This allows to properly handle cases when target wants to receive or send more data then initiator wants to send or receive. Previously in such cases isp(4) returned CAM_DATA_RUN_ERR, while now it returns resid > 0. Modified: stable/11/sys/cam/ctl/scsi_ctl.c stable/11/sys/dev/isp/isp_freebsd.c stable/11/sys/dev/isp/isp_target.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cam/ctl/scsi_ctl.c ============================================================================== --- stable/11/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:36:45 2017 (r314755) +++ stable/11/sys/cam/ctl/scsi_ctl.c Mon Mar 6 06:37:44 2017 (r314756) @@ -1259,7 +1259,8 @@ ctlfedone(struct cam_periph *periph, uni */ switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) { case CAM_REQ_CMP: - io->scsiio.kern_data_resid -= csio->dxfer_len; + io->scsiio.kern_data_resid -= + csio->dxfer_len - csio->resid; io->io_hdr.port_status = 0; break; default: @@ -1286,8 +1287,8 @@ ctlfedone(struct cam_periph *periph, uni * pieces, figure out where we are in the list, and * continue sending pieces if necessary. */ - if ((cmd_info->flags & CTLFE_CMD_PIECEWISE) - && (io->io_hdr.port_status == 0)) { + if ((cmd_info->flags & CTLFE_CMD_PIECEWISE) && + io->io_hdr.port_status == 0 && csio->resid == 0) { ccb_flags flags; uint8_t *data_ptr; uint32_t dxfer_len; Modified: stable/11/sys/dev/isp/isp_freebsd.c ============================================================================== --- stable/11/sys/dev/isp/isp_freebsd.c Mon Mar 6 06:36:45 2017 (r314755) +++ stable/11/sys/dev/isp/isp_freebsd.c Mon Mar 6 06:37:44 2017 (r314756) @@ -1316,13 +1316,24 @@ isp_target_start_ctio(ispsoftc_t *isp, u /* * Check for overflow */ - tmp = atp->bytes_xfered + atp->bytes_in_transit + xfrlen; - if (tmp > atp->orig_datalen) { - isp_prt(isp, ISP_LOGERR, "%s: [0x%x] data overflow by %u bytes", __func__, cso->tag_id, tmp - atp->orig_datalen); + tmp = atp->bytes_xfered + atp->bytes_in_transit; + if (xfrlen > 0 && tmp > atp->orig_datalen) { + isp_prt(isp, ISP_LOGERR, + "%s: [0x%x] data overflow by %u bytes", __func__, + cso->tag_id, tmp + xfrlen - atp->orig_datalen); ccb->ccb_h.status = CAM_DATA_RUN_ERR; xpt_done(ccb); continue; } + if (xfrlen > atp->orig_datalen - tmp) { + xfrlen = atp->orig_datalen - tmp; + if (xfrlen == 0 && !sendstatus) { + cso->resid = cso->dxfer_len; + ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + continue; + } + } if (IS_24XX(isp)) { ct7_entry_t *cto = (ct7_entry_t *) local; @@ -1352,16 +1363,13 @@ isp_target_start_ctio(ispsoftc_t *isp, u cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA; resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; if (sense_length <= MAXRESPLEN_24XX) { - if (resid < 0) { - cto->ct_resid = -resid; - } else if (resid > 0) { - cto->ct_resid = resid; - } cto->ct_flags |= CT7_FLAG_MODE1; cto->ct_scsi_status = cso->scsi_status; if (resid < 0) { + cto->ct_resid = -resid; cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); } else if (resid > 0) { + cto->ct_resid = resid; cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); } if (fctape) { @@ -2238,10 +2246,10 @@ static void isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) { union ccb *ccb; - int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0; + int sentstatus = 0, ok = 0, notify_cam = 0, failure = 0; atio_private_data_t *atp = NULL; int bus; - uint32_t handle, moved_data = 0, data_requested; + uint32_t handle, data_requested, resid; handle = ((ct2_entry_t *)arg)->ct_syshandle; ccb = isp_find_xs(isp, handle); @@ -2250,7 +2258,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp return; } isp_destroy_handle(isp, handle); - data_requested = PISP_PCMD(ccb)->datalen; + resid = data_requested = PISP_PCMD(ccb)->datalen; isp_free_pcmd(isp, ccb); if (isp->isp_nactive) { isp->isp_nactive--; @@ -2296,10 +2304,8 @@ isp_handle_platform_ctio(ispsoftc_t *isp sentstatus = ct->ct_flags & CT7_SENDSTATUS; ok = (ct->ct_nphdl == CT7_OK); notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; - if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { + if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) resid = ct->ct_resid; - moved_data = data_requested - resid; - } } isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct), notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); @@ -2320,22 +2326,20 @@ isp_handle_platform_ctio(ispsoftc_t *isp sentstatus = ct->ct_flags & CT2_SENDSTATUS; ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; - if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { + if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) resid = ct->ct_resid; - moved_data = data_requested - resid; - } } isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct), notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); } if (ok) { - if (moved_data) { - atp->bytes_xfered += moved_data; - ccb->csio.resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; + if (data_requested > 0) { + atp->bytes_xfered += data_requested - resid; + ccb->csio.resid = ccb->csio.dxfer_len - + (data_requested - resid); } - if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) { + if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) ccb->ccb_h.status |= CAM_SENT_SENSE; - } ccb->ccb_h.status |= CAM_REQ_CMP; } else { notify_cam = 1; Modified: stable/11/sys/dev/isp/isp_target.c ============================================================================== --- stable/11/sys/dev/isp/isp_target.c Mon Mar 6 06:36:45 2017 (r314755) +++ stable/11/sys/dev/isp/isp_target.c Mon Mar 6 06:37:44 2017 (r314756) @@ -558,13 +558,9 @@ isp_endcmd(ispsoftc_t *isp, ...) } else { cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; } - if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) { + if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl != 0) { cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; - if (cto->ct_resid < 0) { - cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); - } else if (cto->ct_resid > 0) { - cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); - } + cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); } cto->ct_syshandle = hdl; } else {