[SCSI] qla2xxx: Retrieve board serial-number and description from VPD.

Recent ISPs have this information written at manufacturing time,
so use the information. This also reduces future churn of the
qla_devtbl.h file contents, as the driver can now depend on the
information to be present in VPD.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

Joe Carnuccio and committed by
James Bottomley
1ee27146 e5896bd5

+60 -5
+4 -2
drivers/scsi/qla2xxx/qla_attr.c
··· 557 557 scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); 558 558 uint32_t sn; 559 559 560 - if (IS_FWI2_CAPABLE(ha)) 561 - return snprintf(buf, PAGE_SIZE, "\n"); 560 + if (IS_FWI2_CAPABLE(ha)) { 561 + qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE); 562 + return snprintf(buf, PAGE_SIZE, "%s\n", buf); 563 + } 562 564 563 565 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; 564 566 return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
+1 -1
drivers/scsi/qla2xxx/qla_def.h
··· 2518 2518 2519 2519 uint8_t model_number[16+1]; 2520 2520 #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 2521 - char *model_desc; 2521 + char model_desc[80]; 2522 2522 uint8_t adapter_id[16+1]; 2523 2523 2524 2524 uint8_t *node_name;
+1
drivers/scsi/qla2xxx/qla_gbl.h
··· 314 314 uint16_t, uint16_t); 315 315 316 316 extern void qla2xxx_get_flash_info(scsi_qla_host_t *); 317 + extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); 317 318 318 319 /* 319 320 * Global Function Prototypes in qla_dbg.c source file.
+9 -2
drivers/scsi/qla2xxx/qla_init.c
··· 1501 1501 index = (ha->pdev->subsystem_device & 0xff); 1502 1502 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && 1503 1503 index < QLA_MODEL_NAMES) 1504 - ha->model_desc = qla2x00_model_name[index * 2 + 1]; 1504 + strncpy(ha->model_desc, 1505 + qla2x00_model_name[index * 2 + 1], 1506 + sizeof(ha->model_desc) - 1); 1505 1507 } else { 1506 1508 index = (ha->pdev->subsystem_device & 0xff); 1507 1509 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && 1508 1510 index < QLA_MODEL_NAMES) { 1509 1511 strcpy(ha->model_number, 1510 1512 qla2x00_model_name[index * 2]); 1511 - ha->model_desc = qla2x00_model_name[index * 2 + 1]; 1513 + strncpy(ha->model_desc, 1514 + qla2x00_model_name[index * 2 + 1], 1515 + sizeof(ha->model_desc) - 1); 1512 1516 } else { 1513 1517 strcpy(ha->model_number, def); 1514 1518 } 1515 1519 } 1520 + if (IS_FWI2_CAPABLE(ha)) 1521 + qla2xxx_get_vpd_field(ha, "\x82", ha->model_desc, 1522 + sizeof(ha->model_desc)); 1516 1523 } 1517 1524 1518 1525 /* On sparc systems, obtain port and node WWN from firmware
+45
drivers/scsi/qla2xxx/qla_sup.c
··· 2303 2303 } 2304 2304 2305 2305 static int 2306 + qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end) 2307 + { 2308 + if (pos >= end || *pos != 0x82) 2309 + return 0; 2310 + 2311 + pos += 3 + pos[1]; 2312 + if (pos >= end || *pos != 0x90) 2313 + return 0; 2314 + 2315 + pos += 3 + pos[1]; 2316 + if (pos >= end || *pos != 0x78) 2317 + return 0; 2318 + 2319 + return 1; 2320 + } 2321 + 2322 + int 2323 + qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size) 2324 + { 2325 + uint8_t *pos = ha->vpd; 2326 + uint8_t *end = pos + ha->vpd_size; 2327 + int len = 0; 2328 + 2329 + if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end)) 2330 + return 0; 2331 + 2332 + while (pos < end && *pos != 0x78) { 2333 + len = (*pos == 0x82) ? pos[1] : pos[2]; 2334 + 2335 + if (!strncmp(pos, key, strlen(key))) 2336 + break; 2337 + 2338 + if (*pos != 0x90 && *pos != 0x91) 2339 + pos += len; 2340 + 2341 + pos += 3; 2342 + } 2343 + 2344 + if (pos < end - len && *pos != 0x78) 2345 + return snprintf(str, size, "%.*s", len, pos + 3); 2346 + 2347 + return 0; 2348 + } 2349 + 2350 + static int 2306 2351 qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) 2307 2352 { 2308 2353 uint32_t d[2], faddr;