-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathusb_ids.patch
134 lines (128 loc) · 3.4 KB
/
usb_ids.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
commit 0b9540c5b3cb5e34af4cdc1f6828314a041f8d1a
Author: Andrey Konovalov <[email protected]>
Date: Thu Jul 25 00:26:01 2024 +0200
usb: dump usb and hid device ids on hid enumeration
Signed-off-by: Andrey Konovalov <[email protected]>
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 74efda212c55f..d2f1f9243638e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -27,6 +27,8 @@
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
+#include <linux/usb.h>
+#include "../usb/core/usb.h"
#include <linux/hid.h>
#include <linux/hiddev.h>
@@ -2544,11 +2546,112 @@ static void hid_free_dynids(struct hid_driver *hdrv)
spin_unlock(&hdrv->dyn_lock);
}
+static void hid_device_id_dump_one(const struct hid_device_id *id)
+{
+ char buffer[128];
+ int size = (char *)&id->product + sizeof(id->product) - (char *)id;
+
+ if (id->bus != HID_BUS_ANY && id->bus != BUS_USB)
+ return;
+
+ bin2hex((char *)&buffer[0], (const char *)id, size);
+ buffer[size * 2] = 0;
+ pr_err("HIDID: %s\n", &buffer[0]);
+}
+
+static void hid_device_id_dump_static(struct hid_driver *hdrv)
+{
+ const struct hid_device_id *id = hdrv->id_table;
+
+ for (; id->bus; id++)
+ hid_device_id_dump_one(id);
+}
+
+static void hid_device_id_dump_dynamic(struct hid_driver *hdrv)
+{
+ struct hid_dynid *dynid;
+
+ spin_lock(&hdrv->dyn_lock);
+ list_for_each_entry(dynid, &hdrv->dyn_list, list)
+ hid_device_id_dump_one(&dynid->id);
+ spin_unlock(&hdrv->dyn_lock);
+}
+
+static int hid_device_id_dump_driver(struct device_driver *drv, void *data)
+{
+ struct hid_driver *hdrv = to_hid_driver(drv);
+
+ hid_device_id_dump_static(hdrv);
+ hid_device_id_dump_dynamic(hdrv);
+
+ return 0;
+}
+
+static void usb_device_id_dump_one(const struct usb_device_id *id)
+{
+ char buffer[128];
+ int size = (char *)&id->bInterfaceNumber + sizeof(id->bInterfaceNumber)
+ - (char *)id;
+
+ bin2hex((char *)&buffer[0], (const char *)id, size);
+ buffer[size * 2] = 0;
+ pr_err("USBID: %s\n", &buffer[0]);
+}
+
+static void usb_device_id_dump_static(struct usb_driver *drv)
+{
+ const struct usb_device_id *id = drv->id_table;
+
+ if (id == NULL)
+ return;
+
+ for (; id->idVendor || id->idProduct || id->bDeviceClass ||
+ id->bInterfaceClass || id->driver_info; id++)
+ usb_device_id_dump_one(id);
+}
+
+static void usb_device_id_dump_dynamic(struct usb_driver *drv)
+{
+ struct usb_dynid *dynid;
+
+ spin_lock(&drv->dynids.lock);
+ list_for_each_entry(dynid, &drv->dynids.list, node)
+ usb_device_id_dump_one(&dynid->id);
+ spin_unlock(&drv->dynids.lock);
+}
+
+static int usb_device_id_dump_driver(struct device_driver *drv, void *data)
+{
+ struct usb_driver *usb_drv;
+
+ if (is_usb_device_driver(drv))
+ return 0;
+ usb_drv = to_usb_driver(drv);
+
+ usb_device_id_dump_static(usb_drv);
+ usb_device_id_dump_dynamic(usb_drv);
+
+ return 0;
+}
+
+static int usb_ids_dumped;
+
+static void usb_device_id_dump_all(void)
+{
+ if (usb_ids_dumped)
+ return;
+ usb_ids_dumped = 1;
+ bus_for_each_drv(&usb_bus_type, NULL, NULL, usb_device_id_dump_driver);
+ bus_for_each_drv(&hid_bus_type, NULL, NULL, hid_device_id_dump_driver);
+}
+
const struct hid_device_id *hid_match_device(struct hid_device *hdev,
struct hid_driver *hdrv)
{
struct hid_dynid *dynid;
+ usb_device_id_dump_all();
+
spin_lock(&hdrv->dyn_lock);
list_for_each_entry(dynid, &hdrv->dyn_list, list) {
if (hid_match_one_id(hdev, &dynid->id)) {