svn commit: r300584 - stable/10/sys/dev/isp

Alexander Motin mav at FreeBSD.org
Tue May 24 07:15:54 UTC 2016


Author: mav
Date: Tue May 24 07:15:53 2016
New Revision: 300584
URL: https://svnweb.freebsd.org/changeset/base/300584

Log:
  MFC r300218: Add proper reporting for early task management errors.
  
  This covers unknown requests and requests to unknown virtual ports.
  Previously it "worked" only because of timeout handling on initiator.

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

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Tue May 24 07:15:10 2016	(r300583)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Tue May 24 07:15:53 2016	(r300584)
@@ -2103,7 +2103,7 @@ isp_handle_platform_atio7(ispsoftc_t *is
 			    "%s: [0x%x] no state pointer for lun %jx or wildcard",
 			    __func__, aep->at_rxid, (uintmax_t)lun);
 			if (lun == 0) {
-				isp_endcmd(isp, aep, nphdl, SCSI_STATUS_BUSY, 0);
+				isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0);
 			} else {
 				isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0);
 			}

Modified: stable/10/sys/dev/isp/isp_target.c
==============================================================================
--- stable/10/sys/dev/isp/isp_target.c	Tue May 24 07:15:10 2016	(r300583)
+++ stable/10/sys/dev/isp/isp_target.c	Tue May 24 07:15:53 2016	(r300584)
@@ -539,13 +539,22 @@ isp_endcmd(ispsoftc_t *isp, ...)
 		} else if (code & ECMD_SVALID) {
 			cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
 			cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
-			cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX);
+			cto->ct_senselen = min(16, MAXRESPLEN_24XX);
 			ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
 			cto->rsp.m1.ct_resp[0] = 0xf0;
 			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
 			cto->rsp.m1.ct_resp[7] = 8;
 			cto->rsp.m1.ct_resp[12] = (code >> 16) & 0xff;
 			cto->rsp.m1.ct_resp[13] = (code >> 24) & 0xff;
+		} else if (code & ECMD_RVALID) {
+			cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
+			cto->ct_scsi_status |= (FCP_RSPLEN_VALID << 8);
+			cto->rsp.m1.ct_resplen = 4;
+			ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp));
+			cto->rsp.m1.ct_resp[0] = (code >> 12) & 0xf;
+			cto->rsp.m1.ct_resp[1] = (code >> 16) & 0xff;
+			cto->rsp.m1.ct_resp[2] = (code >> 24) & 0xff;
+			cto->rsp.m1.ct_resp[3] = 0;
 		} else {
 			cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS;
 		}
@@ -764,6 +773,7 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_en
 	isp_notify_t notify;
 	static const char f1[] = "%s from PortID 0x%06x lun %x seq 0x%08x";
 	static const char f2[] = "unknown Task Flag 0x%x lun %x PortID 0x%x tag 0x%08x";
+	fcportdb_t *lp;
 	uint16_t chan;
 	uint32_t sid, did;
 
@@ -774,20 +784,23 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_en
 	notify.nt_tagval = aep->at_rxid;
 	notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32);
 	notify.nt_lreserved = aep;
-	sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] <<  8) | (aep->at_hdr.s_id[2]);
+	sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
 	did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
 	if (ISP_CAP_MULTI_ID(isp) && isp->isp_nchan > 1) {
 		/* Channel has to be derived from D_ID */
 		isp_find_chan_by_did(isp, did, &chan);
 		if (chan == ISP_NOCHAN) {
 			isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did);
-			/* just drop on the floor */
+			isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0);
 			return;
 		}
 	} else {
 		chan = 0;
 	}
-	notify.nt_nphdl = NIL_HANDLE; /* unknown here */
+	if (isp_find_pdb_by_portid(isp, chan, sid, &lp))
+		notify.nt_nphdl = lp->handle;
+	else
+		notify.nt_nphdl = NIL_HANDLE;
 	notify.nt_sid = sid;
 	notify.nt_did = did;
 	notify.nt_channel = chan;
@@ -815,6 +828,7 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_en
 	} else {
 		isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid);
 		notify.nt_ncode = NT_UNKNOWN;
+		isp_endcmd(isp, aep, notify.nt_nphdl, chan, ECMD_RVALID | (0x4 << 12), 0);
 		return;
 	}
 	isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);

Modified: stable/10/sys/dev/isp/ispvar.h
==============================================================================
--- stable/10/sys/dev/isp/ispvar.h	Tue May 24 07:15:10 2016	(r300583)
+++ stable/10/sys/dev/isp/ispvar.h	Tue May 24 07:15:53 2016	(r300584)
@@ -1143,7 +1143,8 @@ int isp_target_put_atio(ispsoftc_t *, vo
  */
 int isp_endcmd(ispsoftc_t *, ...);
 #define	ECMD_SVALID	0x100
-#define	ECMD_TERMINATE	0x200
+#define	ECMD_RVALID	0x200
+#define	ECMD_TERMINATE	0x400
 
 /*
  * Handle an asynchronous event


More information about the svn-src-all mailing list