[SCSI] qla2xxx: Workaround D3 power-management issues.
Early ISP2432 parts have a known hardware issue when coming out of a D3 hot state. This issue can result in a hung PCIe link. Recent firmwares contain a workaround whereby the stop-firmware mailbox command prevents the ISP from entering the D3 hot state. In order to ensure that the workaround succeeded the driver must verify that the stop-firmware mailbox command completes successfully. In the event of a failure, the driver attempts a shutdown-retry after resetting the ISP and re-executing firmware. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
Родитель
f1663ad5db
Коммит
18c6c12759
|
@ -48,6 +48,7 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
|
|||
extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
|
|
|
@ -3948,3 +3948,24 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
|
|||
fail_fw_integrity:
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
void
|
||||
qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
|
||||
{
|
||||
int ret, retries;
|
||||
|
||||
if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
|
||||
return;
|
||||
|
||||
ret = qla2x00_stop_firmware(ha);
|
||||
for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) {
|
||||
qla2x00_reset_chip(ha);
|
||||
if (qla2x00_chip_diag(ha) != QLA_SUCCESS)
|
||||
continue;
|
||||
if (qla2x00_setup_chip(ha) != QLA_SUCCESS)
|
||||
continue;
|
||||
qla_printk(KERN_INFO, ha,
|
||||
"Attempting retry of stop-firmware command...\n");
|
||||
ret = qla2x00_stop_firmware(ha);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1712,8 +1712,10 @@ qla2x00_free_device(scsi_qla_host_t *ha)
|
|||
if (ha->eft)
|
||||
qla2x00_trace_control(ha, TC_DISABLE, 0, 0);
|
||||
|
||||
ha->flags.online = 0;
|
||||
|
||||
/* Stop currently executing firmware. */
|
||||
qla2x00_stop_firmware(ha);
|
||||
qla2x00_try_to_stop_firmware(ha);
|
||||
|
||||
/* turn-off interrupts on the card */
|
||||
if (ha->interrupts_on)
|
||||
|
@ -1721,8 +1723,6 @@ qla2x00_free_device(scsi_qla_host_t *ha)
|
|||
|
||||
qla2x00_mem_free(ha);
|
||||
|
||||
ha->flags.online = 0;
|
||||
|
||||
/* Detach interrupts */
|
||||
if (ha->host->irq)
|
||||
free_irq(ha->host->irq, ha);
|
||||
|
|
Загрузка…
Ссылка в новой задаче