diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0143baf4ba3..f32cd9acd3f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -547,8 +547,10 @@ void lpfc_hb_timeout_handler(struct lpfc_hba *phba) { LPFC_MBOXQ_t *pmboxq; + struct lpfc_dmabuf *buf_ptr; int retval; struct lpfc_sli *psli = &phba->sli; + LIST_HEAD(completions); if ((phba->link_state == LPFC_HBA_ERROR) || (phba->pport->load_flag & FC_UNLOADING) || @@ -575,6 +577,24 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) } spin_unlock_irq(&phba->pport->work_port_lock); + if (phba->elsbuf_cnt && + (phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) { + spin_lock_irq(&phba->hbalock); + list_splice_init(&phba->elsbuf, &completions); + phba->elsbuf_cnt = 0; + phba->elsbuf_prev_cnt = 0; + spin_unlock_irq(&phba->hbalock); + + 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); + } + } + phba->elsbuf_prev_cnt = phba->elsbuf_cnt; + + /* If there is no heart beat outstanding, issue a heartbeat command */ if (!phba->hb_outstanding) { pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); @@ -1999,6 +2019,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) /* Initialize list of fabric iocbs */ INIT_LIST_HEAD(&phba->fabric_iocb_list); + /* Initialize list to save ELS buffers */ + INIT_LIST_HEAD(&phba->elsbuf); + vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); if (!vport) goto out_kthread_stop; |