1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Released under the GPLv2 only. |
4 | */ |
5 | |
6 | #include <linux/usb.h> |
7 | #include <linux/usb/ch9.h> |
8 | #include <linux/usb/hcd.h> |
9 | #include <linux/usb/quirks.h> |
10 | #include <linux/module.h> |
11 | #include <linux/slab.h> |
12 | #include <linux/device.h> |
13 | #include <asm/byteorder.h> |
14 | #include "usb.h" |
15 | |
16 | |
17 | #define USB_MAXALTSETTING 128 /* Hard limit */ |
18 | |
19 | #define USB_MAXCONFIG 8 /* Arbitrary limit */ |
20 | |
21 | |
22 | static inline const char *plural(int n) |
23 | { |
24 | return (n == 1 ? "" : "s" ); |
25 | } |
26 | |
27 | static int find_next_descriptor(unsigned char *buffer, int size, |
28 | int dt1, int dt2, int *num_skipped) |
29 | { |
30 | struct usb_descriptor_header *h; |
31 | int n = 0; |
32 | unsigned char *buffer0 = buffer; |
33 | |
34 | /* Find the next descriptor of type dt1 or dt2 */ |
35 | while (size > 0) { |
36 | h = (struct usb_descriptor_header *) buffer; |
37 | if (h->bDescriptorType == dt1 || h->bDescriptorType == dt2) |
38 | break; |
39 | buffer += h->bLength; |
40 | size -= h->bLength; |
41 | ++n; |
42 | } |
43 | |
44 | /* Store the number of descriptors skipped and return the |
45 | * number of bytes skipped */ |
46 | if (num_skipped) |
47 | *num_skipped = n; |
48 | return buffer - buffer0; |
49 | } |
50 | |
51 | static void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev, |
52 | int cfgno, int inum, int asnum, struct usb_host_endpoint *ep, |
53 | unsigned char *buffer, int size) |
54 | { |
55 | struct usb_ssp_isoc_ep_comp_descriptor *desc; |
56 | |
57 | /* |
58 | * The SuperSpeedPlus Isoc endpoint companion descriptor immediately |
59 | * follows the SuperSpeed Endpoint Companion descriptor |
60 | */ |
61 | desc = (struct usb_ssp_isoc_ep_comp_descriptor *) buffer; |
62 | if (desc->bDescriptorType != USB_DT_SSP_ISOC_ENDPOINT_COMP || |
63 | size < USB_DT_SSP_ISOC_EP_COMP_SIZE) { |
64 | dev_notice(ddev, "Invalid SuperSpeedPlus isoc endpoint companion" |
65 | "for config %d interface %d altsetting %d ep %d.\n" , |
66 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
67 | return; |
68 | } |
69 | memcpy(&ep->ssp_isoc_ep_comp, desc, USB_DT_SSP_ISOC_EP_COMP_SIZE); |
70 | } |
71 | |
72 | static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, |
73 | int inum, int asnum, struct usb_host_endpoint *ep, |
74 | unsigned char *buffer, int size) |
75 | { |
76 | struct usb_ss_ep_comp_descriptor *desc; |
77 | int max_tx; |
78 | |
79 | /* The SuperSpeed endpoint companion descriptor is supposed to |
80 | * be the first thing immediately following the endpoint descriptor. |
81 | */ |
82 | desc = (struct usb_ss_ep_comp_descriptor *) buffer; |
83 | |
84 | if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || |
85 | size < USB_DT_SS_EP_COMP_SIZE) { |
86 | dev_notice(ddev, "No SuperSpeed endpoint companion for config %d " |
87 | " interface %d altsetting %d ep %d: " |
88 | "using minimum values\n" , |
89 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
90 | |
91 | /* Fill in some default values. |
92 | * Leave bmAttributes as zero, which will mean no streams for |
93 | * bulk, and isoc won't support multiple bursts of packets. |
94 | * With bursts of only one packet, and a Mult of 1, the max |
95 | * amount of data moved per endpoint service interval is one |
96 | * packet. |
97 | */ |
98 | ep->ss_ep_comp.bLength = USB_DT_SS_EP_COMP_SIZE; |
99 | ep->ss_ep_comp.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; |
100 | if (usb_endpoint_xfer_isoc(epd: &ep->desc) || |
101 | usb_endpoint_xfer_int(epd: &ep->desc)) |
102 | ep->ss_ep_comp.wBytesPerInterval = |
103 | ep->desc.wMaxPacketSize; |
104 | return; |
105 | } |
106 | buffer += desc->bLength; |
107 | size -= desc->bLength; |
108 | memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE); |
109 | |
110 | /* Check the various values */ |
111 | if (usb_endpoint_xfer_control(epd: &ep->desc) && desc->bMaxBurst != 0) { |
112 | dev_notice(ddev, "Control endpoint with bMaxBurst = %d in " |
113 | "config %d interface %d altsetting %d ep %d: " |
114 | "setting to zero\n" , desc->bMaxBurst, |
115 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
116 | ep->ss_ep_comp.bMaxBurst = 0; |
117 | } else if (desc->bMaxBurst > 15) { |
118 | dev_notice(ddev, "Endpoint with bMaxBurst = %d in " |
119 | "config %d interface %d altsetting %d ep %d: " |
120 | "setting to 15\n" , desc->bMaxBurst, |
121 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
122 | ep->ss_ep_comp.bMaxBurst = 15; |
123 | } |
124 | |
125 | if ((usb_endpoint_xfer_control(epd: &ep->desc) || |
126 | usb_endpoint_xfer_int(epd: &ep->desc)) && |
127 | desc->bmAttributes != 0) { |
128 | dev_notice(ddev, "%s endpoint with bmAttributes = %d in " |
129 | "config %d interface %d altsetting %d ep %d: " |
130 | "setting to zero\n" , |
131 | usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk" , |
132 | desc->bmAttributes, |
133 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
134 | ep->ss_ep_comp.bmAttributes = 0; |
135 | } else if (usb_endpoint_xfer_bulk(epd: &ep->desc) && |
136 | desc->bmAttributes > 16) { |
137 | dev_notice(ddev, "Bulk endpoint with more than 65536 streams in " |
138 | "config %d interface %d altsetting %d ep %d: " |
139 | "setting to max\n" , |
140 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
141 | ep->ss_ep_comp.bmAttributes = 16; |
142 | } else if (usb_endpoint_xfer_isoc(epd: &ep->desc) && |
143 | !USB_SS_SSP_ISOC_COMP(desc->bmAttributes) && |
144 | USB_SS_MULT(desc->bmAttributes) > 3) { |
145 | dev_notice(ddev, "Isoc endpoint has Mult of %d in " |
146 | "config %d interface %d altsetting %d ep %d: " |
147 | "setting to 3\n" , |
148 | USB_SS_MULT(desc->bmAttributes), |
149 | cfgno, inum, asnum, ep->desc.bEndpointAddress); |
150 | ep->ss_ep_comp.bmAttributes = 2; |
151 | } |
152 | |
153 | if (usb_endpoint_xfer_isoc(epd: &ep->desc)) |
154 | max_tx = (desc->bMaxBurst + 1) * |
155 | (USB_SS_MULT(desc->bmAttributes)) * |
156 | usb_endpoint_maxp(epd: &ep->desc); |
157 | else if (usb_endpoint_xfer_int(epd: &ep->desc)) |
158 | max_tx = usb_endpoint_maxp(epd: &ep->desc) * |
159 | (desc->bMaxBurst + 1); |
160 | else |
161 | max_tx = 999999; |
162 | if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { |
163 | dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " |
164 | "config %d interface %d altsetting %d ep %d: " |
165 | "setting to %d\n" , |
166 | usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int" , |
167 | le16_to_cpu(desc->wBytesPerInterval), |
168 | cfgno, inum, asnum, ep->desc.bEndpointAddress, |
169 | max_tx); |
170 | ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); |
171 | } |
172 | /* Parse a possible SuperSpeedPlus isoc ep companion descriptor */ |
173 | if (usb_endpoint_xfer_isoc(epd: &ep->desc) && |
174 | USB_SS_SSP_ISOC_COMP(desc->bmAttributes)) |
175 | usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum, |
176 | ep, buffer, size); |
177 | } |
178 | |
179 | static const unsigned short low_speed_maxpacket_maxes[4] = { |
180 | [USB_ENDPOINT_XFER_CONTROL] = 8, |
181 | [USB_ENDPOINT_XFER_ISOC] = 0, |
182 | [USB_ENDPOINT_XFER_BULK] = 0, |
183 | [USB_ENDPOINT_XFER_INT] = 8, |
184 | }; |
185 | static const unsigned short full_speed_maxpacket_maxes[4] = { |
186 | [USB_ENDPOINT_XFER_CONTROL] = 64, |
187 | [USB_ENDPOINT_XFER_ISOC] = 1023, |
188 | [USB_ENDPOINT_XFER_BULK] = 64, |
189 | [USB_ENDPOINT_XFER_INT] = 64, |
190 | }; |
191 | static const unsigned short high_speed_maxpacket_maxes[4] = { |
192 | [USB_ENDPOINT_XFER_CONTROL] = 64, |
193 | [USB_ENDPOINT_XFER_ISOC] = 1024, |
194 | |
195 | /* Bulk should be 512, but some devices use 1024: we will warn below */ |
196 | [USB_ENDPOINT_XFER_BULK] = 1024, |
197 | [USB_ENDPOINT_XFER_INT] = 1024, |
198 | }; |
199 | static const unsigned short super_speed_maxpacket_maxes[4] = { |
200 | [USB_ENDPOINT_XFER_CONTROL] = 512, |
201 | [USB_ENDPOINT_XFER_ISOC] = 1024, |
202 | [USB_ENDPOINT_XFER_BULK] = 1024, |
203 | [USB_ENDPOINT_XFER_INT] = 1024, |
204 | }; |
205 | |
206 | static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1, |
207 | struct usb_endpoint_descriptor *e2) |
208 | { |
209 | if (e1->bEndpointAddress == e2->bEndpointAddress) |
210 | return true; |
211 | |
212 | if (usb_endpoint_xfer_control(epd: e1) || usb_endpoint_xfer_control(epd: e2)) { |
213 | if (usb_endpoint_num(epd: e1) == usb_endpoint_num(epd: e2)) |
214 | return true; |
215 | } |
216 | |
217 | return false; |
218 | } |
219 | |
220 | /* |
221 | * Check for duplicate endpoint addresses in other interfaces and in the |
222 | * altsetting currently being parsed. |
223 | */ |
224 | static bool config_endpoint_is_duplicate(struct usb_host_config *config, |
225 | int inum, int asnum, struct usb_endpoint_descriptor *d) |
226 | { |
227 | struct usb_endpoint_descriptor *epd; |
228 | struct usb_interface_cache *intfc; |
229 | struct usb_host_interface *alt; |
230 | int i, j, k; |
231 | |
232 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { |
233 | intfc = config->intf_cache[i]; |
234 | |
235 | for (j = 0; j < intfc->num_altsetting; ++j) { |
236 | alt = &intfc->altsetting[j]; |
237 | |
238 | if (alt->desc.bInterfaceNumber == inum && |
239 | alt->desc.bAlternateSetting != asnum) |
240 | continue; |
241 | |
242 | for (k = 0; k < alt->desc.bNumEndpoints; ++k) { |
243 | epd = &alt->endpoint[k].desc; |
244 | |
245 | if (endpoint_is_duplicate(e1: epd, e2: d)) |
246 | return true; |
247 | } |
248 | } |
249 | } |
250 | |
251 | return false; |
252 | } |
253 | |
254 | static int usb_parse_endpoint(struct device *ddev, int cfgno, |
255 | struct usb_host_config *config, int inum, int asnum, |
256 | struct usb_host_interface *ifp, int num_ep, |
257 | unsigned char *buffer, int size) |
258 | { |
259 | struct usb_device *udev = to_usb_device(ddev); |
260 | unsigned char *buffer0 = buffer; |
261 | struct usb_endpoint_descriptor *d; |
262 | struct usb_host_endpoint *endpoint; |
263 | int n, i, j, retval; |
264 | unsigned int maxp; |
265 | const unsigned short *maxpacket_maxes; |
266 | |
267 | d = (struct usb_endpoint_descriptor *) buffer; |
268 | buffer += d->bLength; |
269 | size -= d->bLength; |
270 | |
271 | if (d->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE) |
272 | n = USB_DT_ENDPOINT_AUDIO_SIZE; |
273 | else if (d->bLength >= USB_DT_ENDPOINT_SIZE) |
274 | n = USB_DT_ENDPOINT_SIZE; |
275 | else { |
276 | dev_notice(ddev, "config %d interface %d altsetting %d has an " |
277 | "invalid endpoint descriptor of length %d, skipping\n" , |
278 | cfgno, inum, asnum, d->bLength); |
279 | goto skip_to_next_endpoint_or_interface_descriptor; |
280 | } |
281 | |
282 | i = d->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK; |
283 | if (i >= 16 || i == 0) { |
284 | dev_notice(ddev, "config %d interface %d altsetting %d has an " |
285 | "invalid endpoint with address 0x%X, skipping\n" , |
286 | cfgno, inum, asnum, d->bEndpointAddress); |
287 | goto skip_to_next_endpoint_or_interface_descriptor; |
288 | } |
289 | |
290 | /* Only store as many endpoints as we have room for */ |
291 | if (ifp->desc.bNumEndpoints >= num_ep) |
292 | goto skip_to_next_endpoint_or_interface_descriptor; |
293 | |
294 | /* Check for duplicate endpoint addresses */ |
295 | if (config_endpoint_is_duplicate(config, inum, asnum, d)) { |
296 | dev_notice(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n" , |
297 | cfgno, inum, asnum, d->bEndpointAddress); |
298 | goto skip_to_next_endpoint_or_interface_descriptor; |
299 | } |
300 | |
301 | /* Ignore some endpoints */ |
302 | if (udev->quirks & USB_QUIRK_ENDPOINT_IGNORE) { |
303 | if (usb_endpoint_is_ignored(udev, intf: ifp, epd: d)) { |
304 | dev_notice(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n" , |
305 | cfgno, inum, asnum, |
306 | d->bEndpointAddress); |
307 | goto skip_to_next_endpoint_or_interface_descriptor; |
308 | } |
309 | } |
310 | |
311 | endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; |
312 | ++ifp->desc.bNumEndpoints; |
313 | |
314 | memcpy(&endpoint->desc, d, n); |
315 | INIT_LIST_HEAD(list: &endpoint->urb_list); |
316 | |
317 | /* |
318 | * Fix up bInterval values outside the legal range. |
319 | * Use 10 or 8 ms if no proper value can be guessed. |
320 | */ |
321 | i = 0; /* i = min, j = max, n = default */ |
322 | j = 255; |
323 | if (usb_endpoint_xfer_int(epd: d)) { |
324 | i = 1; |
325 | switch (udev->speed) { |
326 | case USB_SPEED_SUPER_PLUS: |
327 | case USB_SPEED_SUPER: |
328 | case USB_SPEED_HIGH: |
329 | /* |
330 | * Many device manufacturers are using full-speed |
331 | * bInterval values in high-speed interrupt endpoint |
332 | * descriptors. Try to fix those and fall back to an |
333 | * 8-ms default value otherwise. |
334 | */ |
335 | n = fls(x: d->bInterval*8); |
336 | if (n == 0) |
337 | n = 7; /* 8 ms = 2^(7-1) uframes */ |
338 | j = 16; |
339 | |
340 | /* |
341 | * Adjust bInterval for quirked devices. |
342 | */ |
343 | /* |
344 | * This quirk fixes bIntervals reported in ms. |
345 | */ |
346 | if (udev->quirks & USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) { |
347 | n = clamp(fls(d->bInterval) + 3, i, j); |
348 | i = j = n; |
349 | } |
350 | /* |
351 | * This quirk fixes bIntervals reported in |
352 | * linear microframes. |
353 | */ |
354 | if (udev->quirks & USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) { |
355 | n = clamp(fls(d->bInterval), i, j); |
356 | i = j = n; |
357 | } |
358 | break; |
359 | default: /* USB_SPEED_FULL or _LOW */ |
360 | /* |
361 | * For low-speed, 10 ms is the official minimum. |
362 | * But some "overclocked" devices might want faster |
363 | * polling so we'll allow it. |
364 | */ |
365 | n = 10; |
366 | break; |
367 | } |
368 | } else if (usb_endpoint_xfer_isoc(epd: d)) { |
369 | i = 1; |
370 | j = 16; |
371 | switch (udev->speed) { |
372 | case USB_SPEED_HIGH: |
373 | n = 7; /* 8 ms = 2^(7-1) uframes */ |
374 | break; |
375 | default: /* USB_SPEED_FULL */ |
376 | n = 4; /* 8 ms = 2^(4-1) frames */ |
377 | break; |
378 | } |
379 | } |
380 | if (d->bInterval < i || d->bInterval > j) { |
381 | dev_notice(ddev, "config %d interface %d altsetting %d " |
382 | "endpoint 0x%X has an invalid bInterval %d, " |
383 | "changing to %d\n" , |
384 | cfgno, inum, asnum, |
385 | d->bEndpointAddress, d->bInterval, n); |
386 | endpoint->desc.bInterval = n; |
387 | } |
388 | |
389 | /* Some buggy low-speed devices have Bulk endpoints, which is |
390 | * explicitly forbidden by the USB spec. In an attempt to make |
391 | * them usable, we will try treating them as Interrupt endpoints. |
392 | */ |
393 | if (udev->speed == USB_SPEED_LOW && usb_endpoint_xfer_bulk(epd: d)) { |
394 | dev_notice(ddev, "config %d interface %d altsetting %d " |
395 | "endpoint 0x%X is Bulk; changing to Interrupt\n" , |
396 | cfgno, inum, asnum, d->bEndpointAddress); |
397 | endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; |
398 | endpoint->desc.bInterval = 1; |
399 | if (usb_endpoint_maxp(epd: &endpoint->desc) > 8) |
400 | endpoint->desc.wMaxPacketSize = cpu_to_le16(8); |
401 | } |
402 | |
403 | /* |
404 | * Validate the wMaxPacketSize field. |
405 | * Some devices have isochronous endpoints in altsetting 0; |
406 | * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0 |
407 | * (see the end of section 5.6.3), so don't warn about them. |
408 | */ |
409 | maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize); |
410 | if (maxp == 0 && !(usb_endpoint_xfer_isoc(epd: d) && asnum == 0)) { |
411 | dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n" , |
412 | cfgno, inum, asnum, d->bEndpointAddress); |
413 | } |
414 | |
415 | /* Find the highest legal maxpacket size for this endpoint */ |
416 | i = 0; /* additional transactions per microframe */ |
417 | switch (udev->speed) { |
418 | case USB_SPEED_LOW: |
419 | maxpacket_maxes = low_speed_maxpacket_maxes; |
420 | break; |
421 | case USB_SPEED_FULL: |
422 | maxpacket_maxes = full_speed_maxpacket_maxes; |
423 | break; |
424 | case USB_SPEED_HIGH: |
425 | /* Multiple-transactions bits are allowed only for HS periodic endpoints */ |
426 | if (usb_endpoint_xfer_int(epd: d) || usb_endpoint_xfer_isoc(epd: d)) { |
427 | i = maxp & USB_EP_MAXP_MULT_MASK; |
428 | maxp &= ~i; |
429 | } |
430 | fallthrough; |
431 | default: |
432 | maxpacket_maxes = high_speed_maxpacket_maxes; |
433 | break; |
434 | case USB_SPEED_SUPER: |
435 | case USB_SPEED_SUPER_PLUS: |
436 | maxpacket_maxes = super_speed_maxpacket_maxes; |
437 | break; |
438 | } |
439 | j = maxpacket_maxes[usb_endpoint_type(epd: &endpoint->desc)]; |
440 | |
441 | if (maxp > j) { |
442 | dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n" , |
443 | cfgno, inum, asnum, d->bEndpointAddress, maxp, j); |
444 | maxp = j; |
445 | endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp); |
446 | } |
447 | |
448 | /* |
449 | * Some buggy high speed devices have bulk endpoints using |
450 | * maxpacket sizes other than 512. High speed HCDs may not |
451 | * be able to handle that particular bug, so let's warn... |
452 | */ |
453 | if (udev->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(epd: d)) { |
454 | if (maxp != 512) |
455 | dev_notice(ddev, "config %d interface %d altsetting %d " |
456 | "bulk endpoint 0x%X has invalid maxpacket %d\n" , |
457 | cfgno, inum, asnum, d->bEndpointAddress, |
458 | maxp); |
459 | } |
460 | |
461 | /* Parse a possible SuperSpeed endpoint companion descriptor */ |
462 | if (udev->speed >= USB_SPEED_SUPER) |
463 | usb_parse_ss_endpoint_companion(ddev, cfgno, |
464 | inum, asnum, ep: endpoint, buffer, size); |
465 | |
466 | /* Skip over any Class Specific or Vendor Specific descriptors; |
467 | * find the next endpoint or interface descriptor */ |
468 | endpoint->extra = buffer; |
469 | i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, |
470 | USB_DT_INTERFACE, num_skipped: &n); |
471 | endpoint->extralen = i; |
472 | retval = buffer - buffer0 + i; |
473 | if (n > 0) |
474 | dev_dbg(ddev, "skipped %d descriptor%s after %s\n" , |
475 | n, plural(n), "endpoint" ); |
476 | return retval; |
477 | |
478 | skip_to_next_endpoint_or_interface_descriptor: |
479 | i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, |
480 | USB_DT_INTERFACE, NULL); |
481 | return buffer - buffer0 + i; |
482 | } |
483 | |
484 | void usb_release_interface_cache(struct kref *ref) |
485 | { |
486 | struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); |
487 | int j; |
488 | |
489 | for (j = 0; j < intfc->num_altsetting; j++) { |
490 | struct usb_host_interface *alt = &intfc->altsetting[j]; |
491 | |
492 | kfree(objp: alt->endpoint); |
493 | kfree(objp: alt->string); |
494 | } |
495 | kfree(objp: intfc); |
496 | } |
497 | |
498 | static int usb_parse_interface(struct device *ddev, int cfgno, |
499 | struct usb_host_config *config, unsigned char *buffer, int size, |
500 | u8 inums[], u8 nalts[]) |
501 | { |
502 | unsigned char *buffer0 = buffer; |
503 | struct usb_interface_descriptor *d; |
504 | int inum, asnum; |
505 | struct usb_interface_cache *intfc; |
506 | struct usb_host_interface *alt; |
507 | int i, n; |
508 | int len, retval; |
509 | int num_ep, num_ep_orig; |
510 | |
511 | d = (struct usb_interface_descriptor *) buffer; |
512 | buffer += d->bLength; |
513 | size -= d->bLength; |
514 | |
515 | if (d->bLength < USB_DT_INTERFACE_SIZE) |
516 | goto skip_to_next_interface_descriptor; |
517 | |
518 | /* Which interface entry is this? */ |
519 | intfc = NULL; |
520 | inum = d->bInterfaceNumber; |
521 | for (i = 0; i < config->desc.bNumInterfaces; ++i) { |
522 | if (inums[i] == inum) { |
523 | intfc = config->intf_cache[i]; |
524 | break; |
525 | } |
526 | } |
527 | if (!intfc || intfc->num_altsetting >= nalts[i]) |
528 | goto skip_to_next_interface_descriptor; |
529 | |
530 | /* Check for duplicate altsetting entries */ |
531 | asnum = d->bAlternateSetting; |
532 | for ((i = 0, alt = &intfc->altsetting[0]); |
533 | i < intfc->num_altsetting; |
534 | (++i, ++alt)) { |
535 | if (alt->desc.bAlternateSetting == asnum) { |
536 | dev_notice(ddev, "Duplicate descriptor for config %d " |
537 | "interface %d altsetting %d, skipping\n" , |
538 | cfgno, inum, asnum); |
539 | goto skip_to_next_interface_descriptor; |
540 | } |
541 | } |
542 | |
543 | ++intfc->num_altsetting; |
544 | memcpy(&alt->desc, d, USB_DT_INTERFACE_SIZE); |
545 | |
546 | /* Skip over any Class Specific or Vendor Specific descriptors; |
547 | * find the first endpoint or interface descriptor */ |
548 | alt->extra = buffer; |
549 | i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, |
550 | USB_DT_INTERFACE, num_skipped: &n); |
551 | alt->extralen = i; |
552 | if (n > 0) |
553 | dev_dbg(ddev, "skipped %d descriptor%s after %s\n" , |
554 | n, plural(n), "interface" ); |
555 | buffer += i; |
556 | size -= i; |
557 | |
558 | /* Allocate space for the right(?) number of endpoints */ |
559 | num_ep = num_ep_orig = alt->desc.bNumEndpoints; |
560 | alt->desc.bNumEndpoints = 0; /* Use as a counter */ |
561 | if (num_ep > USB_MAXENDPOINTS) { |
562 | dev_notice(ddev, "too many endpoints for config %d interface %d " |
563 | "altsetting %d: %d, using maximum allowed: %d\n" , |
564 | cfgno, inum, asnum, num_ep, USB_MAXENDPOINTS); |
565 | num_ep = USB_MAXENDPOINTS; |
566 | } |
567 | |
568 | if (num_ep > 0) { |
569 | /* Can't allocate 0 bytes */ |
570 | len = sizeof(struct usb_host_endpoint) * num_ep; |
571 | alt->endpoint = kzalloc(size: len, GFP_KERNEL); |
572 | if (!alt->endpoint) |
573 | return -ENOMEM; |
574 | } |
575 | |
576 | /* Parse all the endpoint descriptors */ |
577 | n = 0; |
578 | while (size > 0) { |
579 | if (((struct usb_descriptor_header *) buffer)->bDescriptorType |
580 | == USB_DT_INTERFACE) |
581 | break; |
582 | retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum, |
583 | ifp: alt, num_ep, buffer, size); |
584 | if (retval < 0) |
585 | return retval; |
586 | ++n; |
587 | |
588 | buffer += retval; |
589 | size -= retval; |
590 | } |
591 | |
592 | if (n != num_ep_orig) |
593 | dev_notice(ddev, "config %d interface %d altsetting %d has %d " |
594 | "endpoint descriptor%s, different from the interface " |
595 | "descriptor's value: %d\n" , |
596 | cfgno, inum, asnum, n, plural(n), num_ep_orig); |
597 | return buffer - buffer0; |
598 | |
599 | skip_to_next_interface_descriptor: |
600 | i = find_next_descriptor(buffer, size, USB_DT_INTERFACE, |
601 | USB_DT_INTERFACE, NULL); |
602 | return buffer - buffer0 + i; |
603 | } |
604 | |
605 | static int usb_parse_configuration(struct usb_device *dev, int cfgidx, |
606 | struct usb_host_config *config, unsigned char *buffer, int size) |
607 | { |
608 | struct device *ddev = &dev->dev; |
609 | unsigned char *buffer0 = buffer; |
610 | int cfgno; |
611 | int nintf, nintf_orig; |
612 | int i, j, n; |
613 | struct usb_interface_cache *intfc; |
614 | unsigned char *buffer2; |
615 | int size2; |
616 | struct usb_descriptor_header *; |
617 | int retval; |
618 | u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES]; |
619 | unsigned iad_num = 0; |
620 | |
621 | memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); |
622 | nintf = nintf_orig = config->desc.bNumInterfaces; |
623 | config->desc.bNumInterfaces = 0; // Adjusted later |
624 | |
625 | if (config->desc.bDescriptorType != USB_DT_CONFIG || |
626 | config->desc.bLength < USB_DT_CONFIG_SIZE || |
627 | config->desc.bLength > size) { |
628 | dev_notice(ddev, "invalid descriptor for config index %d: " |
629 | "type = 0x%X, length = %d\n" , cfgidx, |
630 | config->desc.bDescriptorType, config->desc.bLength); |
631 | return -EINVAL; |
632 | } |
633 | cfgno = config->desc.bConfigurationValue; |
634 | |
635 | buffer += config->desc.bLength; |
636 | size -= config->desc.bLength; |
637 | |
638 | if (nintf > USB_MAXINTERFACES) { |
639 | dev_notice(ddev, "config %d has too many interfaces: %d, " |
640 | "using maximum allowed: %d\n" , |
641 | cfgno, nintf, USB_MAXINTERFACES); |
642 | nintf = USB_MAXINTERFACES; |
643 | } |
644 | |
645 | /* Go through the descriptors, checking their length and counting the |
646 | * number of altsettings for each interface */ |
647 | n = 0; |
648 | for ((buffer2 = buffer, size2 = size); |
649 | size2 > 0; |
650 | (buffer2 += header->bLength, size2 -= header->bLength)) { |
651 | |
652 | if (size2 < sizeof(struct usb_descriptor_header)) { |
653 | dev_notice(ddev, "config %d descriptor has %d excess " |
654 | "byte%s, ignoring\n" , |
655 | cfgno, size2, plural(size2)); |
656 | break; |
657 | } |
658 | |
659 | header = (struct usb_descriptor_header *) buffer2; |
660 | if ((header->bLength > size2) || (header->bLength < 2)) { |
661 | dev_notice(ddev, "config %d has an invalid descriptor " |
662 | "of length %d, skipping remainder of the config\n" , |
663 | cfgno, header->bLength); |
664 | break; |
665 | } |
666 | |
667 | if (header->bDescriptorType == USB_DT_INTERFACE) { |
668 | struct usb_interface_descriptor *d; |
669 | int inum; |
670 | |
671 | d = (struct usb_interface_descriptor *) header; |
672 | if (d->bLength < USB_DT_INTERFACE_SIZE) { |
673 | dev_notice(ddev, "config %d has an invalid " |
674 | "interface descriptor of length %d, " |
675 | "skipping\n" , cfgno, d->bLength); |
676 | continue; |
677 | } |
678 | |
679 | inum = d->bInterfaceNumber; |
680 | |
681 | if ((dev->quirks & USB_QUIRK_HONOR_BNUMINTERFACES) && |
682 | n >= nintf_orig) { |
683 | dev_notice(ddev, "config %d has more interface " |
684 | "descriptors, than it declares in " |
685 | "bNumInterfaces, ignoring interface " |
686 | "number: %d\n" , cfgno, inum); |
687 | continue; |
688 | } |
689 | |
690 | if (inum >= nintf_orig) |
691 | dev_notice(ddev, "config %d has an invalid " |
692 | "interface number: %d but max is %d\n" , |
693 | cfgno, inum, nintf_orig - 1); |
694 | |
695 | /* Have we already encountered this interface? |
696 | * Count its altsettings */ |
697 | for (i = 0; i < n; ++i) { |
698 | if (inums[i] == inum) |
699 | break; |
700 | } |
701 | if (i < n) { |
702 | if (nalts[i] < 255) |
703 | ++nalts[i]; |
704 | } else if (n < USB_MAXINTERFACES) { |
705 | inums[n] = inum; |
706 | nalts[n] = 1; |
707 | ++n; |
708 | } |
709 | |
710 | } else if (header->bDescriptorType == |
711 | USB_DT_INTERFACE_ASSOCIATION) { |
712 | struct usb_interface_assoc_descriptor *d; |
713 | |
714 | d = (struct usb_interface_assoc_descriptor *)header; |
715 | if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { |
716 | dev_notice(ddev, |
717 | "config %d has an invalid interface association descriptor of length %d, skipping\n" , |
718 | cfgno, d->bLength); |
719 | continue; |
720 | } |
721 | |
722 | if (iad_num == USB_MAXIADS) { |
723 | dev_notice(ddev, "found more Interface " |
724 | "Association Descriptors " |
725 | "than allocated for in " |
726 | "configuration %d\n" , cfgno); |
727 | } else { |
728 | config->intf_assoc[iad_num] = d; |
729 | iad_num++; |
730 | } |
731 | |
732 | } else if (header->bDescriptorType == USB_DT_DEVICE || |
733 | header->bDescriptorType == USB_DT_CONFIG) |
734 | dev_notice(ddev, "config %d contains an unexpected " |
735 | "descriptor of type 0x%X, skipping\n" , |
736 | cfgno, header->bDescriptorType); |
737 | |
738 | } /* for ((buffer2 = buffer, size2 = size); ...) */ |
739 | size = buffer2 - buffer; |
740 | config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0); |
741 | |
742 | if (n != nintf) |
743 | dev_notice(ddev, "config %d has %d interface%s, different from " |
744 | "the descriptor's value: %d\n" , |
745 | cfgno, n, plural(n), nintf_orig); |
746 | else if (n == 0) |
747 | dev_notice(ddev, "config %d has no interfaces?\n" , cfgno); |
748 | config->desc.bNumInterfaces = nintf = n; |
749 | |
750 | /* Check for missing interface numbers */ |
751 | for (i = 0; i < nintf; ++i) { |
752 | for (j = 0; j < nintf; ++j) { |
753 | if (inums[j] == i) |
754 | break; |
755 | } |
756 | if (j >= nintf) |
757 | dev_notice(ddev, "config %d has no interface number " |
758 | "%d\n" , cfgno, i); |
759 | } |
760 | |
761 | /* Allocate the usb_interface_caches and altsetting arrays */ |
762 | for (i = 0; i < nintf; ++i) { |
763 | j = nalts[i]; |
764 | if (j > USB_MAXALTSETTING) { |
765 | dev_notice(ddev, "too many alternate settings for " |
766 | "config %d interface %d: %d, " |
767 | "using maximum allowed: %d\n" , |
768 | cfgno, inums[i], j, USB_MAXALTSETTING); |
769 | nalts[i] = j = USB_MAXALTSETTING; |
770 | } |
771 | |
772 | intfc = kzalloc(struct_size(intfc, altsetting, j), GFP_KERNEL); |
773 | config->intf_cache[i] = intfc; |
774 | if (!intfc) |
775 | return -ENOMEM; |
776 | kref_init(kref: &intfc->ref); |
777 | } |
778 | |
779 | /* FIXME: parse the BOS descriptor */ |
780 | |
781 | /* Skip over any Class Specific or Vendor Specific descriptors; |
782 | * find the first interface descriptor */ |
783 | config->extra = buffer; |
784 | i = find_next_descriptor(buffer, size, USB_DT_INTERFACE, |
785 | USB_DT_INTERFACE, num_skipped: &n); |
786 | config->extralen = i; |
787 | if (n > 0) |
788 | dev_dbg(ddev, "skipped %d descriptor%s after %s\n" , |
789 | n, plural(n), "configuration" ); |
790 | buffer += i; |
791 | size -= i; |
792 | |
793 | /* Parse all the interface/altsetting descriptors */ |
794 | while (size > 0) { |
795 | retval = usb_parse_interface(ddev, cfgno, config, |
796 | buffer, size, inums, nalts); |
797 | if (retval < 0) |
798 | return retval; |
799 | |
800 | buffer += retval; |
801 | size -= retval; |
802 | } |
803 | |
804 | /* Check for missing altsettings */ |
805 | for (i = 0; i < nintf; ++i) { |
806 | intfc = config->intf_cache[i]; |
807 | for (j = 0; j < intfc->num_altsetting; ++j) { |
808 | for (n = 0; n < intfc->num_altsetting; ++n) { |
809 | if (intfc->altsetting[n].desc. |
810 | bAlternateSetting == j) |
811 | break; |
812 | } |
813 | if (n >= intfc->num_altsetting) |
814 | dev_notice(ddev, "config %d interface %d has no " |
815 | "altsetting %d\n" , cfgno, inums[i], j); |
816 | } |
817 | } |
818 | |
819 | return 0; |
820 | } |
821 | |
822 | /* hub-only!! ... and only exported for reset/reinit path. |
823 | * otherwise used internally on disconnect/destroy path |
824 | */ |
825 | void usb_destroy_configuration(struct usb_device *dev) |
826 | { |
827 | int c, i; |
828 | |
829 | if (!dev->config) |
830 | return; |
831 | |
832 | if (dev->rawdescriptors) { |
833 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) |
834 | kfree(objp: dev->rawdescriptors[i]); |
835 | |
836 | kfree(objp: dev->rawdescriptors); |
837 | dev->rawdescriptors = NULL; |
838 | } |
839 | |
840 | for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { |
841 | struct usb_host_config *cf = &dev->config[c]; |
842 | |
843 | kfree(objp: cf->string); |
844 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { |
845 | if (cf->intf_cache[i]) |
846 | kref_put(kref: &cf->intf_cache[i]->ref, |
847 | release: usb_release_interface_cache); |
848 | } |
849 | } |
850 | kfree(objp: dev->config); |
851 | dev->config = NULL; |
852 | } |
853 | |
854 | |
855 | /* |
856 | * Get the USB config descriptors, cache and parse'em |
857 | * |
858 | * hub-only!! ... and only in reset path, or usb_new_device() |
859 | * (used by real hubs and virtual root hubs) |
860 | */ |
861 | int usb_get_configuration(struct usb_device *dev) |
862 | { |
863 | struct device *ddev = &dev->dev; |
864 | int ncfg = dev->descriptor.bNumConfigurations; |
865 | unsigned int cfgno, length; |
866 | unsigned char *bigbuffer; |
867 | struct usb_config_descriptor *desc; |
868 | int result; |
869 | |
870 | if (ncfg > USB_MAXCONFIG) { |
871 | dev_notice(ddev, "too many configurations: %d, " |
872 | "using maximum allowed: %d\n" , ncfg, USB_MAXCONFIG); |
873 | dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; |
874 | } |
875 | |
876 | if (ncfg < 1) { |
877 | dev_err(ddev, "no configurations\n" ); |
878 | return -EINVAL; |
879 | } |
880 | |
881 | length = ncfg * sizeof(struct usb_host_config); |
882 | dev->config = kzalloc(size: length, GFP_KERNEL); |
883 | if (!dev->config) |
884 | return -ENOMEM; |
885 | |
886 | length = ncfg * sizeof(char *); |
887 | dev->rawdescriptors = kzalloc(size: length, GFP_KERNEL); |
888 | if (!dev->rawdescriptors) |
889 | return -ENOMEM; |
890 | |
891 | desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); |
892 | if (!desc) |
893 | return -ENOMEM; |
894 | |
895 | for (cfgno = 0; cfgno < ncfg; cfgno++) { |
896 | /* We grab just the first descriptor so we know how long |
897 | * the whole configuration is */ |
898 | result = usb_get_descriptor(dev, USB_DT_CONFIG, descindex: cfgno, |
899 | buf: desc, USB_DT_CONFIG_SIZE); |
900 | if (result < 0) { |
901 | dev_err(ddev, "unable to read config index %d " |
902 | "descriptor/%s: %d\n" , cfgno, "start" , result); |
903 | if (result != -EPIPE) |
904 | goto err; |
905 | dev_notice(ddev, "chopping to %d config(s)\n" , cfgno); |
906 | dev->descriptor.bNumConfigurations = cfgno; |
907 | break; |
908 | } else if (result < 4) { |
909 | dev_err(ddev, "config index %d descriptor too short " |
910 | "(expected %i, got %i)\n" , cfgno, |
911 | USB_DT_CONFIG_SIZE, result); |
912 | result = -EINVAL; |
913 | goto err; |
914 | } |
915 | length = max((int) le16_to_cpu(desc->wTotalLength), |
916 | USB_DT_CONFIG_SIZE); |
917 | |
918 | /* Now that we know the length, get the whole thing */ |
919 | bigbuffer = kmalloc(size: length, GFP_KERNEL); |
920 | if (!bigbuffer) { |
921 | result = -ENOMEM; |
922 | goto err; |
923 | } |
924 | |
925 | if (dev->quirks & USB_QUIRK_DELAY_INIT) |
926 | msleep(msecs: 200); |
927 | |
928 | result = usb_get_descriptor(dev, USB_DT_CONFIG, descindex: cfgno, |
929 | buf: bigbuffer, size: length); |
930 | if (result < 0) { |
931 | dev_err(ddev, "unable to read config index %d " |
932 | "descriptor/%s\n" , cfgno, "all" ); |
933 | kfree(objp: bigbuffer); |
934 | goto err; |
935 | } |
936 | if (result < length) { |
937 | dev_notice(ddev, "config index %d descriptor too short " |
938 | "(expected %i, got %i)\n" , cfgno, length, result); |
939 | length = result; |
940 | } |
941 | |
942 | dev->rawdescriptors[cfgno] = bigbuffer; |
943 | |
944 | result = usb_parse_configuration(dev, cfgidx: cfgno, |
945 | config: &dev->config[cfgno], buffer: bigbuffer, size: length); |
946 | if (result < 0) { |
947 | ++cfgno; |
948 | goto err; |
949 | } |
950 | } |
951 | |
952 | err: |
953 | kfree(objp: desc); |
954 | dev->descriptor.bNumConfigurations = cfgno; |
955 | |
956 | return result; |
957 | } |
958 | |
959 | void usb_release_bos_descriptor(struct usb_device *dev) |
960 | { |
961 | if (dev->bos) { |
962 | kfree(objp: dev->bos->desc); |
963 | kfree(objp: dev->bos); |
964 | dev->bos = NULL; |
965 | } |
966 | } |
967 | |
968 | static const __u8 bos_desc_len[256] = { |
969 | [USB_CAP_TYPE_WIRELESS_USB] = USB_DT_USB_WIRELESS_CAP_SIZE, |
970 | [USB_CAP_TYPE_EXT] = USB_DT_USB_EXT_CAP_SIZE, |
971 | [USB_SS_CAP_TYPE] = USB_DT_USB_SS_CAP_SIZE, |
972 | [USB_SSP_CAP_TYPE] = USB_DT_USB_SSP_CAP_SIZE(1), |
973 | [CONTAINER_ID_TYPE] = USB_DT_USB_SS_CONTN_ID_SIZE, |
974 | [USB_PTM_CAP_TYPE] = USB_DT_USB_PTM_ID_SIZE, |
975 | }; |
976 | |
977 | /* Get BOS descriptor set */ |
978 | int usb_get_bos_descriptor(struct usb_device *dev) |
979 | { |
980 | struct device *ddev = &dev->dev; |
981 | struct usb_bos_descriptor *bos; |
982 | struct usb_dev_cap_header *cap; |
983 | struct usb_ssp_cap_descriptor *ssp_cap; |
984 | unsigned char *buffer, *buffer0; |
985 | int length, total_len, num, i, ssac; |
986 | __u8 cap_type; |
987 | int ret; |
988 | |
989 | bos = kzalloc(size: sizeof(*bos), GFP_KERNEL); |
990 | if (!bos) |
991 | return -ENOMEM; |
992 | |
993 | /* Get BOS descriptor */ |
994 | ret = usb_get_descriptor(dev, USB_DT_BOS, descindex: 0, buf: bos, USB_DT_BOS_SIZE); |
995 | if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) { |
996 | dev_notice(ddev, "unable to get BOS descriptor or descriptor too short\n" ); |
997 | if (ret >= 0) |
998 | ret = -ENOMSG; |
999 | kfree(objp: bos); |
1000 | return ret; |
1001 | } |
1002 | |
1003 | length = bos->bLength; |
1004 | total_len = le16_to_cpu(bos->wTotalLength); |
1005 | num = bos->bNumDeviceCaps; |
1006 | kfree(objp: bos); |
1007 | if (total_len < length) |
1008 | return -EINVAL; |
1009 | |
1010 | dev->bos = kzalloc(size: sizeof(*dev->bos), GFP_KERNEL); |
1011 | if (!dev->bos) |
1012 | return -ENOMEM; |
1013 | |
1014 | /* Now let's get the whole BOS descriptor set */ |
1015 | buffer = kzalloc(size: total_len, GFP_KERNEL); |
1016 | if (!buffer) { |
1017 | ret = -ENOMEM; |
1018 | goto err; |
1019 | } |
1020 | dev->bos->desc = (struct usb_bos_descriptor *)buffer; |
1021 | |
1022 | ret = usb_get_descriptor(dev, USB_DT_BOS, descindex: 0, buf: buffer, size: total_len); |
1023 | if (ret < total_len) { |
1024 | dev_notice(ddev, "unable to get BOS descriptor set\n" ); |
1025 | if (ret >= 0) |
1026 | ret = -ENOMSG; |
1027 | goto err; |
1028 | } |
1029 | |
1030 | buffer0 = buffer; |
1031 | total_len -= length; |
1032 | buffer += length; |
1033 | |
1034 | for (i = 0; i < num; i++) { |
1035 | cap = (struct usb_dev_cap_header *)buffer; |
1036 | |
1037 | if (total_len < sizeof(*cap) || total_len < cap->bLength) { |
1038 | dev->bos->desc->bNumDeviceCaps = i; |
1039 | break; |
1040 | } |
1041 | cap_type = cap->bDevCapabilityType; |
1042 | length = cap->bLength; |
1043 | if (bos_desc_len[cap_type] && length < bos_desc_len[cap_type]) { |
1044 | dev->bos->desc->bNumDeviceCaps = i; |
1045 | break; |
1046 | } |
1047 | |
1048 | if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { |
1049 | dev_notice(ddev, "descriptor type invalid, skip\n" ); |
1050 | goto skip_to_next_descriptor; |
1051 | } |
1052 | |
1053 | switch (cap_type) { |
1054 | case USB_CAP_TYPE_EXT: |
1055 | dev->bos->ext_cap = |
1056 | (struct usb_ext_cap_descriptor *)buffer; |
1057 | break; |
1058 | case USB_SS_CAP_TYPE: |
1059 | dev->bos->ss_cap = |
1060 | (struct usb_ss_cap_descriptor *)buffer; |
1061 | break; |
1062 | case USB_SSP_CAP_TYPE: |
1063 | ssp_cap = (struct usb_ssp_cap_descriptor *)buffer; |
1064 | ssac = (le32_to_cpu(ssp_cap->bmAttributes) & |
1065 | USB_SSP_SUBLINK_SPEED_ATTRIBS); |
1066 | if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac)) |
1067 | dev->bos->ssp_cap = ssp_cap; |
1068 | break; |
1069 | case CONTAINER_ID_TYPE: |
1070 | dev->bos->ss_id = |
1071 | (struct usb_ss_container_id_descriptor *)buffer; |
1072 | break; |
1073 | case USB_PTM_CAP_TYPE: |
1074 | dev->bos->ptm_cap = |
1075 | (struct usb_ptm_cap_descriptor *)buffer; |
1076 | break; |
1077 | default: |
1078 | break; |
1079 | } |
1080 | |
1081 | skip_to_next_descriptor: |
1082 | total_len -= length; |
1083 | buffer += length; |
1084 | } |
1085 | dev->bos->desc->wTotalLength = cpu_to_le16(buffer - buffer0); |
1086 | |
1087 | return 0; |
1088 | |
1089 | err: |
1090 | usb_release_bos_descriptor(dev); |
1091 | return ret; |
1092 | } |
1093 | |