diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mem.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mem.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 812d0cd7c86d..ed419aad2b1f 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -38,10 +38,29 @@ #include "lpfc_scsi.h" #include "lpfc.h" #include "lpfc_crtn.h" +#include "lpfc_logmsg.h" #define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */ #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ +#define LPFC_DEVICE_DATA_POOL_SIZE 64 /* max elements in device data pool */ +int +lpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *phba) { + size_t bytes; + int max_xri = phba->sli4_hba.max_cfg_param.max_xri; + + if (max_xri <= 0) + return -ENOMEM; + bytes = ((BITS_PER_LONG - 1 + max_xri) / BITS_PER_LONG) * + sizeof(unsigned long); + phba->cfg_rrq_xri_bitmap_sz = bytes; + phba->active_rrq_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE, + bytes); + if (!phba->active_rrq_pool) + return -ENOMEM; + else + return 0; +} /** * lpfc_mem_alloc - create and allocate all PCI and memory pools @@ -146,6 +165,16 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) phba->lpfc_drb_pool = NULL; } + if (phba->cfg_EnableXLane) { + phba->device_data_mem_pool = mempool_create_kmalloc_pool( + LPFC_DEVICE_DATA_POOL_SIZE, + sizeof(struct lpfc_device_data)); + if (!phba->device_data_mem_pool) + goto fail_free_hrb_pool; + } else { + phba->device_data_mem_pool = NULL; + } + return 0; fail_free_hrb_pool: pci_pool_destroy(phba->lpfc_hrb_pool); @@ -188,6 +217,7 @@ lpfc_mem_free(struct lpfc_hba *phba) { int i; struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; + struct lpfc_device_data *device_data; /* Free HBQ pools */ lpfc_sli_hbqbuf_free_all(phba); @@ -209,6 +239,10 @@ lpfc_mem_free(struct lpfc_hba *phba) /* Free NLP memory pool */ mempool_destroy(phba->nlp_mem_pool); phba->nlp_mem_pool = NULL; + if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) { + mempool_destroy(phba->active_rrq_pool); + phba->active_rrq_pool = NULL; + } /* Free mbox memory pool */ mempool_destroy(phba->mbox_mem_pool); @@ -227,6 +261,19 @@ lpfc_mem_free(struct lpfc_hba *phba) pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); phba->lpfc_scsi_dma_buf_pool = NULL; + /* Free Device Data memory pool */ + if (phba->device_data_mem_pool) { + /* Ensure all objects have been returned to the pool */ + while (!list_empty(&phba->luns)) { + device_data = list_first_entry(&phba->luns, + struct lpfc_device_data, + listentry); + list_del(&device_data->listentry); + mempool_free(device_data, phba->device_data_mem_pool); + } + mempool_destroy(phba->device_data_mem_pool); + } + phba->device_data_mem_pool = NULL; return; } |