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

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
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -429,8 +429,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
	case USB_ENDPOINT_XFER_ISOC:
	case USB_ENDPOINT_XFER_INT:
		/* too small? */
		switch (dev->speed) {
		case USB_SPEED_VARIABLE:
			if (urb->interval < 6)
				return -EINVAL;
			break;
		default:
			if (urb->interval <= 0)
				return -EINVAL;
			break;
		}
		/* too big? */
		switch (dev->speed) {
		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))
				return -EINVAL;
			max = 1 << 15;
		case USB_SPEED_VARIABLE:
			if (urb->interval > 16)
				return -EINVAL;
			break;
		case USB_SPEED_HIGH:	/* units are microframes */
			/* NOTE usb handles 2^15 */
			if (urb->interval > (1024 * 8))
@@ -461,9 +473,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
		default:
			return -EINVAL;
		}
		if (dev->speed != USB_SPEED_VARIABLE) {
			/* Round down to a power of 2, no more than max */
			urb->interval = min(max, 1 << ilog2(urb->interval));
		}
	}

	return usb_hcd_submit_urb(urb, mem_flags);
}