diff options
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_common.h | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_eeprom.c | 27 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_pe800.c | 2 |
4 files changed, 38 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index 106f8f49cbb1..3130a7ed254b 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h @@ -476,7 +476,7 @@ struct ipath_sma_pkt * Data layout in I2C flash (for GUID, etc.) * All fields are little-endian binary unless otherwise stated */ -#define IPATH_FLASH_VERSION 1 +#define IPATH_FLASH_VERSION 2 struct ipath_flash { /* flash layout version (IPATH_FLASH_VERSION) */ __u8 if_fversion; @@ -484,14 +484,14 @@ struct ipath_flash { __u8 if_csum; /* * valid length (in use, protected by if_csum), including - * if_fversion and if_sum themselves) + * if_fversion and if_csum themselves) */ __u8 if_length; /* the GUID, in network order */ __u8 if_guid[8]; /* number of GUIDs to use, starting from if_guid */ __u8 if_numguid; - /* the board serial number, in ASCII */ + /* the (last 10 characters of) board serial number, in ASCII */ char if_serial[12]; /* board mfg date (YYYYMMDD ASCII) */ char if_mfgdate[8]; @@ -503,8 +503,10 @@ struct ipath_flash { __u8 if_powerhour[2]; /* ASCII free-form comment field */ char if_comment[32]; - /* 78 bytes used, min flash size is 128 bytes */ - __u8 if_future[50]; + /* Backwards compatible prefix for longer QLogic Serial Numbers */ + char if_sprefix[4]; + /* 82 bytes used, min flash size is 128 bytes */ + __u8 if_future[46]; }; /* diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c index f086e3360459..3313356ab93a 100644 --- a/drivers/infiniband/hw/ipath/ipath_eeprom.c +++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c @@ -601,8 +601,31 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd) guid = *(__be64 *) ifp->if_guid; dd->ipath_guid = guid; dd->ipath_nguid = ifp->if_numguid; - memcpy(dd->ipath_serial, ifp->if_serial, - sizeof(ifp->if_serial)); + /* + * Things are slightly complicated by the desire to transparently + * support both the Pathscale 10-digit serial number and the QLogic + * 13-character version. + */ + if ((ifp->if_fversion > 1) && ifp->if_sprefix[0] + && ((u8 *)ifp->if_sprefix)[0] != 0xFF) { + /* This board has a Serial-prefix, which is stored + * elsewhere for backward-compatibility. + */ + char *snp = dd->ipath_serial; + int len; + memcpy(snp, ifp->if_sprefix, sizeof ifp->if_sprefix); + snp[sizeof ifp->if_sprefix] = '\0'; + len = strlen(snp); + snp += len; + len = (sizeof dd->ipath_serial) - len; + if (len > sizeof ifp->if_serial) { + len = sizeof ifp->if_serial; + } + memcpy(snp, ifp->if_serial, len); + } else + memcpy(dd->ipath_serial, ifp->if_serial, + sizeof ifp->if_serial); + ipath_cdbg(VERBOSE, "Initted GUID to %llx from eeprom\n", (unsigned long long) be64_to_cpu(dd->ipath_guid)); diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index fe3c862e23b5..00a6bbdbe957 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -491,8 +491,11 @@ struct ipath_devdata { u16 ipath_lid; /* list of pkeys programmed; 0 if not set */ u16 ipath_pkeys[4]; - /* ASCII serial number, from flash */ - u8 ipath_serial[12]; + /* + * ASCII serial number, from flash, large enough for original + * all digit strings, and longer QLogic serial number format + */ + u8 ipath_serial[16]; /* human readable board version */ u8 ipath_boardversion[80]; /* chip major rev, from ipath_revision */ diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_pe800.c index 98fd5d37dfff..b83f66d8262c 100644 --- a/drivers/infiniband/hw/ipath/ipath_pe800.c +++ b/drivers/infiniband/hw/ipath/ipath_pe800.c @@ -533,7 +533,7 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, if (n) snprintf(name, namelen, "%s", n); - if (dd->ipath_majrev != 4 || dd->ipath_minrev != 1) { + if (dd->ipath_majrev != 4 || !dd->ipath_minrev || dd->ipath_minrev>2) { ipath_dev_err(dd, "Unsupported PE-800 revision %u.%u!\n", dd->ipath_majrev, dd->ipath_minrev); ret = 1; |