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

Alexander Motin mav at FreeBSD.org
Mon Nov 30 21:42:37 UTC 2015


Author: mav
Date: Mon Nov 30 21:42:35 2015
New Revision: 291517
URL: https://svnweb.freebsd.org/changeset/base/291517

Log:
  MFC r291144: Fix target mode with fabric for pre-24xx chips.
  
  For those chips we are not receiving login events, adding initiators
  based on ATIO requests.  But there is no port ID in that structure, so
  in fabric mode we have to explicitly fetch it from firmware to be able
  to do normal scan after that.

Modified:
  stable/10/sys/dev/isp/isp.c
  stable/10/sys/dev/isp/isp_freebsd.c
  stable/10/sys/dev/isp/isp_library.c
  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 Nov 30 21:41:56 2015	(r291516)
+++ stable/10/sys/dev/isp/isp.c	Mon Nov 30 21:42:35 2015	(r291517)
@@ -2320,7 +2320,8 @@ isp_mark_portdb(ispsoftc_t *isp, int cha
 		lp = &fcp->portdb[i];
 		if (lp->state == FC_PORTDB_STATE_NIL)
 			continue;
-		if ((lp->portid & 0xfffc00) == 0xfffc00)
+		if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
+		    lp->portid <= DOMAIN_CONTROLLER_END)
 			continue;
 		fcp->portdb[i].probational = 1;
 	}
@@ -2787,9 +2788,6 @@ isp_fclink_test(ispsoftc_t *isp, int cha
 
 	fcp = FCPARAM(isp, chan);
 
-	/* Mark port database entries probational for following scan. */
-	isp_mark_portdb(isp, chan);
-
 	if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
 		return (0);
 
@@ -3079,6 +3077,48 @@ isp_pdb_add_update(ispsoftc_t *isp, int 
 }
 
 /*
+ * Fix port IDs for logged-in initiators on pre-2400 chips.
+ * For those chips we are not receiving login events, adding initiators
+ * based on ATIO requests, but there is no port ID in that structure.
+ */
+static void
+isp_fix_portids(ispsoftc_t *isp, int chan)
+{
+	fcparam *fcp = FCPARAM(isp, chan);
+	isp_pdb_t pdb;
+	uint64_t wwpn;
+	int i, r;
+
+	for (i = 0; i < MAX_FC_TARG; i++) {
+		fcportdb_t *lp = &fcp->portdb[i];
+
+		if (lp->state == FC_PORTDB_STATE_NIL ||
+		    lp->state == FC_PORTDB_STATE_ZOMBIE)
+			continue;
+		if (VALID_PORT(lp->portid))
+			continue;
+
+		r = isp_getpdb(isp, chan, lp->handle, &pdb, 1);
+		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
+			return;
+		if (r != 0) {
+			isp_prt(isp, ISP_LOGDEBUG1,
+			    "Chan %d FC Scan Loop handle %d returned %x",
+			    chan, lp->handle, r);
+			continue;
+		}
+
+		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
+		if (lp->port_wwn != wwpn)
+			continue;
+		lp->portid = lp->new_portid = pdb.portid;
+		isp_prt(isp, ISP_LOG_SANCFG,
+		    "Chan %d Port 0x%06x at 0x%04x is fixed",
+		    chan, pdb.portid, pdb.handle);
+	}
+}
+
+/*
  * Scan local loop for devices.
  */
 static int
@@ -3097,13 +3137,18 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 		return (0);
 	}
 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
+	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
 	if (TOPO_IS_FABRIC(fcp->isp_topo)) {
+		if (!IS_24XX(isp)) {
+			isp_fix_portids(isp, chan);
+			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
+				goto abort;
+		}
 		isp_prt(isp, ISP_LOG_SANCFG,
 		    "Chan %d FC loop scan done (no loop)", chan);
 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
 		return (0);
 	}
-	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
 
 	lim = LOCAL_LOOP_LIM;
 	r = isp_gethandles(isp, chan, handles, &lim, 1, 1);
@@ -3121,6 +3166,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 	/*
 	 * Run through the list and get the port database info for each one.
 	 */
+	isp_mark_portdb(isp, chan);
 	for (idx = 0; idx < lim; idx++) {
 		handle = handles[idx];
 
@@ -3162,8 +3208,6 @@ abort:
 			isp_prt(isp, ISP_LOGDEBUG1,
 			    "Chan %d FC Scan Loop handle %d returned %x",
 			    chan, handle, r);
-			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
-				goto abort;
 			continue;
 		}
 
@@ -3363,13 +3407,13 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 		return (0);
 	}
 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
+	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
 		isp_prt(isp, ISP_LOG_SANCFG,
 		    "Chan %d FC fabric scan done (no fabric)", chan);
 		return (0);
 	}
-	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 
 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 		isp_prt(isp, ISP_LOGERR, sacq);
@@ -3493,7 +3537,7 @@ abort:
 	 * than one entry that has the same PortID or the same
 	 * WWNN/WWPN duple, we enter the device into our database.
 	 */
-
+	isp_mark_portdb(isp, chan);
 	for (portidx = 0; portidx < portlim; portidx++) {
 		portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) |
 			 ((rs1->snscb_ports[portidx].portid[1]) << 8) |
@@ -3502,13 +3546,13 @@ abort:
 		    "Chan %d Checking fabric port 0x%06x", chan, portid);
 		if (portid == 0) {
 			isp_prt(isp, ISP_LOG_SANCFG,
-			    "Chan %d Skipping null PortID at idx %d",
+			    "Chan %d Port at idx %d is zero",
 			    chan, portidx);
 			continue;
 		}
 		if (portid == fcp->isp_portid) {
 			isp_prt(isp, ISP_LOG_SANCFG,
-			    "Chan %d Skipping our PortID 0x%06x", chan, portid);
+			    "Chan %d Port 0x%06x is our", chan, portid);
 			continue;
 		}
 
@@ -3555,8 +3599,11 @@ abort:
 		}
 
 relogin:
-		if ((fcp->role & ISP_ROLE_INITIATOR) == 0)
+		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
+			isp_prt(isp, ISP_LOG_SANCFG,
+			    "Chan %d Port 0x%06x is not logged in", chan, portid);
 			continue;
+		}
 
 		if (isp_login_device(isp, chan, portid, &pdb,
 		    &FCPARAM(isp, 0)->isp_lasthdl)) {
@@ -5850,11 +5897,14 @@ isp_handle_other_response(ispsoftc_t *is
 				if (fcp->role == ISP_ROLE_NONE)
 					continue;
 				c = (chan == 0) ? 127 : (chan - 1);
-				if (rid.ridacq_map[c / 16] & (1 << (c % 16)))
+				if (rid.ridacq_map[c / 16] & (1 << (c % 16))) {
+					fcp->isp_loopstate = LOOP_NIL;
 					isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
 					    chan, ISPASYNC_CHANGE_OTHER);
+				}
 			}
 		} else {
+			FCPARAM(isp, rid.ridacq_vp_index)->isp_loopstate = LOOP_NIL;
 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
 			    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
 		}

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Mon Nov 30 21:41:56 2015	(r291516)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Mon Nov 30 21:42:35 2015	(r291517)
@@ -2342,7 +2342,7 @@ isp_handle_platform_atio(ispsoftc_t *isp
 	atp->bytes_xfered = 0;
 	atp->lun = aep->at_lun;
 	atp->nphdl = aep->at_iid;
-	atp->portid = PORT_NONE;
+	atp->portid = PORT_ANY;
 	atp->oxid = 0;
 	atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
 	atp->tattr = aep->at_tag_type;

Modified: stable/10/sys/dev/isp/isp_library.c
==============================================================================
--- stable/10/sys/dev/isp/isp_library.c	Mon Nov 30 21:41:56 2015	(r291516)
+++ stable/10/sys/dev/isp/isp_library.c	Mon Nov 30 21:42:35 2015	(r291517)
@@ -2580,12 +2580,12 @@ isp_add_wwn_entry(ispsoftc_t *isp, int c
 	 * so log them verbosely and dump the whole port database.
 	 */
 	if ((VALID_INI(wwpn) && isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) ||
-	    (s_id != PORT_NONE && isp_find_pdb_by_portid(isp, chan, s_id, &lp))) {
+	    (VALID_PORT(s_id) && isp_find_pdb_by_portid(isp, chan, s_id, &lp))) {
 		change = 0;
 		lp->new_portid = lp->portid;
 		lp->new_prli_word3 = lp->prli_word3;
-		if (s_id != PORT_NONE && lp->portid != s_id) {
-			if (lp->portid == PORT_NONE) {
+		if (VALID_PORT(s_id) && lp->portid != s_id) {
+			if (!VALID_PORT(lp->portid)) {
 				isp_prt(isp, ISP_LOGTINFO,
 				    "Chan %d WWPN 0x%016llx handle 0x%x "
 				    "gets PortID 0x%06x",
@@ -2804,13 +2804,13 @@ isp_del_wwn_entries(ispsoftc_t *isp, isp
 			return;
 		}
 	}
-	if (mp->nt_wwn != INI_ANY) {
+	if (VALID_INI(mp->nt_wwn)) {
 		if (isp_find_pdb_by_wwpn(isp, mp->nt_channel, mp->nt_wwn, &lp)) {
 			isp_del_wwn_entry(isp, mp->nt_channel, lp->port_wwn, lp->handle, lp->portid);
 			return;
 		}
 	}
-	if (mp->nt_sid != PORT_ANY && mp->nt_sid != PORT_NONE) {
+	if (VALID_PORT(mp->nt_sid)) {
 		if (isp_find_pdb_by_portid(isp, mp->nt_channel, mp->nt_sid, &lp)) {
 			isp_del_wwn_entry(isp, mp->nt_channel, lp->port_wwn, lp->handle, lp->portid);
 			return;

Modified: stable/10/sys/dev/isp/ispvar.h
==============================================================================
--- stable/10/sys/dev/isp/ispvar.h	Mon Nov 30 21:41:56 2015	(r291516)
+++ stable/10/sys/dev/isp/ispvar.h	Mon Nov 30 21:42:35 2015	(r291517)
@@ -282,6 +282,7 @@ typedef struct {
 #define	FABRIC_PORT_ID		0xFFFFFE
 #define	PORT_ANY		0xFFFFFF
 #define	PORT_NONE		0
+#define	VALID_PORT(port)	(port != PORT_NONE && port != PORT_ANY)
 #define	DOMAIN_CONTROLLER_BASE	0xFFFC00
 #define	DOMAIN_CONTROLLER_END	0xFFFCFF
 


More information about the svn-src-all mailing list