summaryrefslogtreecommitdiff
path: root/samples/hid/hid_mouse.bpf.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2022-11-03 16:57:54 +0100
committerJiri Kosina <jkosina@suse.cz>2022-11-15 16:28:40 +0100
commit6008105b4f4e470da0e9159a3a74ca7ff6e869ba (patch)
treec92d7cc2eb6742894183b99c44f574eb8a844adf /samples/hid/hid_mouse.bpf.c
parent80e189f2af37d383b4840f3f89896071392cb58f (diff)
samples/hid: add new hid BPF example
Everything should be available in the selftest part of the tree, but providing an example without uhid and hidraw will be more easy to follow for users. This example will probably ever only work on the Etekcity Scroll 6E because we need to adapt the various raw values to the actual device. On that device, the X and Y axis will be swapped and inverted, and on any other device, chances are high that the device will not work until Ctrl-C is hit. The Makefiles are taken from samples/bpf to not reinvent the wheel and to force using in-kernel libbpf and bpftool. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'samples/hid/hid_mouse.bpf.c')
-rw-r--r--samples/hid/hid_mouse.bpf.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/samples/hid/hid_mouse.bpf.c b/samples/hid/hid_mouse.bpf.c
new file mode 100644
index 000000000000..7c8b453ccb16
--- /dev/null
+++ b/samples/hid/hid_mouse.bpf.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include "hid_bpf_helpers.h"
+
+SEC("fmod_ret/hid_bpf_device_event")
+int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx)
+{
+ s16 y;
+ __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ bpf_printk("event: size: %d", hctx->size);
+ bpf_printk("incoming event: %02x %02x %02x",
+ data[0],
+ data[1],
+ data[2]);
+ bpf_printk(" %02x %02x %02x",
+ data[3],
+ data[4],
+ data[5]);
+ bpf_printk(" %02x %02x %02x",
+ data[6],
+ data[7],
+ data[8]);
+
+ y = data[3] | (data[4] << 8);
+
+ y = -y;
+
+ data[3] = y & 0xFF;
+ data[4] = (y >> 8) & 0xFF;
+
+ bpf_printk("modified event: %02x %02x %02x",
+ data[0],
+ data[1],
+ data[2]);
+ bpf_printk(" %02x %02x %02x",
+ data[3],
+ data[4],
+ data[5]);
+ bpf_printk(" %02x %02x %02x",
+ data[6],
+ data[7],
+ data[8]);
+
+ return 0;
+}
+
+SEC("fmod_ret/hid_bpf_device_event")
+int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx)
+{
+ s16 x;
+ __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ x = data[1] | (data[2] << 8);
+
+ x = -x;
+
+ data[1] = x & 0xFF;
+ data[2] = (x >> 8) & 0xFF;
+ return 0;
+}
+
+SEC("fmod_ret/hid_bpf_rdesc_fixup")
+int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
+{
+ __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ bpf_printk("rdesc: %02x %02x %02x",
+ data[0],
+ data[1],
+ data[2]);
+ bpf_printk(" %02x %02x %02x",
+ data[3],
+ data[4],
+ data[5]);
+ bpf_printk(" %02x %02x %02x ...",
+ data[6],
+ data[7],
+ data[8]);
+
+ /*
+ * The original report descriptor contains:
+ *
+ * 0x05, 0x01, // Usage Page (Generic Desktop) 30
+ * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32
+ * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35
+ * 0x09, 0x30, // Usage (X) 38
+ * 0x09, 0x31, // Usage (Y) 40
+ *
+ * So byte 39 contains Usage X and byte 41 Usage Y.
+ *
+ * We simply swap the axes here.
+ */
+ data[39] = 0x31;
+ data[41] = 0x30;
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";