drivers/scsi/elx/efct/efct_hw_queues.c

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

File Facts

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

if (!eq) {
			efct_hw_queue_teardown(hw);
			return -ENOMEM;
		}

		eqs[i] = eq;

		/* Create one MQ */
		if (!i) {
			cq = efct_hw_new_cq(eq,
					    hw->num_qentries[SLI4_QTYPE_CQ]);
			if (!cq) {
				efct_hw_queue_teardown(hw);
				return -ENOMEM;
			}

			mq = efct_hw_new_mq(cq, EFCT_HW_MQ_DEPTH);
			if (!mq) {
				efct_hw_queue_teardown(hw);
				return -ENOMEM;
			}
		}

		/* Create WQ */
		cq = efct_hw_new_cq(eq, hw->num_qentries[SLI4_QTYPE_CQ]);
		if (!cq) {
			efct_hw_queue_teardown(hw);
			return -ENOMEM;
		}

		wq = efct_hw_new_wq(cq, hw->num_qentries[SLI4_QTYPE_WQ]);
		if (!wq) {
			efct_hw_queue_teardown(hw);
			return -ENOMEM;
		}
	}

	/* Create CQ set */
	if (efct_hw_new_cq_set(eqs, cqs, i, hw->num_qentries[SLI4_QTYPE_CQ])) {
		efct_hw_queue_teardown(hw);
		return -EIO;
	}

	/* Create RQ set */
	if (efct_hw_new_rq_set(cqs, rqs, i, EFCT_HW_RQ_ENTRIES_DEF)) {
		efct_hw_queue_teardown(hw);
		return -EIO;
	}

	for (j = 0; j < i ; j++) {
		rqs[j]->filter_mask = 0;
		rqs[j]->is_mrq = true;
		rqs[j]->base_mrq_id = rqs[0]->hdr->id;
	}

	hw->hw_mrq_count = i;

	return 0;
}

int
efct_hw_map_wq_cpu(struct efct_hw *hw)
{
	struct efct *efct = hw->os;
	u32 cpu = 0, i;

	/* Init cpu_map array */
	hw->wq_cpu_array = kcalloc(num_possible_cpus(), sizeof(void *),
				   GFP_KERNEL);
	if (!hw->wq_cpu_array)
		return -ENOMEM;

	for (i = 0; i < hw->config.n_eq; i++) {
		const struct cpumask *maskp;

		/* Get a CPU mask for all CPUs affinitized to this vector */
		maskp = pci_irq_get_affinity(efct->pci, i);
		if (!maskp) {
			efc_log_debug(efct, "maskp null for vector:%d\n", i);
			continue;
		}

		/* Loop through all CPUs associated with vector idx */
		for_each_cpu_and(cpu, maskp, cpu_present_mask) {
			efc_log_debug(efct, "CPU:%d irq vector:%d\n", cpu, i);
			hw->wq_cpu_array[cpu] = hw->hw_wq[i];
		}
	}

	return 0;

Annotation

Implementation Notes