diff options
author | James Smart <james.smart@emulex.com> | 2014-05-21 16:04:59 +0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-06-02 20:29:49 +0400 |
commit | 68e814f587700b935f696b9e18403fe6c900a4a1 (patch) | |
tree | 19c2e4b2f788544da2c17ee587fcf65971c63983 /drivers/scsi/lpfc | |
parent | 2e61f50490d0ac4fec03b2409ea981dc4c87e4d6 (diff) | |
download | linux-68e814f587700b935f696b9e18403fe6c900a4a1.tar.xz |
lpfc: Fix for cleaning up stale ring flag and sp_queue_event entries
Fix for cleaning up stale ring flag and sp_queue_event entries.
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-By: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 48 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 1 |
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 2fb0396c3806..38a4119d6294 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -820,6 +820,52 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) } /** + * lpfc_sli4_free_sp_events - Cleanup sp_queue_events to free + * rspiocb which got deferred + * + * @phba: pointer to lpfc HBA data structure. + * + * This routine will cleanup completed slow path events after HBA is reset + * when bringing down the SLI Layer. + * + * + * Return codes + * void. + **/ +static void +lpfc_sli4_free_sp_events(struct lpfc_hba *phba) +{ + struct lpfc_iocbq *rspiocbq; + struct hbq_dmabuf *dmabuf; + struct lpfc_cq_event *cq_event; + + spin_lock_irq(&phba->hbalock); + phba->hba_flag &= ~HBA_SP_QUEUE_EVT; + spin_unlock_irq(&phba->hbalock); + + while (!list_empty(&phba->sli4_hba.sp_queue_event)) { + /* Get the response iocb from the head of work queue */ + spin_lock_irq(&phba->hbalock); + list_remove_head(&phba->sli4_hba.sp_queue_event, + cq_event, struct lpfc_cq_event, list); + spin_unlock_irq(&phba->hbalock); + + switch (bf_get(lpfc_wcqe_c_code, &cq_event->cqe.wcqe_cmpl)) { + case CQE_CODE_COMPL_WQE: + rspiocbq = container_of(cq_event, struct lpfc_iocbq, + cq_event); + lpfc_sli_release_iocbq(phba, rspiocbq); + break; + case CQE_CODE_RECEIVE: + case CQE_CODE_RECEIVE_V1: + dmabuf = container_of(cq_event, struct hbq_dmabuf, + cq_event); + lpfc_in_buf_free(phba, &dmabuf->dbuf); + } + } +} + +/** * lpfc_hba_free_post_buf - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * @@ -981,6 +1027,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag); list_splice(&aborts, &phba->lpfc_scsi_buf_list_put); spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag); + + lpfc_sli4_free_sp_events(phba); return 0; } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f2a614a1f8f2..bdcdadd6db4a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -9244,6 +9244,7 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba) pring->sli.sli3.next_cmdidx = 0; pring->sli.sli3.local_getidx = 0; pring->sli.sli3.cmdidx = 0; + pring->flag = 0; INIT_LIST_HEAD(&pring->txq); INIT_LIST_HEAD(&pring->txcmplq); INIT_LIST_HEAD(&pring->iocb_continueq); |