summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c6
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c46
2 files changed, 51 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 62a22cfae20e..3b708606b932 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -281,6 +281,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
return count;
}
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing NVRAM update.\n");
+ return -EAGAIN;
+ }
+
DEBUG2(qla_printk(KERN_INFO, ha,
"Reading flash region -- 0x%x/0x%x.\n",
ha->optrom_region_start, ha->optrom_region_size));
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 5104aefdc7e6..0de92d376677 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -676,6 +676,50 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
return (return_status);
}
+/*
+ * qla2x00_wait_for_reset_ready
+ * Wait till the HBA is online after going through
+ * <= MAX_RETRIES_OF_ISP_ABORT or
+ * finally HBA is disabled ie marked offline or flash
+ * operations are in progress.
+ *
+ * Input:
+ * ha - pointer to host adapter structure
+ *
+ * Note:
+ * Does context switching-Release SPIN_LOCK
+ * (if any) before calling this routine.
+ *
+ * Return:
+ * Success (Adapter is online/no flash ops) : 0
+ * Failed (Adapter is offline/disabled/flash ops in progress) : 1
+ */
+int
+qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
+{
+ int return_status;
+ unsigned long wait_online;
+ struct qla_hw_data *ha = vha->hw;
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+
+ wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
+ while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
+ test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+ test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+ ha->optrom_state != QLA_SWAITING ||
+ ha->dpc_active) && time_before(jiffies, wait_online))
+ msleep(1000);
+
+ if (base_vha->flags.online && ha->optrom_state == QLA_SWAITING)
+ return_status = QLA_SUCCESS;
+ else
+ return_status = QLA_FUNCTION_FAILED;
+
+ DEBUG2(printk("%s return_status=%d\n", __func__, return_status));
+
+ return return_status;
+}
+
int
qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
{
@@ -1081,7 +1125,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
qla_printk(KERN_INFO, ha,
"scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", vha->host_no, id, lun);
- if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
+ if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS)
goto eh_host_reset_lock;
/*