drivers/scsi/elx/efct/efct_io.c

Source file repositories/reference/linux-study-clean/drivers/scsi/elx/efct/efct_io.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/efct/efct_io.c
Extension
.c
Size
4208 bytes
Lines
191
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

struct efct_io_pool {
	struct efct *efct;
	spinlock_t lock;	/* IO pool lock */
	u32 io_num_ios;		/* Total IOs allocated */
	struct efct_io *ios[EFCT_NUM_SCSI_IOS];
	struct list_head freelist;

};

struct efct_io_pool *
efct_io_pool_create(struct efct *efct, u32 num_sgl)
{
	u32 i = 0;
	struct efct_io_pool *io_pool;
	struct efct_io *io;

	/* Allocate the IO pool */
	io_pool = kzalloc_obj(*io_pool);
	if (!io_pool)
		return NULL;

	io_pool->efct = efct;
	INIT_LIST_HEAD(&io_pool->freelist);
	/* initialize IO pool lock */
	spin_lock_init(&io_pool->lock);

	for (i = 0; i < EFCT_NUM_SCSI_IOS; i++) {
		io = kzalloc_obj(*io);
		if (!io)
			break;

		io_pool->io_num_ios++;
		io_pool->ios[i] = io;
		io->tag = i;
		io->instance_index = i;

		/* Allocate a response buffer */
		io->rspbuf.size = SCSI_RSP_BUF_LENGTH;
		io->rspbuf.virt = dma_alloc_coherent(&efct->pci->dev,
						     io->rspbuf.size,
						     &io->rspbuf.phys, GFP_KERNEL);
		if (!io->rspbuf.virt) {
			efc_log_err(efct, "dma_alloc rspbuf failed\n");
			efct_io_pool_free(io_pool);
			return NULL;
		}

		/* Allocate SGL */
		io->sgl = kzalloc(sizeof(*io->sgl) * num_sgl, GFP_KERNEL);
		if (!io->sgl) {
			efct_io_pool_free(io_pool);
			return NULL;
		}

		io->sgl_allocated = num_sgl;
		io->sgl_count = 0;

		INIT_LIST_HEAD(&io->list_entry);
		list_add_tail(&io->list_entry, &io_pool->freelist);
	}

	return io_pool;
}

int
efct_io_pool_free(struct efct_io_pool *io_pool)
{
	struct efct *efct;
	u32 i;
	struct efct_io *io;

	if (io_pool) {
		efct = io_pool->efct;

		for (i = 0; i < io_pool->io_num_ios; i++) {
			io = io_pool->ios[i];
			if (!io)
				continue;

			kfree(io->sgl);
			dma_free_coherent(&efct->pci->dev,
					  io->rspbuf.size, io->rspbuf.virt,
					  io->rspbuf.phys);
			memset(&io->rspbuf, 0, sizeof(struct efc_dma));
		}

		kfree(io_pool);
		efct->xport->io_pool = NULL;
	}

Annotation

Implementation Notes