[SCSI] qla2xxx: Correct ISP abort semantics for NVRAM, VPD, and flash update.
Ensure that an ISP-abort has completed before performing any update. After the update do not wait for an ISP-abort completion, instead just wait until the ISP is reset. This avoids long delays due to waiting for loop ready in qla2x00_abort_isp(). Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com> Additional cleanups and Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
1d2874de80
commit
2533cf671d
|
@ -137,12 +137,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
|
||||||
*iter = chksum;
|
*iter = chksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||||
|
qla_printk(KERN_WARNING, ha,
|
||||||
|
"HBA not online, failing NVRAM update.\n");
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write NVRAM. */
|
/* Write NVRAM. */
|
||||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
|
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
|
||||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
|
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
|
||||||
count);
|
count);
|
||||||
|
|
||||||
|
/* NVRAM settings take effect immediately. */
|
||||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||||
|
qla2xxx_wake_dpc(vha);
|
||||||
|
qla2x00_wait_for_chip_reset(vha);
|
||||||
|
|
||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
@ -330,6 +339,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
|
||||||
if (ha->optrom_state != QLA_SWRITING)
|
if (ha->optrom_state != QLA_SWRITING)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||||
|
qla_printk(KERN_WARNING, ha,
|
||||||
|
"HBA not online, failing flash update.\n");
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||||
"Writing flash region -- 0x%x/0x%x.\n",
|
"Writing flash region -- 0x%x/0x%x.\n",
|
||||||
ha->optrom_region_start, ha->optrom_region_size));
|
ha->optrom_region_start, ha->optrom_region_size));
|
||||||
|
@ -380,6 +395,12 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
|
||||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
|
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||||
|
qla_printk(KERN_WARNING, ha,
|
||||||
|
"HBA not online, failing VPD update.\n");
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write NVRAM. */
|
/* Write NVRAM. */
|
||||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
|
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
|
||||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
|
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
|
||||||
|
|
|
@ -2261,6 +2261,7 @@ struct qla_hw_data {
|
||||||
uint32_t npiv_supported :1;
|
uint32_t npiv_supported :1;
|
||||||
uint32_t fce_enabled :1;
|
uint32_t fce_enabled :1;
|
||||||
uint32_t fac_supported :1;
|
uint32_t fac_supported :1;
|
||||||
|
uint32_t chip_reset_done :1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
/* This spinlock is used to protect "io transactions", you must
|
/* This spinlock is used to protect "io transactions", you must
|
||||||
|
|
|
@ -110,6 +110,7 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
|
||||||
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
|
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
|
||||||
|
|
||||||
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
|
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
|
||||||
|
extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
|
||||||
|
|
||||||
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
|
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
|
||||||
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
|
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
|
||||||
|
|
|
@ -61,8 +61,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
|
||||||
int rval;
|
int rval;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
struct req_que *req = ha->req_q_map[0];
|
struct req_que *req = ha->req_q_map[0];
|
||||||
|
|
||||||
/* Clear adapter flags. */
|
/* Clear adapter flags. */
|
||||||
vha->flags.online = 0;
|
vha->flags.online = 0;
|
||||||
|
ha->flags.chip_reset_done = 0;
|
||||||
vha->flags.reset_active = 0;
|
vha->flags.reset_active = 0;
|
||||||
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
||||||
atomic_set(&vha->loop_state, LOOP_DOWN);
|
atomic_set(&vha->loop_state, LOOP_DOWN);
|
||||||
|
@ -131,6 +133,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rval = qla2x00_init_rings(vha);
|
rval = qla2x00_init_rings(vha);
|
||||||
|
ha->flags.chip_reset_done = 1;
|
||||||
|
|
||||||
return (rval);
|
return (rval);
|
||||||
}
|
}
|
||||||
|
@ -3321,6 +3324,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
if (vha->flags.online) {
|
if (vha->flags.online) {
|
||||||
vha->flags.online = 0;
|
vha->flags.online = 0;
|
||||||
|
ha->flags.chip_reset_done = 0;
|
||||||
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||||
ha->qla_stats.total_isp_aborts++;
|
ha->qla_stats.total_isp_aborts++;
|
||||||
|
|
||||||
|
@ -3470,6 +3474,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
if (!status && !(status = qla2x00_init_rings(vha))) {
|
if (!status && !(status = qla2x00_init_rings(vha))) {
|
||||||
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
|
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
|
||||||
|
ha->flags.chip_reset_done = 1;
|
||||||
/* Initialize the queues in use */
|
/* Initialize the queues in use */
|
||||||
qla25xx_init_queues(ha);
|
qla25xx_init_queues(ha);
|
||||||
|
|
||||||
|
|
|
@ -535,6 +535,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
|
||||||
return (return_status);
|
return (return_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
|
||||||
|
{
|
||||||
|
int return_status;
|
||||||
|
unsigned long wait_reset;
|
||||||
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||||
|
|
||||||
|
wait_reset = 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->dpc_active) && time_before(jiffies, wait_reset)) {
|
||||||
|
|
||||||
|
msleep(1000);
|
||||||
|
|
||||||
|
if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
|
||||||
|
ha->flags.chip_reset_done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ha->flags.chip_reset_done)
|
||||||
|
return_status = QLA_SUCCESS;
|
||||||
|
else
|
||||||
|
return_status = QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
return return_status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qla2x00_wait_for_loop_ready
|
* qla2x00_wait_for_loop_ready
|
||||||
* Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
|
* Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
|
||||||
|
|
|
@ -1949,7 +1949,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha)
|
||||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||||
qla2xxx_wake_dpc(vha);
|
qla2xxx_wake_dpc(vha);
|
||||||
qla2x00_wait_for_hba_online(vha);
|
qla2x00_wait_for_chip_reset(vha);
|
||||||
scsi_unblock_requests(vha->host);
|
scsi_unblock_requests(vha->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue