Commit 8e08b976 authored by David Vrabel's avatar David Vrabel Committed by Greg Kroah-Hartman

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: default avatarDavid Vrabel <david.vrabel@csr.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 294a39e7
...@@ -429,8 +429,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) ...@@ -429,8 +429,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_ISOC:
case USB_ENDPOINT_XFER_INT: case USB_ENDPOINT_XFER_INT:
/* too small? */ /* too small? */
switch (dev->speed) {
case USB_SPEED_VARIABLE:
if (urb->interval < 6)
return -EINVAL;
break;
default:
if (urb->interval <= 0) if (urb->interval <= 0)
return -EINVAL; return -EINVAL;
break;
}
/* too big? */ /* too big? */
switch (dev->speed) { switch (dev->speed) {
case USB_SPEED_SUPER: /* units are 125us */ case USB_SPEED_SUPER: /* units are 125us */
...@@ -438,6 +446,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) ...@@ -438,6 +446,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (urb->interval > (1 << 15)) if (urb->interval > (1 << 15))
return -EINVAL; return -EINVAL;
max = 1 << 15; max = 1 << 15;
case USB_SPEED_VARIABLE:
if (urb->interval > 16)
return -EINVAL;
break;
case USB_SPEED_HIGH: /* units are microframes */ case USB_SPEED_HIGH: /* units are microframes */
/* NOTE usb handles 2^15 */ /* NOTE usb handles 2^15 */
if (urb->interval > (1024 * 8)) if (urb->interval > (1024 * 8))
...@@ -461,9 +473,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) ...@@ -461,9 +473,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
default: default:
return -EINVAL; return -EINVAL;
} }
if (dev->speed != USB_SPEED_VARIABLE) {
/* Round down to a power of 2, no more than max */ /* Round down to a power of 2, no more than max */
urb->interval = min(max, 1 << ilog2(urb->interval)); urb->interval = min(max, 1 << ilog2(urb->interval));
} }
}
return usb_hcd_submit_urb(urb, mem_flags); return usb_hcd_submit_urb(urb, mem_flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment