From 51ef4c26891a734bc8416b639ad460a8162926bc Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 2 Aug 2007 11:10:31 -0400 Subject: [SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes - Fix vport ndlp ref counting errors - Fix use after free of ndlp structure - Use the correct flag to check for LOADING setting. - Fix driver unload bugs (related to shost references) after link down or rscn - Fix up HBQ initialization - Fix port_list locking around driver unload. - Fix references to hostdata as a phba - Fix GFFID type offset to work correctly with big endian structure. - Only call pci_disable_msi if the pci_enable_msi succeeded - Fix vport_delete wait/fail if in discovery - Put a reference on the nameservers ndlp when performing CT traffic. - Remove unbalanced hba unlock. - Fix up HBQ processing - Fix lpfc debugfs discovery trace output for ELS rsp cmpl - Send ADISC when rpi is 0 - Stop FDISC retrying forever - Unable to retrieve correct config parameter for vport - Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware. - Fix index-out-of-range error in iocb. Spotted by Coverity. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_mem.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_mem.c') diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 3594c469494..43c3b8a0d76 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -231,21 +231,34 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma) return; } -void * -lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle) +struct hbq_dmabuf * +lpfc_els_hbq_alloc(struct lpfc_hba *phba) { - void *ret; - ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle); - return ret; + struct hbq_dmabuf *hbqbp; + + hbqbp = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); + if (!hbqbp) + return NULL; + + hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL, + &hbqbp->dbuf.phys); + if (!hbqbp->dbuf.virt) { + kfree(hbqbp); + return NULL; + } + hbqbp->size = LPFC_BPL_SIZE; + return hbqbp; } void -lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma) +lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp) { - pci_pool_free(phba->lpfc_hbq_pool, virt, dma); + pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys); + kfree(hbqbp); return; } +/* This is ONLY called for the LPFC_ELS_HBQ */ void lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) { @@ -254,9 +267,8 @@ lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf); if (hbq_entry->tag == -1) { - lpfc_hbq_free(phba, hbq_entry->dbuf.virt, - hbq_entry->dbuf.phys); - kfree(hbq_entry); + (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) + (phba, hbq_entry); } else { lpfc_sli_free_hbq(phba, hbq_entry); } -- cgit v1.2.3-70-g09d2