drivers/hid/bpf/hid_bpf_dispatch.c

Source file repositories/reference/linux-study-clean/drivers/hid/bpf/hid_bpf_dispatch.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/bpf/hid_bpf_dispatch.c
Extension
.c
Size
16734 bytes
Lines
683
Domain
Driver Families
Bucket
drivers/hid
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (e->hid_device_event) {
			ret = e->hid_device_event(&ctx_kern.ctx, type, source);
			if (ret < 0) {
				rcu_read_unlock();
				return ERR_PTR(ret);
			}

			if (ret)
				ctx_kern.ctx.size = ret;
		}
	}
	rcu_read_unlock();

	ret = ctx_kern.ctx.size;
	if (ret) {
		if (ret > ctx_kern.ctx.allocated_size)
			return ERR_PTR(-EINVAL);

		*size = ret;
	}

	*buf_size = ctx_kern.ctx.allocated_size;
	return ctx_kern.data;
}
EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event);

int dispatch_hid_bpf_raw_requests(struct hid_device *hdev,
				  unsigned char reportnum, u8 *buf,
				  u32 size, enum hid_report_type rtype,
				  enum hid_class_request reqtype,
				  u64 source, bool from_bpf)
{
	struct hid_bpf_ctx_kern ctx_kern = {
		.ctx = {
			.hid = hdev,
			.allocated_size = size,
			.size = size,
		},
		.data = buf,
		.from_bpf = from_bpf,
	};
	struct hid_bpf_ops *e;
	int ret, idx;

	if (unlikely(hdev->bpf.destroyed))
		return -ENODEV;

	if (rtype >= HID_REPORT_TYPES)
		return -EINVAL;

	idx = srcu_read_lock(&hdev->bpf.srcu);
	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
				 srcu_read_lock_held(&hdev->bpf.srcu)) {
		if (!e->hid_hw_request)
			continue;

		ret = e->hid_hw_request(&ctx_kern.ctx, reportnum, rtype, reqtype, source);
		if (ret)
			goto out;
	}
	ret = 0;

out:
	srcu_read_unlock(&hdev->bpf.srcu, idx);
	return ret;
}
EXPORT_SYMBOL_GPL(dispatch_hid_bpf_raw_requests);

int dispatch_hid_bpf_output_report(struct hid_device *hdev,
				   __u8 *buf, u32 size, u64 source,
				   bool from_bpf)
{
	struct hid_bpf_ctx_kern ctx_kern = {
		.ctx = {
			.hid = hdev,
			.allocated_size = size,
			.size = size,
		},
		.data = buf,
		.from_bpf = from_bpf,
	};
	struct hid_bpf_ops *e;
	int ret, idx;

	if (unlikely(hdev->bpf.destroyed))
		return -ENODEV;

	idx = srcu_read_lock(&hdev->bpf.srcu);
	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
				 srcu_read_lock_held(&hdev->bpf.srcu)) {

Annotation

Implementation Notes