Rework WWNs generation to make cards without NVRAM more useful.
This commit is contained in:
parent
69a946104c
commit
20e04de48a
@ -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.
|
||||
*/
|
||||
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) {
|
||||
return (seed);
|
||||
}
|
||||
return (0x400000007F000009ull);
|
||||
}
|
||||
|
||||
/* First try to use explicitly configured WWNs. */
|
||||
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) {
|
||||
if (seed)
|
||||
return (seed);
|
||||
|
||||
/* Otherwise try to use WWNs from NVRAM. */
|
||||
if (isactive) {
|
||||
seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram :
|
||||
FCPARAM(isp, chan)->isp_wwpn_nvram;
|
||||
if (seed)
|
||||
return (seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
/* If still nothing -- improvise. */
|
||||
if (seed == 0) {
|
||||
seed = 0x400000007F000000ull + device_get_unit(isp->isp_dev);
|
||||
if (!iswwnn)
|
||||
seed ^= 0x0100000000000000ULL;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user