Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Dec 2015 21:38:04 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r291868 - head/sys/dev/isp
Message-ID:  <201512052138.tB5Lc4x9014566@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Dec  5 21:38:04 2015
New Revision: 291868
URL: https://svnweb.freebsd.org/changeset/base/291868

Log:
  Rework WWNs generation to make cards without NVRAM more useful.

Modified:
  head/sys/dev/isp/isp_freebsd.c

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Sat Dec  5 21:28:54 2015	(r291867)
+++ head/sys/dev/isp/isp_freebsd.c	Sat Dec  5 21:38:04 2015	(r291868)
@@ -4550,91 +4550,52 @@ isp_uninit(ispsoftc_t *isp)
 	ISP_DISABLE_INTS(isp);
 }
 
-/*
- * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them
- * up from our platform default (defww{p|n}n) and morph them based upon
- * channel.
- * 
- * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them
- * based upon channel.
- */
-
 uint64_t
 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
 {
 	uint64_t seed;
 	struct isp_fc *fc = ISP_FC_PC(isp, chan);
 
-	/*
-	 * If we're asking for a active WWN, the default overrides get
-	 * returned, otherwise the NVRAM value is picked.
-	 * 
-	 * If we're asking for a default WWN, we just pick the default override.
-	 */
+	/* First try to use explicitly configured WWNs. */
+	seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
+	if (seed)
+		return (seed);
+
+	/* Otherwise try to use WWNs from NVRAM. */
 	if (isactive) {
-		seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
-		if (seed) {
-			return (seed);
-		}
-		seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram;
-		if (seed) {
+		seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram :
+		    FCPARAM(isp, chan)->isp_wwpn_nvram;
+		if (seed)
 			return (seed);
-		}
-		return (0x400000007F000009ull);
 	}
 
-	seed = iswwnn ? fc->def_wwnn : fc->def_wwpn;
-
-	/*
-	 * For channel zero just return what we have. For either ACTIVE or
-	 * DEFAULT cases, we depend on default override of NVRAM values for
-	 * channel zero.
-	 */
-	if (chan == 0) {
-		return (seed);
+	/* If still no WWNs, try to steal them from the first channel. */
+	if (chan > 0) {
+		seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn :
+		    ISP_FC_PC(isp, 0)->def_wwpn;
+		if (seed == 0) {
+			seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram :
+			    FCPARAM(isp, 0)->isp_wwpn_nvram;
+		}
 	}
 
-	/*
-	 * For other channels, we are doing one of three things:
-	 * 
-	 * 1. If what we have now is non-zero, return it. Otherwise we morph
-	 * values from channel 0. 2. If we're here for a WWPN we synthesize
-	 * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a
-	 * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA.
-	 */
-
-	if (seed) {
-		return (seed);
+	/* If still nothing -- improvise. */
+	if (seed == 0) {
+		seed = 0x400000007F000000ull + device_get_unit(isp->isp_dev);
+		if (!iswwnn)
+			seed ^= 0x0100000000000000ULL;
 	}
-	seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn;
-	if (seed == 0)
-		seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram;
 
-	if (((seed >> 60) & 0xf) == 2) {
+	/* For additional channels we have to improvise even more. */
+	if (!iswwnn && chan > 0) {
 		/*
-		 * The type 2 NAA fields for QLogic cards appear be laid out
-		 * thusly:
-		 * 
-		 * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56
-		 * port (1) or node (0) WWN distinguishor bit 48
-		 * physical port on dual-port chips (23XX/24XX)
-		 * 
-		 * This is somewhat nutty, particularly since bit 48 is
-		 * irrelevant as they assign separate serial numbers to
-		 * different physical ports anyway.
-		 * 
 		 * We'll stick our channel number plus one first into bits
 		 * 57..59 and thence into bits 52..55 which allows for 8 bits
-		 * of channel which is comfortably more than our maximum
-		 * (126) now.
+		 * of channel which is enough for our maximum of 255 channels.
 		 */
-		seed &= ~0x0FF0000000000000ULL;
-		if (iswwnn == 0) {
-			seed |= ((uint64_t) (chan + 1) & 0xf) << 56;
-			seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
-		}
-	} else {
-		seed = 0;
+		seed ^= 0x0100000000000000ULL;
+		seed ^= ((uint64_t) (chan + 1) & 0xf) << 56;
+		seed ^= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52;
 	}
 	return (seed);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512052138.tB5Lc4x9014566>