diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2025-10-13 09:19:19 +0200 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-10-13 09:19:19 +0200 |
| commit | 9b966ae42235a88eaea714be09ff3d698535bdfe (patch) | |
| tree | 7470df78fb74fdfda1f773feb3822c1c9ab38616 /drivers/hid/hid-core.c | |
| parent | 5385871282e5c2831c226d32cf2ce26b45a7b164 (diff) | |
| parent | 3a8660878839faadb4f1a6dd72c3179c1df56787 (diff) | |
Merge drm/drm-next into drm-misc-next
Updating drm-misc-next to the state of v6.18-rc1.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'drivers/hid/hid-core.c')
| -rw-r--r-- | drivers/hid/hid-core.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5419a6c10907..a5b3a8ca2fcb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -944,6 +944,15 @@ static int hid_scan_report(struct hid_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 * hid_open_report() anyway. @@ -2708,12 +2717,32 @@ static bool hid_check_device_match(struct hid_device *hdev, return !hid_ignore_special_drivers && !(hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER); } +static void hid_set_group(struct hid_device *hdev) +{ + int ret; + + if (hid_ignore_special_drivers) { + hdev->group = HID_GROUP_GENERIC; + } else if (!hdev->group && + !(hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER)) { + ret = hid_scan_report(hdev); + if (ret) + hid_warn(hdev, "bad device descriptor (%d)\n", ret); + } +} + static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) { const struct hid_device_id *id; 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); @@ -2723,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)) @@ -2903,14 +2938,7 @@ int hid_add_device(struct hid_device *hdev) /* * Scan generic devices for group information */ - if (hid_ignore_special_drivers) { - hdev->group = HID_GROUP_GENERIC; - } else if (!hdev->group && - !(hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER)) { - ret = hid_scan_report(hdev); - if (ret) - hid_warn(hdev, "bad device descriptor (%d)\n", ret); - } + hid_set_group(hdev); hdev->id = atomic_inc_return(&id); |