summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-01-11 01:52:36 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 11:29:21 -0600
commit0ff10d46cf0a373c9c855a23cc9383ba4030d8d2 (patch)
tree111eb8303ad63cecad266d507af4c2c0bfec4d5b /drivers/scsi/lpfc/lpfc_sli.c
parentb18268fc631034882f5f3dd93daa248a3bfdd085 (diff)
downloadlinux-0ff10d46cf0a373c9c855a23cc9383ba4030d8d2.tar.bz2
[SCSI] lpfc 8.2.4 : Miscellaneous Discovery/ELS Fixes
Miscellaneous Discovery/ELS Fixes: - Delay free's of ELS requests if adapter reject conditions - Fix concurrent PLOGI vs ADISC state handling - Add retry mechanism for GFF_ID - Correct some illegal state transitions around RSCN timeouts - Fix missing return in FAN handling Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dcc48988040c..be6519793f8a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1147,6 +1147,12 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
IOSTAT_LOCAL_REJECT;
saveq->iocb.un.ulpWord[4] =
IOERR_SLI_ABORTED;
+
+ /* Firmware could still be in progress
+ * of DMAing payload, so don't free data
+ * buffer till after a hbeat.
+ */
+ saveq->iocb_flag |= LPFC_DELAY_MEM_FREE;
}
}
(cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -3281,6 +3287,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
LIST_HEAD(completions);
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
+ struct lpfc_dmabuf *buf_ptr;
LPFC_MBOXQ_t *pmb;
struct lpfc_iocbq *iocb;
IOCB_t *cmd = NULL;
@@ -3320,6 +3327,19 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
}
}
+ spin_lock_irqsave(&phba->hbalock, flags);
+ list_splice_init(&phba->elsbuf, &completions);
+ phba->elsbuf_cnt = 0;
+ phba->elsbuf_prev_cnt = 0;
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+
+ while (!list_empty(&completions)) {
+ list_remove_head(&completions, buf_ptr,
+ struct lpfc_dmabuf, list);
+ lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
+ kfree(buf_ptr);
+ }
+
/* Return any active mbox cmds */
del_timer_sync(&psli->mbox_tmo);
spin_lock_irqsave(&phba->hbalock, flags);
@@ -3490,6 +3510,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
pring->txcmplq_cnt--;
spin_unlock_irq(&phba->hbalock);
+ /* Firmware could still be in progress of DMAing
+ * payload, so don't free data buffer till after
+ * a hbeat.
+ */
+ abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE;
+
abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED;