Loading drivers/scsi/lpfc/lpfc_init.c +60 −19 Original line number Diff line number Diff line Loading @@ -820,29 +820,28 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) } /** * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset * lpfc_hba_free_post_buf - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * This routine will cleanup posted ELS buffers after the HBA is reset * when bringing down the SLI Layer. * * * Return codes * 0 - success. * Any other value - error. * void. **/ static int lpfc_hba_down_post_s3(struct lpfc_hba *phba) static void lpfc_hba_free_post_buf(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; struct lpfc_dmabuf *mp, *next_mp; LIST_HEAD(completions); int i; if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) lpfc_sli_hbqbuf_free_all(phba); else { /* Cleanup preposted buffers on the ELS ring */ spin_lock_irq(&phba->hbalock); pring = &psli->ring[LPFC_ELS_RING]; list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { list_del(&mp->list); Loading @@ -850,27 +849,70 @@ lpfc_hba_down_post_s3(struct lpfc_hba *phba) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } spin_unlock_irq(&phba->hbalock); } } spin_lock_irq(&phba->hbalock); /** * lpfc_hba_clean_txcmplq - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will cleanup the txcmplq after the HBA is reset when bringing * down the SLI Layer. * * Return codes * void **/ static void lpfc_hba_clean_txcmplq(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; LIST_HEAD(completions); int i; for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; if (phba->sli_rev >= LPFC_SLI_REV4) spin_lock_irq(&pring->ring_lock); else spin_lock_irq(&phba->hbalock); /* At this point in time the HBA is either reset or DOA. Either * way, nothing should be on txcmplq as it will NEVER complete. */ list_splice_init(&pring->txcmplq, &completions); if (phba->sli_rev >= LPFC_SLI_REV4) spin_unlock_irq(&pring->ring_lock); else spin_unlock_irq(&phba->hbalock); /* Cancel all the IOCBs from the completions list */ lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED); lpfc_sli_abort_iocb_ring(phba, pring); spin_lock_irq(&phba->hbalock); } spin_unlock_irq(&phba->hbalock); } /** * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset int i; * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ static int lpfc_hba_down_post_s3(struct lpfc_hba *phba) { lpfc_hba_free_post_buf(phba); lpfc_hba_clean_txcmplq(phba); return 0; } Loading @@ -890,13 +932,12 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) { struct lpfc_scsi_buf *psb, *psb_next; LIST_HEAD(aborts); int ret; unsigned long iflag = 0; struct lpfc_sglq *sglq_entry = NULL; ret = lpfc_hba_down_post_s3(phba); if (ret) return ret; lpfc_hba_free_post_buf(phba); lpfc_hba_clean_txcmplq(phba); /* At this point in time the HBA is either reset or DOA. Either * way, nothing should be on lpfc_abts_els_sgl_list, it needs to be * on the lpfc_sgl_list so that it can either be freed if the Loading Loading
drivers/scsi/lpfc/lpfc_init.c +60 −19 Original line number Diff line number Diff line Loading @@ -820,29 +820,28 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) } /** * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset * lpfc_hba_free_post_buf - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * This routine will cleanup posted ELS buffers after the HBA is reset * when bringing down the SLI Layer. * * * Return codes * 0 - success. * Any other value - error. * void. **/ static int lpfc_hba_down_post_s3(struct lpfc_hba *phba) static void lpfc_hba_free_post_buf(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; struct lpfc_dmabuf *mp, *next_mp; LIST_HEAD(completions); int i; if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) lpfc_sli_hbqbuf_free_all(phba); else { /* Cleanup preposted buffers on the ELS ring */ spin_lock_irq(&phba->hbalock); pring = &psli->ring[LPFC_ELS_RING]; list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { list_del(&mp->list); Loading @@ -850,27 +849,70 @@ lpfc_hba_down_post_s3(struct lpfc_hba *phba) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } spin_unlock_irq(&phba->hbalock); } } spin_lock_irq(&phba->hbalock); /** * lpfc_hba_clean_txcmplq - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will cleanup the txcmplq after the HBA is reset when bringing * down the SLI Layer. * * Return codes * void **/ static void lpfc_hba_clean_txcmplq(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; LIST_HEAD(completions); int i; for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; if (phba->sli_rev >= LPFC_SLI_REV4) spin_lock_irq(&pring->ring_lock); else spin_lock_irq(&phba->hbalock); /* At this point in time the HBA is either reset or DOA. Either * way, nothing should be on txcmplq as it will NEVER complete. */ list_splice_init(&pring->txcmplq, &completions); if (phba->sli_rev >= LPFC_SLI_REV4) spin_unlock_irq(&pring->ring_lock); else spin_unlock_irq(&phba->hbalock); /* Cancel all the IOCBs from the completions list */ lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED); lpfc_sli_abort_iocb_ring(phba, pring); spin_lock_irq(&phba->hbalock); } spin_unlock_irq(&phba->hbalock); } /** * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset int i; * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ static int lpfc_hba_down_post_s3(struct lpfc_hba *phba) { lpfc_hba_free_post_buf(phba); lpfc_hba_clean_txcmplq(phba); return 0; } Loading @@ -890,13 +932,12 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) { struct lpfc_scsi_buf *psb, *psb_next; LIST_HEAD(aborts); int ret; unsigned long iflag = 0; struct lpfc_sglq *sglq_entry = NULL; ret = lpfc_hba_down_post_s3(phba); if (ret) return ret; lpfc_hba_free_post_buf(phba); lpfc_hba_clean_txcmplq(phba); /* At this point in time the HBA is either reset or DOA. Either * way, nothing should be on lpfc_abts_els_sgl_list, it needs to be * on the lpfc_sgl_list so that it can either be freed if the Loading