|
@@ -3131,15 +3131,25 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
|
|
scsi_qla_host_t *base_vha;
|
|
|
struct qla_hw_data *ha;
|
|
|
|
|
|
+ base_vha = pci_get_drvdata(pdev);
|
|
|
+ ha = base_vha->hw;
|
|
|
+
|
|
|
+ /* Indicate device removal to prevent future board_disable and wait
|
|
|
+ * until any pending board_disable has completed. */
|
|
|
+ set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
|
|
|
+ cancel_work_sync(&ha->board_disable);
|
|
|
+
|
|
|
/*
|
|
|
- * If the PCI device is disabled that means that probe failed and any
|
|
|
- * resources should be have cleaned up on probe exit.
|
|
|
+ * If the PCI device is disabled then there was a PCI-disconnect and
|
|
|
+ * qla2x00_disable_board_on_pci_error has taken care of most of the
|
|
|
+ * resources.
|
|
|
*/
|
|
|
- if (!atomic_read(&pdev->enable_cnt))
|
|
|
+ if (!atomic_read(&pdev->enable_cnt)) {
|
|
|
+ scsi_host_put(base_vha->host);
|
|
|
+ kfree(ha);
|
|
|
+ pci_set_drvdata(pdev, NULL);
|
|
|
return;
|
|
|
-
|
|
|
- base_vha = pci_get_drvdata(pdev);
|
|
|
- ha = base_vha->hw;
|
|
|
+ }
|
|
|
|
|
|
qla2x00_wait_for_hba_ready(base_vha);
|
|
|
|
|
@@ -4799,18 +4809,15 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
|
|
|
qla82xx_md_free(base_vha);
|
|
|
qla2x00_free_queues(ha);
|
|
|
|
|
|
- scsi_host_put(base_vha->host);
|
|
|
-
|
|
|
qla2x00_unmap_iobases(ha);
|
|
|
|
|
|
pci_release_selected_regions(ha->pdev, ha->bars);
|
|
|
- kfree(ha);
|
|
|
- ha = NULL;
|
|
|
-
|
|
|
pci_disable_pcie_error_reporting(pdev);
|
|
|
pci_disable_device(pdev);
|
|
|
- pci_set_drvdata(pdev, NULL);
|
|
|
|
|
|
+ /*
|
|
|
+ * Let qla2x00_remove_one cleanup qla_hw_data on device removal.
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/**************************************************************************
|