drivers/soc/fsl/qbman/qman_test_stash.c

Source file repositories/reference/linux-study-clean/drivers/soc/fsl/qbman/qman_test_stash.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/fsl/qbman/qman_test_stash.c
Extension
.c
Size
17492 bytes
Lines
628
Domain
Driver Families
Bucket
drivers/soc
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 bstrap {
	int (*fn)(void);
	atomic_t started;
};
static int bstrap_fn(void *bs)
{
	struct bstrap *bstrap = bs;
	int err;

	atomic_inc(&bstrap->started);
	err = bstrap->fn();
	if (err)
		return err;
	while (!kthread_should_stop())
		msleep(20);
	return 0;
}
static int on_all_cpus(int (*fn)(void))
{
	int cpu;

	for_each_online_cpu(cpu) {
		struct bstrap bstrap = {
			.fn = fn,
			.started = ATOMIC_INIT(0)
		};
		struct task_struct *k = kthread_run_on_cpu(bstrap_fn, &bstrap,
							   cpu, "hotpotato%d");
		int ret;

		if (IS_ERR(k))
			return -ENOMEM;
		/*
		 * If we call kthread_stop() before the "wake up" has had an
		 * effect, then the thread may exit with -EINTR without ever
		 * running the function. So poll until it's started before
		 * requesting it to stop.
		 */
		while (!atomic_read(&bstrap.started))
			msleep(20);
		ret = kthread_stop(k);
		if (ret)
			return ret;
	}
	return 0;
}

struct hp_handler {

	/* The following data is stashed when 'rx' is dequeued; */
	/* -------------- */
	/* The Rx FQ, dequeues of which will stash the entire hp_handler */
	struct qman_fq rx;
	/* The Tx FQ we should forward to */
	struct qman_fq tx;
	/* The value we XOR post-dequeue, prior to validating */
	u32 rx_mixer;
	/* The value we XOR pre-enqueue, after validating */
	u32 tx_mixer;
	/* what the hotpotato address should be on dequeue */
	dma_addr_t addr;
	u32 *frame_ptr;

	/* The following data isn't (necessarily) stashed on dequeue; */
	/* -------------- */
	u32 fqid_rx, fqid_tx;
	/* list node for linking us into 'hp_cpu' */
	struct list_head node;
	/* Just to check ... */
	unsigned int processor_id;
} ____cacheline_aligned;

struct hp_cpu {
	/* identify the cpu we run on; */
	unsigned int processor_id;
	/* root node for the per-cpu list of handlers */
	struct list_head handlers;
	/* list node for linking us into 'hp_cpu_list' */
	struct list_head node;
	/*
	 * when repeatedly scanning 'hp_list', each time linking the n'th
	 * handlers together, this is used as per-cpu iterator state
	 */
	struct hp_handler *iterator;
};

/* Each cpu has one of these */
static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);

/* links together the hp_cpu structs, in first-come first-serve order. */

Annotation

Implementation Notes