]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
lpfc: Fix for cleaning up stale ring flag and sp_queue_event entries
authorJames Smart <james.smart@emulex.com>
Wed, 21 May 2014 12:04:59 +0000 (08:04 -0400)
committerChristoph Hellwig <hch@lst.de>
Mon, 2 Jun 2014 16:29:49 +0000 (18:29 +0200)
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>
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c

index 2fb0396c3806bf7cc1314f2db4e5c68e5529538e..38a4119d6294bd7d58af09b944e827c7e931b262 100644 (file)
@@ -819,6 +819,52 @@ lpfc_hba_down_prep(struct lpfc_hba *phba)
        return 0;
 }
 
+/**
+ * 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;
 }
 
index f2a614a1f8f2ce6f7918f533533a9d94f7cf5c70..bdcdadd6db4ac5b627ef1cf0dba3b1045d163b29 100644 (file)
@@ -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);