1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/usb.h>
15#include <linux/usb/quirks.h>
16#include <linux/usb/hcd.h>
17#include "usb.h"
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36static const struct usb_device_id usb_quirk_list[] = {
37
38 { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
39
40
41 { USB_DEVICE(0x03f0, 0x0701), .driver_info =
42 USB_QUIRK_STRING_FETCH_255 },
43
44
45 { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
46
47
48 { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
49
50
51 { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
52 { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
53
54
55 { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
56
57
58 { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME },
59
60
61 { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME },
62
63
64 { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME },
65
66
67 { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME },
68
69
70 { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME },
71
72
73 { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
74
75
76 { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
77
78
79 { USB_DEVICE(0x04b4, 0x0526), .driver_info =
80 USB_QUIRK_CONFIG_INTF_STRINGS },
81
82
83 { USB_DEVICE(0x04d8, 0x000c), .driver_info =
84 USB_QUIRK_CONFIG_INTF_STRINGS },
85
86
87 { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME },
88
89
90 { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
91
92
93 { USB_DEVICE(0x04e8, 0x6601), .driver_info =
94 USB_QUIRK_CONFIG_INTF_STRINGS },
95
96
97 { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
98
99
100 { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
101
102
103 { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME },
104
105
106 { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
107
108
109 { USB_DEVICE(0x0638, 0x0a13), .driver_info =
110 USB_QUIRK_STRING_FETCH_255 },
111
112
113 { USB_DEVICE(0x06a3, 0x0006), .driver_info =
114 USB_QUIRK_CONFIG_INTF_STRINGS },
115
116
117 { USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
118
119
120 { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
121
122
123 { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
124
125
126 { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
127
128
129 { USB_DEVICE(0x0926, 0x3333), .driver_info =
130 USB_QUIRK_CONFIG_INTF_STRINGS },
131
132
133 { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
134
135
136 { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME },
137
138
139 { USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },
140
141
142 { USB_DEVICE(0x10d6, 0x2200), .driver_info =
143 USB_QUIRK_STRING_FETCH_255 },
144
145
146 { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
147
148
149 { USB_DEVICE(0x1908, 0x1315), .driver_info =
150 USB_QUIRK_HONOR_BNUMINTERFACES },
151
152
153 { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
154
155 { }
156};
157
158static const struct usb_device_id usb_interface_quirk_list[] = {
159
160 { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
161 .driver_info = USB_QUIRK_RESET_RESUME },
162
163 { }
164};
165
166static const struct usb_device_id usb_amd_resume_quirk_list[] = {
167
168 { USB_DEVICE(0x17ef, 0x602e), .driver_info = USB_QUIRK_RESET_RESUME },
169
170
171 { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
172 { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
173 { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
174
175
176 { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
177
178 { }
179};
180
181static bool usb_match_any_interface(struct usb_device *udev,
182 const struct usb_device_id *id)
183{
184 unsigned int i;
185
186 for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) {
187 struct usb_host_config *cfg = &udev->config[i];
188 unsigned int j;
189
190 for (j = 0; j < cfg->desc.bNumInterfaces; ++j) {
191 struct usb_interface_cache *cache;
192 struct usb_host_interface *intf;
193
194 cache = cfg->intf_cache[j];
195 if (cache->num_altsetting == 0)
196 continue;
197
198 intf = &cache->altsetting[0];
199 if (usb_match_one_id_intf(udev, intf, id))
200 return true;
201 }
202 }
203
204 return false;
205}
206
207static int usb_amd_resume_quirk(struct usb_device *udev)
208{
209 struct usb_hcd *hcd;
210
211 hcd = bus_to_hcd(udev->bus);
212
213 if (udev->level == 1 && hcd->amd_resume_bug == 1)
214 return 1;
215
216 return 0;
217}
218
219static u32 __usb_detect_quirks(struct usb_device *udev,
220 const struct usb_device_id *id)
221{
222 u32 quirks = 0;
223
224 for (; id->match_flags; id++) {
225 if (!usb_match_device(udev, id))
226 continue;
227
228 if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) &&
229 !usb_match_any_interface(udev, id))
230 continue;
231
232 quirks |= (u32)(id->driver_info);
233 }
234
235 return quirks;
236}
237
238
239
240
241void usb_detect_quirks(struct usb_device *udev)
242{
243 udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
244
245
246
247
248
249 if (usb_amd_resume_quirk(udev))
250 udev->quirks |= __usb_detect_quirks(udev,
251 usb_amd_resume_quirk_list);
252
253 if (udev->quirks)
254 dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
255 udev->quirks);
256
257#ifdef CONFIG_USB_DEFAULT_PERSIST
258 if (!(udev->quirks & USB_QUIRK_RESET))
259 udev->persist_enabled = 1;
260#else
261
262 if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
263 udev->persist_enabled = 1;
264#endif
265}
266
267void usb_detect_interface_quirks(struct usb_device *udev)
268{
269 u32 quirks;
270
271 quirks = __usb_detect_quirks(udev, usb_interface_quirk_list);
272 if (quirks == 0)
273 return;
274
275 dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n",
276 quirks);
277 udev->quirks |= quirks;
278}
279