From: David C Somayajulu Date: Thu, 24 May 2007 01:03:32 +0000 (-0700) Subject: [SCSI] qla4xxx: ql4_os.c bugfixes X-Git-Tag: v2.6.23-rc1~1053^2~144 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bee4fe8e63ea1985f3955323dbc98b6d6bd5c6f8;p=linux-2.6 [SCSI] qla4xxx: ql4_os.c bugfixes Free memory resources after invoking free_irq() in qla4xxx_free_adapter(). QLA4xxx has two pci functions per port (Ethernet and iSCSI). When one of these PCI functions issues a HBA reset, all other functions are notified and need to acknowledge and re-initialize. During module qla4xxx_remove_adapter() gets invoked. This function needs to wait if it is currently responding to a reset from another function. Signed-off-by: David Somayajulu Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index da21f5fbbf..0e4688c9e0 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -10,6 +10,10 @@ #include #include "ql4_def.h" +#include "ql4_version.h" +#include "ql4_glbl.h" +#include "ql4_dbg.h" +#include "ql4_inline.h" /* * Driver version @@ -711,7 +715,7 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) return stat; } -static void qla4xxx_hw_reset(struct scsi_qla_host *ha) +void qla4xxx_hw_reset(struct scsi_qla_host *ha) { uint32_t ctrl_status; unsigned long flags = 0; @@ -1081,13 +1085,13 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) if (ha->timer_active) qla4xxx_stop_timer(ha); - /* free extra memory */ - qla4xxx_mem_free(ha); - /* Detach interrupts */ if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) free_irq(ha->pdev->irq, ha); + /* free extra memory */ + qla4xxx_mem_free(ha); + pci_disable_device(ha->pdev); } @@ -1332,6 +1336,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) ha = pci_get_drvdata(pdev); + qla4xxx_disable_intrs(ha); + + while (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) + ssleep(1); + /* remove devs from iscsi_sessions to scsi_devices */ qla4xxx_free_ddb_list(ha);