[SCSI] qla4xxx: Fix failure of mbox 0x31

Issue:
While unloading driver MBOX 0x31 fail as DDB logout (MBOX 0x56)
operation is not completed.

Fix:
Wait for DDB Logout completion before MBOX 0x31

Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Vikas Chaudhary 2014-01-17 04:43:28 -05:00 committed by James Bottomley
parent 4ebbb5cf64
commit 28d958bad8

View File

@ -8886,10 +8886,56 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
}
}
static void qla4xxx_destroy_ddb(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry)
{
struct dev_db_entry *fw_ddb_entry = NULL;
dma_addr_t fw_ddb_entry_dma;
unsigned long wtime;
uint32_t ddb_state;
int options;
int status;
options = LOGOUT_OPTION_CLOSE_SESSION;
if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) {
ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__);
goto clear_ddb;
}
fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
&fw_ddb_entry_dma, GFP_KERNEL);
if (!fw_ddb_entry) {
ql4_printk(KERN_ERR, ha,
"%s: Unable to allocate dma buffer\n", __func__);
goto clear_ddb;
}
wtime = jiffies + (HZ * LOGOUT_TOV);
do {
status = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,
fw_ddb_entry, fw_ddb_entry_dma,
NULL, NULL, &ddb_state, NULL,
NULL, NULL);
if (status == QLA_ERROR)
goto free_ddb;
if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||
(ddb_state == DDB_DS_SESSION_FAILED))
goto free_ddb;
schedule_timeout_uninterruptible(HZ);
} while ((time_after(wtime, jiffies)));
free_ddb:
dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
fw_ddb_entry, fw_ddb_entry_dma);
clear_ddb:
qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
}
static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha)
{
struct ddb_entry *ddb_entry;
int options;
int idx;
for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
@ -8898,13 +8944,7 @@ static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha)
if ((ddb_entry != NULL) &&
(ddb_entry->ddb_type == FLASH_DDB)) {
options = LOGOUT_OPTION_CLOSE_SESSION;
if (qla4xxx_session_logout_ddb(ha, ddb_entry, options)
== QLA_ERROR)
ql4_printk(KERN_ERR, ha, "%s: Logout failed\n",
__func__);
qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
qla4xxx_destroy_ddb(ha, ddb_entry);
/*
* we have decremented the reference count of the driver
* when we setup the session to have the driver unload