aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2009-08-18 11:11:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:14 -0500
commit8e08b9766b50826e12139a821b6b3bdfcadcceda (patch)
tree0430b4ea03a4e92b6e1d503c763a2a38359a4873 /drivers
parent294a39e7829dfd663e6c5c94cede0c6a0c13e37f (diff)
USB: allow interrupt transfers to WUSB devices
Check urb->interval on interrupt transfers and allow those with valid values (6 <= interval <= 16). Signed-off-by: David Vrabel <david.vrabel@csr.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/urb.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 0885d4abdc62..e7cae1334693 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -429,8 +429,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
429 case USB_ENDPOINT_XFER_ISOC: 429 case USB_ENDPOINT_XFER_ISOC:
430 case USB_ENDPOINT_XFER_INT: 430 case USB_ENDPOINT_XFER_INT:
431 /* too small? */ 431 /* too small? */
432 if (urb->interval <= 0) 432 switch (dev->speed) {
433 return -EINVAL; 433 case USB_SPEED_VARIABLE:
434 if (urb->interval < 6)
435 return -EINVAL;
436 break;
437 default:
438 if (urb->interval <= 0)
439 return -EINVAL;
440 break;
441 }
434 /* too big? */ 442 /* too big? */
435 switch (dev->speed) { 443 switch (dev->speed) {
436 case USB_SPEED_SUPER: /* units are 125us */ 444 case USB_SPEED_SUPER: /* units are 125us */
@@ -438,6 +446,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
438 if (urb->interval > (1 << 15)) 446 if (urb->interval > (1 << 15))
439 return -EINVAL; 447 return -EINVAL;
440 max = 1 << 15; 448 max = 1 << 15;
449 case USB_SPEED_VARIABLE:
450 if (urb->interval > 16)
451 return -EINVAL;
452 break;
441 case USB_SPEED_HIGH: /* units are microframes */ 453 case USB_SPEED_HIGH: /* units are microframes */
442 /* NOTE usb handles 2^15 */ 454 /* NOTE usb handles 2^15 */
443 if (urb->interval > (1024 * 8)) 455 if (urb->interval > (1024 * 8))
@@ -461,8 +473,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
461 default: 473 default:
462 return -EINVAL; 474 return -EINVAL;
463 } 475 }
464 /* Round down to a power of 2, no more than max */ 476 if (dev->speed != USB_SPEED_VARIABLE) {
465 urb->interval = min(max, 1 << ilog2(urb->interval)); 477 /* Round down to a power of 2, no more than max */
478 urb->interval = min(max, 1 << ilog2(urb->interval));
479 }
466 } 480 }
467 481
468 return usb_hcd_submit_urb(urb, mem_flags); 482 return usb_hcd_submit_urb(urb, mem_flags);