diff options
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
| -rw-r--r-- | drivers/usb/host/xhci-mem.c | 32 | 
1 files changed, 24 insertions, 8 deletions
| diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 36cbe2226a4..383fc857491 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1126,26 +1126,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,  }  /* - * Convert bInterval expressed in frames (in 1-255 range) to exponent of + * Convert bInterval expressed in microframes (in 1-255 range) to exponent of   * microframes, rounded down to nearest power of 2.   */ -static unsigned int xhci_parse_frame_interval(struct usb_device *udev, -		struct usb_host_endpoint *ep) +static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, +		struct usb_host_endpoint *ep, unsigned int desc_interval, +		unsigned int min_exponent, unsigned int max_exponent)  {  	unsigned int interval; -	interval = fls(8 * ep->desc.bInterval) - 1; -	interval = clamp_val(interval, 3, 10); -	if ((1 << interval) != 8 * ep->desc.bInterval) +	interval = fls(desc_interval) - 1; +	interval = clamp_val(interval, min_exponent, max_exponent); +	if ((1 << interval) != desc_interval)  		dev_warn(&udev->dev,  			 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",  			 ep->desc.bEndpointAddress,  			 1 << interval, -			 8 * ep->desc.bInterval); +			 desc_interval);  	return interval;  } +static unsigned int xhci_parse_microframe_interval(struct usb_device *udev, +		struct usb_host_endpoint *ep) +{ +	return xhci_microframes_to_exponent(udev, ep, +			ep->desc.bInterval, 0, 15); +} + + +static unsigned int xhci_parse_frame_interval(struct usb_device *udev, +		struct usb_host_endpoint *ep) +{ +	return xhci_microframes_to_exponent(udev, ep, +			ep->desc.bInterval * 8, 3, 10); +} +  /* Return the polling or NAK interval.   *   * The polling interval is expressed in "microframes".  If xHCI's Interval field @@ -1164,7 +1180,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,  		/* Max NAK rate */  		if (usb_endpoint_xfer_control(&ep->desc) ||  		    usb_endpoint_xfer_bulk(&ep->desc)) { -			interval = ep->desc.bInterval; +			interval = xhci_parse_microframe_interval(udev, ep);  			break;  		}  		/* Fall through - SS and HS isoc/int have same decoding */ | 
