summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 8377624d76..eda3bdab93 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1842,10 +1842,18 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
return qla2x00_post_work(vha, e);
}
+static void qla_rscn_gen_tick(scsi_qla_host_t *vha, u32 *ret_rscn_gen)
+{
+ *ret_rscn_gen = atomic_inc_return(&vha->rscn_gen);
+ /* memory barrier */
+ wmb();
+}
+
void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport;
unsigned long flags;
+ u32 rscn_gen;
switch (ea->id.b.rsvd_1) {
case RSCN_PORT_ADDR:
@@ -1875,15 +1883,16 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
* Otherwise we're already in the middle of a relogin
*/
fcport->scan_needed = 1;
- fcport->rscn_gen++;
+ qla_rscn_gen_tick(vha, &fcport->rscn_gen);
}
} else {
fcport->scan_needed = 1;
- fcport->rscn_gen++;
+ qla_rscn_gen_tick(vha, &fcport->rscn_gen);
}
}
break;
case RSCN_AREA_ADDR:
+ qla_rscn_gen_tick(vha, &rscn_gen);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->flags & FCF_FCP2_DEVICE &&
atomic_read(&fcport->state) == FCS_ONLINE)
@@ -1891,11 +1900,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
fcport->scan_needed = 1;
- fcport->rscn_gen++;
+ fcport->rscn_gen = rscn_gen;
}
}
break;
case RSCN_DOM_ADDR:
+ qla_rscn_gen_tick(vha, &rscn_gen);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->flags & FCF_FCP2_DEVICE &&
atomic_read(&fcport->state) == FCS_ONLINE)
@@ -1903,19 +1913,20 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
fcport->scan_needed = 1;
- fcport->rscn_gen++;
+ fcport->rscn_gen = rscn_gen;
}
}
break;
case RSCN_FAB_ADDR:
default:
+ qla_rscn_gen_tick(vha, &rscn_gen);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->flags & FCF_FCP2_DEVICE &&
atomic_read(&fcport->state) == FCS_ONLINE)
continue;
fcport->scan_needed = 1;
- fcport->rscn_gen++;
+ fcport->rscn_gen = rscn_gen;
}
break;
}
@@ -1924,6 +1935,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
+ vha->scan.rscn_gen_start = atomic_read(&vha->rscn_gen);
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
@@ -6393,10 +6405,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
qlt_do_generation_tick(vha, &discovery_gen);
if (USE_ASYNC_SCAN(ha)) {
- rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI,
- NULL);
- if (rval)
- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+ /* start of scan begins here */
+ vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen);
+ qla_fab_scan_start(vha);
} else {
list_for_each_entry(fcport, &vha->vp_fcports, list)
fcport->scan_state = QLA_FCPORT_SCAN;
@@ -8207,15 +8218,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)) {
@@ -8246,9 +8263,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)) {
@@ -8306,6 +8329,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");
@@ -8347,8 +8371,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)) {
@@ -8420,11 +8450,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]);
@@ -8438,7 +8467,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) {
@@ -8454,7 +8488,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]);
@@ -8483,7 +8523,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",
@@ -8509,11 +8556,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;
}