]>
Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0 |
bfad65ee | 2 | /* |
72246da4 FB |
3 | * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling |
4 | * | |
5 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com | |
72246da4 FB |
6 | * |
7 | * Authors: Felipe Balbi <balbi@ti.com>, | |
8 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
72246da4 FB |
9 | */ |
10 | ||
11 | #include <linux/kernel.h> | |
12 | #include <linux/slab.h> | |
13 | #include <linux/spinlock.h> | |
14 | #include <linux/platform_device.h> | |
15 | #include <linux/pm_runtime.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/io.h> | |
18 | #include <linux/list.h> | |
19 | #include <linux/dma-mapping.h> | |
20 | ||
21 | #include <linux/usb/ch9.h> | |
22 | #include <linux/usb/gadget.h> | |
5bdb1dcc | 23 | #include <linux/usb/composite.h> |
72246da4 FB |
24 | |
25 | #include "core.h" | |
80977dc9 | 26 | #include "debug.h" |
72246da4 FB |
27 | #include "gadget.h" |
28 | #include "io.h" | |
29 | ||
788a23f4 | 30 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep); |
a0807881 FB |
31 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, |
32 | struct dwc3_ep *dep, struct dwc3_request *req); | |
5bdb1dcc | 33 | |
d686a5ff | 34 | static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep, |
7931ec86 | 35 | dma_addr_t buf_dma, u32 len, u32 type, bool chain) |
72246da4 | 36 | { |
f6bafc6a | 37 | struct dwc3_trb *trb; |
d686a5ff | 38 | struct dwc3 *dwc; |
72246da4 | 39 | |
d686a5ff | 40 | dwc = dep->dwc; |
53fd8818 | 41 | trb = &dwc->ep0_trb[dep->trb_enqueue]; |
2abd9d5f KVA |
42 | |
43 | if (chain) | |
53fd8818 | 44 | dep->trb_enqueue++; |
72246da4 | 45 | |
f6bafc6a FB |
46 | trb->bpl = lower_32_bits(buf_dma); |
47 | trb->bph = upper_32_bits(buf_dma); | |
48 | trb->size = len; | |
49 | trb->ctrl = type; | |
72246da4 | 50 | |
f6bafc6a | 51 | trb->ctrl |= (DWC3_TRB_CTRL_HWO |
f6bafc6a | 52 | | DWC3_TRB_CTRL_ISP_IMI); |
72246da4 | 53 | |
2abd9d5f KVA |
54 | if (chain) |
55 | trb->ctrl |= DWC3_TRB_CTRL_CHN; | |
56 | else | |
57 | trb->ctrl |= (DWC3_TRB_CTRL_IOC | |
58 | | DWC3_TRB_CTRL_LST); | |
59 | ||
7931ec86 FB |
60 | trace_dwc3_prepare_trb(dep, trb); |
61 | } | |
62 | ||
d686a5ff | 63 | static int dwc3_ep0_start_trans(struct dwc3_ep *dep) |
7931ec86 FB |
64 | { |
65 | struct dwc3_gadget_ep_cmd_params params; | |
d686a5ff | 66 | struct dwc3 *dwc; |
7931ec86 FB |
67 | int ret; |
68 | ||
5f2e7975 | 69 | if (dep->flags & DWC3_EP_TRANSFER_STARTED) |
2abd9d5f KVA |
70 | return 0; |
71 | ||
d686a5ff FB |
72 | dwc = dep->dwc; |
73 | ||
72246da4 | 74 | memset(¶ms, 0, sizeof(params)); |
dc1c70a7 FB |
75 | params.param0 = upper_32_bits(dwc->ep0_trb_addr); |
76 | params.param1 = lower_32_bits(dwc->ep0_trb_addr); | |
72246da4 | 77 | |
2cd4718d | 78 | ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); |
8566cd1a | 79 | if (ret < 0) |
72246da4 | 80 | return ret; |
72246da4 | 81 | |
1ddcb218 FB |
82 | dwc->ep0_next_event = DWC3_EP0_COMPLETE; |
83 | ||
72246da4 FB |
84 | return 0; |
85 | } | |
86 | ||
87 | static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, | |
88 | struct dwc3_request *req) | |
89 | { | |
5bdb1dcc | 90 | struct dwc3 *dwc = dep->dwc; |
72246da4 FB |
91 | |
92 | req->request.actual = 0; | |
93 | req->request.status = -EINPROGRESS; | |
72246da4 FB |
94 | req->epnum = dep->number; |
95 | ||
aa3342c8 | 96 | list_add_tail(&req->list, &dep->pending_list); |
a6829706 | 97 | |
c7fcdeb2 FB |
98 | /* |
99 | * Gadget driver might not be quick enough to queue a request | |
100 | * before we get a Transfer Not Ready event on this endpoint. | |
101 | * | |
102 | * In that case, we will set DWC3_EP_PENDING_REQUEST. When that | |
103 | * flag is set, it's telling us that as soon as Gadget queues the | |
104 | * required request, we should kick the transfer here because the | |
105 | * IRQ we were waiting for is long gone. | |
106 | */ | |
107 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | |
c7fcdeb2 | 108 | unsigned direction; |
c7fcdeb2 FB |
109 | |
110 | direction = !!(dep->flags & DWC3_EP0_DIR_IN); | |
111 | ||
68d8a781 FB |
112 | if (dwc->ep0state != EP0_DATA_PHASE) { |
113 | dev_WARN(dwc->dev, "Unexpected pending request\n"); | |
c7fcdeb2 FB |
114 | return 0; |
115 | } | |
72246da4 | 116 | |
a0807881 FB |
117 | __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req); |
118 | ||
c7fcdeb2 FB |
119 | dep->flags &= ~(DWC3_EP_PENDING_REQUEST | |
120 | DWC3_EP0_DIR_IN); | |
d9b33c60 FB |
121 | |
122 | return 0; | |
123 | } | |
124 | ||
125 | /* | |
126 | * In case gadget driver asked us to delay the STATUS phase, | |
127 | * handle it here. | |
128 | */ | |
129 | if (dwc->delayed_status) { | |
7125d584 FB |
130 | unsigned direction; |
131 | ||
132 | direction = !dwc->ep0_expect_in; | |
5bdb1dcc | 133 | dwc->delayed_status = false; |
7c81290e | 134 | usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); |
68d3e668 FB |
135 | |
136 | if (dwc->ep0state == EP0_STATUS_PHASE) | |
7125d584 | 137 | __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); |
d9b33c60 FB |
138 | |
139 | return 0; | |
72246da4 FB |
140 | } |
141 | ||
fca8892a FB |
142 | /* |
143 | * Unfortunately we have uncovered a limitation wrt the Data Phase. | |
144 | * | |
145 | * Section 9.4 says we can wait for the XferNotReady(DATA) event to | |
146 | * come before issueing Start Transfer command, but if we do, we will | |
147 | * miss situations where the host starts another SETUP phase instead of | |
148 | * the DATA phase. Such cases happen at least on TD.7.6 of the Link | |
149 | * Layer Compliance Suite. | |
150 | * | |
151 | * The problem surfaces due to the fact that in case of back-to-back | |
152 | * SETUP packets there will be no XferNotReady(DATA) generated and we | |
153 | * will be stuck waiting for XferNotReady(DATA) forever. | |
154 | * | |
155 | * By looking at tables 9-13 and 9-14 of the Databook, we can see that | |
156 | * it tells us to start Data Phase right away. It also mentions that if | |
157 | * we receive a SETUP phase instead of the DATA phase, core will issue | |
158 | * XferComplete for the DATA phase, before actually initiating it in | |
159 | * the wire, with the TRB's status set to "SETUP_PENDING". Such status | |
160 | * can only be used to print some debugging logs, as the core expects | |
161 | * us to go through to the STATUS phase and start a CONTROL_STATUS TRB, | |
162 | * just so it completes right away, without transferring anything and, | |
163 | * only then, we can go back to the SETUP phase. | |
164 | * | |
165 | * Because of this scenario, SNPS decided to change the programming | |
166 | * model of control transfers and support on-demand transfers only for | |
167 | * the STATUS phase. To fix the issue we have now, we will always wait | |
168 | * for gadget driver to queue the DATA phase's struct usb_request, then | |
169 | * start it right away. | |
170 | * | |
171 | * If we're actually in a 2-stage transfer, we will wait for | |
172 | * XferNotReady(STATUS). | |
173 | */ | |
174 | if (dwc->three_stage_setup) { | |
175 | unsigned direction; | |
176 | ||
177 | direction = dwc->ep0_expect_in; | |
178 | dwc->ep0state = EP0_DATA_PHASE; | |
179 | ||
180 | __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req); | |
181 | ||
182 | dep->flags &= ~DWC3_EP0_DIR_IN; | |
183 | } | |
184 | ||
35f75696 | 185 | return 0; |
72246da4 FB |
186 | } |
187 | ||
188 | int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | |
189 | gfp_t gfp_flags) | |
190 | { | |
191 | struct dwc3_request *req = to_dwc3_request(request); | |
192 | struct dwc3_ep *dep = to_dwc3_ep(ep); | |
193 | struct dwc3 *dwc = dep->dwc; | |
194 | ||
195 | unsigned long flags; | |
196 | ||
197 | int ret; | |
198 | ||
72246da4 | 199 | spin_lock_irqsave(&dwc->lock, flags); |
16e78db7 | 200 | if (!dep->endpoint.desc) { |
5eb30ced FB |
201 | dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", |
202 | dep->name); | |
72246da4 FB |
203 | ret = -ESHUTDOWN; |
204 | goto out; | |
205 | } | |
206 | ||
207 | /* we share one TRB for ep0/1 */ | |
aa3342c8 | 208 | if (!list_empty(&dep->pending_list)) { |
72246da4 FB |
209 | ret = -EBUSY; |
210 | goto out; | |
211 | } | |
212 | ||
72246da4 FB |
213 | ret = __dwc3_gadget_ep0_queue(dep, req); |
214 | ||
215 | out: | |
216 | spin_unlock_irqrestore(&dwc->lock, flags); | |
217 | ||
218 | return ret; | |
219 | } | |
220 | ||
221 | static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) | |
222 | { | |
2dfe37d4 FB |
223 | struct dwc3_ep *dep; |
224 | ||
225 | /* reinitialize physical ep1 */ | |
226 | dep = dwc->eps[1]; | |
227 | dep->flags = DWC3_EP_ENABLED; | |
d742220b | 228 | |
72246da4 | 229 | /* stall is always issued on EP0 */ |
2dfe37d4 | 230 | dep = dwc->eps[0]; |
7a608559 | 231 | __dwc3_gadget_ep_set_halt(dep, 1, false); |
c2da2ff0 | 232 | dep->flags = DWC3_EP_ENABLED; |
5bdb1dcc | 233 | dwc->delayed_status = false; |
d742220b | 234 | |
aa3342c8 | 235 | if (!list_empty(&dep->pending_list)) { |
d742220b FB |
236 | struct dwc3_request *req; |
237 | ||
aa3342c8 | 238 | req = next_request(&dep->pending_list); |
d742220b FB |
239 | dwc3_gadget_giveback(dep, req, -ECONNRESET); |
240 | } | |
241 | ||
c7fcdeb2 | 242 | dwc->ep0state = EP0_SETUP_PHASE; |
72246da4 FB |
243 | dwc3_ep0_out_start(dwc); |
244 | } | |
245 | ||
33fb691b | 246 | int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) |
08f0d966 PA |
247 | { |
248 | struct dwc3_ep *dep = to_dwc3_ep(ep); | |
249 | struct dwc3 *dwc = dep->dwc; | |
250 | ||
251 | dwc3_ep0_stall_and_restart(dwc); | |
252 | ||
253 | return 0; | |
254 | } | |
255 | ||
33fb691b FB |
256 | int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) |
257 | { | |
258 | struct dwc3_ep *dep = to_dwc3_ep(ep); | |
259 | struct dwc3 *dwc = dep->dwc; | |
260 | unsigned long flags; | |
261 | int ret; | |
262 | ||
263 | spin_lock_irqsave(&dwc->lock, flags); | |
264 | ret = __dwc3_gadget_ep0_set_halt(ep, value); | |
265 | spin_unlock_irqrestore(&dwc->lock, flags); | |
266 | ||
267 | return ret; | |
268 | } | |
269 | ||
72246da4 FB |
270 | void dwc3_ep0_out_start(struct dwc3 *dwc) |
271 | { | |
d686a5ff | 272 | struct dwc3_ep *dep; |
72246da4 FB |
273 | int ret; |
274 | ||
bb014736 BW |
275 | complete(&dwc->ep0_in_setup); |
276 | ||
d686a5ff FB |
277 | dep = dwc->eps[0]; |
278 | dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8, | |
368ca113 | 279 | DWC3_TRBCTL_CONTROL_SETUP, false); |
d686a5ff | 280 | ret = dwc3_ep0_start_trans(dep); |
72246da4 FB |
281 | WARN_ON(ret < 0); |
282 | } | |
283 | ||
72246da4 FB |
284 | static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) |
285 | { | |
286 | struct dwc3_ep *dep; | |
287 | u32 windex = le16_to_cpu(wIndex_le); | |
288 | u32 epnum; | |
289 | ||
290 | epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1; | |
291 | if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) | |
292 | epnum |= 1; | |
293 | ||
294 | dep = dwc->eps[epnum]; | |
295 | if (dep->flags & DWC3_EP_ENABLED) | |
296 | return dep; | |
297 | ||
298 | return NULL; | |
299 | } | |
300 | ||
8ee6270c | 301 | static void dwc3_ep0_status_cmpl(struct usb_ep *ep, struct usb_request *req) |
72246da4 | 302 | { |
72246da4 | 303 | } |
72246da4 FB |
304 | /* |
305 | * ch 9.4.5 | |
306 | */ | |
25b8ff68 FB |
307 | static int dwc3_ep0_handle_status(struct dwc3 *dwc, |
308 | struct usb_ctrlrequest *ctrl) | |
72246da4 FB |
309 | { |
310 | struct dwc3_ep *dep; | |
311 | u32 recip; | |
9b0a1f95 | 312 | u32 value; |
e6a3b5e2 | 313 | u32 reg; |
72246da4 FB |
314 | u16 usb_status = 0; |
315 | __le16 *response_pkt; | |
316 | ||
9b0a1f95 FB |
317 | /* We don't support PTM_STATUS */ |
318 | value = le16_to_cpu(ctrl->wValue); | |
319 | if (value != 0) | |
320 | return -EINVAL; | |
321 | ||
72246da4 FB |
322 | recip = ctrl->bRequestType & USB_RECIP_MASK; |
323 | switch (recip) { | |
324 | case USB_RECIP_DEVICE: | |
325 | /* | |
e6a3b5e2 | 326 | * LTM will be set once we know how to set this in HW. |
72246da4 | 327 | */ |
bcdea503 | 328 | usb_status |= dwc->gadget.is_selfpowered; |
e6a3b5e2 | 329 | |
ee5cd41c JY |
330 | if ((dwc->speed == DWC3_DSTS_SUPERSPEED) || |
331 | (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) { | |
e6a3b5e2 SAS |
332 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
333 | if (reg & DWC3_DCTL_INITU1ENA) | |
334 | usb_status |= 1 << USB_DEV_STAT_U1_ENABLED; | |
335 | if (reg & DWC3_DCTL_INITU2ENA) | |
336 | usb_status |= 1 << USB_DEV_STAT_U2_ENABLED; | |
337 | } | |
338 | ||
72246da4 FB |
339 | break; |
340 | ||
341 | case USB_RECIP_INTERFACE: | |
342 | /* | |
343 | * Function Remote Wake Capable D0 | |
344 | * Function Remote Wakeup D1 | |
345 | */ | |
346 | break; | |
347 | ||
348 | case USB_RECIP_ENDPOINT: | |
349 | dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); | |
350 | if (!dep) | |
25b8ff68 | 351 | return -EINVAL; |
72246da4 FB |
352 | |
353 | if (dep->flags & DWC3_EP_STALL) | |
354 | usb_status = 1 << USB_ENDPOINT_HALT; | |
355 | break; | |
356 | default: | |
357 | return -EINVAL; | |
2b84f92b | 358 | } |
72246da4 FB |
359 | |
360 | response_pkt = (__le16 *) dwc->setup_buf; | |
361 | *response_pkt = cpu_to_le16(usb_status); | |
e2617796 FB |
362 | |
363 | dep = dwc->eps[0]; | |
364 | dwc->ep0_usb_req.dep = dep; | |
e0ce0b0a | 365 | dwc->ep0_usb_req.request.length = sizeof(*response_pkt); |
0fc9a1be | 366 | dwc->ep0_usb_req.request.buf = dwc->setup_buf; |
e0ce0b0a | 367 | dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl; |
e2617796 FB |
368 | |
369 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); | |
72246da4 FB |
370 | } |
371 | ||
39e07ffb FB |
372 | static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, |
373 | int set) | |
374 | { | |
375 | u32 reg; | |
376 | ||
377 | if (state != USB_STATE_CONFIGURED) | |
378 | return -EINVAL; | |
379 | if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && | |
380 | (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) | |
381 | return -EINVAL; | |
729dcffd AKV |
382 | if (set && dwc->dis_u1_entry_quirk) |
383 | return -EINVAL; | |
39e07ffb FB |
384 | |
385 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | |
386 | if (set) | |
387 | reg |= DWC3_DCTL_INITU1ENA; | |
388 | else | |
389 | reg &= ~DWC3_DCTL_INITU1ENA; | |
390 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | |
391 | ||
392 | return 0; | |
393 | } | |
394 | ||
395 | static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, | |
396 | int set) | |
397 | { | |
398 | u32 reg; | |
399 | ||
400 | ||
401 | if (state != USB_STATE_CONFIGURED) | |
402 | return -EINVAL; | |
403 | if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && | |
404 | (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) | |
405 | return -EINVAL; | |
729dcffd AKV |
406 | if (set && dwc->dis_u2_entry_quirk) |
407 | return -EINVAL; | |
39e07ffb FB |
408 | |
409 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | |
410 | if (set) | |
411 | reg |= DWC3_DCTL_INITU2ENA; | |
412 | else | |
413 | reg &= ~DWC3_DCTL_INITU2ENA; | |
414 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | |
415 | ||
416 | return 0; | |
417 | } | |
418 | ||
419 | static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state, | |
420 | u32 wIndex, int set) | |
421 | { | |
422 | if ((wIndex & 0xff) != 0) | |
423 | return -EINVAL; | |
424 | if (!set) | |
425 | return -EINVAL; | |
426 | ||
427 | switch (wIndex >> 8) { | |
428 | case TEST_J: | |
429 | case TEST_K: | |
430 | case TEST_SE0_NAK: | |
431 | case TEST_PACKET: | |
432 | case TEST_FORCE_EN: | |
433 | dwc->test_mode_nr = wIndex >> 8; | |
434 | dwc->test_mode = true; | |
435 | break; | |
436 | default: | |
437 | return -EINVAL; | |
438 | } | |
439 | ||
440 | return 0; | |
441 | } | |
442 | ||
443 | static int dwc3_ep0_handle_device(struct dwc3 *dwc, | |
72246da4 FB |
444 | struct usb_ctrlrequest *ctrl, int set) |
445 | { | |
39e07ffb | 446 | enum usb_device_state state; |
72246da4 FB |
447 | u32 wValue; |
448 | u32 wIndex; | |
39e07ffb | 449 | int ret = 0; |
72246da4 FB |
450 | |
451 | wValue = le16_to_cpu(ctrl->wValue); | |
452 | wIndex = le16_to_cpu(ctrl->wIndex); | |
fdba5aa5 FB |
453 | state = dwc->gadget.state; |
454 | ||
39e07ffb FB |
455 | switch (wValue) { |
456 | case USB_DEVICE_REMOTE_WAKEUP: | |
457 | break; | |
458 | /* | |
459 | * 9.4.1 says only only for SS, in AddressState only for | |
460 | * default control pipe | |
461 | */ | |
462 | case USB_DEVICE_U1_ENABLE: | |
463 | ret = dwc3_ep0_handle_u1(dwc, state, set); | |
464 | break; | |
465 | case USB_DEVICE_U2_ENABLE: | |
466 | ret = dwc3_ep0_handle_u2(dwc, state, set); | |
467 | break; | |
468 | case USB_DEVICE_LTM_ENABLE: | |
469 | ret = -EINVAL; | |
470 | break; | |
471 | case USB_DEVICE_TEST_MODE: | |
472 | ret = dwc3_ep0_handle_test(dwc, state, wIndex, set); | |
473 | break; | |
474 | default: | |
475 | ret = -EINVAL; | |
476 | } | |
72246da4 | 477 | |
39e07ffb FB |
478 | return ret; |
479 | } | |
72246da4 | 480 | |
39e07ffb FB |
481 | static int dwc3_ep0_handle_intf(struct dwc3 *dwc, |
482 | struct usb_ctrlrequest *ctrl, int set) | |
483 | { | |
39e07ffb | 484 | u32 wValue; |
39e07ffb | 485 | int ret = 0; |
e6a3b5e2 | 486 | |
39e07ffb | 487 | wValue = le16_to_cpu(ctrl->wValue); |
e6a3b5e2 | 488 | |
39e07ffb FB |
489 | switch (wValue) { |
490 | case USB_INTRF_FUNC_SUSPEND: | |
1c404b51 AB |
491 | /* |
492 | * REVISIT: Ideally we would enable some low power mode here, | |
493 | * however it's unclear what we should be doing here. | |
494 | * | |
495 | * For now, we're not doing anything, just making sure we return | |
496 | * 0 so USB Command Verifier tests pass without any errors. | |
497 | */ | |
39e07ffb FB |
498 | break; |
499 | default: | |
500 | ret = -EINVAL; | |
501 | } | |
e6a3b5e2 | 502 | |
39e07ffb FB |
503 | return ret; |
504 | } | |
505 | ||
506 | static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc, | |
507 | struct usb_ctrlrequest *ctrl, int set) | |
508 | { | |
509 | struct dwc3_ep *dep; | |
39e07ffb | 510 | u32 wValue; |
39e07ffb FB |
511 | int ret; |
512 | ||
513 | wValue = le16_to_cpu(ctrl->wValue); | |
39e07ffb FB |
514 | |
515 | switch (wValue) { | |
516 | case USB_ENDPOINT_HALT: | |
517 | dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); | |
518 | if (!dep) | |
e6a3b5e2 | 519 | return -EINVAL; |
72246da4 | 520 | |
39e07ffb | 521 | if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) |
ecb07797 | 522 | break; |
39e07ffb FB |
523 | |
524 | ret = __dwc3_gadget_ep_set_halt(dep, set, true); | |
525 | if (ret) | |
ecb07797 | 526 | return -EINVAL; |
72246da4 | 527 | break; |
39e07ffb FB |
528 | default: |
529 | return -EINVAL; | |
530 | } | |
531 | ||
532 | return 0; | |
533 | } | |
534 | ||
535 | static int dwc3_ep0_handle_feature(struct dwc3 *dwc, | |
536 | struct usb_ctrlrequest *ctrl, int set) | |
537 | { | |
538 | u32 recip; | |
539 | int ret; | |
39e07ffb FB |
540 | |
541 | recip = ctrl->bRequestType & USB_RECIP_MASK; | |
72246da4 | 542 | |
39e07ffb FB |
543 | switch (recip) { |
544 | case USB_RECIP_DEVICE: | |
545 | ret = dwc3_ep0_handle_device(dwc, ctrl, set); | |
546 | break; | |
72246da4 | 547 | case USB_RECIP_INTERFACE: |
39e07ffb | 548 | ret = dwc3_ep0_handle_intf(dwc, ctrl, set); |
72246da4 | 549 | break; |
72246da4 | 550 | case USB_RECIP_ENDPOINT: |
39e07ffb | 551 | ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set); |
72246da4 | 552 | break; |
72246da4 | 553 | default: |
39e07ffb | 554 | ret = -EINVAL; |
2b84f92b | 555 | } |
72246da4 | 556 | |
39e07ffb | 557 | return ret; |
72246da4 FB |
558 | } |
559 | ||
560 | static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |
561 | { | |
fdba5aa5 | 562 | enum usb_device_state state = dwc->gadget.state; |
72246da4 FB |
563 | u32 addr; |
564 | u32 reg; | |
565 | ||
566 | addr = le16_to_cpu(ctrl->wValue); | |
f96a6ec1 | 567 | if (addr > 127) { |
5eb30ced | 568 | dev_err(dwc->dev, "invalid device address %d\n", addr); |
72246da4 | 569 | return -EINVAL; |
f96a6ec1 FB |
570 | } |
571 | ||
fdba5aa5 | 572 | if (state == USB_STATE_CONFIGURED) { |
5eb30ced | 573 | dev_err(dwc->dev, "can't SetAddress() from Configured State\n"); |
f96a6ec1 FB |
574 | return -EINVAL; |
575 | } | |
72246da4 | 576 | |
2646021e FB |
577 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); |
578 | reg &= ~(DWC3_DCFG_DEVADDR_MASK); | |
579 | reg |= DWC3_DCFG_DEVADDR(addr); | |
580 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | |
72246da4 | 581 | |
fdba5aa5 | 582 | if (addr) |
14cd592f | 583 | usb_gadget_set_state(&dwc->gadget, USB_STATE_ADDRESS); |
fdba5aa5 | 584 | else |
14cd592f | 585 | usb_gadget_set_state(&dwc->gadget, USB_STATE_DEFAULT); |
c7fcdeb2 | 586 | |
2646021e | 587 | return 0; |
72246da4 FB |
588 | } |
589 | ||
590 | static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |
591 | { | |
592 | int ret; | |
593 | ||
594 | spin_unlock(&dwc->lock); | |
595 | ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl); | |
596 | spin_lock(&dwc->lock); | |
597 | return ret; | |
598 | } | |
599 | ||
600 | static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |
601 | { | |
fdba5aa5 | 602 | enum usb_device_state state = dwc->gadget.state; |
72246da4 FB |
603 | u32 cfg; |
604 | int ret; | |
e274a31e | 605 | u32 reg; |
72246da4 FB |
606 | |
607 | cfg = le16_to_cpu(ctrl->wValue); | |
608 | ||
fdba5aa5 FB |
609 | switch (state) { |
610 | case USB_STATE_DEFAULT: | |
72246da4 | 611 | return -EINVAL; |
72246da4 | 612 | |
fdba5aa5 | 613 | case USB_STATE_ADDRESS: |
72246da4 FB |
614 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
615 | /* if the cfg matches and the cfg is non zero */ | |
457e84b6 | 616 | if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { |
7c81290e FB |
617 | |
618 | /* | |
619 | * only change state if set_config has already | |
620 | * been processed. If gadget driver returns | |
621 | * USB_GADGET_DELAYED_STATUS, we will wait | |
622 | * to change the state on the next usb_ep_queue() | |
623 | */ | |
624 | if (ret == 0) | |
625 | usb_gadget_set_state(&dwc->gadget, | |
626 | USB_STATE_CONFIGURED); | |
14cd592f | 627 | |
e274a31e PA |
628 | /* |
629 | * Enable transition to U1/U2 state when | |
630 | * nothing is pending from application. | |
631 | */ | |
632 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | |
729dcffd AKV |
633 | if (!dwc->dis_u1_entry_quirk) |
634 | reg |= DWC3_DCTL_ACCEPTU1ENA; | |
635 | if (!dwc->dis_u2_entry_quirk) | |
636 | reg |= DWC3_DCTL_ACCEPTU2ENA; | |
e274a31e | 637 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
457e84b6 | 638 | } |
72246da4 FB |
639 | break; |
640 | ||
fdba5aa5 | 641 | case USB_STATE_CONFIGURED: |
72246da4 | 642 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
7a42d835 | 643 | if (!cfg && !ret) |
14cd592f FB |
644 | usb_gadget_set_state(&dwc->gadget, |
645 | USB_STATE_ADDRESS); | |
72246da4 | 646 | break; |
5bdb1dcc SAS |
647 | default: |
648 | ret = -EINVAL; | |
72246da4 | 649 | } |
5bdb1dcc | 650 | return ret; |
72246da4 FB |
651 | } |
652 | ||
865e09e7 FB |
653 | static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req) |
654 | { | |
655 | struct dwc3_ep *dep = to_dwc3_ep(ep); | |
656 | struct dwc3 *dwc = dep->dwc; | |
657 | ||
658 | u32 param = 0; | |
659 | u32 reg; | |
660 | ||
661 | struct timing { | |
662 | u8 u1sel; | |
663 | u8 u1pel; | |
501058ed JY |
664 | __le16 u2sel; |
665 | __le16 u2pel; | |
865e09e7 FB |
666 | } __packed timing; |
667 | ||
668 | int ret; | |
669 | ||
670 | memcpy(&timing, req->buf, sizeof(timing)); | |
671 | ||
672 | dwc->u1sel = timing.u1sel; | |
673 | dwc->u1pel = timing.u1pel; | |
c8cf7af4 FB |
674 | dwc->u2sel = le16_to_cpu(timing.u2sel); |
675 | dwc->u2pel = le16_to_cpu(timing.u2pel); | |
865e09e7 FB |
676 | |
677 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | |
678 | if (reg & DWC3_DCTL_INITU2ENA) | |
679 | param = dwc->u2pel; | |
680 | if (reg & DWC3_DCTL_INITU1ENA) | |
681 | param = dwc->u1pel; | |
682 | ||
683 | /* | |
684 | * According to Synopsys Databook, if parameter is | |
685 | * greater than 125, a value of zero should be | |
686 | * programmed in the register. | |
687 | */ | |
688 | if (param > 125) | |
689 | param = 0; | |
690 | ||
691 | /* now that we have the time, issue DGCMD Set Sel */ | |
692 | ret = dwc3_send_gadget_generic_command(dwc, | |
693 | DWC3_DGCMD_SET_PERIODIC_PAR, param); | |
694 | WARN_ON(ret < 0); | |
695 | } | |
696 | ||
697 | static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) | |
698 | { | |
699 | struct dwc3_ep *dep; | |
fdba5aa5 | 700 | enum usb_device_state state = dwc->gadget.state; |
865e09e7 | 701 | u16 wLength; |
865e09e7 | 702 | |
fdba5aa5 | 703 | if (state == USB_STATE_DEFAULT) |
865e09e7 FB |
704 | return -EINVAL; |
705 | ||
865e09e7 FB |
706 | wLength = le16_to_cpu(ctrl->wLength); |
707 | ||
708 | if (wLength != 6) { | |
709 | dev_err(dwc->dev, "Set SEL should be 6 bytes, got %d\n", | |
710 | wLength); | |
711 | return -EINVAL; | |
712 | } | |
713 | ||
714 | /* | |
715 | * To handle Set SEL we need to receive 6 bytes from Host. So let's | |
716 | * queue a usb_request for 6 bytes. | |
717 | * | |
718 | * Remember, though, this controller can't handle non-wMaxPacketSize | |
719 | * aligned transfers on the OUT direction, so we queue a request for | |
720 | * wMaxPacketSize instead. | |
721 | */ | |
722 | dep = dwc->eps[0]; | |
723 | dwc->ep0_usb_req.dep = dep; | |
724 | dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket; | |
725 | dwc->ep0_usb_req.request.buf = dwc->setup_buf; | |
726 | dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl; | |
727 | ||
728 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); | |
729 | } | |
730 | ||
c12a0d86 FB |
731 | static int dwc3_ep0_set_isoch_delay(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
732 | { | |
733 | u16 wLength; | |
734 | u16 wValue; | |
735 | u16 wIndex; | |
736 | ||
737 | wValue = le16_to_cpu(ctrl->wValue); | |
738 | wLength = le16_to_cpu(ctrl->wLength); | |
739 | wIndex = le16_to_cpu(ctrl->wIndex); | |
740 | ||
741 | if (wIndex || wLength) | |
742 | return -EINVAL; | |
743 | ||
19e0b203 | 744 | dwc->gadget.isoch_delay = wValue; |
c12a0d86 FB |
745 | |
746 | return 0; | |
747 | } | |
748 | ||
72246da4 FB |
749 | static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) |
750 | { | |
751 | int ret; | |
752 | ||
753 | switch (ctrl->bRequest) { | |
754 | case USB_REQ_GET_STATUS: | |
72246da4 FB |
755 | ret = dwc3_ep0_handle_status(dwc, ctrl); |
756 | break; | |
757 | case USB_REQ_CLEAR_FEATURE: | |
72246da4 FB |
758 | ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); |
759 | break; | |
760 | case USB_REQ_SET_FEATURE: | |
72246da4 FB |
761 | ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); |
762 | break; | |
763 | case USB_REQ_SET_ADDRESS: | |
72246da4 FB |
764 | ret = dwc3_ep0_set_address(dwc, ctrl); |
765 | break; | |
766 | case USB_REQ_SET_CONFIGURATION: | |
72246da4 FB |
767 | ret = dwc3_ep0_set_config(dwc, ctrl); |
768 | break; | |
865e09e7 | 769 | case USB_REQ_SET_SEL: |
865e09e7 FB |
770 | ret = dwc3_ep0_set_sel(dwc, ctrl); |
771 | break; | |
c12a0d86 | 772 | case USB_REQ_SET_ISOCH_DELAY: |
c12a0d86 FB |
773 | ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); |
774 | break; | |
72246da4 | 775 | default: |
72246da4 FB |
776 | ret = dwc3_ep0_delegate_req(dwc, ctrl); |
777 | break; | |
2b84f92b | 778 | } |
72246da4 FB |
779 | |
780 | return ret; | |
781 | } | |
782 | ||
783 | static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, | |
784 | const struct dwc3_event_depevt *event) | |
785 | { | |
7d5e650a | 786 | struct usb_ctrlrequest *ctrl = (void *) dwc->ep0_trb; |
ef21ede6 | 787 | int ret = -EINVAL; |
72246da4 FB |
788 | u32 len; |
789 | ||
790 | if (!dwc->gadget_driver) | |
ef21ede6 | 791 | goto out; |
72246da4 | 792 | |
2c4cbe6e FB |
793 | trace_dwc3_ctrl_req(ctrl); |
794 | ||
72246da4 | 795 | len = le16_to_cpu(ctrl->wLength); |
1ddcb218 | 796 | if (!len) { |
d95b09b9 FB |
797 | dwc->three_stage_setup = false; |
798 | dwc->ep0_expect_in = false; | |
1ddcb218 FB |
799 | dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; |
800 | } else { | |
d95b09b9 FB |
801 | dwc->three_stage_setup = true; |
802 | dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN); | |
1ddcb218 FB |
803 | dwc->ep0_next_event = DWC3_EP0_NRDY_DATA; |
804 | } | |
72246da4 FB |
805 | |
806 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) | |
807 | ret = dwc3_ep0_std_request(dwc, ctrl); | |
808 | else | |
809 | ret = dwc3_ep0_delegate_req(dwc, ctrl); | |
810 | ||
5bdb1dcc SAS |
811 | if (ret == USB_GADGET_DELAYED_STATUS) |
812 | dwc->delayed_status = true; | |
813 | ||
ef21ede6 FB |
814 | out: |
815 | if (ret < 0) | |
816 | dwc3_ep0_stall_and_restart(dwc); | |
72246da4 FB |
817 | } |
818 | ||
819 | static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |
820 | const struct dwc3_event_depevt *event) | |
821 | { | |
7642d838 | 822 | struct dwc3_request *r; |
72246da4 | 823 | struct usb_request *ur; |
f6bafc6a | 824 | struct dwc3_trb *trb; |
c2da2ff0 | 825 | struct dwc3_ep *ep0; |
8a344220 | 826 | u32 transferred = 0; |
fca8892a | 827 | u32 status; |
f6bafc6a | 828 | u32 length; |
72246da4 FB |
829 | u8 epnum; |
830 | ||
831 | epnum = event->endpoint_number; | |
c2da2ff0 | 832 | ep0 = dwc->eps[0]; |
72246da4 | 833 | |
1ddcb218 | 834 | dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; |
f6bafc6a | 835 | trb = dwc->ep0_trb; |
ccb072de FB |
836 | trace_dwc3_complete_trb(ep0, trb); |
837 | ||
aa3342c8 | 838 | r = next_request(&ep0->pending_list); |
520fe763 FB |
839 | if (!r) |
840 | return; | |
841 | ||
fca8892a FB |
842 | status = DWC3_TRB_SIZE_TRBSTS(trb->size); |
843 | if (status == DWC3_TRBSTS_SETUP_PENDING) { | |
b5d335e5 | 844 | dwc->setup_packet_pending = true; |
fca8892a FB |
845 | if (r) |
846 | dwc3_gadget_giveback(ep0, r, -ECONNRESET); | |
847 | ||
848 | return; | |
849 | } | |
850 | ||
6856d30c FB |
851 | ur = &r->request; |
852 | ||
f6bafc6a | 853 | length = trb->size & DWC3_TRB_SIZE_MASK; |
4199c5f8 FB |
854 | transferred = ur->length - length; |
855 | ur->actual += transferred; | |
8a344220 | 856 | |
d6e5a549 FB |
857 | if ((IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) && |
858 | ur->length && ur->zero) || dwc->ep0_bounced) { | |
4199c5f8 FB |
859 | trb++; |
860 | trb->ctrl &= ~DWC3_TRB_CTRL_HWO; | |
d6e5a549 | 861 | trace_dwc3_complete_trb(ep0, trb); |
f035d139 TN |
862 | |
863 | if (r->direction) | |
864 | dwc->eps[1]->trb_enqueue = 0; | |
865 | else | |
866 | dwc->eps[0]->trb_enqueue = 0; | |
867 | ||
4199c5f8 | 868 | dwc->ep0_bounced = false; |
a6829706 | 869 | } |
72246da4 | 870 | |
d6e5a549 | 871 | if ((epnum & 1) && ur->actual < ur->length) |
72246da4 | 872 | dwc3_ep0_stall_and_restart(dwc); |
d6e5a549 | 873 | else |
36f84ffb | 874 | dwc3_gadget_giveback(ep0, r, 0); |
72246da4 FB |
875 | } |
876 | ||
85a78101 | 877 | static void dwc3_ep0_complete_status(struct dwc3 *dwc, |
72246da4 FB |
878 | const struct dwc3_event_depevt *event) |
879 | { | |
880 | struct dwc3_request *r; | |
881 | struct dwc3_ep *dep; | |
fca8892a FB |
882 | struct dwc3_trb *trb; |
883 | u32 status; | |
72246da4 | 884 | |
c7fcdeb2 | 885 | dep = dwc->eps[0]; |
fca8892a | 886 | trb = dwc->ep0_trb; |
72246da4 | 887 | |
ccb072de FB |
888 | trace_dwc3_complete_trb(dep, trb); |
889 | ||
aa3342c8 FB |
890 | if (!list_empty(&dep->pending_list)) { |
891 | r = next_request(&dep->pending_list); | |
72246da4 FB |
892 | |
893 | dwc3_gadget_giveback(dep, r, 0); | |
894 | } | |
895 | ||
3b637367 GC |
896 | if (dwc->test_mode) { |
897 | int ret; | |
898 | ||
899 | ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); | |
900 | if (ret < 0) { | |
5eb30ced | 901 | dev_err(dwc->dev, "invalid test #%d\n", |
3b637367 GC |
902 | dwc->test_mode_nr); |
903 | dwc3_ep0_stall_and_restart(dwc); | |
5c81abab | 904 | return; |
3b637367 GC |
905 | } |
906 | } | |
907 | ||
fca8892a | 908 | status = DWC3_TRB_SIZE_TRBSTS(trb->size); |
5eb30ced | 909 | if (status == DWC3_TRBSTS_SETUP_PENDING) |
b5d335e5 | 910 | dwc->setup_packet_pending = true; |
fca8892a | 911 | |
c7fcdeb2 | 912 | dwc->ep0state = EP0_SETUP_PHASE; |
72246da4 FB |
913 | dwc3_ep0_out_start(dwc); |
914 | } | |
915 | ||
916 | static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, | |
917 | const struct dwc3_event_depevt *event) | |
918 | { | |
c7fcdeb2 FB |
919 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; |
920 | ||
5f2e7975 | 921 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; |
b4996a86 | 922 | dep->resource_index = 0; |
df62df56 | 923 | dwc->setup_packet_pending = false; |
c7fcdeb2 | 924 | |
72246da4 | 925 | switch (dwc->ep0state) { |
c7fcdeb2 | 926 | case EP0_SETUP_PHASE: |
72246da4 FB |
927 | dwc3_ep0_inspect_setup(dwc, event); |
928 | break; | |
929 | ||
c7fcdeb2 | 930 | case EP0_DATA_PHASE: |
72246da4 FB |
931 | dwc3_ep0_complete_data(dwc, event); |
932 | break; | |
933 | ||
c7fcdeb2 | 934 | case EP0_STATUS_PHASE: |
85a78101 | 935 | dwc3_ep0_complete_status(dwc, event); |
72246da4 | 936 | break; |
c7fcdeb2 FB |
937 | default: |
938 | WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state); | |
939 | } | |
940 | } | |
72246da4 | 941 | |
a0807881 FB |
942 | static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, |
943 | struct dwc3_ep *dep, struct dwc3_request *req) | |
c7fcdeb2 | 944 | { |
c7fcdeb2 FB |
945 | int ret; |
946 | ||
a0807881 | 947 | req->direction = !!dep->number; |
c7fcdeb2 | 948 | |
c7fcdeb2 | 949 | if (req->request.length == 0) { |
d686a5ff | 950 | dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0, |
368ca113 | 951 | DWC3_TRBCTL_CONTROL_DATA, false); |
d686a5ff | 952 | ret = dwc3_ep0_start_trans(dep); |
c74c6d4a | 953 | } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) |
a0807881 | 954 | && (dep->number == 0)) { |
c390b036 | 955 | u32 maxpacket; |
4199c5f8 | 956 | u32 rem; |
a0807881 | 957 | |
d64ff406 AB |
958 | ret = usb_gadget_map_request_by_dev(dwc->sysdev, |
959 | &req->request, dep->number); | |
5eb30ced | 960 | if (ret) |
0fc9a1be | 961 | return; |
c7fcdeb2 | 962 | |
c390b036 | 963 | maxpacket = dep->endpoint.maxpacket; |
4199c5f8 | 964 | rem = req->request.length % maxpacket; |
c7fcdeb2 FB |
965 | dwc->ep0_bounced = true; |
966 | ||
4199c5f8 FB |
967 | /* prepare normal TRB */ |
968 | dwc3_ep0_prepare_one_trb(dep, req->request.dma, | |
969 | req->request.length, | |
970 | DWC3_TRBCTL_CONTROL_DATA, | |
971 | true); | |
972 | ||
55168470 FB |
973 | req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; |
974 | ||
4199c5f8 FB |
975 | /* Now prepare one extra TRB to align transfer size */ |
976 | dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, | |
977 | maxpacket - rem, | |
978 | DWC3_TRBCTL_CONTROL_DATA, | |
d686a5ff FB |
979 | false); |
980 | ret = dwc3_ep0_start_trans(dep); | |
d6e5a549 FB |
981 | } else if (IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && |
982 | req->request.length && req->request.zero) { | |
d6e5a549 FB |
983 | |
984 | ret = usb_gadget_map_request_by_dev(dwc->sysdev, | |
985 | &req->request, dep->number); | |
986 | if (ret) | |
987 | return; | |
988 | ||
d6e5a549 FB |
989 | /* prepare normal TRB */ |
990 | dwc3_ep0_prepare_one_trb(dep, req->request.dma, | |
991 | req->request.length, | |
992 | DWC3_TRBCTL_CONTROL_DATA, | |
993 | true); | |
994 | ||
55168470 FB |
995 | req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; |
996 | ||
d6e5a549 FB |
997 | /* Now prepare one extra TRB to align transfer size */ |
998 | dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, | |
999 | 0, DWC3_TRBCTL_CONTROL_DATA, | |
1000 | false); | |
1001 | ret = dwc3_ep0_start_trans(dep); | |
c7fcdeb2 | 1002 | } else { |
d64ff406 AB |
1003 | ret = usb_gadget_map_request_by_dev(dwc->sysdev, |
1004 | &req->request, dep->number); | |
5eb30ced | 1005 | if (ret) |
0fc9a1be | 1006 | return; |
c7fcdeb2 | 1007 | |
d686a5ff | 1008 | dwc3_ep0_prepare_one_trb(dep, req->request.dma, |
368ca113 KVA |
1009 | req->request.length, DWC3_TRBCTL_CONTROL_DATA, |
1010 | false); | |
55168470 FB |
1011 | |
1012 | req->trb = &dwc->ep0_trb[dep->trb_enqueue]; | |
1013 | ||
d686a5ff | 1014 | ret = dwc3_ep0_start_trans(dep); |
c7fcdeb2 FB |
1015 | } |
1016 | ||
1017 | WARN_ON(ret < 0); | |
72246da4 FB |
1018 | } |
1019 | ||
f0f2b2a2 | 1020 | static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) |
72246da4 | 1021 | { |
f0f2b2a2 | 1022 | struct dwc3 *dwc = dep->dwc; |
c7fcdeb2 | 1023 | u32 type; |
72246da4 | 1024 | |
c7fcdeb2 FB |
1025 | type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 |
1026 | : DWC3_TRBCTL_CONTROL_STATUS2; | |
1027 | ||
d686a5ff FB |
1028 | dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0, type, false); |
1029 | return dwc3_ep0_start_trans(dep); | |
f0f2b2a2 | 1030 | } |
c7fcdeb2 | 1031 | |
788a23f4 | 1032 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) |
f0f2b2a2 | 1033 | { |
f0f2b2a2 | 1034 | WARN_ON(dwc3_ep0_start_control_status(dep)); |
c7fcdeb2 FB |
1035 | } |
1036 | ||
788a23f4 FB |
1037 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, |
1038 | const struct dwc3_event_depevt *event) | |
1039 | { | |
1040 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; | |
1041 | ||
1042 | __dwc3_ep0_do_control_status(dwc, dep); | |
1043 | } | |
1044 | ||
2e3db064 FB |
1045 | static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) |
1046 | { | |
1047 | struct dwc3_gadget_ep_cmd_params params; | |
1048 | u32 cmd; | |
1049 | int ret; | |
1050 | ||
1051 | if (!dep->resource_index) | |
1052 | return; | |
1053 | ||
1054 | cmd = DWC3_DEPCMD_ENDTRANSFER; | |
1055 | cmd |= DWC3_DEPCMD_CMDIOC; | |
1056 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); | |
1057 | memset(¶ms, 0, sizeof(params)); | |
2cd4718d | 1058 | ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); |
2e3db064 FB |
1059 | WARN_ON_ONCE(ret); |
1060 | dep->resource_index = 0; | |
1061 | } | |
1062 | ||
c7fcdeb2 FB |
1063 | static void dwc3_ep0_xfernotready(struct dwc3 *dwc, |
1064 | const struct dwc3_event_depevt *event) | |
1065 | { | |
1066 | switch (event->status) { | |
c7fcdeb2 | 1067 | case DEPEVT_STATUS_CONTROL_DATA: |
55f3fba6 | 1068 | /* |
2e3db064 FB |
1069 | * We already have a DATA transfer in the controller's cache, |
1070 | * if we receive a XferNotReady(DATA) we will ignore it, unless | |
1071 | * it's for the wrong direction. | |
55f3fba6 | 1072 | * |
2e3db064 FB |
1073 | * In that case, we must issue END_TRANSFER command to the Data |
1074 | * Phase we already have started and issue SetStall on the | |
1075 | * control endpoint. | |
55f3fba6 FB |
1076 | */ |
1077 | if (dwc->ep0_expect_in != event->endpoint_number) { | |
2e3db064 FB |
1078 | struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; |
1079 | ||
5eb30ced | 1080 | dev_err(dwc->dev, "unexpected direction for Data Phase\n"); |
2e3db064 | 1081 | dwc3_ep0_end_control_data(dwc, dep); |
55f3fba6 FB |
1082 | dwc3_ep0_stall_and_restart(dwc); |
1083 | return; | |
1084 | } | |
1085 | ||
c7fcdeb2 | 1086 | break; |
1ddcb218 | 1087 | |
c7fcdeb2 | 1088 | case DEPEVT_STATUS_CONTROL_STATUS: |
77fa6df8 FB |
1089 | if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) |
1090 | return; | |
1091 | ||
f0f2b2a2 SAS |
1092 | dwc->ep0state = EP0_STATUS_PHASE; |
1093 | ||
5bdb1dcc | 1094 | if (dwc->delayed_status) { |
53896798 BW |
1095 | struct dwc3_ep *dep = dwc->eps[0]; |
1096 | ||
5bdb1dcc | 1097 | WARN_ON_ONCE(event->endpoint_number != 1); |
53896798 BW |
1098 | /* |
1099 | * We should handle the delay STATUS phase here if the | |
1100 | * request for handling delay STATUS has been queued | |
1101 | * into the list. | |
1102 | */ | |
1103 | if (!list_empty(&dep->pending_list)) { | |
1104 | dwc->delayed_status = false; | |
1105 | usb_gadget_set_state(&dwc->gadget, | |
1106 | USB_STATE_CONFIGURED); | |
1107 | dwc3_ep0_do_control_status(dwc, event); | |
1108 | } | |
1109 | ||
5bdb1dcc SAS |
1110 | return; |
1111 | } | |
1112 | ||
788a23f4 | 1113 | dwc3_ep0_do_control_status(dwc, event); |
72246da4 FB |
1114 | } |
1115 | } | |
1116 | ||
1117 | void dwc3_ep0_interrupt(struct dwc3 *dwc, | |
8becf270 | 1118 | const struct dwc3_event_depevt *event) |
72246da4 | 1119 | { |
2d7b78f5 TN |
1120 | struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; |
1121 | u8 cmd; | |
1122 | ||
72246da4 FB |
1123 | switch (event->endpoint_event) { |
1124 | case DWC3_DEPEVT_XFERCOMPLETE: | |
1125 | dwc3_ep0_xfer_complete(dwc, event); | |
1126 | break; | |
1127 | ||
1128 | case DWC3_DEPEVT_XFERNOTREADY: | |
1129 | dwc3_ep0_xfernotready(dwc, event); | |
1130 | break; | |
1131 | ||
1132 | case DWC3_DEPEVT_XFERINPROGRESS: | |
1133 | case DWC3_DEPEVT_RXTXFIFOEVT: | |
1134 | case DWC3_DEPEVT_STREAMEVT: | |
2d7b78f5 | 1135 | break; |
72246da4 | 1136 | case DWC3_DEPEVT_EPCMDCMPLT: |
2d7b78f5 TN |
1137 | cmd = DEPEVT_PARAMETER_CMD(event->parameters); |
1138 | ||
1139 | if (cmd == DWC3_DEPCMD_ENDTRANSFER) | |
1140 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; | |
72246da4 FB |
1141 | break; |
1142 | } | |
1143 | } |