scsi: qla2xxx: Fix flash read failure
Link up failure is observed as a result of flash read failure. Current code does not check flash read return code where it relies on FW checksum to detect the problem. Add check of flash read failure to detect the problem sooner. Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/202406210815.rPDRDMBi-lkp@intel.com/ Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20240710171057.35066-6-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
ce2065c4cc
commit
29e222085d
@ -8221,15 +8221,21 @@ qla28xx_get_aux_images(
|
||||
struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
|
||||
bool valid_pri_image = false, valid_sec_image = false;
|
||||
bool active_pri_image = false, active_sec_image = false;
|
||||
int rc;
|
||||
|
||||
if (!ha->flt_region_aux_img_status_pri) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
|
||||
goto check_sec_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
|
||||
ha->flt_region_aux_img_status_pri,
|
||||
sizeof(pri_aux_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a1,
|
||||
"Unable to read Primary aux image(%x).\n", rc);
|
||||
goto check_sec_image;
|
||||
}
|
||||
qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
|
||||
|
||||
if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
|
||||
@ -8260,9 +8266,15 @@ check_sec_image:
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
|
||||
ha->flt_region_aux_img_status_sec,
|
||||
sizeof(sec_aux_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a2,
|
||||
"Unable to read Secondary aux image(%x).\n", rc);
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
|
||||
|
||||
if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
|
||||
@ -8320,6 +8332,7 @@ qla27xx_get_active_image(struct scsi_qla_host *vha,
|
||||
struct qla27xx_image_status pri_image_status, sec_image_status;
|
||||
bool valid_pri_image = false, valid_sec_image = false;
|
||||
bool active_pri_image = false, active_sec_image = false;
|
||||
int rc;
|
||||
|
||||
if (!ha->flt_region_img_status_pri) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
|
||||
@ -8361,8 +8374,14 @@ check_sec_image:
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
|
||||
ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a3,
|
||||
"Unable to read Secondary image status(%x).\n", rc);
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla27xx_print_image(vha, "Secondary image", &sec_image_status);
|
||||
|
||||
if (qla27xx_check_image_status_signature(&sec_image_status)) {
|
||||
@ -8434,11 +8453,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
"FW: Loading firmware from flash (%x).\n", faddr);
|
||||
|
||||
dcode = (uint32_t *)req->ring;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (rval || qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_fatal, vha, 0x008c,
|
||||
"Unable to verify the integrity of flash firmware "
|
||||
"image.\n");
|
||||
"Unable to verify the integrity of flash firmware image (rval %x).\n", rval);
|
||||
ql_log(ql_log_fatal, vha, 0x008d,
|
||||
"Firmware data: %08x %08x %08x %08x.\n",
|
||||
dcode[0], dcode[1], dcode[2], dcode[3]);
|
||||
@ -8452,7 +8470,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
for (j = 0; j < segments; j++) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x008d,
|
||||
"-> Loading segment %u...\n", j);
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 10);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 10);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016a,
|
||||
"-> Unable to read segment addr + size .\n");
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
risc_addr = be32_to_cpu((__force __be32)dcode[2]);
|
||||
risc_size = be32_to_cpu((__force __be32)dcode[3]);
|
||||
if (!*srisc_addr) {
|
||||
@ -8468,7 +8491,13 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
ql_dbg(ql_dbg_init, vha, 0x008e,
|
||||
"-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
|
||||
fragment, risc_addr, faddr, dlen);
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, dlen);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, dlen);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016b,
|
||||
"-> Unable to read fragment(faddr %#x dlen %#lx).\n",
|
||||
faddr, dlen);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
for (i = 0; i < dlen; i++)
|
||||
dcode[i] = swab32(dcode[i]);
|
||||
|
||||
@ -8497,7 +8526,14 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
fwdt->length = 0;
|
||||
|
||||
dcode = (uint32_t *)req->ring;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 7);
|
||||
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 7);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016c,
|
||||
"-> Unable to read template size.\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
risc_size = be32_to_cpu((__force __be32)dcode[2]);
|
||||
ql_dbg(ql_dbg_init, vha, 0x0161,
|
||||
"-> fwdt%u template array at %#x (%#x dwords)\n",
|
||||
@ -8523,11 +8559,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
}
|
||||
|
||||
dcode = fwdt->template;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
|
||||
|
||||
if (!qla27xx_fwdt_template_valid(dcode)) {
|
||||
if (rval || !qla27xx_fwdt_template_valid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x0165,
|
||||
"-> fwdt%u failed template validate\n", j);
|
||||
"-> fwdt%u failed template validate (rval %x)\n",
|
||||
j, rval);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -555,6 +555,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
struct qla_flt_location *fltl = (void *)req->ring;
|
||||
uint32_t *dcode = (uint32_t *)req->ring;
|
||||
uint8_t *buf = (void *)req->ring, *bcode, last_image;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* FLT-location structure resides after the last PCI region.
|
||||
@ -584,14 +585,24 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
pcihdr = 0;
|
||||
do {
|
||||
/* Verify PCI expansion ROM header. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x016d,
|
||||
"Unable to read PCI Expansion Rom Header (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
bcode = buf + (pcihdr % 4);
|
||||
if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
|
||||
goto end;
|
||||
|
||||
/* Locate PCI data structure. */
|
||||
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
|
||||
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x0179,
|
||||
"Unable to read PCI Data Structure (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
bcode = buf + (pcihdr % 4);
|
||||
|
||||
/* Validate signature of PCI data structure. */
|
||||
@ -606,7 +617,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
} while (!last_image);
|
||||
|
||||
/* Now verify FLT-location structure. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x017a,
|
||||
"Unable to read FLT (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
if (memcmp(fltl->sig, "QFLT", 4))
|
||||
goto end;
|
||||
|
||||
@ -2605,13 +2621,18 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf,
|
||||
uint32_t offset, uint32_t length)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rc;
|
||||
|
||||
/* Suspend HBA. */
|
||||
scsi_block_requests(vha->host);
|
||||
set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
|
||||
/* Go with read. */
|
||||
qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
|
||||
rc = qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a0,
|
||||
"Unable to perform optrom read(%x).\n", rc);
|
||||
}
|
||||
|
||||
/* Resume HBA. */
|
||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
@ -3412,7 +3433,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
struct active_regions active_regions = { };
|
||||
|
||||
if (IS_P3P_TYPE(ha))
|
||||
return ret;
|
||||
return QLA_SUCCESS;
|
||||
|
||||
if (!mbuf)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@ -3432,20 +3453,31 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
|
||||
do {
|
||||
/* Verify PCI expansion ROM header. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x017d,
|
||||
"Unable to read PCI EXP Rom Header(%x).\n", ret);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
bcode = mbuf + (pcihdr % 4);
|
||||
if (memcmp(bcode, "\x55\xaa", 2)) {
|
||||
/* No signature */
|
||||
ql_log(ql_log_fatal, vha, 0x0059,
|
||||
"No matching ROM signature.\n");
|
||||
ret = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* Locate PCI data structure. */
|
||||
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
|
||||
|
||||
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x018e,
|
||||
"Unable to read PCI Data Structure (%x).\n", ret);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
bcode = mbuf + (pcihdr % 4);
|
||||
|
||||
/* Validate signature of PCI data structure. */
|
||||
@ -3454,8 +3486,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
ql_log(ql_log_fatal, vha, 0x005a,
|
||||
"PCI data struct not found pcir_adr=%x.\n", pcids);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32);
|
||||
ret = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* Read version */
|
||||
@ -3507,7 +3538,12 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
faddr = ha->flt_region_fw_sec;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x019e,
|
||||
"Unable to read FW version (%x).\n", ret);
|
||||
return ret;
|
||||
} else {
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x005f,
|
||||
"Unrecognized fw revision at %x.\n",
|
||||
@ -3522,6 +3558,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
ha->fw_revision[0], ha->fw_revision[1],
|
||||
ha->fw_revision[2], ha->fw_revision[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for golden firmware and get version if available */
|
||||
if (!IS_QLA81XX(ha)) {
|
||||
@ -3531,18 +3568,23 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
|
||||
memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version));
|
||||
faddr = ha->flt_region_gold_fw;
|
||||
qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x019f,
|
||||
"Unable to read Gold FW version (%x).\n", ret);
|
||||
return ret;
|
||||
} else {
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x0056,
|
||||
"Unrecognized golden fw at %#x.\n", faddr);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32);
|
||||
return ret;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ha->gold_fw_version[i] =
|
||||
be32_to_cpu((__force __be32)dcode[4+i]);
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user