diff options
| author | David Vrabel <david.vrabel@csr.com> | 2009-08-18 16:11:24 +0100 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 11:55:14 -0800 | 
| commit | 8e08b9766b50826e12139a821b6b3bdfcadcceda (patch) | |
| tree | 0430b4ea03a4e92b6e1d503c763a2a38359a4873 /drivers/usb/core/urb.c | |
| parent | 294a39e7829dfd663e6c5c94cede0c6a0c13e37f (diff) | |
| download | olio-linux-3.10-8e08b9766b50826e12139a821b6b3bdfcadcceda.tar.xz olio-linux-3.10-8e08b9766b50826e12139a821b6b3bdfcadcceda.zip  | |
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/usb/core/urb.c')
| -rw-r--r-- | drivers/usb/core/urb.c | 22 | 
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 0885d4abdc6..e7cae133469 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)  	case USB_ENDPOINT_XFER_ISOC:  	case USB_ENDPOINT_XFER_INT:  		/* too small? */ -		if (urb->interval <= 0) -			return -EINVAL; +		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,8 +473,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)  		default:  			return -EINVAL;  		} -		/* Round down to a power of 2, no more than max */ -		urb->interval = min(max, 1 << ilog2(urb->interval)); +		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);  |