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>
This commit is contained in:
Родитель
294a39e782
Коммит
8e08b9766b
|
@ -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)
|
||||||
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)
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче