summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/cxgbe/common/t4_hw.c88
1 files changed, 72 insertions, 16 deletions
diff --git a/usr/src/uts/common/io/cxgbe/common/t4_hw.c b/usr/src/uts/common/io/cxgbe/common/t4_hw.c
index 0f3ebc7da8..1f31a53d14 100644
--- a/usr/src/uts/common/io/cxgbe/common/t4_hw.c
+++ b/usr/src/uts/common/io/cxgbe/common/t4_hw.c
@@ -8876,9 +8876,9 @@ struct flash_desc {
int t4_get_flash_params(struct adapter *adapter)
{
- /* Table for non-Numonix supported flash parts. Numonix parts are left
- * to the preexisting well-tested code. All flash parts have 64KB
- * sectors.
+ /*
+ * Table for non-standard supported Flash parts. Note, all Flash
+ * parts must have 64KB sectors.
*/
static struct flash_desc supported_flash[] = {
{ 0x00150201, 4 << 20 }, /* Spansion 4MB S25FL032P */
@@ -8887,14 +8887,14 @@ int t4_get_flash_params(struct adapter *adapter)
int ret;
u32 flashid = 0;
unsigned int part, manufacturer;
- unsigned int density, size;
+ unsigned int density, size = 0;
/*
* Issue a Read ID Command to the Flash part. We decode supported
* Flash parts and their sizes from this. There's a newer Query
- * Command which can retrieve detailed geometry information but
- * many Flash parts don't support it.
+ * Command which can retrieve detailed geometry information but many
+ * Flash parts don't support it.
*/
ret = sf1_write(adapter, 1, 1, 0, SF_RD_ID);
if (!ret)
@@ -8903,6 +8903,9 @@ int t4_get_flash_params(struct adapter *adapter)
if (ret < 0)
return ret;
+ /*
+ * Check to see if it's one of our non-standard supported Flash parts.
+ */
for (part = 0; part < ARRAY_SIZE(supported_flash); part++)
if (supported_flash[part].vendor_and_model_id == flashid) {
adapter->params.sf_size =
@@ -8912,6 +8915,15 @@ int t4_get_flash_params(struct adapter *adapter)
goto found;
}
+ /*
+ * Decode Flash part size. The code below looks repetitive with
+ * common encodings, but that's not guaranteed in the JEDEC
+ * specification for the Read JEDEC ID command. The only thing that
+ * we're guaranteed by the JEDEC specification is where the
+ * Manufacturer ID is in the returned result. After that each
+ * Manufacturer ~could~ encode things completely differently.
+ * Note, all Flash parts must have 64KB sectors.
+ */
manufacturer = flashid & 0xff;
switch (manufacturer) {
case 0x20: { /* Micron/Numonix */
@@ -8930,24 +8942,68 @@ int t4_get_flash_params(struct adapter *adapter)
case 0x20: size = 1 << 26; break; /* 64MB */
case 0x21: size = 1 << 27; break; /* 128MB */
case 0x22: size = 1 << 28; break; /* 256MB */
+ }
+ break;
+ }
- default:
- CH_ERR(adapter, "Micron Flash Part has bad size, "
- "ID = %#x, Density code = %#x\n",
- flashid, density);
- return -EINVAL;
+ case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */
+ /*
+ * This Density -> Size decoding table is taken from ISSI
+ * Data Sheets.
+ */
+ density = (flashid >> 16) & 0xff;
+ switch (density) {
+ case 0x16: size = 1 << 25; break; /* 32MB */
+ case 0x17: size = 1 << 26; break; /* 64MB */
+ }
+ break;
+ }
+
+ case 0xc2: { /* Macronix */
+ /*
+ * This Density -> Size decoding table is taken from Macronix
+ * Data Sheets.
+ */
+ density = (flashid >> 16) & 0xff;
+ switch (density) {
+ case 0x17: size = 1 << 23; break; /* 8MB */
+ case 0x18: size = 1 << 24; break; /* 16MB */
}
+ break;
+ }
- adapter->params.sf_size = size;
- adapter->params.sf_nsec = size / SF_SEC_SIZE;
+ case 0xef: { /* Winbond */
+ /*
+ * This Density -> Size decoding table is taken from Winbond
+ * Data Sheets.
+ */
+ density = (flashid >> 16) & 0xff;
+ switch (density) {
+ case 0x17: size = 1 << 23; break; /* 8MB */
+ case 0x18: size = 1 << 24; break; /* 16MB */
+ }
break;
}
+ }
- default:
- CH_ERR(adapter, "Unsupported Flash Part, ID = %#x\n", flashid);
- return -EINVAL;
+ /*
+ * If we didn't recognize the FLASH part, that's no real issue: the
+ * Hardware/Software contract says that Hardware will _*ALWAYS*_
+ * use a FLASH part which is at least 4MB in size and has 64KB
+ * sectors. The unrecognized FLASH part is likely to be much larger
+ * than 4MB, but that's all we really need.
+ */
+ if (size == 0) {
+ CH_WARN(adapter, "Unknown Flash Part, ID = %#x, assuming 4MB\n", flashid);
+ size = 1 << 22;
}
+ /*
+ * Store decoded Flash size and fall through into vetting code.
+ */
+ adapter->params.sf_size = size;
+ adapter->params.sf_nsec = size / SF_SEC_SIZE;
+
found:
/*
* We should ~probably~ reject adapters with FLASHes which are too