diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-03-04 14:26:53 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-03-05 13:03:17 -0500 |
commit | 50a29aec9c47d26e869df83ef1d69e3b63c83bf4 (patch) | |
tree | f7f035b965da8850078f48a039a10d2ed541d1b2 /drivers | |
parent | 21f1e91d4bb8fa7cd3a59938471fc7c7d27f82da (diff) |
[SCSI] qla4xxx: fix host reset dpc race
The host reset callout could be starting to reset the hba at the same
time the dpc thread is. This creates lots of problems because they both
want to do wierd things with the firmware and interrupts, etc.
This patch just has the host reset function fully shutdown the dpc
thread before resetting the hba.
This patch also moves the setting of the session online bit to fix
a potential race with the dpc thread and iscsi recovery thread.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Acked-by: David C Somayajulu <david.somayajulu@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 13 |
2 files changed, 10 insertions, 5 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 10b3b9a620f3..109c5f5985ec 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -1299,9 +1299,9 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | |||
1299 | ddb_entry->fw_ddb_device_state = state; | 1299 | ddb_entry->fw_ddb_device_state = state; |
1300 | /* Device is back online. */ | 1300 | /* Device is back online. */ |
1301 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { | 1301 | if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { |
1302 | atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | ||
1302 | atomic_set(&ddb_entry->port_down_timer, | 1303 | atomic_set(&ddb_entry->port_down_timer, |
1303 | ha->port_down_retry_count); | 1304 | ha->port_down_retry_count); |
1304 | atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); | ||
1305 | atomic_set(&ddb_entry->relogin_retry_count, 0); | 1305 | atomic_set(&ddb_entry->relogin_retry_count, 0); |
1306 | atomic_set(&ddb_entry->relogin_timer, 0); | 1306 | atomic_set(&ddb_entry->relogin_timer, 0); |
1307 | clear_bit(DF_RELOGIN, &ddb_entry->flags); | 1307 | clear_bit(DF_RELOGIN, &ddb_entry->flags); |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c3c59d763037..10a233e65bc9 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -864,8 +864,9 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) | |||
864 | * qla4xxx_recover_adapter - recovers adapter after a fatal error | 864 | * qla4xxx_recover_adapter - recovers adapter after a fatal error |
865 | * @ha: Pointer to host adapter structure. | 865 | * @ha: Pointer to host adapter structure. |
866 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list | 866 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list |
867 | * after adapter recovery has completed. | 867 | * |
868 | * 0=preserve ddb list, 1=destroy and rebuild ddb list | 868 | * renew_ddb_list value can be 0=preserve ddb list, 1=destroy and rebuild |
869 | * ddb list. | ||
869 | **/ | 870 | **/ |
870 | static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | 871 | static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, |
871 | uint8_t renew_ddb_list) | 872 | uint8_t renew_ddb_list) |
@@ -874,6 +875,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |||
874 | 875 | ||
875 | /* Stall incoming I/O until we are done */ | 876 | /* Stall incoming I/O until we are done */ |
876 | clear_bit(AF_ONLINE, &ha->flags); | 877 | clear_bit(AF_ONLINE, &ha->flags); |
878 | |||
877 | DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no, | 879 | DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no, |
878 | __func__)); | 880 | __func__)); |
879 | 881 | ||
@@ -1600,9 +1602,12 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1600 | return FAILED; | 1602 | return FAILED; |
1601 | } | 1603 | } |
1602 | 1604 | ||
1603 | if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) { | 1605 | /* make sure the dpc thread is stopped while we reset the hba */ |
1606 | clear_bit(AF_ONLINE, &ha->flags); | ||
1607 | flush_workqueue(ha->dpc_thread); | ||
1608 | |||
1609 | if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) | ||
1604 | return_status = SUCCESS; | 1610 | return_status = SUCCESS; |
1605 | } | ||
1606 | 1611 | ||
1607 | dev_info(&ha->pdev->dev, "HOST RESET %s.\n", | 1612 | dev_info(&ha->pdev->dev, "HOST RESET %s.\n", |
1608 | return_status == FAILED ? "FAILED" : "SUCCEDED"); | 1613 | return_status == FAILED ? "FAILED" : "SUCCEDED"); |