]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.1/usb-dwc2-host-fix-wmaxpacketsize-handling-fix-webcam-regression.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-5.1 / usb-dwc2-host-fix-wmaxpacketsize-handling-fix-webcam-regression.patch
1 From babd183915e91a64e976b9e8ab682bb56624df76 Mon Sep 17 00:00:00 2001
2 From: Douglas Anderson <dianders@chromium.org>
3 Date: Fri, 31 May 2019 13:04:12 -0700
4 Subject: usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression)
5
6 From: Douglas Anderson <dianders@chromium.org>
7
8 commit babd183915e91a64e976b9e8ab682bb56624df76 upstream.
9
10 In commit abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return
11 only packet size") the API to usb_endpoint_maxp() changed. It used to
12 just return wMaxPacketSize but after that commit it returned
13 wMaxPacketSize with the high bits (the multiplier) masked off. If you
14 wanted to get the multiplier it was now up to your code to call the
15 new usb_endpoint_maxp_mult() which was introduced in
16 commit 541b6fe63023 ("usb: add helper to extract bits 12:11 of
17 wMaxPacketSize").
18
19 Prior to the API change most host drivers were updated, but no update
20 was made to dwc2. Presumably it was assumed that dwc2 was too
21 simplistic to use the multiplier and thus just didn't support a
22 certain class of USB devices. However, it turns out that dwc2 did use
23 the multiplier and many devices using it were working quite nicely.
24 That means that many USB devices have been broken since the API
25 change. One such device is a Logitech HD Pro Webcam C920.
26
27 Specifically, though dwc2 didn't directly call usb_endpoint_maxp(), it
28 did call usb_maxpacket() which in turn called usb_endpoint_maxp().
29
30 Let's update dwc2 to work properly with the new API.
31
32 Fixes: abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size")
33 Cc: stable@vger.kernel.org
34 Acked-by: Minas Harutyunyan <hminas@synopsys.com>
35 Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
36 Signed-off-by: Douglas Anderson <dianders@chromium.org>
37 Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
38 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
39
40 ---
41 drivers/usb/dwc2/hcd.c | 29 +++++++++++++++++------------
42 drivers/usb/dwc2/hcd.h | 20 +++++++++++---------
43 drivers/usb/dwc2/hcd_intr.c | 5 +++--
44 drivers/usb/dwc2/hcd_queue.c | 10 ++++++----
45 4 files changed, 37 insertions(+), 27 deletions(-)
46
47 --- a/drivers/usb/dwc2/hcd.c
48 +++ b/drivers/usb/dwc2/hcd.c
49 @@ -2796,7 +2796,7 @@ static int dwc2_assign_and_init_hc(struc
50 chan->dev_addr = dwc2_hcd_get_dev_addr(&urb->pipe_info);
51 chan->ep_num = dwc2_hcd_get_ep_num(&urb->pipe_info);
52 chan->speed = qh->dev_speed;
53 - chan->max_packet = dwc2_max_packet(qh->maxp);
54 + chan->max_packet = qh->maxp;
55
56 chan->xfer_started = 0;
57 chan->halt_status = DWC2_HC_XFER_NO_HALT_STATUS;
58 @@ -2874,7 +2874,7 @@ static int dwc2_assign_and_init_hc(struc
59 * This value may be modified when the transfer is started
60 * to reflect the actual transfer length
61 */
62 - chan->multi_count = dwc2_hb_mult(qh->maxp);
63 + chan->multi_count = qh->maxp_mult;
64
65 if (hsotg->params.dma_desc_enable) {
66 chan->desc_list_addr = qh->desc_list_dma;
67 @@ -3994,19 +3994,21 @@ static struct dwc2_hcd_urb *dwc2_hcd_urb
68
69 static void dwc2_hcd_urb_set_pipeinfo(struct dwc2_hsotg *hsotg,
70 struct dwc2_hcd_urb *urb, u8 dev_addr,
71 - u8 ep_num, u8 ep_type, u8 ep_dir, u16 mps)
72 + u8 ep_num, u8 ep_type, u8 ep_dir,
73 + u16 maxp, u16 maxp_mult)
74 {
75 if (dbg_perio() ||
76 ep_type == USB_ENDPOINT_XFER_BULK ||
77 ep_type == USB_ENDPOINT_XFER_CONTROL)
78 dev_vdbg(hsotg->dev,
79 - "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, mps=%d\n",
80 - dev_addr, ep_num, ep_dir, ep_type, mps);
81 + "addr=%d, ep_num=%d, ep_dir=%1x, ep_type=%1x, maxp=%d (%d mult)\n",
82 + dev_addr, ep_num, ep_dir, ep_type, maxp, maxp_mult);
83 urb->pipe_info.dev_addr = dev_addr;
84 urb->pipe_info.ep_num = ep_num;
85 urb->pipe_info.pipe_type = ep_type;
86 urb->pipe_info.pipe_dir = ep_dir;
87 - urb->pipe_info.mps = mps;
88 + urb->pipe_info.maxp = maxp;
89 + urb->pipe_info.maxp_mult = maxp_mult;
90 }
91
92 /*
93 @@ -4097,8 +4099,9 @@ void dwc2_hcd_dump_state(struct dwc2_hso
94 dwc2_hcd_is_pipe_in(&urb->pipe_info) ?
95 "IN" : "OUT");
96 dev_dbg(hsotg->dev,
97 - " Max packet size: %d\n",
98 - dwc2_hcd_get_mps(&urb->pipe_info));
99 + " Max packet size: %d (%d mult)\n",
100 + dwc2_hcd_get_maxp(&urb->pipe_info),
101 + dwc2_hcd_get_maxp_mult(&urb->pipe_info));
102 dev_dbg(hsotg->dev,
103 " transfer_buffer: %p\n",
104 urb->buf);
105 @@ -4665,8 +4668,10 @@ static void dwc2_dump_urb_info(struct us
106 }
107
108 dev_vdbg(hsotg->dev, " Speed: %s\n", speed);
109 - dev_vdbg(hsotg->dev, " Max packet size: %d\n",
110 - usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
111 + dev_vdbg(hsotg->dev, " Max packet size: %d (%d mult)\n",
112 + usb_endpoint_maxp(&urb->ep->desc),
113 + usb_endpoint_maxp_mult(&urb->ep->desc));
114 +
115 dev_vdbg(hsotg->dev, " Data buffer length: %d\n",
116 urb->transfer_buffer_length);
117 dev_vdbg(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n",
118 @@ -4749,8 +4754,8 @@ static int _dwc2_hcd_urb_enqueue(struct
119 dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, usb_pipedevice(urb->pipe),
120 usb_pipeendpoint(urb->pipe), ep_type,
121 usb_pipein(urb->pipe),
122 - usb_maxpacket(urb->dev, urb->pipe,
123 - !(usb_pipein(urb->pipe))));
124 + usb_endpoint_maxp(&ep->desc),
125 + usb_endpoint_maxp_mult(&ep->desc));
126
127 buf = urb->transfer_buffer;
128
129 --- a/drivers/usb/dwc2/hcd.h
130 +++ b/drivers/usb/dwc2/hcd.h
131 @@ -171,7 +171,8 @@ struct dwc2_hcd_pipe_info {
132 u8 ep_num;
133 u8 pipe_type;
134 u8 pipe_dir;
135 - u16 mps;
136 + u16 maxp;
137 + u16 maxp_mult;
138 };
139
140 struct dwc2_hcd_iso_packet_desc {
141 @@ -264,6 +265,7 @@ struct dwc2_hs_transfer_time {
142 * - USB_ENDPOINT_XFER_ISOC
143 * @ep_is_in: Endpoint direction
144 * @maxp: Value from wMaxPacketSize field of Endpoint Descriptor
145 + * @maxp_mult: Multiplier for maxp
146 * @dev_speed: Device speed. One of the following values:
147 * - USB_SPEED_LOW
148 * - USB_SPEED_FULL
149 @@ -340,6 +342,7 @@ struct dwc2_qh {
150 u8 ep_type;
151 u8 ep_is_in;
152 u16 maxp;
153 + u16 maxp_mult;
154 u8 dev_speed;
155 u8 data_toggle;
156 u8 ping_state;
157 @@ -503,9 +506,14 @@ static inline u8 dwc2_hcd_get_pipe_type(
158 return pipe->pipe_type;
159 }
160
161 -static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe)
162 +static inline u16 dwc2_hcd_get_maxp(struct dwc2_hcd_pipe_info *pipe)
163 +{
164 + return pipe->maxp;
165 +}
166 +
167 +static inline u16 dwc2_hcd_get_maxp_mult(struct dwc2_hcd_pipe_info *pipe)
168 {
169 - return pipe->mps;
170 + return pipe->maxp_mult;
171 }
172
173 static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe)
174 @@ -620,12 +628,6 @@ static inline bool dbg_urb(struct urb *u
175 static inline bool dbg_perio(void) { return false; }
176 #endif
177
178 -/* High bandwidth multiplier as encoded in highspeed endpoint descriptors */
179 -#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03))
180 -
181 -/* Packet size for any kind of endpoint descriptor */
182 -#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff)
183 -
184 /*
185 * Returns true if frame1 index is greater than frame2 index. The comparison
186 * is done modulo FRLISTEN_64_SIZE. This accounts for the rollover of the
187 --- a/drivers/usb/dwc2/hcd_intr.c
188 +++ b/drivers/usb/dwc2/hcd_intr.c
189 @@ -1617,8 +1617,9 @@ static void dwc2_hc_ahberr_intr(struct d
190
191 dev_err(hsotg->dev, " Speed: %s\n", speed);
192
193 - dev_err(hsotg->dev, " Max packet size: %d\n",
194 - dwc2_hcd_get_mps(&urb->pipe_info));
195 + dev_err(hsotg->dev, " Max packet size: %d (mult %d)\n",
196 + dwc2_hcd_get_maxp(&urb->pipe_info),
197 + dwc2_hcd_get_maxp_mult(&urb->pipe_info));
198 dev_err(hsotg->dev, " Data buffer length: %d\n", urb->length);
199 dev_err(hsotg->dev, " Transfer buffer: %p, Transfer DMA: %08lx\n",
200 urb->buf, (unsigned long)urb->dma);
201 --- a/drivers/usb/dwc2/hcd_queue.c
202 +++ b/drivers/usb/dwc2/hcd_queue.c
203 @@ -708,7 +708,7 @@ static void dwc2_hs_pmap_unschedule(stru
204 static int dwc2_uframe_schedule_split(struct dwc2_hsotg *hsotg,
205 struct dwc2_qh *qh)
206 {
207 - int bytecount = dwc2_hb_mult(qh->maxp) * dwc2_max_packet(qh->maxp);
208 + int bytecount = qh->maxp_mult * qh->maxp;
209 int ls_search_slice;
210 int err = 0;
211 int host_interval_in_sched;
212 @@ -1332,7 +1332,7 @@ static int dwc2_check_max_xfer_size(stru
213 u32 max_channel_xfer_size;
214 int status = 0;
215
216 - max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp);
217 + max_xfer_size = qh->maxp * qh->maxp_mult;
218 max_channel_xfer_size = hsotg->params.max_transfer_size;
219
220 if (max_xfer_size > max_channel_xfer_size) {
221 @@ -1517,8 +1517,9 @@ static void dwc2_qh_init(struct dwc2_hso
222 u32 prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
223 bool do_split = (prtspd == HPRT0_SPD_HIGH_SPEED &&
224 dev_speed != USB_SPEED_HIGH);
225 - int maxp = dwc2_hcd_get_mps(&urb->pipe_info);
226 - int bytecount = dwc2_hb_mult(maxp) * dwc2_max_packet(maxp);
227 + int maxp = dwc2_hcd_get_maxp(&urb->pipe_info);
228 + int maxp_mult = dwc2_hcd_get_maxp_mult(&urb->pipe_info);
229 + int bytecount = maxp_mult * maxp;
230 char *speed, *type;
231
232 /* Initialize QH */
233 @@ -1531,6 +1532,7 @@ static void dwc2_qh_init(struct dwc2_hso
234
235 qh->data_toggle = DWC2_HC_PID_DATA0;
236 qh->maxp = maxp;
237 + qh->maxp_mult = maxp_mult;
238 INIT_LIST_HEAD(&qh->qtd_list);
239 INIT_LIST_HEAD(&qh->qh_list_entry);
240