Skip to content

Commit a1bbd84

Browse files
author
Jiri Kosina
committed
Merge branch 'for-7.1/hid-bpf' into for-linus
- sync of HID-BPF with udev-hid-bpf (Benjamin Tissoires, Muhammed Rishal)
2 parents b3793af + 30fb45c commit a1bbd84

11 files changed

Lines changed: 3865 additions & 22 deletions
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright (c) 2025 Benjamin Tissoires
3+
*/
4+
5+
#include "vmlinux.h"
6+
#include "hid_bpf.h"
7+
#include "hid_bpf_helpers.h"
8+
#include "hid_report_helpers.h"
9+
#include "hid_usages.h"
10+
#include <bpf/bpf_tracing.h>
11+
12+
HID_BPF_CONFIG(
13+
HID_DEVICE(BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8, HID_VID_ANY, HID_PID_ANY),
14+
);
15+
16+
EXPORT_UDEV_PROP(HID_DIGITIZER_PAD_TYPE, 32);
17+
18+
__u8 hw_req_buf[1024];
19+
20+
/* to be filled by udev-hid-bpf */
21+
struct hid_rdesc_descriptor HID_REPORT_DESCRIPTOR;
22+
23+
SEC("syscall")
24+
int probe(struct hid_bpf_probe_args *ctx)
25+
{
26+
struct hid_rdesc_report *pad_type_feature = NULL;
27+
struct hid_rdesc_field *pad_type = NULL;
28+
struct hid_rdesc_report *feature;
29+
struct hid_bpf_ctx *hid_ctx;
30+
char *pad_type_str = "";
31+
int ret;
32+
33+
hid_bpf_for_each_feature_report(&HID_REPORT_DESCRIPTOR, feature) {
34+
struct hid_rdesc_field *field;
35+
36+
hid_bpf_for_each_field(feature, field) {
37+
if (field->usage_page == HidUsagePage_Digitizers &&
38+
field->usage_id == HidUsage_Dig_PadType) {
39+
pad_type = field;
40+
pad_type_feature = feature;
41+
break;
42+
}
43+
}
44+
if (pad_type)
45+
break;
46+
}
47+
48+
if (!pad_type || !pad_type_feature) {
49+
ctx->retval = -EINVAL;
50+
return 0;
51+
}
52+
53+
hid_ctx = hid_bpf_allocate_context(ctx->hid);
54+
55+
if (!hid_ctx)
56+
return -1; /* EPERM check */
57+
58+
hw_req_buf[0] = pad_type_feature->report_id;
59+
60+
ret = hid_bpf_hw_request(hid_ctx, hw_req_buf, sizeof(hw_req_buf),
61+
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
62+
hid_bpf_release_context(hid_ctx);
63+
64+
if (ret < 0) {
65+
ctx->retval = ret;
66+
return 0;
67+
}
68+
69+
ctx->retval = 0;
70+
71+
switch (EXTRACT_BITS(hw_req_buf, pad_type)) {
72+
case 0:
73+
pad_type_str = "Clickpad";
74+
break;
75+
case 1:
76+
pad_type_str = "Pressurepad";
77+
break;
78+
case 2:
79+
pad_type_str = "Discrete";
80+
break;
81+
default:
82+
pad_type_str = "Unknown";
83+
}
84+
85+
UDEV_PROP_SPRINTF(HID_DIGITIZER_PAD_TYPE, "%s", pad_type_str);
86+
87+
return 0;
88+
}
89+
90+
char _license[] SEC("license") = "GPL";

drivers/hid/bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c

Lines changed: 492 additions & 0 deletions
Large diffs are not rendered by default.

drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ int BPF_PROG(k20_fix_events, struct hid_bpf_ctx *hctx)
462462
__u32 buttons;
463463
__u8 wheel;
464464
} __attribute__((packed)) *pad_report;
465-
int i, b;
465+
int i;
466+
size_t b;
466467
__u8 modifiers = data[1];
467468
__u32 buttons = 0;
468469

drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
3434
if (data[3] != 0x06)
3535
return 0;
3636

37-
for (int idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
37+
for (size_t idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
3838
u8 offset = offsets[idx];
3939

4040
/* if Input (Cnst,Var,Abs) , make it Input (Data,Var,Abs) */
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Fix for Trust Philips SPK6327 (145f:024b)
3+
* Modifier keys report as Array (0x00) instead of Variable (0x02)
4+
* causing LCtrl, LAlt, Super etc. to all act as LShift
5+
*/
6+
#include "vmlinux.h"
7+
#include "hid_bpf.h"
8+
#include "hid_bpf_helpers.h"
9+
#include <bpf/bpf_tracing.h>
10+
11+
#define VID_TRUST 0x145F
12+
#define PID_SPK6327 0x024B
13+
14+
HID_BPF_CONFIG(
15+
HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_TRUST, PID_SPK6327)
16+
);
17+
18+
SEC(HID_BPF_RDESC_FIXUP)
19+
int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx)
20+
{
21+
__u8 *data = hid_bpf_get_data(hctx, 0, 4096);
22+
23+
if (!data)
24+
return 0;
25+
26+
/* Fix modifier keys: Input Array (0x00) -> Input Variable (0x02) */
27+
if (data[101] == 0x00)
28+
data[101] = 0x02;
29+
30+
return 0;
31+
}
32+
33+
HID_BPF_OPS(trust_spk6327) = {
34+
.hid_rdesc_fixup = (void *)hid_fix_rdesc,
35+
};
36+
37+
SEC("syscall")
38+
int probe(struct hid_bpf_probe_args *ctx)
39+
{
40+
/* Only apply to interface 1 (169 bytes) not interface 0 (62 bytes) */
41+
if (ctx->rdesc_size == 169)
42+
ctx->retval = 0;
43+
else
44+
ctx->retval = -EINVAL;
45+
46+
return 0;
47+
}
48+
49+
char _license[] SEC("license") = "GPL";

drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ int probe(struct hid_bpf_probe_args *ctx)
148148
{
149149
struct hid_bpf_ctx *hid_ctx;
150150
__u16 pid;
151-
int i;
151+
size_t i;
152152

153153
/* get a struct hid_device to access the actual pid of the device */
154154
hid_ctx = hid_bpf_allocate_context(ctx->hid);

drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ int BPF_PROG(hid_device_event_xppen_deco_mini_4, struct hid_bpf_ctx *hctx)
173173
{
174174
__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 8 /* size */);
175175
__u8 button_mask = 0;
176-
int d, b;
176+
size_t d, b;
177177

178178
if (!data)
179179
return 0; /* EPERM check */

drivers/hid/bpf/progs/hid_bpf_async.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,14 @@ static int hid_bpf_async_find_empty_key(void)
116116
if (!elem)
117117
return -ENOMEM; /* should never happen */
118118

119-
bpf_spin_lock(&elem->lock);
119+
{
120+
guard(bpf_spin)(&elem->lock);
120121

121-
if (elem->state == HID_BPF_ASYNC_STATE_UNSET) {
122-
elem->state = HID_BPF_ASYNC_STATE_INITIALIZING;
123-
bpf_spin_unlock(&elem->lock);
124-
return i;
122+
if (elem->state == HID_BPF_ASYNC_STATE_UNSET) {
123+
elem->state = HID_BPF_ASYNC_STATE_INITIALIZING;
124+
return i;
125+
}
125126
}
126-
127-
bpf_spin_unlock(&elem->lock);
128127
}
129128

130129
return -EINVAL;
@@ -175,18 +174,19 @@ static int hid_bpf_async_delayed_call(struct hid_bpf_ctx *hctx, u64 milliseconds
175174
if (!elem)
176175
return -EINVAL;
177176

178-
bpf_spin_lock(&elem->lock);
179-
/* The wq must be:
180-
* - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called
181-
* - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself
182-
*/
183-
if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED &&
184-
elem->state != HID_BPF_ASYNC_STATE_RUNNING) {
185-
bpf_spin_unlock(&elem->lock);
186-
return -EINVAL;
177+
{
178+
guard(bpf_spin)(&elem->lock);
179+
180+
/* The wq must be:
181+
* - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called
182+
* - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself
183+
*/
184+
if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED &&
185+
elem->state != HID_BPF_ASYNC_STATE_RUNNING)
186+
return -EINVAL;
187+
188+
elem->state = HID_BPF_ASYNC_STATE_STARTING;
187189
}
188-
elem->state = HID_BPF_ASYNC_STATE_STARTING;
189-
bpf_spin_unlock(&elem->lock);
190190

191191
elem->hid = hctx->hid->id;
192192

0 commit comments

Comments
 (0)