]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.0.23/xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch
Fix up backported ptrace patch
[thirdparty/kernel/stable-queue.git] / releases / 3.0.23 / xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch
1 From 340a3504fd39dad753ba908fb6f894ee81fc3ae2 Mon Sep 17 00:00:00 2001
2 From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
3 Date: Mon, 13 Feb 2012 14:42:11 -0800
4 Subject: xhci: Fix encoding for HS bulk/control NAK rate.
5
6 From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
7
8 commit 340a3504fd39dad753ba908fb6f894ee81fc3ae2 upstream.
9
10 The xHCI 0.96 spec says that HS bulk and control endpoint NAK rate must
11 be encoded as an exponent of two number of microframes. The endpoint
12 descriptor has the NAK rate encoded in number of microframes. We were
13 just copying the value from the endpoint descriptor into the endpoint
14 context interval field, which was not correct. This lead to the VIA
15 host rejecting the add of a bulk OUT endpoint from any USB 2.0 mass
16 storage device.
17
18 The fix is to use the correct encoding. Refactor the code to convert
19 number of frames to an exponential number of microframes, and make sure
20 we convert the number of microframes in HS bulk and control endpoints to
21 an exponent.
22
23 This should be back ported to kernels as old as 2.6.31, that contain the
24 commit dfa49c4ad120a784ef1ff0717168aa79f55a483a "USB: xhci - fix math
25 in xhci_get_endpoint_interval"
26
27 Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
28 Tested-by: Felipe Contreras <felipe.contreras@gmail.com>
29 Suggested-by: Andiry Xu <andiry.xu@amd.com>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31
32 ---
33 drivers/usb/host/xhci-mem.c | 32 ++++++++++++++++++++++++--------
34 1 file changed, 24 insertions(+), 8 deletions(-)
35
36 --- a/drivers/usb/host/xhci-mem.c
37 +++ b/drivers/usb/host/xhci-mem.c
38 @@ -1002,26 +1002,42 @@ static unsigned int xhci_parse_exponent_
39 }
40
41 /*
42 - * Convert bInterval expressed in frames (in 1-255 range) to exponent of
43 + * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
44 * microframes, rounded down to nearest power of 2.
45 */
46 -static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
47 - struct usb_host_endpoint *ep)
48 +static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
49 + struct usb_host_endpoint *ep, unsigned int desc_interval,
50 + unsigned int min_exponent, unsigned int max_exponent)
51 {
52 unsigned int interval;
53
54 - interval = fls(8 * ep->desc.bInterval) - 1;
55 - interval = clamp_val(interval, 3, 10);
56 - if ((1 << interval) != 8 * ep->desc.bInterval)
57 + interval = fls(desc_interval) - 1;
58 + interval = clamp_val(interval, min_exponent, max_exponent);
59 + if ((1 << interval) != desc_interval)
60 dev_warn(&udev->dev,
61 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
62 ep->desc.bEndpointAddress,
63 1 << interval,
64 - 8 * ep->desc.bInterval);
65 + desc_interval);
66
67 return interval;
68 }
69
70 +static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
71 + struct usb_host_endpoint *ep)
72 +{
73 + return xhci_microframes_to_exponent(udev, ep,
74 + ep->desc.bInterval, 0, 15);
75 +}
76 +
77 +
78 +static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
79 + struct usb_host_endpoint *ep)
80 +{
81 + return xhci_microframes_to_exponent(udev, ep,
82 + ep->desc.bInterval * 8, 3, 10);
83 +}
84 +
85 /* Return the polling or NAK interval.
86 *
87 * The polling interval is expressed in "microframes". If xHCI's Interval field
88 @@ -1040,7 +1056,7 @@ static unsigned int xhci_get_endpoint_in
89 /* Max NAK rate */
90 if (usb_endpoint_xfer_control(&ep->desc) ||
91 usb_endpoint_xfer_bulk(&ep->desc)) {
92 - interval = ep->desc.bInterval;
93 + interval = xhci_parse_microframe_interval(udev, ep);
94 break;
95 }
96 /* Fall through - SS and HS isoc/int have same decoding */