aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaren Higgins <karen.higgins@qlogic.com>2011-03-21 06:34:29 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 13:53:01 -0400
commit7eece5a084264c1bff908b0d6a1b176b39dd272f (patch)
tree953d4a0bc0ec43f5b91b53ea43e60cc32d38f4dd
parent58da51dcfc13b2222ce8565e308852aef001f5d2 (diff)
[SCSI] qla4xxx: Prevent other port reinitialization during remove_adapter
remove ha flag AF_HBA_GOING_AWAY and added flag AF_HA_REMOVAL to mark the other ISP-4xxx port to indicate that the driver is being removed, so that the other port will not re-initialize while in the process of removing the ha due to driver unload or hba hotplug. Signed-off-by: Karen Higgins <karen.higgins@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c53
4 files changed, 46 insertions, 16 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 7aa60ee485e1..c1f8d1b150f7 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -53,6 +53,9 @@
53#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022 53#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022
54#endif 54#endif
55 55
56#define ISP4XXX_PCI_FN_1 0x1
57#define ISP4XXX_PCI_FN_2 0x3
58
56#define QLA_SUCCESS 0 59#define QLA_SUCCESS 0
57#define QLA_ERROR 1 60#define QLA_ERROR 1
58 61
@@ -371,7 +374,7 @@ struct scsi_qla_host {
371#define AF_LINK_UP 8 /* 0x00000100 */ 374#define AF_LINK_UP 8 /* 0x00000100 */
372#define AF_IRQ_ATTACHED 10 /* 0x00000400 */ 375#define AF_IRQ_ATTACHED 10 /* 0x00000400 */
373#define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */ 376#define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */
374#define AF_HBA_GOING_AWAY 12 /* 0x00001000 */ 377#define AF_HA_REMOVAL 12 /* 0x00001000 */
375#define AF_INTx_ENABLED 15 /* 0x00008000 */ 378#define AF_INTx_ENABLED 15 /* 0x00008000 */
376#define AF_MSI_ENABLED 16 /* 0x00010000 */ 379#define AF_MSI_ENABLED 16 /* 0x00010000 */
377#define AF_MSIX_ENABLED 17 /* 0x00020000 */ 380#define AF_MSIX_ENABLED 17 /* 0x00020000 */
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 2ef1a986f5c0..2f40ac761cd4 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -801,7 +801,7 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
801 &ha->reg->ctrl_status); 801 &ha->reg->ctrl_status);
802 readl(&ha->reg->ctrl_status); 802 readl(&ha->reg->ctrl_status);
803 803
804 if (!test_bit(AF_HBA_GOING_AWAY, &ha->flags)) 804 if (!test_bit(AF_HA_REMOVAL, &ha->flags))
805 set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); 805 set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
806 806
807 break; 807 break;
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 379df2bde9db..199fa643cdad 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -151,7 +151,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
151 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) && 151 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
152 test_bit(AF_INTERRUPTS_ON, &ha->flags) && 152 test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
153 test_bit(AF_ONLINE, &ha->flags) && 153 test_bit(AF_ONLINE, &ha->flags) &&
154 !test_bit(AF_HBA_GOING_AWAY, &ha->flags)) { 154 !test_bit(AF_HA_REMOVAL, &ha->flags)) {
155 /* Do not poll for completion. Use completion queue */ 155 /* Do not poll for completion. Use completion queue */
156 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); 156 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
157 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ); 157 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 1d5c6fbbfaae..f80b702730ad 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -749,12 +749,6 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
749 if (!pci_channel_offline(ha->pdev)) 749 if (!pci_channel_offline(ha->pdev))
750 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 750 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
751 751
752 if (test_bit(AF_HBA_GOING_AWAY, &ha->flags)) {
753 DEBUG2(ql4_printk(KERN_INFO, ha, "%s exited. HBA GOING AWAY\n",
754 __func__));
755 return;
756 }
757
758 if (is_qla8022(ha)) { 752 if (is_qla8022(ha)) {
759 qla4_8xxx_watchdog(ha); 753 qla4_8xxx_watchdog(ha);
760 } 754 }
@@ -1063,7 +1057,6 @@ void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha)
1063 1057
1064 /* Disable the board */ 1058 /* Disable the board */
1065 ql4_printk(KERN_INFO, ha, "Disabling the board\n"); 1059 ql4_printk(KERN_INFO, ha, "Disabling the board\n");
1066 set_bit(AF_HBA_GOING_AWAY, &ha->flags);
1067 1060
1068 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16); 1061 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);
1069 qla4xxx_mark_all_devices_missing(ha); 1062 qla4xxx_mark_all_devices_missing(ha);
@@ -1255,11 +1248,6 @@ static void qla4xxx_do_dpc(struct work_struct *work)
1255 goto do_dpc_exit; 1248 goto do_dpc_exit;
1256 } 1249 }
1257 1250
1258 /* HBA is in the process of being permanently disabled.
1259 * Don't process anything */
1260 if (test_bit(AF_HBA_GOING_AWAY, &ha->flags))
1261 return;
1262
1263 if (is_qla8022(ha)) { 1251 if (is_qla8022(ha)) {
1264 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { 1252 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
1265 qla4_8xxx_idc_lock(ha); 1253 qla4_8xxx_idc_lock(ha);
@@ -1824,6 +1812,44 @@ probe_disable_device:
1824} 1812}
1825 1813
1826/** 1814/**
1815 * qla4xxx_prevent_other_port_reinit - prevent other port from re-initialize
1816 * @ha: pointer to adapter structure
1817 *
1818 * Mark the other ISP-4xxx port to indicate that the driver is being removed,
1819 * so that the other port will not re-initialize while in the process of
1820 * removing the ha due to driver unload or hba hotplug.
1821 **/
1822static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
1823{
1824 struct scsi_qla_host *other_ha = NULL;
1825 struct pci_dev *other_pdev = NULL;
1826 int fn = ISP4XXX_PCI_FN_2;
1827
1828 /*iscsi function numbers for ISP4xxx is 1 and 3*/
1829 if (PCI_FUNC(ha->pdev->devfn) & BIT_1)
1830 fn = ISP4XXX_PCI_FN_1;
1831
1832 other_pdev =
1833 pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
1834 ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
1835 fn));
1836
1837 /* Get other_ha if other_pdev is valid and state is enable*/
1838 if (other_pdev) {
1839 if (atomic_read(&other_pdev->enable_cnt)) {
1840 other_ha = pci_get_drvdata(other_pdev);
1841 if (other_ha) {
1842 set_bit(AF_HA_REMOVAL, &other_ha->flags);
1843 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: "
1844 "Prevent %s reinit\n", __func__,
1845 dev_name(&other_ha->pdev->dev)));
1846 }
1847 }
1848 pci_dev_put(other_pdev);
1849 }
1850}
1851
1852/**
1827 * qla4xxx_remove_adapter - calback function to remove adapter. 1853 * qla4xxx_remove_adapter - calback function to remove adapter.
1828 * @pci_dev: PCI device pointer 1854 * @pci_dev: PCI device pointer
1829 **/ 1855 **/
@@ -1833,7 +1859,8 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
1833 1859
1834 ha = pci_get_drvdata(pdev); 1860 ha = pci_get_drvdata(pdev);
1835 1861
1836 set_bit(AF_HBA_GOING_AWAY, &ha->flags); 1862 if (!is_qla8022(ha))
1863 qla4xxx_prevent_other_port_reinit(ha);
1837 1864
1838 /* remove devs from iscsi_sessions to scsi_devices */ 1865 /* remove devs from iscsi_sessions to scsi_devices */
1839 qla4xxx_free_ddb_list(ha); 1866 qla4xxx_free_ddb_list(ha);