diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 26 |
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, | |||
1147 | IOSTAT_LOCAL_REJECT; | 1147 | IOSTAT_LOCAL_REJECT; |
1148 | saveq->iocb.un.ulpWord[4] = | 1148 | saveq->iocb.un.ulpWord[4] = |
1149 | IOERR_SLI_ABORTED; | 1149 | IOERR_SLI_ABORTED; |
1150 | |||
1151 | /* Firmware could still be in progress | ||
1152 | * of DMAing payload, so don't free data | ||
1153 | * buffer till after a hbeat. | ||
1154 | */ | ||
1155 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
1150 | } | 1156 | } |
1151 | } | 1157 | } |
1152 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 1158 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -3281,6 +3287,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3281 | LIST_HEAD(completions); | 3287 | LIST_HEAD(completions); |
3282 | struct lpfc_sli *psli = &phba->sli; | 3288 | struct lpfc_sli *psli = &phba->sli; |
3283 | struct lpfc_sli_ring *pring; | 3289 | struct lpfc_sli_ring *pring; |
3290 | struct lpfc_dmabuf *buf_ptr; | ||
3284 | LPFC_MBOXQ_t *pmb; | 3291 | LPFC_MBOXQ_t *pmb; |
3285 | struct lpfc_iocbq *iocb; | 3292 | struct lpfc_iocbq *iocb; |
3286 | IOCB_t *cmd = NULL; | 3293 | IOCB_t *cmd = NULL; |
@@ -3320,6 +3327,19 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3320 | } | 3327 | } |
3321 | } | 3328 | } |
3322 | 3329 | ||
3330 | spin_lock_irqsave(&phba->hbalock, flags); | ||
3331 | list_splice_init(&phba->elsbuf, &completions); | ||
3332 | phba->elsbuf_cnt = 0; | ||
3333 | phba->elsbuf_prev_cnt = 0; | ||
3334 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
3335 | |||
3336 | while (!list_empty(&completions)) { | ||
3337 | list_remove_head(&completions, buf_ptr, | ||
3338 | struct lpfc_dmabuf, list); | ||
3339 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
3340 | kfree(buf_ptr); | ||
3341 | } | ||
3342 | |||
3323 | /* Return any active mbox cmds */ | 3343 | /* Return any active mbox cmds */ |
3324 | del_timer_sync(&psli->mbox_tmo); | 3344 | del_timer_sync(&psli->mbox_tmo); |
3325 | spin_lock_irqsave(&phba->hbalock, flags); | 3345 | spin_lock_irqsave(&phba->hbalock, flags); |
@@ -3490,6 +3510,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3490 | pring->txcmplq_cnt--; | 3510 | pring->txcmplq_cnt--; |
3491 | spin_unlock_irq(&phba->hbalock); | 3511 | spin_unlock_irq(&phba->hbalock); |
3492 | 3512 | ||
3513 | /* Firmware could still be in progress of DMAing | ||
3514 | * payload, so don't free data buffer till after | ||
3515 | * a hbeat. | ||
3516 | */ | ||
3517 | abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE; | ||
3518 | |||
3493 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; | 3519 | abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
3494 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; | 3520 | abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; |
3495 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; | 3521 | abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; |