drivers/scsi/lpfc/lpfc_mem.c

Source file repositories/reference/linux-study-clean/drivers/scsi/lpfc/lpfc_mem.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/lpfc/lpfc_mem.c
Extension
.c
Size
22208 bytes
Lines
762
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

bf_get(lpfc_mqe_command, &mbox->u.mqe) == MBX_SLI4_CONFIG) {
		lpfc_sli4_mbox_cmd_free(phba, mbox);
	} else {
		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
	}
}

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
 * @phba: HBA to allocate pools for
 * @align: alignment requirement for blocks; must be a power of two
 *
 * Description: Creates and allocates PCI pools lpfc_mbuf_pool,
 * lpfc_hrb_pool.  Creates and allocates kmalloc-backed mempools
 * for LPFC_MBOXQ_t and lpfc_nodelist.  Also allocates the VPI bitmask.
 *
 * Notes: Not interrupt-safe.  Must be called with no locks held.  If any
 * allocation fails, frees all successfully allocated memory before returning.
 *
 * Returns:
 *   0 on success
 *   -ENOMEM on failure (if any memory allocations fail)
 **/
int
lpfc_mem_alloc(struct lpfc_hba *phba, int align)
{
	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
	int i;


	phba->lpfc_mbuf_pool = dma_pool_create("lpfc_mbuf_pool", &phba->pcidev->dev,
							LPFC_BPL_SIZE,
							align, 0);
	if (!phba->lpfc_mbuf_pool)
		goto fail;

	pool->elements = kmalloc_objs(struct lpfc_dmabuf, LPFC_MBUF_POOL_SIZE);
	if (!pool->elements)
		goto fail_free_lpfc_mbuf_pool;

	pool->max_count = 0;
	pool->current_count = 0;
	for ( i = 0; i < LPFC_MBUF_POOL_SIZE; i++) {
		pool->elements[i].virt = dma_pool_alloc(phba->lpfc_mbuf_pool,
				       GFP_KERNEL, &pool->elements[i].phys);
		if (!pool->elements[i].virt)
			goto fail_free_mbuf_pool;
		pool->max_count++;
		pool->current_count++;
	}

	phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MBX_POOL_SIZE,
							  sizeof(LPFC_MBOXQ_t));
	if (!phba->mbox_mem_pool)
		goto fail_free_mbuf_pool;

	phba->nlp_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE,
						sizeof(struct lpfc_nodelist));
	if (!phba->nlp_mem_pool)
		goto fail_free_mbox_pool;

	if (phba->sli_rev == LPFC_SLI_REV4) {
		phba->rrq_pool =
			mempool_create_kmalloc_pool(LPFC_RRQ_POOL_SIZE,
						sizeof(struct lpfc_node_rrq));
		if (!phba->rrq_pool)
			goto fail_free_nlp_mem_pool;
		phba->lpfc_hrb_pool = dma_pool_create("lpfc_hrb_pool",
					      &phba->pcidev->dev,
					      LPFC_HDR_BUF_SIZE, align, 0);
		if (!phba->lpfc_hrb_pool)
			goto fail_free_rrq_mem_pool;

Annotation

Implementation Notes