aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2006-10-13 12:33:38 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-25 18:13:04 -0400
commit18c6c12759813c988bb05796d1b3352e98ae77de (patch)
tree4766e8b68a3ed124efc9c2c43b12a067eccf7bff
parentf1663ad5dbb801e03c4c99c24d698ad5dba9aaff (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>
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c6
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 *);
48extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); 48extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
49 49
50extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); 50extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
51extern 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)
3948fail_fw_integrity: 3948fail_fw_integrity:
3949 return QLA_FUNCTION_FAILED; 3949 return QLA_FUNCTION_FAILED;
3950} 3950}
3951
3952void
3953qla2x00_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);