Commit 7eece5a0 authored by Karen Higgins's avatar Karen Higgins Committed by James Bottomley

[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: default avatarKaren Higgins <karen.higgins@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 58da51dc
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
#define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022 #define PCI_DEVICE_ID_QLOGIC_ISP8022 0x8022
#endif #endif
#define ISP4XXX_PCI_FN_1 0x1
#define ISP4XXX_PCI_FN_2 0x3
#define QLA_SUCCESS 0 #define QLA_SUCCESS 0
#define QLA_ERROR 1 #define QLA_ERROR 1
...@@ -371,7 +374,7 @@ struct scsi_qla_host { ...@@ -371,7 +374,7 @@ struct scsi_qla_host {
#define AF_LINK_UP 8 /* 0x00000100 */ #define AF_LINK_UP 8 /* 0x00000100 */
#define AF_IRQ_ATTACHED 10 /* 0x00000400 */ #define AF_IRQ_ATTACHED 10 /* 0x00000400 */
#define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */ #define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */
#define AF_HBA_GOING_AWAY 12 /* 0x00001000 */ #define AF_HA_REMOVAL 12 /* 0x00001000 */
#define AF_INTx_ENABLED 15 /* 0x00008000 */ #define AF_INTx_ENABLED 15 /* 0x00008000 */
#define AF_MSI_ENABLED 16 /* 0x00010000 */ #define AF_MSI_ENABLED 16 /* 0x00010000 */
#define AF_MSIX_ENABLED 17 /* 0x00020000 */ #define AF_MSIX_ENABLED 17 /* 0x00020000 */
......
...@@ -801,7 +801,7 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) ...@@ -801,7 +801,7 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
&ha->reg->ctrl_status); &ha->reg->ctrl_status);
readl(&ha->reg->ctrl_status); readl(&ha->reg->ctrl_status);
if (!test_bit(AF_HBA_GOING_AWAY, &ha->flags)) if (!test_bit(AF_HA_REMOVAL, &ha->flags))
set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
break; break;
......
...@@ -151,7 +151,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, ...@@ -151,7 +151,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
if (test_bit(AF_IRQ_ATTACHED, &ha->flags) && if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
test_bit(AF_INTERRUPTS_ON, &ha->flags) && test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
test_bit(AF_ONLINE, &ha->flags) && test_bit(AF_ONLINE, &ha->flags) &&
!test_bit(AF_HBA_GOING_AWAY, &ha->flags)) { !test_bit(AF_HA_REMOVAL, &ha->flags)) {
/* Do not poll for completion. Use completion queue */ /* Do not poll for completion. Use completion queue */
set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags); set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ); wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
......
...@@ -749,12 +749,6 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) ...@@ -749,12 +749,6 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
if (!pci_channel_offline(ha->pdev)) if (!pci_channel_offline(ha->pdev))
pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
if (test_bit(AF_HBA_GOING_AWAY, &ha->flags)) {
DEBUG2(ql4_printk(KERN_INFO, ha, "%s exited. HBA GOING AWAY\n",
__func__));
return;
}
if (is_qla8022(ha)) { if (is_qla8022(ha)) {
qla4_8xxx_watchdog(ha); qla4_8xxx_watchdog(ha);
} }
...@@ -1063,7 +1057,6 @@ void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha) ...@@ -1063,7 +1057,6 @@ void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha)
/* Disable the board */ /* Disable the board */
ql4_printk(KERN_INFO, ha, "Disabling the board\n"); ql4_printk(KERN_INFO, ha, "Disabling the board\n");
set_bit(AF_HBA_GOING_AWAY, &ha->flags);
qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16); qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);
qla4xxx_mark_all_devices_missing(ha); qla4xxx_mark_all_devices_missing(ha);
...@@ -1255,11 +1248,6 @@ static void qla4xxx_do_dpc(struct work_struct *work) ...@@ -1255,11 +1248,6 @@ static void qla4xxx_do_dpc(struct work_struct *work)
goto do_dpc_exit; goto do_dpc_exit;
} }
/* HBA is in the process of being permanently disabled.
* Don't process anything */
if (test_bit(AF_HBA_GOING_AWAY, &ha->flags))
return;
if (is_qla8022(ha)) { if (is_qla8022(ha)) {
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
qla4_8xxx_idc_lock(ha); qla4_8xxx_idc_lock(ha);
...@@ -1823,6 +1811,44 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, ...@@ -1823,6 +1811,44 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
return ret; return ret;
} }
/**
* qla4xxx_prevent_other_port_reinit - prevent other port from re-initialize
* @ha: pointer to adapter structure
*
* 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.
**/
static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
{
struct scsi_qla_host *other_ha = NULL;
struct pci_dev *other_pdev = NULL;
int fn = ISP4XXX_PCI_FN_2;
/*iscsi function numbers for ISP4xxx is 1 and 3*/
if (PCI_FUNC(ha->pdev->devfn) & BIT_1)
fn = ISP4XXX_PCI_FN_1;
other_pdev =
pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
fn));
/* Get other_ha if other_pdev is valid and state is enable*/
if (other_pdev) {
if (atomic_read(&other_pdev->enable_cnt)) {
other_ha = pci_get_drvdata(other_pdev);
if (other_ha) {
set_bit(AF_HA_REMOVAL, &other_ha->flags);
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: "
"Prevent %s reinit\n", __func__,
dev_name(&other_ha->pdev->dev)));
}
}
pci_dev_put(other_pdev);
}
}
/** /**
* qla4xxx_remove_adapter - calback function to remove adapter. * qla4xxx_remove_adapter - calback function to remove adapter.
* @pci_dev: PCI device pointer * @pci_dev: PCI device pointer
...@@ -1833,7 +1859,8 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) ...@@ -1833,7 +1859,8 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
ha = pci_get_drvdata(pdev); ha = pci_get_drvdata(pdev);
set_bit(AF_HBA_GOING_AWAY, &ha->flags); if (!is_qla8022(ha))
qla4xxx_prevent_other_port_reinit(ha);
/* remove devs from iscsi_sessions to scsi_devices */ /* remove devs from iscsi_sessions to scsi_devices */
qla4xxx_free_ddb_list(ha); qla4xxx_free_ddb_list(ha);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment