aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 36cbe2226a44..383fc857491c 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,
1126} 1126}
1127 1127
1128/* 1128/*
1129 * Convert bInterval expressed in frames (in 1-255 range) to exponent of 1129 * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
1130 * microframes, rounded down to nearest power of 2. 1130 * microframes, rounded down to nearest power of 2.
1131 */ 1131 */
1132static unsigned int xhci_parse_frame_interval(struct usb_device *udev, 1132static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
1133 struct usb_host_endpoint *ep) 1133 struct usb_host_endpoint *ep, unsigned int desc_interval,
1134 unsigned int min_exponent, unsigned int max_exponent)
1134{ 1135{
1135 unsigned int interval; 1136 unsigned int interval;
1136 1137
1137 interval = fls(8 * ep->desc.bInterval) - 1; 1138 interval = fls(desc_interval) - 1;
1138 interval = clamp_val(interval, 3, 10); 1139 interval = clamp_val(interval, min_exponent, max_exponent);
1139 if ((1 << interval) != 8 * ep->desc.bInterval) 1140 if ((1 << interval) != desc_interval)
1140 dev_warn(&udev->dev, 1141 dev_warn(&udev->dev,
1141 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", 1142 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
1142 ep->desc.bEndpointAddress, 1143 ep->desc.bEndpointAddress,
1143 1 << interval, 1144 1 << interval,
1144 8 * ep->desc.bInterval); 1145 desc_interval);
1145 1146
1146 return interval; 1147 return interval;
1147} 1148}
1148 1149
1150static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
1151 struct usb_host_endpoint *ep)
1152{
1153 return xhci_microframes_to_exponent(udev, ep,
1154 ep->desc.bInterval, 0, 15);
1155}
1156
1157
1158static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
1159 struct usb_host_endpoint *ep)
1160{
1161 return xhci_microframes_to_exponent(udev, ep,
1162 ep->desc.bInterval * 8, 3, 10);
1163}
1164
1149/* Return the polling or NAK interval. 1165/* Return the polling or NAK interval.
1150 * 1166 *
1151 * The polling interval is expressed in "microframes". If xHCI's Interval field 1167 * 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,
1164 /* Max NAK rate */ 1180 /* Max NAK rate */
1165 if (usb_endpoint_xfer_control(&ep->desc) || 1181 if (usb_endpoint_xfer_control(&ep->desc) ||
1166 usb_endpoint_xfer_bulk(&ep->desc)) { 1182 usb_endpoint_xfer_bulk(&ep->desc)) {
1167 interval = ep->desc.bInterval; 1183 interval = xhci_parse_microframe_interval(udev, ep);
1168 break; 1184 break;
1169 } 1185 }
1170 /* Fall through - SS and HS isoc/int have same decoding */ 1186 /* Fall through - SS and HS isoc/int have same decoding */