[SCSI] lpfc: Fixes in mbox_timeout_handler
Analysis:
Timeout of READ_SPARM64 causes call to lpfc_mbox_timeout_handler which
reads psli->mbox_active to determine the timeout mbox. Timeout
handler then NULL's psli->mbox_active and calls
lpfc_mbx_cmpl_read_sparam(), which on timeout condition, calls
link_down(). link_down() now calls disc_done() which calls
mbox_timeout_hander() again since WORKER_MBOX_TMO is still set, which
goes back to read psli->mbox_active which is already NULL'ed.
Remove redundant if statement in lpfc_mbox_timeout_handler. pmbox is
assigned psli->mbox_active so there is no need to check if it actually
equals psli->mbox_active.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 9493ec1..46e062d 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1724,6 +1724,8 @@
return;
}
+ phba->work_hba_events &= ~WORKER_MBOX_TMO;
+
pmbox = phba->sli.mbox_active;
mb = &pmbox->mb;
@@ -1738,16 +1740,14 @@
phba->sli.sli_flag,
phba->sli.mbox_active);
- if (phba->sli.mbox_active == pmbox) {
- phba->sli.mbox_active = NULL;
- if (pmbox->mbox_cmpl) {
- mb->mbxStatus = MBX_NOT_FINISHED;
- spin_unlock_irq(phba->host->host_lock);
- (pmbox->mbox_cmpl) (phba, pmbox);
- spin_lock_irq(phba->host->host_lock);
- }
- phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
+ phba->sli.mbox_active = NULL;
+ if (pmbox->mbox_cmpl) {
+ mb->mbxStatus = MBX_NOT_FINISHED;
+ spin_unlock_irq(phba->host->host_lock);
+ (pmbox->mbox_cmpl) (phba, pmbox);
+ spin_lock_irq(phba->host->host_lock);
}
+ phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
spin_unlock_irq(phba->host->host_lock);
lpfc_mbox_abort(phba);