summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-12-22 12:54:13 +0000
committermav <mav@FreeBSD.org>2015-12-22 12:54:13 +0000
commit2c4aa6921414a03bff2da6a080e1b3fec7a04f97 (patch)
tree1701bc386e919672ebd9fe9a7e4c9c0e8bc3374e /sys/dev
parent88f7208f5800456cdf4949f98354e922b5060515 (diff)
downloadFreeBSD-src-2c4aa6921414a03bff2da6a080e1b3fec7a04f97.zip
FreeBSD-src-2c4aa6921414a03bff2da6a080e1b3fec7a04f97.tar.gz
MFC r291868: Rework WWNs generation to make cards without NVRAM more useful.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/isp/isp_freebsd.c95
1 files changed, 28 insertions, 67 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 73741eb..c533d69 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -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);
}
OpenPOWER on IntegriCloud