mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
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>
This commit is contained in:
committed by
Jiri Kosina
parent
4e411a3f7b
commit
4c2c5ff9f3
@@ -943,6 +943,15 @@ static int hid_scan_report(struct hid_device *hid)
|
||||
parser->device = hid;
|
||||
hid->group = HID_GROUP_GENERIC;
|
||||
|
||||
/*
|
||||
* In case we are re-scanning after a BPF has been loaded,
|
||||
* we need to use the bpf report descriptor, not the original one.
|
||||
*/
|
||||
if (hid->bpf_rdesc && hid->bpf_rsize) {
|
||||
start = hid->bpf_rdesc;
|
||||
end = start + hid->bpf_rsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* The parsing is simpler than the one in hid_open_report() as we should
|
||||
* 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)
|
||||
int ret;
|
||||
|
||||
if (!hdev->bpf_rsize) {
|
||||
/* we keep a reference to the currently scanned report descriptor */
|
||||
const __u8 *original_rdesc = hdev->bpf_rdesc;
|
||||
|
||||
if (!original_rdesc)
|
||||
original_rdesc = hdev->dev_rdesc;
|
||||
|
||||
/* in case a bpf program gets detached, we need to free the old one */
|
||||
hid_free_bpf_rdesc(hdev);
|
||||
|
||||
@@ -2737,6 +2752,12 @@ static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
|
||||
/* call_hid_bpf_rdesc_fixup will always return a valid pointer */
|
||||
hdev->bpf_rdesc = call_hid_bpf_rdesc_fixup(hdev, hdev->dev_rdesc,
|
||||
&hdev->bpf_rsize);
|
||||
|
||||
/* the report descriptor changed, we need to re-scan it */
|
||||
if (original_rdesc != hdev->bpf_rdesc) {
|
||||
hdev->group = 0;
|
||||
hid_set_group(hdev);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hid_check_device_match(hdev, hdrv, &id))
|
||||
|
||||
Reference in New Issue
Block a user