summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorSawan Chandak2016-07-06 17:14:25 +0200
committerMartin K. Petersen2016-07-15 21:31:31 +0200
commit783e0dc4f66ade6bbd8833b6bae778158d54c1a6 (patch)
tree730b6f3f3b3912a45e70b07ee2504c820f883385 /drivers/scsi/qla2xxx/qla_os.c
parentqla2xxx: Properly reset firmware statistics. (diff)
downloadkernel-qcow2-linux-783e0dc4f66ade6bbd8833b6bae778158d54c1a6.tar.gz
kernel-qcow2-linux-783e0dc4f66ade6bbd8833b6bae778158d54c1a6.tar.xz
kernel-qcow2-linux-783e0dc4f66ade6bbd8833b6bae778158d54c1a6.zip
qla2xxx: Check for device state before unloading the driver.
During hot swap of PCI device, there can be PCI error on device, during normal driver unload. The race between normal driver unload and driver unload due to PCI error, can lead to system crash.Fix is to check if there is unload going on and allow that function to unload the driver. Signed-off-by: Sawan Chandak <sawan.chandak@qlogic.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f1a2394a99e5..fde7ee17ed85 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -897,12 +897,16 @@ static void
qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
while (((qla2x00_reset_active(vha)) || ha->dpc_active ||
ha->flags.mbox_busy) ||
test_bit(FX00_RESET_RECOVERY, &vha->dpc_flags) ||
- test_bit(FX00_TARGET_SCAN, &vha->dpc_flags))
+ test_bit(FX00_TARGET_SCAN, &vha->dpc_flags)) {
+ if (test_bit(UNLOADING, &base_vha->dpc_flags))
+ break;
msleep(1000);
+ }
}
int
@@ -2954,10 +2958,7 @@ iospace_config_failed:
ha = NULL;
probe_out:
- pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
- if (test_bit(UNLOADING, &base_vha->dpc_flags))
- return -ENODEV;
return ret;
}
@@ -3138,6 +3139,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
qla2x00_wait_for_hba_ready(base_vha);
+ /* if UNLOAD flag is already set, then continue unload,
+ * where it was set first.
+ */
+ if (test_bit(UNLOADING, &base_vha->dpc_flags))
+ return;
+
set_bit(UNLOADING, &base_vha->dpc_flags);
if (IS_QLAFX00(ha))
@@ -4917,6 +4924,12 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
struct pci_dev *pdev = ha->pdev;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ /* if UNLOAD flag is already set, then continue unload,
+ * where it was set first.
+ */
+ if (test_bit(UNLOADING, &base_vha->dpc_flags))
+ return;
+
ql_log(ql_log_warn, base_vha, 0x015b,
"Disabling adapter.\n");