Skip to content

Commit 29e2220

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
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 <[email protected]> Reported-by: Dan Carpenter <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Cc: [email protected] Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent ce2065c commit 29e2220

File tree

2 files changed

+125
-46
lines changed

2 files changed

+125
-46
lines changed

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8221,15 +8221,21 @@ qla28xx_get_aux_images(
82218221
struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
82228222
bool valid_pri_image = false, valid_sec_image = false;
82238223
bool active_pri_image = false, active_sec_image = false;
8224+
int rc;
82248225

82258226
if (!ha->flt_region_aux_img_status_pri) {
82268227
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
82278228
goto check_sec_image;
82288229
}
82298230

8230-
qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
8231+
rc = qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
82318232
ha->flt_region_aux_img_status_pri,
82328233
sizeof(pri_aux_image_status) >> 2);
8234+
if (rc) {
8235+
ql_log(ql_log_info, vha, 0x01a1,
8236+
"Unable to read Primary aux image(%x).\n", rc);
8237+
goto check_sec_image;
8238+
}
82338239
qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
82348240

82358241
if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
@@ -8260,9 +8266,15 @@ qla28xx_get_aux_images(
82608266
goto check_valid_image;
82618267
}
82628268

8263-
qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
8269+
rc = qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
82648270
ha->flt_region_aux_img_status_sec,
82658271
sizeof(sec_aux_image_status) >> 2);
8272+
if (rc) {
8273+
ql_log(ql_log_info, vha, 0x01a2,
8274+
"Unable to read Secondary aux image(%x).\n", rc);
8275+
goto check_valid_image;
8276+
}
8277+
82668278
qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
82678279

82688280
if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
@@ -8320,6 +8332,7 @@ qla27xx_get_active_image(struct scsi_qla_host *vha,
83208332
struct qla27xx_image_status pri_image_status, sec_image_status;
83218333
bool valid_pri_image = false, valid_sec_image = false;
83228334
bool active_pri_image = false, active_sec_image = false;
8335+
int rc;
83238336

83248337
if (!ha->flt_region_img_status_pri) {
83258338
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
@@ -8361,8 +8374,14 @@ qla27xx_get_active_image(struct scsi_qla_host *vha,
83618374
goto check_valid_image;
83628375
}
83638376

8364-
qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
8377+
rc = qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
83658378
ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
8379+
if (rc) {
8380+
ql_log(ql_log_info, vha, 0x01a3,
8381+
"Unable to read Secondary image status(%x).\n", rc);
8382+
goto check_valid_image;
8383+
}
8384+
83668385
qla27xx_print_image(vha, "Secondary image", &sec_image_status);
83678386

83688387
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,
84348453
"FW: Loading firmware from flash (%x).\n", faddr);
84358454

84368455
dcode = (uint32_t *)req->ring;
8437-
qla24xx_read_flash_data(vha, dcode, faddr, 8);
8438-
if (qla24xx_risc_firmware_invalid(dcode)) {
8456+
rval = qla24xx_read_flash_data(vha, dcode, faddr, 8);
8457+
if (rval || qla24xx_risc_firmware_invalid(dcode)) {
84398458
ql_log(ql_log_fatal, vha, 0x008c,
8440-
"Unable to verify the integrity of flash firmware "
8441-
"image.\n");
8459+
"Unable to verify the integrity of flash firmware image (rval %x).\n", rval);
84428460
ql_log(ql_log_fatal, vha, 0x008d,
84438461
"Firmware data: %08x %08x %08x %08x.\n",
84448462
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,
84528470
for (j = 0; j < segments; j++) {
84538471
ql_dbg(ql_dbg_init, vha, 0x008d,
84548472
"-> Loading segment %u...\n", j);
8455-
qla24xx_read_flash_data(vha, dcode, faddr, 10);
8473+
rval = qla24xx_read_flash_data(vha, dcode, faddr, 10);
8474+
if (rval) {
8475+
ql_log(ql_log_fatal, vha, 0x016a,
8476+
"-> Unable to read segment addr + size .\n");
8477+
return QLA_FUNCTION_FAILED;
8478+
}
84568479
risc_addr = be32_to_cpu((__force __be32)dcode[2]);
84578480
risc_size = be32_to_cpu((__force __be32)dcode[3]);
84588481
if (!*srisc_addr) {
@@ -8468,7 +8491,13 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
84688491
ql_dbg(ql_dbg_init, vha, 0x008e,
84698492
"-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
84708493
fragment, risc_addr, faddr, dlen);
8471-
qla24xx_read_flash_data(vha, dcode, faddr, dlen);
8494+
rval = qla24xx_read_flash_data(vha, dcode, faddr, dlen);
8495+
if (rval) {
8496+
ql_log(ql_log_fatal, vha, 0x016b,
8497+
"-> Unable to read fragment(faddr %#x dlen %#lx).\n",
8498+
faddr, dlen);
8499+
return QLA_FUNCTION_FAILED;
8500+
}
84728501
for (i = 0; i < dlen; i++)
84738502
dcode[i] = swab32(dcode[i]);
84748503

@@ -8497,7 +8526,14 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
84978526
fwdt->length = 0;
84988527

84998528
dcode = (uint32_t *)req->ring;
8500-
qla24xx_read_flash_data(vha, dcode, faddr, 7);
8529+
8530+
rval = qla24xx_read_flash_data(vha, dcode, faddr, 7);
8531+
if (rval) {
8532+
ql_log(ql_log_fatal, vha, 0x016c,
8533+
"-> Unable to read template size.\n");
8534+
goto failed;
8535+
}
8536+
85018537
risc_size = be32_to_cpu((__force __be32)dcode[2]);
85028538
ql_dbg(ql_dbg_init, vha, 0x0161,
85038539
"-> 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,
85238559
}
85248560

85258561
dcode = fwdt->template;
8526-
qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
8562+
rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
85278563

8528-
if (!qla27xx_fwdt_template_valid(dcode)) {
8564+
if (rval || !qla27xx_fwdt_template_valid(dcode)) {
85298565
ql_log(ql_log_warn, vha, 0x0165,
8530-
"-> fwdt%u failed template validate\n", j);
8566+
"-> fwdt%u failed template validate (rval %x)\n",
8567+
j, rval);
85318568
goto failed;
85328569
}
85338570

drivers/scsi/qla2xxx/qla_sup.c

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
555555
struct qla_flt_location *fltl = (void *)req->ring;
556556
uint32_t *dcode = (uint32_t *)req->ring;
557557
uint8_t *buf = (void *)req->ring, *bcode, last_image;
558+
int rc;
558559

559560
/*
560561
* 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)
584585
pcihdr = 0;
585586
do {
586587
/* Verify PCI expansion ROM header. */
587-
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
588+
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
589+
if (rc) {
590+
ql_log(ql_log_info, vha, 0x016d,
591+
"Unable to read PCI Expansion Rom Header (%x).\n", rc);
592+
return QLA_FUNCTION_FAILED;
593+
}
588594
bcode = buf + (pcihdr % 4);
589595
if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
590596
goto end;
591597

592598
/* Locate PCI data structure. */
593599
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
594-
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
600+
rc = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
601+
if (rc) {
602+
ql_log(ql_log_info, vha, 0x0179,
603+
"Unable to read PCI Data Structure (%x).\n", rc);
604+
return QLA_FUNCTION_FAILED;
605+
}
595606
bcode = buf + (pcihdr % 4);
596607

597608
/* Validate signature of PCI data structure. */
@@ -606,7 +617,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
606617
} while (!last_image);
607618

608619
/* Now verify FLT-location structure. */
609-
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
620+
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
621+
if (rc) {
622+
ql_log(ql_log_info, vha, 0x017a,
623+
"Unable to read FLT (%x).\n", rc);
624+
return QLA_FUNCTION_FAILED;
625+
}
610626
if (memcmp(fltl->sig, "QFLT", 4))
611627
goto end;
612628

@@ -2605,13 +2621,18 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf,
26052621
uint32_t offset, uint32_t length)
26062622
{
26072623
struct qla_hw_data *ha = vha->hw;
2624+
int rc;
26082625

26092626
/* Suspend HBA. */
26102627
scsi_block_requests(vha->host);
26112628
set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
26122629

26132630
/* Go with read. */
2614-
qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
2631+
rc = qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
2632+
if (rc) {
2633+
ql_log(ql_log_info, vha, 0x01a0,
2634+
"Unable to perform optrom read(%x).\n", rc);
2635+
}
26152636

26162637
/* Resume HBA. */
26172638
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)
34123433
struct active_regions active_regions = { };
34133434

34143435
if (IS_P3P_TYPE(ha))
3415-
return ret;
3436+
return QLA_SUCCESS;
34163437

34173438
if (!mbuf)
34183439
return QLA_FUNCTION_FAILED;
@@ -3432,20 +3453,31 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
34323453

34333454
do {
34343455
/* Verify PCI expansion ROM header. */
3435-
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
3456+
ret = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
3457+
if (ret) {
3458+
ql_log(ql_log_info, vha, 0x017d,
3459+
"Unable to read PCI EXP Rom Header(%x).\n", ret);
3460+
return QLA_FUNCTION_FAILED;
3461+
}
3462+
34363463
bcode = mbuf + (pcihdr % 4);
34373464
if (memcmp(bcode, "\x55\xaa", 2)) {
34383465
/* No signature */
34393466
ql_log(ql_log_fatal, vha, 0x0059,
34403467
"No matching ROM signature.\n");
3441-
ret = QLA_FUNCTION_FAILED;
3442-
break;
3468+
return QLA_FUNCTION_FAILED;
34433469
}
34443470

34453471
/* Locate PCI data structure. */
34463472
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
34473473

3448-
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
3474+
ret = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
3475+
if (ret) {
3476+
ql_log(ql_log_info, vha, 0x018e,
3477+
"Unable to read PCI Data Structure (%x).\n", ret);
3478+
return QLA_FUNCTION_FAILED;
3479+
}
3480+
34493481
bcode = mbuf + (pcihdr % 4);
34503482

34513483
/* Validate signature of PCI data structure. */
@@ -3454,8 +3486,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
34543486
ql_log(ql_log_fatal, vha, 0x005a,
34553487
"PCI data struct not found pcir_adr=%x.\n", pcids);
34563488
ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32);
3457-
ret = QLA_FUNCTION_FAILED;
3458-
break;
3489+
return QLA_FUNCTION_FAILED;
34593490
}
34603491

34613492
/* Read version */
@@ -3507,20 +3538,26 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
35073538
faddr = ha->flt_region_fw_sec;
35083539
}
35093540

3510-
qla24xx_read_flash_data(vha, dcode, faddr, 8);
3511-
if (qla24xx_risc_firmware_invalid(dcode)) {
3512-
ql_log(ql_log_warn, vha, 0x005f,
3513-
"Unrecognized fw revision at %x.\n",
3514-
ha->flt_region_fw * 4);
3515-
ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32);
3541+
ret = qla24xx_read_flash_data(vha, dcode, faddr, 8);
3542+
if (ret) {
3543+
ql_log(ql_log_info, vha, 0x019e,
3544+
"Unable to read FW version (%x).\n", ret);
3545+
return ret;
35163546
} else {
3517-
for (i = 0; i < 4; i++)
3518-
ha->fw_revision[i] =
3547+
if (qla24xx_risc_firmware_invalid(dcode)) {
3548+
ql_log(ql_log_warn, vha, 0x005f,
3549+
"Unrecognized fw revision at %x.\n",
3550+
ha->flt_region_fw * 4);
3551+
ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32);
3552+
} else {
3553+
for (i = 0; i < 4; i++)
3554+
ha->fw_revision[i] =
35193555
be32_to_cpu((__force __be32)dcode[4+i]);
3520-
ql_dbg(ql_dbg_init, vha, 0x0060,
3521-
"Firmware revision (flash) %u.%u.%u (%x).\n",
3522-
ha->fw_revision[0], ha->fw_revision[1],
3523-
ha->fw_revision[2], ha->fw_revision[3]);
3556+
ql_dbg(ql_dbg_init, vha, 0x0060,
3557+
"Firmware revision (flash) %u.%u.%u (%x).\n",
3558+
ha->fw_revision[0], ha->fw_revision[1],
3559+
ha->fw_revision[2], ha->fw_revision[3]);
3560+
}
35243561
}
35253562

35263563
/* Check for golden firmware and get version if available */
@@ -3531,18 +3568,23 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
35313568

35323569
memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version));
35333570
faddr = ha->flt_region_gold_fw;
3534-
qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
3535-
if (qla24xx_risc_firmware_invalid(dcode)) {
3536-
ql_log(ql_log_warn, vha, 0x0056,
3537-
"Unrecognized golden fw at %#x.\n", faddr);
3538-
ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32);
3571+
ret = qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
3572+
if (ret) {
3573+
ql_log(ql_log_info, vha, 0x019f,
3574+
"Unable to read Gold FW version (%x).\n", ret);
35393575
return ret;
3540-
}
3541-
3542-
for (i = 0; i < 4; i++)
3543-
ha->gold_fw_version[i] =
3544-
be32_to_cpu((__force __be32)dcode[4+i]);
3576+
} else {
3577+
if (qla24xx_risc_firmware_invalid(dcode)) {
3578+
ql_log(ql_log_warn, vha, 0x0056,
3579+
"Unrecognized golden fw at %#x.\n", faddr);
3580+
ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32);
3581+
return QLA_FUNCTION_FAILED;
3582+
}
35453583

3584+
for (i = 0; i < 4; i++)
3585+
ha->gold_fw_version[i] =
3586+
be32_to_cpu((__force __be32)dcode[4+i]);
3587+
}
35463588
return ret;
35473589
}
35483590

0 commit comments

Comments
 (0)