diff options
Diffstat (limited to 'drivers/usb/core/urb.c')
-rw-r--r-- | drivers/usb/core/urb.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 3376055f36e7..0885d4abdc62 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -241,6 +241,12 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); | |||
241 | * If the USB subsystem can't allocate sufficient bandwidth to perform | 241 | * If the USB subsystem can't allocate sufficient bandwidth to perform |
242 | * the periodic request, submitting such a periodic request should fail. | 242 | * the periodic request, submitting such a periodic request should fail. |
243 | * | 243 | * |
244 | * For devices under xHCI, the bandwidth is reserved at configuration time, or | ||
245 | * when the alt setting is selected. If there is not enough bus bandwidth, the | ||
246 | * configuration/alt setting request will fail. Therefore, submissions to | ||
247 | * periodic endpoints on devices under xHCI should never fail due to bandwidth | ||
248 | * constraints. | ||
249 | * | ||
244 | * Device drivers must explicitly request that repetition, by ensuring that | 250 | * Device drivers must explicitly request that repetition, by ensuring that |
245 | * some URB is always on the endpoint's queue (except possibly for short | 251 | * some URB is always on the endpoint's queue (except possibly for short |
246 | * periods during completion callacks). When there is no longer an urb | 252 | * periods during completion callacks). When there is no longer an urb |
@@ -351,6 +357,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
351 | if (xfertype == USB_ENDPOINT_XFER_ISOC) { | 357 | if (xfertype == USB_ENDPOINT_XFER_ISOC) { |
352 | int n, len; | 358 | int n, len; |
353 | 359 | ||
360 | /* FIXME SuperSpeed isoc endpoints have up to 16 bursts */ | ||
354 | /* "high bandwidth" mode, 1-3 packets/uframe? */ | 361 | /* "high bandwidth" mode, 1-3 packets/uframe? */ |
355 | if (dev->speed == USB_SPEED_HIGH) { | 362 | if (dev->speed == USB_SPEED_HIGH) { |
356 | int mult = 1 + ((max >> 11) & 0x03); | 363 | int mult = 1 + ((max >> 11) & 0x03); |
@@ -426,6 +433,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
426 | return -EINVAL; | 433 | return -EINVAL; |
427 | /* too big? */ | 434 | /* too big? */ |
428 | switch (dev->speed) { | 435 | switch (dev->speed) { |
436 | case USB_SPEED_SUPER: /* units are 125us */ | ||
437 | /* Handle up to 2^(16-1) microframes */ | ||
438 | if (urb->interval > (1 << 15)) | ||
439 | return -EINVAL; | ||
440 | max = 1 << 15; | ||
429 | case USB_SPEED_HIGH: /* units are microframes */ | 441 | case USB_SPEED_HIGH: /* units are microframes */ |
430 | /* NOTE usb handles 2^15 */ | 442 | /* NOTE usb handles 2^15 */ |
431 | if (urb->interval > (1024 * 8)) | 443 | if (urb->interval > (1024 * 8)) |