Skip to content

Commit 4c2c5ff

Browse files
Benjamin TissoiresJiri Kosina
authored andcommitted
HID: bpf: rescan the device for the group after a load/unload
When a BPF gets loaded, it was previously not possible to bind a hid-generic device to hid-multitouch because the group was never updated. This change forces a rescan of the report descriptor after a bpf is loaded/unloaded so we set up the proper group. This was detected while Peter was trying to fix a Viewsonic device: the HID device sending multiotuch data through a proprietary collection was handled by hid-generic, and we don't have any way of attaching it to hid-multitouch because the pre-scanning wasn't able to see the Contact ID HID usage. Suggested-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 4e411a3 commit 4c2c5ff

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

drivers/hid/hid-core.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,15 @@ static int hid_scan_report(struct hid_device *hid)
943943
parser->device = hid;
944944
hid->group = HID_GROUP_GENERIC;
945945

946+
/*
947+
* In case we are re-scanning after a BPF has been loaded,
948+
* we need to use the bpf report descriptor, not the original one.
949+
*/
950+
if (hid->bpf_rdesc && hid->bpf_rsize) {
951+
start = hid->bpf_rdesc;
952+
end = start + hid->bpf_rsize;
953+
}
954+
946955
/*
947956
* The parsing is simpler than the one in hid_open_report() as we should
948957
* be robust against hid errors. Those errors will be raised by
@@ -2728,6 +2737,12 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
27282737
int ret;
27292738

27302739
if (!hdev->bpf_rsize) {
2740+
/* we keep a reference to the currently scanned report descriptor */
2741+
const __u8 *original_rdesc = hdev->bpf_rdesc;
2742+
2743+
if (!original_rdesc)
2744+
original_rdesc = hdev->dev_rdesc;
2745+
27312746
/* in case a bpf program gets detached, we need to free the old one */
27322747
hid_free_bpf_rdesc(hdev);
27332748

@@ -2737,6 +2752,12 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
27372752
/* call_hid_bpf_rdesc_fixup will always return a valid pointer */
27382753
hdev->bpf_rdesc = call_hid_bpf_rdesc_fixup(hdev, hdev->dev_rdesc,
27392754
&hdev->bpf_rsize);
2755+
2756+
/* the report descriptor changed, we need to re-scan it */
2757+
if (original_rdesc != hdev->bpf_rdesc) {
2758+
hdev->group = 0;
2759+
hid_set_group(hdev);
2760+
}
27402761
}
27412762

27422763
if (!hid_check_device_match(hdev, hdrv, &id))

0 commit comments

Comments
 (0)