diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2006-10-13 12:33:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-10-25 18:13:04 -0400 |
commit | 18c6c12759813c988bb05796d1b3352e98ae77de (patch) | |
tree | 4766e8b68a3ed124efc9c2c43b12a067eccf7bff /drivers | |
parent | f1663ad5dbb801e03c4c99c24d698ad5dba9aaff (diff) |
[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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 21 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 6 |
3 files changed, 25 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index b51ce8f59cb9..ca2f660a5438 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -48,6 +48,7 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | |||
48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
49 | 49 | ||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | 50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); |
51 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); | ||
51 | 52 | ||
52 | /* | 53 | /* |
53 | * Global Data in qla_os.c source file. | 54 | * Global Data in qla_os.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d5e0a124c4f4..08cb5e3fb553 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -3948,3 +3948,24 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3948 | fail_fw_integrity: | 3948 | fail_fw_integrity: |
3949 | return QLA_FUNCTION_FAILED; | 3949 | return QLA_FUNCTION_FAILED; |
3950 | } | 3950 | } |
3951 | |||
3952 | void | ||
3953 | qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) | ||
3954 | { | ||
3955 | int ret, retries; | ||
3956 | |||
3957 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
3958 | return; | ||
3959 | |||
3960 | ret = qla2x00_stop_firmware(ha); | ||
3961 | for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { | ||
3962 | qla2x00_reset_chip(ha); | ||
3963 | if (qla2x00_chip_diag(ha) != QLA_SUCCESS) | ||
3964 | continue; | ||
3965 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) | ||
3966 | continue; | ||
3967 | qla_printk(KERN_INFO, ha, | ||
3968 | "Attempting retry of stop-firmware command...\n"); | ||
3969 | ret = qla2x00_stop_firmware(ha); | ||
3970 | } | ||
3971 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 34b6eb71e450..54f561d9c7a7 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1712,8 +1712,10 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1712 | if (ha->eft) | 1712 | if (ha->eft) |
1713 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); | 1713 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); |
1714 | 1714 | ||
1715 | ha->flags.online = 0; | ||
1716 | |||
1715 | /* Stop currently executing firmware. */ | 1717 | /* Stop currently executing firmware. */ |
1716 | qla2x00_stop_firmware(ha); | 1718 | qla2x00_try_to_stop_firmware(ha); |
1717 | 1719 | ||
1718 | /* turn-off interrupts on the card */ | 1720 | /* turn-off interrupts on the card */ |
1719 | if (ha->interrupts_on) | 1721 | if (ha->interrupts_on) |
@@ -1721,8 +1723,6 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1721 | 1723 | ||
1722 | qla2x00_mem_free(ha); | 1724 | qla2x00_mem_free(ha); |
1723 | 1725 | ||
1724 | ha->flags.online = 0; | ||
1725 | |||
1726 | /* Detach interrupts */ | 1726 | /* Detach interrupts */ |
1727 | if (ha->host->irq) | 1727 | if (ha->host->irq) |
1728 | free_irq(ha->host->irq, ha); | 1728 | free_irq(ha->host->irq, ha); |