15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2bfad65eeSFelipe Balbi /*
372246da4SFelipe Balbi * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling
472246da4SFelipe Balbi *
510623b87SAlexander A. Klimov * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
672246da4SFelipe Balbi *
772246da4SFelipe Balbi * Authors: Felipe Balbi <balbi@ti.com>,
872246da4SFelipe Balbi * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
972246da4SFelipe Balbi */
1072246da4SFelipe Balbi
1172246da4SFelipe Balbi #include <linux/kernel.h>
1272246da4SFelipe Balbi #include <linux/slab.h>
1372246da4SFelipe Balbi #include <linux/spinlock.h>
1472246da4SFelipe Balbi #include <linux/platform_device.h>
1572246da4SFelipe Balbi #include <linux/pm_runtime.h>
1672246da4SFelipe Balbi #include <linux/interrupt.h>
1772246da4SFelipe Balbi #include <linux/io.h>
1872246da4SFelipe Balbi #include <linux/list.h>
1972246da4SFelipe Balbi #include <linux/dma-mapping.h>
2072246da4SFelipe Balbi
2172246da4SFelipe Balbi #include <linux/usb/ch9.h>
2272246da4SFelipe Balbi #include <linux/usb/gadget.h>
235bdb1dccSSebastian Andrzej Siewior #include <linux/usb/composite.h>
2472246da4SFelipe Balbi
2572246da4SFelipe Balbi #include "core.h"
2680977dc9SFelipe Balbi #include "debug.h"
2772246da4SFelipe Balbi #include "gadget.h"
2872246da4SFelipe Balbi #include "io.h"
2972246da4SFelipe Balbi
30788a23f4SFelipe Balbi static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
31a0807881SFelipe Balbi static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
32a0807881SFelipe Balbi struct dwc3_ep *dep, struct dwc3_request *req);
3392c08a84SElson Roy Serrao static int dwc3_ep0_delegate_req(struct dwc3 *dwc,
3492c08a84SElson Roy Serrao struct usb_ctrlrequest *ctrl);
355bdb1dccSSebastian Andrzej Siewior
dwc3_ep0_prepare_one_trb(struct dwc3_ep * dep,dma_addr_t buf_dma,u32 len,u32 type,bool chain)36d686a5ffSFelipe Balbi static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep,
377931ec86SFelipe Balbi dma_addr_t buf_dma, u32 len, u32 type, bool chain)
3872246da4SFelipe Balbi {
39f6bafc6aSFelipe Balbi struct dwc3_trb *trb;
40d686a5ffSFelipe Balbi struct dwc3 *dwc;
4172246da4SFelipe Balbi
42d686a5ffSFelipe Balbi dwc = dep->dwc;
4353fd8818SFelipe Balbi trb = &dwc->ep0_trb[dep->trb_enqueue];
442abd9d5fSKishon Vijay Abraham I
452abd9d5fSKishon Vijay Abraham I if (chain)
4653fd8818SFelipe Balbi dep->trb_enqueue++;
4772246da4SFelipe Balbi
48f6bafc6aSFelipe Balbi trb->bpl = lower_32_bits(buf_dma);
49f6bafc6aSFelipe Balbi trb->bph = upper_32_bits(buf_dma);
50f6bafc6aSFelipe Balbi trb->size = len;
51f6bafc6aSFelipe Balbi trb->ctrl = type;
5272246da4SFelipe Balbi
53f6bafc6aSFelipe Balbi trb->ctrl |= (DWC3_TRB_CTRL_HWO
54f6bafc6aSFelipe Balbi | DWC3_TRB_CTRL_ISP_IMI);
5572246da4SFelipe Balbi
562abd9d5fSKishon Vijay Abraham I if (chain)
572abd9d5fSKishon Vijay Abraham I trb->ctrl |= DWC3_TRB_CTRL_CHN;
582abd9d5fSKishon Vijay Abraham I else
592abd9d5fSKishon Vijay Abraham I trb->ctrl |= (DWC3_TRB_CTRL_IOC
602abd9d5fSKishon Vijay Abraham I | DWC3_TRB_CTRL_LST);
612abd9d5fSKishon Vijay Abraham I
627931ec86SFelipe Balbi trace_dwc3_prepare_trb(dep, trb);
637931ec86SFelipe Balbi }
647931ec86SFelipe Balbi
dwc3_ep0_start_trans(struct dwc3_ep * dep)65d686a5ffSFelipe Balbi static int dwc3_ep0_start_trans(struct dwc3_ep *dep)
667931ec86SFelipe Balbi {
677931ec86SFelipe Balbi struct dwc3_gadget_ep_cmd_params params;
68d686a5ffSFelipe Balbi struct dwc3 *dwc;
697931ec86SFelipe Balbi int ret;
707931ec86SFelipe Balbi
715f2e7975SFelipe Balbi if (dep->flags & DWC3_EP_TRANSFER_STARTED)
722abd9d5fSKishon Vijay Abraham I return 0;
732abd9d5fSKishon Vijay Abraham I
74d686a5ffSFelipe Balbi dwc = dep->dwc;
75d686a5ffSFelipe Balbi
7672246da4SFelipe Balbi memset(¶ms, 0, sizeof(params));
77dc1c70a7SFelipe Balbi params.param0 = upper_32_bits(dwc->ep0_trb_addr);
78dc1c70a7SFelipe Balbi params.param1 = lower_32_bits(dwc->ep0_trb_addr);
7972246da4SFelipe Balbi
802cd4718dSFelipe Balbi ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms);
818566cd1aSFelipe Balbi if (ret < 0)
8272246da4SFelipe Balbi return ret;
8372246da4SFelipe Balbi
841ddcb218SFelipe Balbi dwc->ep0_next_event = DWC3_EP0_COMPLETE;
851ddcb218SFelipe Balbi
8672246da4SFelipe Balbi return 0;
8772246da4SFelipe Balbi }
8872246da4SFelipe Balbi
__dwc3_gadget_ep0_queue(struct dwc3_ep * dep,struct dwc3_request * req)8972246da4SFelipe Balbi static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
9072246da4SFelipe Balbi struct dwc3_request *req)
9172246da4SFelipe Balbi {
925bdb1dccSSebastian Andrzej Siewior struct dwc3 *dwc = dep->dwc;
9372246da4SFelipe Balbi
9472246da4SFelipe Balbi req->request.actual = 0;
9572246da4SFelipe Balbi req->request.status = -EINPROGRESS;
9672246da4SFelipe Balbi req->epnum = dep->number;
9772246da4SFelipe Balbi
98aa3342c8SFelipe Balbi list_add_tail(&req->list, &dep->pending_list);
99a6829706SFelipe Balbi
100a6829706SFelipe Balbi /*
101c7fcdeb2SFelipe Balbi * Gadget driver might not be quick enough to queue a request
102c7fcdeb2SFelipe Balbi * before we get a Transfer Not Ready event on this endpoint.
103c7fcdeb2SFelipe Balbi *
104c7fcdeb2SFelipe Balbi * In that case, we will set DWC3_EP_PENDING_REQUEST. When that
105c7fcdeb2SFelipe Balbi * flag is set, it's telling us that as soon as Gadget queues the
106c7fcdeb2SFelipe Balbi * required request, we should kick the transfer here because the
107c7fcdeb2SFelipe Balbi * IRQ we were waiting for is long gone.
108a6829706SFelipe Balbi */
109c7fcdeb2SFelipe Balbi if (dep->flags & DWC3_EP_PENDING_REQUEST) {
110c64b475bSFelipe Balbi unsigned int direction;
11172246da4SFelipe Balbi
112c7fcdeb2SFelipe Balbi direction = !!(dep->flags & DWC3_EP0_DIR_IN);
113c7fcdeb2SFelipe Balbi
11468d8a781SFelipe Balbi if (dwc->ep0state != EP0_DATA_PHASE) {
11568d8a781SFelipe Balbi dev_WARN(dwc->dev, "Unexpected pending request\n");
116c7fcdeb2SFelipe Balbi return 0;
117a6829706SFelipe Balbi }
118a6829706SFelipe Balbi
119a0807881SFelipe Balbi __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req);
120a0807881SFelipe Balbi
121c7fcdeb2SFelipe Balbi dep->flags &= ~(DWC3_EP_PENDING_REQUEST |
122c7fcdeb2SFelipe Balbi DWC3_EP0_DIR_IN);
123d9b33c60SFelipe Balbi
124d9b33c60SFelipe Balbi return 0;
125d9b33c60SFelipe Balbi }
126d9b33c60SFelipe Balbi
127d9b33c60SFelipe Balbi /*
128d9b33c60SFelipe Balbi * In case gadget driver asked us to delay the STATUS phase,
129d9b33c60SFelipe Balbi * handle it here.
130d9b33c60SFelipe Balbi */
131d9b33c60SFelipe Balbi if (dwc->delayed_status) {
132c64b475bSFelipe Balbi unsigned int direction;
1337125d584SFelipe Balbi
1347125d584SFelipe Balbi direction = !dwc->ep0_expect_in;
1355bdb1dccSSebastian Andrzej Siewior dwc->delayed_status = false;
136e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget, USB_STATE_CONFIGURED);
13768d3e668SFelipe Balbi
13868d3e668SFelipe Balbi if (dwc->ep0state == EP0_STATUS_PHASE)
1397125d584SFelipe Balbi __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
140d9b33c60SFelipe Balbi
141d9b33c60SFelipe Balbi return 0;
14272246da4SFelipe Balbi }
14372246da4SFelipe Balbi
144fca8892aSFelipe Balbi /*
145fca8892aSFelipe Balbi * Unfortunately we have uncovered a limitation wrt the Data Phase.
146fca8892aSFelipe Balbi *
147fca8892aSFelipe Balbi * Section 9.4 says we can wait for the XferNotReady(DATA) event to
148fca8892aSFelipe Balbi * come before issueing Start Transfer command, but if we do, we will
149fca8892aSFelipe Balbi * miss situations where the host starts another SETUP phase instead of
150fca8892aSFelipe Balbi * the DATA phase. Such cases happen at least on TD.7.6 of the Link
151fca8892aSFelipe Balbi * Layer Compliance Suite.
152fca8892aSFelipe Balbi *
153fca8892aSFelipe Balbi * The problem surfaces due to the fact that in case of back-to-back
154fca8892aSFelipe Balbi * SETUP packets there will be no XferNotReady(DATA) generated and we
155fca8892aSFelipe Balbi * will be stuck waiting for XferNotReady(DATA) forever.
156fca8892aSFelipe Balbi *
157fca8892aSFelipe Balbi * By looking at tables 9-13 and 9-14 of the Databook, we can see that
158fca8892aSFelipe Balbi * it tells us to start Data Phase right away. It also mentions that if
159fca8892aSFelipe Balbi * we receive a SETUP phase instead of the DATA phase, core will issue
160fca8892aSFelipe Balbi * XferComplete for the DATA phase, before actually initiating it in
161fca8892aSFelipe Balbi * the wire, with the TRB's status set to "SETUP_PENDING". Such status
162fca8892aSFelipe Balbi * can only be used to print some debugging logs, as the core expects
163fca8892aSFelipe Balbi * us to go through to the STATUS phase and start a CONTROL_STATUS TRB,
164fca8892aSFelipe Balbi * just so it completes right away, without transferring anything and,
165fca8892aSFelipe Balbi * only then, we can go back to the SETUP phase.
166fca8892aSFelipe Balbi *
167fca8892aSFelipe Balbi * Because of this scenario, SNPS decided to change the programming
168fca8892aSFelipe Balbi * model of control transfers and support on-demand transfers only for
169fca8892aSFelipe Balbi * the STATUS phase. To fix the issue we have now, we will always wait
170fca8892aSFelipe Balbi * for gadget driver to queue the DATA phase's struct usb_request, then
171fca8892aSFelipe Balbi * start it right away.
172fca8892aSFelipe Balbi *
173fca8892aSFelipe Balbi * If we're actually in a 2-stage transfer, we will wait for
174fca8892aSFelipe Balbi * XferNotReady(STATUS).
175fca8892aSFelipe Balbi */
176fca8892aSFelipe Balbi if (dwc->three_stage_setup) {
177c64b475bSFelipe Balbi unsigned int direction;
178fca8892aSFelipe Balbi
179fca8892aSFelipe Balbi direction = dwc->ep0_expect_in;
180fca8892aSFelipe Balbi dwc->ep0state = EP0_DATA_PHASE;
181fca8892aSFelipe Balbi
182fca8892aSFelipe Balbi __dwc3_ep0_do_control_data(dwc, dwc->eps[direction], req);
183fca8892aSFelipe Balbi
184fca8892aSFelipe Balbi dep->flags &= ~DWC3_EP0_DIR_IN;
185fca8892aSFelipe Balbi }
186fca8892aSFelipe Balbi
18735f75696SFelipe Balbi return 0;
18872246da4SFelipe Balbi }
18972246da4SFelipe Balbi
dwc3_gadget_ep0_queue(struct usb_ep * ep,struct usb_request * request,gfp_t gfp_flags)19072246da4SFelipe Balbi int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
19172246da4SFelipe Balbi gfp_t gfp_flags)
19272246da4SFelipe Balbi {
19372246da4SFelipe Balbi struct dwc3_request *req = to_dwc3_request(request);
19472246da4SFelipe Balbi struct dwc3_ep *dep = to_dwc3_ep(ep);
19572246da4SFelipe Balbi struct dwc3 *dwc = dep->dwc;
19672246da4SFelipe Balbi
19772246da4SFelipe Balbi unsigned long flags;
19872246da4SFelipe Balbi
19972246da4SFelipe Balbi int ret;
20072246da4SFelipe Balbi
20172246da4SFelipe Balbi spin_lock_irqsave(&dwc->lock, flags);
202359d5a85SWesley Cheng if (!dep->endpoint.desc || !dwc->pullups_connected || !dwc->connected) {
2035eb30cedSFelipe Balbi dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
2045eb30cedSFelipe Balbi dep->name);
20572246da4SFelipe Balbi ret = -ESHUTDOWN;
20672246da4SFelipe Balbi goto out;
20772246da4SFelipe Balbi }
20872246da4SFelipe Balbi
20972246da4SFelipe Balbi /* we share one TRB for ep0/1 */
210aa3342c8SFelipe Balbi if (!list_empty(&dep->pending_list)) {
21172246da4SFelipe Balbi ret = -EBUSY;
21272246da4SFelipe Balbi goto out;
21372246da4SFelipe Balbi }
21472246da4SFelipe Balbi
21572246da4SFelipe Balbi ret = __dwc3_gadget_ep0_queue(dep, req);
21672246da4SFelipe Balbi
21772246da4SFelipe Balbi out:
21872246da4SFelipe Balbi spin_unlock_irqrestore(&dwc->lock, flags);
21972246da4SFelipe Balbi
22072246da4SFelipe Balbi return ret;
22172246da4SFelipe Balbi }
22272246da4SFelipe Balbi
dwc3_ep0_stall_and_restart(struct dwc3 * dwc)2239d778f0cSMayank Rana void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
22472246da4SFelipe Balbi {
2252dfe37d4SFelipe Balbi struct dwc3_ep *dep;
2262dfe37d4SFelipe Balbi
2272dfe37d4SFelipe Balbi /* reinitialize physical ep1 */
2282dfe37d4SFelipe Balbi dep = dwc->eps[1];
229*fe330624SThinh Nguyen dep->flags &= DWC3_EP_RESOURCE_ALLOCATED;
230*fe330624SThinh Nguyen dep->flags |= DWC3_EP_ENABLED;
231d742220bSFelipe Balbi
23272246da4SFelipe Balbi /* stall is always issued on EP0 */
2332dfe37d4SFelipe Balbi dep = dwc->eps[0];
2347a608559SFelipe Balbi __dwc3_gadget_ep_set_halt(dep, 1, false);
235c6a3fa83SThinh Nguyen dep->flags &= DWC3_EP_RESOURCE_ALLOCATED | DWC3_EP_TRANSFER_STARTED;
2363df5497bSMichael Grzeschik dep->flags |= DWC3_EP_ENABLED;
2375bdb1dccSSebastian Andrzej Siewior dwc->delayed_status = false;
238d742220bSFelipe Balbi
239aa3342c8SFelipe Balbi if (!list_empty(&dep->pending_list)) {
240d742220bSFelipe Balbi struct dwc3_request *req;
241d742220bSFelipe Balbi
242aa3342c8SFelipe Balbi req = next_request(&dep->pending_list);
24373e20c2fSUttkarsh Aggarwal if (!dwc->connected)
24473e20c2fSUttkarsh Aggarwal dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
24573e20c2fSUttkarsh Aggarwal else
246d742220bSFelipe Balbi dwc3_gadget_giveback(dep, req, -ECONNRESET);
247d742220bSFelipe Balbi }
248d742220bSFelipe Balbi
2495e76ee96SWesley Cheng dwc->eps[0]->trb_enqueue = 0;
2505e76ee96SWesley Cheng dwc->eps[1]->trb_enqueue = 0;
251c7fcdeb2SFelipe Balbi dwc->ep0state = EP0_SETUP_PHASE;
25272246da4SFelipe Balbi dwc3_ep0_out_start(dwc);
25372246da4SFelipe Balbi }
25472246da4SFelipe Balbi
__dwc3_gadget_ep0_set_halt(struct usb_ep * ep,int value)25533fb691bSFelipe Balbi int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
25608f0d966SPratyush Anand {
25708f0d966SPratyush Anand struct dwc3_ep *dep = to_dwc3_ep(ep);
25808f0d966SPratyush Anand struct dwc3 *dwc = dep->dwc;
25908f0d966SPratyush Anand
26008f0d966SPratyush Anand dwc3_ep0_stall_and_restart(dwc);
26108f0d966SPratyush Anand
26208f0d966SPratyush Anand return 0;
26308f0d966SPratyush Anand }
26408f0d966SPratyush Anand
dwc3_gadget_ep0_set_halt(struct usb_ep * ep,int value)26533fb691bSFelipe Balbi int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
26633fb691bSFelipe Balbi {
26733fb691bSFelipe Balbi struct dwc3_ep *dep = to_dwc3_ep(ep);
26833fb691bSFelipe Balbi struct dwc3 *dwc = dep->dwc;
26933fb691bSFelipe Balbi unsigned long flags;
27033fb691bSFelipe Balbi int ret;
27133fb691bSFelipe Balbi
27233fb691bSFelipe Balbi spin_lock_irqsave(&dwc->lock, flags);
27333fb691bSFelipe Balbi ret = __dwc3_gadget_ep0_set_halt(ep, value);
27433fb691bSFelipe Balbi spin_unlock_irqrestore(&dwc->lock, flags);
27533fb691bSFelipe Balbi
27633fb691bSFelipe Balbi return ret;
27733fb691bSFelipe Balbi }
27833fb691bSFelipe Balbi
dwc3_ep0_out_start(struct dwc3 * dwc)27972246da4SFelipe Balbi void dwc3_ep0_out_start(struct dwc3 *dwc)
28072246da4SFelipe Balbi {
281d686a5ffSFelipe Balbi struct dwc3_ep *dep;
28272246da4SFelipe Balbi int ret;
283e4cf6580SThinh Nguyen int i;
28472246da4SFelipe Balbi
285bb014736SBaolin Wang complete(&dwc->ep0_in_setup);
286bb014736SBaolin Wang
287d686a5ffSFelipe Balbi dep = dwc->eps[0];
288d686a5ffSFelipe Balbi dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8,
289368ca113SKishon Vijay Abraham I DWC3_TRBCTL_CONTROL_SETUP, false);
290d686a5ffSFelipe Balbi ret = dwc3_ep0_start_trans(dep);
29172246da4SFelipe Balbi WARN_ON(ret < 0);
292e4cf6580SThinh Nguyen for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) {
293e4cf6580SThinh Nguyen struct dwc3_ep *dwc3_ep;
294e4cf6580SThinh Nguyen
295e4cf6580SThinh Nguyen dwc3_ep = dwc->eps[i];
296e4cf6580SThinh Nguyen if (!dwc3_ep)
297e4cf6580SThinh Nguyen continue;
298e4cf6580SThinh Nguyen
299e4cf6580SThinh Nguyen if (!(dwc3_ep->flags & DWC3_EP_DELAY_STOP))
300e4cf6580SThinh Nguyen continue;
301e4cf6580SThinh Nguyen
302e4cf6580SThinh Nguyen dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP;
3032b2da657SWesley Cheng if (dwc->connected)
304e4cf6580SThinh Nguyen dwc3_stop_active_transfer(dwc3_ep, true, true);
3052b2da657SWesley Cheng else
3062b2da657SWesley Cheng dwc3_remove_requests(dwc, dwc3_ep, -ESHUTDOWN);
307e4cf6580SThinh Nguyen }
30872246da4SFelipe Balbi }
30972246da4SFelipe Balbi
dwc3_wIndex_to_dep(struct dwc3 * dwc,__le16 wIndex_le)31072246da4SFelipe Balbi static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
31172246da4SFelipe Balbi {
31272246da4SFelipe Balbi struct dwc3_ep *dep;
31372246da4SFelipe Balbi u32 windex = le16_to_cpu(wIndex_le);
31472246da4SFelipe Balbi u32 epnum;
31572246da4SFelipe Balbi
31672246da4SFelipe Balbi epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1;
31772246da4SFelipe Balbi if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
31872246da4SFelipe Balbi epnum |= 1;
31972246da4SFelipe Balbi
32072246da4SFelipe Balbi dep = dwc->eps[epnum];
321d0088908SMarian-Cristian Rotariu if (dep == NULL)
322d0088908SMarian-Cristian Rotariu return NULL;
323d0088908SMarian-Cristian Rotariu
32472246da4SFelipe Balbi if (dep->flags & DWC3_EP_ENABLED)
32572246da4SFelipe Balbi return dep;
32672246da4SFelipe Balbi
32772246da4SFelipe Balbi return NULL;
32872246da4SFelipe Balbi }
32972246da4SFelipe Balbi
dwc3_ep0_status_cmpl(struct usb_ep * ep,struct usb_request * req)3308ee6270cSSebastian Andrzej Siewior static void dwc3_ep0_status_cmpl(struct usb_ep *ep, struct usb_request *req)
33172246da4SFelipe Balbi {
33272246da4SFelipe Balbi }
33372246da4SFelipe Balbi /*
33472246da4SFelipe Balbi * ch 9.4.5
33572246da4SFelipe Balbi */
dwc3_ep0_handle_status(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)33625b8ff68SFelipe Balbi static int dwc3_ep0_handle_status(struct dwc3 *dwc,
33725b8ff68SFelipe Balbi struct usb_ctrlrequest *ctrl)
33872246da4SFelipe Balbi {
33972246da4SFelipe Balbi struct dwc3_ep *dep;
34072246da4SFelipe Balbi u32 recip;
3419b0a1f95SFelipe Balbi u32 value;
342e6a3b5e2SSebastian Andrzej Siewior u32 reg;
34372246da4SFelipe Balbi u16 usb_status = 0;
34472246da4SFelipe Balbi __le16 *response_pkt;
34572246da4SFelipe Balbi
3469b0a1f95SFelipe Balbi /* We don't support PTM_STATUS */
3479b0a1f95SFelipe Balbi value = le16_to_cpu(ctrl->wValue);
3489b0a1f95SFelipe Balbi if (value != 0)
3499b0a1f95SFelipe Balbi return -EINVAL;
3509b0a1f95SFelipe Balbi
35172246da4SFelipe Balbi recip = ctrl->bRequestType & USB_RECIP_MASK;
35272246da4SFelipe Balbi switch (recip) {
35372246da4SFelipe Balbi case USB_RECIP_DEVICE:
35472246da4SFelipe Balbi /*
355e6a3b5e2SSebastian Andrzej Siewior * LTM will be set once we know how to set this in HW.
35672246da4SFelipe Balbi */
357e81a7018SPeter Chen usb_status |= dwc->gadget->is_selfpowered;
358e6a3b5e2SSebastian Andrzej Siewior
359ee5cd41cSJohn Youn if ((dwc->speed == DWC3_DSTS_SUPERSPEED) ||
360ee5cd41cSJohn Youn (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
361e6a3b5e2SSebastian Andrzej Siewior reg = dwc3_readl(dwc->regs, DWC3_DCTL);
362e6a3b5e2SSebastian Andrzej Siewior if (reg & DWC3_DCTL_INITU1ENA)
363e6a3b5e2SSebastian Andrzej Siewior usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
364e6a3b5e2SSebastian Andrzej Siewior if (reg & DWC3_DCTL_INITU2ENA)
365e6a3b5e2SSebastian Andrzej Siewior usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
36604716168SElson Roy Serrao } else {
36704716168SElson Roy Serrao usb_status |= dwc->gadget->wakeup_armed <<
36804716168SElson Roy Serrao USB_DEVICE_REMOTE_WAKEUP;
369e6a3b5e2SSebastian Andrzej Siewior }
370e6a3b5e2SSebastian Andrzej Siewior
37172246da4SFelipe Balbi break;
37272246da4SFelipe Balbi
37372246da4SFelipe Balbi case USB_RECIP_INTERFACE:
37472246da4SFelipe Balbi /*
37572246da4SFelipe Balbi * Function Remote Wake Capable D0
37672246da4SFelipe Balbi * Function Remote Wakeup D1
37772246da4SFelipe Balbi */
37892c08a84SElson Roy Serrao return dwc3_ep0_delegate_req(dwc, ctrl);
37972246da4SFelipe Balbi
38072246da4SFelipe Balbi case USB_RECIP_ENDPOINT:
38172246da4SFelipe Balbi dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
38272246da4SFelipe Balbi if (!dep)
38372246da4SFelipe Balbi return -EINVAL;
38472246da4SFelipe Balbi
38572246da4SFelipe Balbi if (dep->flags & DWC3_EP_STALL)
38672246da4SFelipe Balbi usb_status = 1 << USB_ENDPOINT_HALT;
38772246da4SFelipe Balbi break;
38872246da4SFelipe Balbi default:
38972246da4SFelipe Balbi return -EINVAL;
3902b84f92bSJoe Perches }
39172246da4SFelipe Balbi
39272246da4SFelipe Balbi response_pkt = (__le16 *) dwc->setup_buf;
39372246da4SFelipe Balbi *response_pkt = cpu_to_le16(usb_status);
394e2617796SFelipe Balbi
395e2617796SFelipe Balbi dep = dwc->eps[0];
396e2617796SFelipe Balbi dwc->ep0_usb_req.dep = dep;
397e0ce0b0aSSebastian Andrzej Siewior dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
3980fc9a1beSFelipe Balbi dwc->ep0_usb_req.request.buf = dwc->setup_buf;
399e0ce0b0aSSebastian Andrzej Siewior dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;
400e2617796SFelipe Balbi
401e2617796SFelipe Balbi return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
40272246da4SFelipe Balbi }
40372246da4SFelipe Balbi
dwc3_ep0_handle_u1(struct dwc3 * dwc,enum usb_device_state state,int set)40439e07ffbSFelipe Balbi static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
40539e07ffbSFelipe Balbi int set)
40672246da4SFelipe Balbi {
407e6a3b5e2SSebastian Andrzej Siewior u32 reg;
40872246da4SFelipe Balbi
409fdba5aa5SFelipe Balbi if (state != USB_STATE_CONFIGURED)
41072246da4SFelipe Balbi return -EINVAL;
411ee5cd41cSJohn Youn if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
412ee5cd41cSJohn Youn (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
41372246da4SFelipe Balbi return -EINVAL;
414729dcffdSAnurag Kumar Vulisha if (set && dwc->dis_u1_entry_quirk)
415729dcffdSAnurag Kumar Vulisha return -EINVAL;
41672246da4SFelipe Balbi
417e6a3b5e2SSebastian Andrzej Siewior reg = dwc3_readl(dwc->regs, DWC3_DCTL);
418e6a3b5e2SSebastian Andrzej Siewior if (set)
419e6a3b5e2SSebastian Andrzej Siewior reg |= DWC3_DCTL_INITU1ENA;
420e6a3b5e2SSebastian Andrzej Siewior else
421e6a3b5e2SSebastian Andrzej Siewior reg &= ~DWC3_DCTL_INITU1ENA;
422e6a3b5e2SSebastian Andrzej Siewior dwc3_writel(dwc->regs, DWC3_DCTL, reg);
423e6a3b5e2SSebastian Andrzej Siewior
42439e07ffbSFelipe Balbi return 0;
42539e07ffbSFelipe Balbi }
42639e07ffbSFelipe Balbi
dwc3_ep0_handle_u2(struct dwc3 * dwc,enum usb_device_state state,int set)42739e07ffbSFelipe Balbi static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
42839e07ffbSFelipe Balbi int set)
42939e07ffbSFelipe Balbi {
43039e07ffbSFelipe Balbi u32 reg;
43139e07ffbSFelipe Balbi
43239e07ffbSFelipe Balbi
433fdba5aa5SFelipe Balbi if (state != USB_STATE_CONFIGURED)
434e6a3b5e2SSebastian Andrzej Siewior return -EINVAL;
435ee5cd41cSJohn Youn if ((dwc->speed != DWC3_DSTS_SUPERSPEED) &&
436ee5cd41cSJohn Youn (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS))
437e6a3b5e2SSebastian Andrzej Siewior return -EINVAL;
438729dcffdSAnurag Kumar Vulisha if (set && dwc->dis_u2_entry_quirk)
439729dcffdSAnurag Kumar Vulisha return -EINVAL;
440e6a3b5e2SSebastian Andrzej Siewior
441e6a3b5e2SSebastian Andrzej Siewior reg = dwc3_readl(dwc->regs, DWC3_DCTL);
442e6a3b5e2SSebastian Andrzej Siewior if (set)
443e6a3b5e2SSebastian Andrzej Siewior reg |= DWC3_DCTL_INITU2ENA;
444e6a3b5e2SSebastian Andrzej Siewior else
445e6a3b5e2SSebastian Andrzej Siewior reg &= ~DWC3_DCTL_INITU2ENA;
446e6a3b5e2SSebastian Andrzej Siewior dwc3_writel(dwc->regs, DWC3_DCTL, reg);
447e6a3b5e2SSebastian Andrzej Siewior
44839e07ffbSFelipe Balbi return 0;
44939e07ffbSFelipe Balbi }
45072246da4SFelipe Balbi
dwc3_ep0_handle_test(struct dwc3 * dwc,enum usb_device_state state,u32 wIndex,int set)45139e07ffbSFelipe Balbi static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state,
45239e07ffbSFelipe Balbi u32 wIndex, int set)
45339e07ffbSFelipe Balbi {
45472246da4SFelipe Balbi if ((wIndex & 0xff) != 0)
45572246da4SFelipe Balbi return -EINVAL;
45672246da4SFelipe Balbi if (!set)
45772246da4SFelipe Balbi return -EINVAL;
45872246da4SFelipe Balbi
459ae411413SFei Yang switch (wIndex >> 8) {
46062fb45d3SGreg Kroah-Hartman case USB_TEST_J:
46162fb45d3SGreg Kroah-Hartman case USB_TEST_K:
46262fb45d3SGreg Kroah-Hartman case USB_TEST_SE0_NAK:
46362fb45d3SGreg Kroah-Hartman case USB_TEST_PACKET:
46462fb45d3SGreg Kroah-Hartman case USB_TEST_FORCE_ENABLE:
4653b637367SGerard Cauvy dwc->test_mode_nr = wIndex >> 8;
4663b637367SGerard Cauvy dwc->test_mode = true;
467ecb07797SGerard Cauvy break;
468ecb07797SGerard Cauvy default:
469ecb07797SGerard Cauvy return -EINVAL;
47072246da4SFelipe Balbi }
47139e07ffbSFelipe Balbi
47239e07ffbSFelipe Balbi return 0;
47339e07ffbSFelipe Balbi }
47439e07ffbSFelipe Balbi
dwc3_ep0_handle_device(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl,int set)47539e07ffbSFelipe Balbi static int dwc3_ep0_handle_device(struct dwc3 *dwc,
47639e07ffbSFelipe Balbi struct usb_ctrlrequest *ctrl, int set)
47739e07ffbSFelipe Balbi {
47839e07ffbSFelipe Balbi enum usb_device_state state;
47939e07ffbSFelipe Balbi u32 wValue;
48039e07ffbSFelipe Balbi u32 wIndex;
48139e07ffbSFelipe Balbi int ret = 0;
48239e07ffbSFelipe Balbi
48339e07ffbSFelipe Balbi wValue = le16_to_cpu(ctrl->wValue);
48439e07ffbSFelipe Balbi wIndex = le16_to_cpu(ctrl->wIndex);
485e81a7018SPeter Chen state = dwc->gadget->state;
48639e07ffbSFelipe Balbi
48739e07ffbSFelipe Balbi switch (wValue) {
48839e07ffbSFelipe Balbi case USB_DEVICE_REMOTE_WAKEUP:
48904716168SElson Roy Serrao if (dwc->wakeup_configured)
49004716168SElson Roy Serrao dwc->gadget->wakeup_armed = set;
49104716168SElson Roy Serrao else
49204716168SElson Roy Serrao ret = -EINVAL;
49339e07ffbSFelipe Balbi break;
49439e07ffbSFelipe Balbi /*
495d1b39dd5SKushagra Verma * 9.4.1 says only for SS, in AddressState only for
49639e07ffbSFelipe Balbi * default control pipe
49739e07ffbSFelipe Balbi */
49839e07ffbSFelipe Balbi case USB_DEVICE_U1_ENABLE:
49939e07ffbSFelipe Balbi ret = dwc3_ep0_handle_u1(dwc, state, set);
50039e07ffbSFelipe Balbi break;
50139e07ffbSFelipe Balbi case USB_DEVICE_U2_ENABLE:
50239e07ffbSFelipe Balbi ret = dwc3_ep0_handle_u2(dwc, state, set);
50339e07ffbSFelipe Balbi break;
50439e07ffbSFelipe Balbi case USB_DEVICE_LTM_ENABLE:
50539e07ffbSFelipe Balbi ret = -EINVAL;
50639e07ffbSFelipe Balbi break;
50739e07ffbSFelipe Balbi case USB_DEVICE_TEST_MODE:
50839e07ffbSFelipe Balbi ret = dwc3_ep0_handle_test(dwc, state, wIndex, set);
50972246da4SFelipe Balbi break;
510ae411413SFei Yang default:
51139e07ffbSFelipe Balbi ret = -EINVAL;
512ae411413SFei Yang }
51372246da4SFelipe Balbi
51439e07ffbSFelipe Balbi return ret;
51539e07ffbSFelipe Balbi }
51639e07ffbSFelipe Balbi
dwc3_ep0_handle_intf(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl,int set)51739e07ffbSFelipe Balbi static int dwc3_ep0_handle_intf(struct dwc3 *dwc,
51839e07ffbSFelipe Balbi struct usb_ctrlrequest *ctrl, int set)
51939e07ffbSFelipe Balbi {
52039e07ffbSFelipe Balbi u32 wValue;
52139e07ffbSFelipe Balbi int ret = 0;
52239e07ffbSFelipe Balbi
52339e07ffbSFelipe Balbi wValue = le16_to_cpu(ctrl->wValue);
52439e07ffbSFelipe Balbi
52572246da4SFelipe Balbi switch (wValue) {
52672246da4SFelipe Balbi case USB_INTRF_FUNC_SUSPEND:
52792c08a84SElson Roy Serrao ret = dwc3_ep0_delegate_req(dwc, ctrl);
52872246da4SFelipe Balbi break;
52972246da4SFelipe Balbi default:
53039e07ffbSFelipe Balbi ret = -EINVAL;
53172246da4SFelipe Balbi }
53272246da4SFelipe Balbi
53339e07ffbSFelipe Balbi return ret;
53439e07ffbSFelipe Balbi }
53539e07ffbSFelipe Balbi
dwc3_ep0_handle_endpoint(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl,int set)53639e07ffbSFelipe Balbi static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc,
53739e07ffbSFelipe Balbi struct usb_ctrlrequest *ctrl, int set)
53839e07ffbSFelipe Balbi {
53939e07ffbSFelipe Balbi struct dwc3_ep *dep;
54039e07ffbSFelipe Balbi u32 wValue;
54139e07ffbSFelipe Balbi int ret;
54239e07ffbSFelipe Balbi
54339e07ffbSFelipe Balbi wValue = le16_to_cpu(ctrl->wValue);
54439e07ffbSFelipe Balbi
54572246da4SFelipe Balbi switch (wValue) {
54672246da4SFelipe Balbi case USB_ENDPOINT_HALT:
547958b9fa7SJohn Youn dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
54872246da4SFelipe Balbi if (!dep)
54972246da4SFelipe Balbi return -EINVAL;
55039e07ffbSFelipe Balbi
551a535d81cSAlan Stern if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
552a535d81cSAlan Stern break;
55339e07ffbSFelipe Balbi
5547a608559SFelipe Balbi ret = __dwc3_gadget_ep_set_halt(dep, set, true);
55572246da4SFelipe Balbi if (ret)
55672246da4SFelipe Balbi return -EINVAL;
557d97c78a1SThinh Nguyen
558d97c78a1SThinh Nguyen /* ClearFeature(Halt) may need delayed status */
559d97c78a1SThinh Nguyen if (!set && (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
560d97c78a1SThinh Nguyen return USB_GADGET_DELAYED_STATUS;
561d97c78a1SThinh Nguyen
56272246da4SFelipe Balbi break;
56372246da4SFelipe Balbi default:
56472246da4SFelipe Balbi return -EINVAL;
56572246da4SFelipe Balbi }
56672246da4SFelipe Balbi
56772246da4SFelipe Balbi return 0;
56872246da4SFelipe Balbi }
56972246da4SFelipe Balbi
dwc3_ep0_handle_feature(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl,int set)57039e07ffbSFelipe Balbi static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
57139e07ffbSFelipe Balbi struct usb_ctrlrequest *ctrl, int set)
57239e07ffbSFelipe Balbi {
57339e07ffbSFelipe Balbi u32 recip;
57439e07ffbSFelipe Balbi int ret;
57539e07ffbSFelipe Balbi
57639e07ffbSFelipe Balbi recip = ctrl->bRequestType & USB_RECIP_MASK;
57739e07ffbSFelipe Balbi
57839e07ffbSFelipe Balbi switch (recip) {
57939e07ffbSFelipe Balbi case USB_RECIP_DEVICE:
58039e07ffbSFelipe Balbi ret = dwc3_ep0_handle_device(dwc, ctrl, set);
58139e07ffbSFelipe Balbi break;
58239e07ffbSFelipe Balbi case USB_RECIP_INTERFACE:
58339e07ffbSFelipe Balbi ret = dwc3_ep0_handle_intf(dwc, ctrl, set);
58439e07ffbSFelipe Balbi break;
58539e07ffbSFelipe Balbi case USB_RECIP_ENDPOINT:
58639e07ffbSFelipe Balbi ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set);
58739e07ffbSFelipe Balbi break;
58839e07ffbSFelipe Balbi default:
58939e07ffbSFelipe Balbi ret = -EINVAL;
59039e07ffbSFelipe Balbi }
59139e07ffbSFelipe Balbi
59239e07ffbSFelipe Balbi return ret;
59339e07ffbSFelipe Balbi }
59439e07ffbSFelipe Balbi
dwc3_ep0_set_address(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)59572246da4SFelipe Balbi static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
59672246da4SFelipe Balbi {
597e81a7018SPeter Chen enum usb_device_state state = dwc->gadget->state;
59872246da4SFelipe Balbi u32 addr;
59972246da4SFelipe Balbi u32 reg;
60072246da4SFelipe Balbi
60172246da4SFelipe Balbi addr = le16_to_cpu(ctrl->wValue);
602f96a6ec1SFelipe Balbi if (addr > 127) {
6035eb30cedSFelipe Balbi dev_err(dwc->dev, "invalid device address %d\n", addr);
60472246da4SFelipe Balbi return -EINVAL;
605f96a6ec1SFelipe Balbi }
606f96a6ec1SFelipe Balbi
607fdba5aa5SFelipe Balbi if (state == USB_STATE_CONFIGURED) {
6085eb30cedSFelipe Balbi dev_err(dwc->dev, "can't SetAddress() from Configured State\n");
609f96a6ec1SFelipe Balbi return -EINVAL;
610f96a6ec1SFelipe Balbi }
61172246da4SFelipe Balbi
61272246da4SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_DCFG);
61372246da4SFelipe Balbi reg &= ~(DWC3_DCFG_DEVADDR_MASK);
61472246da4SFelipe Balbi reg |= DWC3_DCFG_DEVADDR(addr);
61572246da4SFelipe Balbi dwc3_writel(dwc->regs, DWC3_DCFG, reg);
61672246da4SFelipe Balbi
617fdba5aa5SFelipe Balbi if (addr)
618e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget, USB_STATE_ADDRESS);
619fdba5aa5SFelipe Balbi else
620e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget, USB_STATE_DEFAULT);
62172246da4SFelipe Balbi
6222646021eSFelipe Balbi return 0;
62372246da4SFelipe Balbi }
62472246da4SFelipe Balbi
dwc3_ep0_delegate_req(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)62572246da4SFelipe Balbi static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
62672246da4SFelipe Balbi {
62740edb522SLinyu Yuan int ret = -EINVAL;
62872246da4SFelipe Balbi
62940edb522SLinyu Yuan if (dwc->async_callbacks) {
63072246da4SFelipe Balbi spin_unlock(&dwc->lock);
631e81a7018SPeter Chen ret = dwc->gadget_driver->setup(dwc->gadget, ctrl);
63272246da4SFelipe Balbi spin_lock(&dwc->lock);
63340edb522SLinyu Yuan }
63472246da4SFelipe Balbi return ret;
63572246da4SFelipe Balbi }
63672246da4SFelipe Balbi
dwc3_ep0_set_config(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)63772246da4SFelipe Balbi static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
63872246da4SFelipe Balbi {
639e81a7018SPeter Chen enum usb_device_state state = dwc->gadget->state;
64072246da4SFelipe Balbi u32 cfg;
64172246da4SFelipe Balbi int ret;
642e274a31eSPratyush Anand u32 reg;
64372246da4SFelipe Balbi
64472246da4SFelipe Balbi cfg = le16_to_cpu(ctrl->wValue);
64572246da4SFelipe Balbi
646fdba5aa5SFelipe Balbi switch (state) {
647fdba5aa5SFelipe Balbi case USB_STATE_DEFAULT:
64872246da4SFelipe Balbi return -EINVAL;
64972246da4SFelipe Balbi
650fdba5aa5SFelipe Balbi case USB_STATE_ADDRESS:
65165b1f311SThinh Nguyen dwc3_gadget_start_config(dwc, 2);
6529f607a30SWesley Cheng dwc3_gadget_clear_tx_fifos(dwc);
6539f607a30SWesley Cheng
65472246da4SFelipe Balbi ret = dwc3_ep0_delegate_req(dwc, ctrl);
65572246da4SFelipe Balbi /* if the cfg matches and the cfg is non zero */
656457e84b6SFelipe Balbi if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) {
6577c81290eSFelipe Balbi
6587c81290eSFelipe Balbi /*
6597c81290eSFelipe Balbi * only change state if set_config has already
6607c81290eSFelipe Balbi * been processed. If gadget driver returns
6617c81290eSFelipe Balbi * USB_GADGET_DELAYED_STATUS, we will wait
6627c81290eSFelipe Balbi * to change the state on the next usb_ep_queue()
6637c81290eSFelipe Balbi */
6647c81290eSFelipe Balbi if (ret == 0)
665e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget,
66614cd592fSFelipe Balbi USB_STATE_CONFIGURED);
66714cd592fSFelipe Balbi
668e274a31eSPratyush Anand /*
669e274a31eSPratyush Anand * Enable transition to U1/U2 state when
670e274a31eSPratyush Anand * nothing is pending from application.
671e274a31eSPratyush Anand */
672e274a31eSPratyush Anand reg = dwc3_readl(dwc->regs, DWC3_DCTL);
673729dcffdSAnurag Kumar Vulisha if (!dwc->dis_u1_entry_quirk)
674729dcffdSAnurag Kumar Vulisha reg |= DWC3_DCTL_ACCEPTU1ENA;
675729dcffdSAnurag Kumar Vulisha if (!dwc->dis_u2_entry_quirk)
676729dcffdSAnurag Kumar Vulisha reg |= DWC3_DCTL_ACCEPTU2ENA;
677e274a31eSPratyush Anand dwc3_writel(dwc->regs, DWC3_DCTL, reg);
678457e84b6SFelipe Balbi }
67972246da4SFelipe Balbi break;
68072246da4SFelipe Balbi
681fdba5aa5SFelipe Balbi case USB_STATE_CONFIGURED:
68272246da4SFelipe Balbi ret = dwc3_ep0_delegate_req(dwc, ctrl);
6837a42d835SFelipe Balbi if (!cfg && !ret)
684e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget,
68514cd592fSFelipe Balbi USB_STATE_ADDRESS);
68672246da4SFelipe Balbi break;
6875bdb1dccSSebastian Andrzej Siewior default:
6885bdb1dccSSebastian Andrzej Siewior ret = -EINVAL;
68972246da4SFelipe Balbi }
6905bdb1dccSSebastian Andrzej Siewior return ret;
69172246da4SFelipe Balbi }
69272246da4SFelipe Balbi
dwc3_ep0_set_sel_cmpl(struct usb_ep * ep,struct usb_request * req)693865e09e7SFelipe Balbi static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req)
694865e09e7SFelipe Balbi {
695865e09e7SFelipe Balbi struct dwc3_ep *dep = to_dwc3_ep(ep);
696865e09e7SFelipe Balbi struct dwc3 *dwc = dep->dwc;
697865e09e7SFelipe Balbi
698865e09e7SFelipe Balbi u32 param = 0;
699865e09e7SFelipe Balbi u32 reg;
700865e09e7SFelipe Balbi
701865e09e7SFelipe Balbi struct timing {
702865e09e7SFelipe Balbi u8 u1sel;
703865e09e7SFelipe Balbi u8 u1pel;
704501058edSJohn Youn __le16 u2sel;
705501058edSJohn Youn __le16 u2pel;
706865e09e7SFelipe Balbi } __packed timing;
707865e09e7SFelipe Balbi
708865e09e7SFelipe Balbi int ret;
709865e09e7SFelipe Balbi
710865e09e7SFelipe Balbi memcpy(&timing, req->buf, sizeof(timing));
711865e09e7SFelipe Balbi
712865e09e7SFelipe Balbi dwc->u1sel = timing.u1sel;
713865e09e7SFelipe Balbi dwc->u1pel = timing.u1pel;
714c8cf7af4SFelipe Balbi dwc->u2sel = le16_to_cpu(timing.u2sel);
715c8cf7af4SFelipe Balbi dwc->u2pel = le16_to_cpu(timing.u2pel);
716865e09e7SFelipe Balbi
717865e09e7SFelipe Balbi reg = dwc3_readl(dwc->regs, DWC3_DCTL);
718865e09e7SFelipe Balbi if (reg & DWC3_DCTL_INITU2ENA)
719865e09e7SFelipe Balbi param = dwc->u2pel;
720865e09e7SFelipe Balbi if (reg & DWC3_DCTL_INITU1ENA)
721865e09e7SFelipe Balbi param = dwc->u1pel;
722865e09e7SFelipe Balbi
723865e09e7SFelipe Balbi /*
724865e09e7SFelipe Balbi * According to Synopsys Databook, if parameter is
725865e09e7SFelipe Balbi * greater than 125, a value of zero should be
726865e09e7SFelipe Balbi * programmed in the register.
727865e09e7SFelipe Balbi */
728865e09e7SFelipe Balbi if (param > 125)
729865e09e7SFelipe Balbi param = 0;
730865e09e7SFelipe Balbi
731865e09e7SFelipe Balbi /* now that we have the time, issue DGCMD Set Sel */
732865e09e7SFelipe Balbi ret = dwc3_send_gadget_generic_command(dwc,
733865e09e7SFelipe Balbi DWC3_DGCMD_SET_PERIODIC_PAR, param);
734865e09e7SFelipe Balbi WARN_ON(ret < 0);
735865e09e7SFelipe Balbi }
736865e09e7SFelipe Balbi
dwc3_ep0_set_sel(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)737865e09e7SFelipe Balbi static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
738865e09e7SFelipe Balbi {
739865e09e7SFelipe Balbi struct dwc3_ep *dep;
740e81a7018SPeter Chen enum usb_device_state state = dwc->gadget->state;
741865e09e7SFelipe Balbi u16 wLength;
742865e09e7SFelipe Balbi
743fdba5aa5SFelipe Balbi if (state == USB_STATE_DEFAULT)
744865e09e7SFelipe Balbi return -EINVAL;
745865e09e7SFelipe Balbi
746865e09e7SFelipe Balbi wLength = le16_to_cpu(ctrl->wLength);
747865e09e7SFelipe Balbi
748865e09e7SFelipe Balbi if (wLength != 6) {
749865e09e7SFelipe Balbi dev_err(dwc->dev, "Set SEL should be 6 bytes, got %d\n",
750865e09e7SFelipe Balbi wLength);
751865e09e7SFelipe Balbi return -EINVAL;
752865e09e7SFelipe Balbi }
753865e09e7SFelipe Balbi
754865e09e7SFelipe Balbi /*
755865e09e7SFelipe Balbi * To handle Set SEL we need to receive 6 bytes from Host. So let's
756865e09e7SFelipe Balbi * queue a usb_request for 6 bytes.
757865e09e7SFelipe Balbi *
758865e09e7SFelipe Balbi * Remember, though, this controller can't handle non-wMaxPacketSize
759865e09e7SFelipe Balbi * aligned transfers on the OUT direction, so we queue a request for
760865e09e7SFelipe Balbi * wMaxPacketSize instead.
761865e09e7SFelipe Balbi */
762865e09e7SFelipe Balbi dep = dwc->eps[0];
763865e09e7SFelipe Balbi dwc->ep0_usb_req.dep = dep;
764865e09e7SFelipe Balbi dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
765865e09e7SFelipe Balbi dwc->ep0_usb_req.request.buf = dwc->setup_buf;
766865e09e7SFelipe Balbi dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
767865e09e7SFelipe Balbi
768865e09e7SFelipe Balbi return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
769865e09e7SFelipe Balbi }
770865e09e7SFelipe Balbi
dwc3_ep0_set_isoch_delay(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)771c12a0d86SFelipe Balbi static int dwc3_ep0_set_isoch_delay(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
772c12a0d86SFelipe Balbi {
773c12a0d86SFelipe Balbi u16 wLength;
774c12a0d86SFelipe Balbi u16 wValue;
775c12a0d86SFelipe Balbi u16 wIndex;
776c12a0d86SFelipe Balbi
777c12a0d86SFelipe Balbi wValue = le16_to_cpu(ctrl->wValue);
778c12a0d86SFelipe Balbi wLength = le16_to_cpu(ctrl->wLength);
779c12a0d86SFelipe Balbi wIndex = le16_to_cpu(ctrl->wIndex);
780c12a0d86SFelipe Balbi
781c12a0d86SFelipe Balbi if (wIndex || wLength)
782c12a0d86SFelipe Balbi return -EINVAL;
783c12a0d86SFelipe Balbi
784e81a7018SPeter Chen dwc->gadget->isoch_delay = wValue;
785c12a0d86SFelipe Balbi
786c12a0d86SFelipe Balbi return 0;
787c12a0d86SFelipe Balbi }
788c12a0d86SFelipe Balbi
dwc3_ep0_std_request(struct dwc3 * dwc,struct usb_ctrlrequest * ctrl)78972246da4SFelipe Balbi static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
79072246da4SFelipe Balbi {
79172246da4SFelipe Balbi int ret;
79272246da4SFelipe Balbi
79372246da4SFelipe Balbi switch (ctrl->bRequest) {
79472246da4SFelipe Balbi case USB_REQ_GET_STATUS:
79572246da4SFelipe Balbi ret = dwc3_ep0_handle_status(dwc, ctrl);
79672246da4SFelipe Balbi break;
79772246da4SFelipe Balbi case USB_REQ_CLEAR_FEATURE:
79872246da4SFelipe Balbi ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
79972246da4SFelipe Balbi break;
80072246da4SFelipe Balbi case USB_REQ_SET_FEATURE:
80172246da4SFelipe Balbi ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
80272246da4SFelipe Balbi break;
80372246da4SFelipe Balbi case USB_REQ_SET_ADDRESS:
80472246da4SFelipe Balbi ret = dwc3_ep0_set_address(dwc, ctrl);
80572246da4SFelipe Balbi break;
80672246da4SFelipe Balbi case USB_REQ_SET_CONFIGURATION:
80772246da4SFelipe Balbi ret = dwc3_ep0_set_config(dwc, ctrl);
80872246da4SFelipe Balbi break;
809865e09e7SFelipe Balbi case USB_REQ_SET_SEL:
810865e09e7SFelipe Balbi ret = dwc3_ep0_set_sel(dwc, ctrl);
811865e09e7SFelipe Balbi break;
812c12a0d86SFelipe Balbi case USB_REQ_SET_ISOCH_DELAY:
813c12a0d86SFelipe Balbi ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
814c12a0d86SFelipe Balbi break;
81572246da4SFelipe Balbi default:
81672246da4SFelipe Balbi ret = dwc3_ep0_delegate_req(dwc, ctrl);
81772246da4SFelipe Balbi break;
8182b84f92bSJoe Perches }
81972246da4SFelipe Balbi
82072246da4SFelipe Balbi return ret;
82172246da4SFelipe Balbi }
82272246da4SFelipe Balbi
dwc3_ep0_inspect_setup(struct dwc3 * dwc,const struct dwc3_event_depevt * event)82372246da4SFelipe Balbi static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
82472246da4SFelipe Balbi const struct dwc3_event_depevt *event)
82572246da4SFelipe Balbi {
8267d5e650aSFelipe Balbi struct usb_ctrlrequest *ctrl = (void *) dwc->ep0_trb;
827ef21ede6SFelipe Balbi int ret = -EINVAL;
82872246da4SFelipe Balbi u32 len;
82972246da4SFelipe Balbi
830359d5a85SWesley Cheng if (!dwc->gadget_driver || !dwc->softconnect || !dwc->connected)
831ef21ede6SFelipe Balbi goto out;
83272246da4SFelipe Balbi
8332c4cbe6eSFelipe Balbi trace_dwc3_ctrl_req(ctrl);
8342c4cbe6eSFelipe Balbi
83572246da4SFelipe Balbi len = le16_to_cpu(ctrl->wLength);
8361ddcb218SFelipe Balbi if (!len) {
837d95b09b9SFelipe Balbi dwc->three_stage_setup = false;
838d95b09b9SFelipe Balbi dwc->ep0_expect_in = false;
8391ddcb218SFelipe Balbi dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
8401ddcb218SFelipe Balbi } else {
841d95b09b9SFelipe Balbi dwc->three_stage_setup = true;
842d95b09b9SFelipe Balbi dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
8431ddcb218SFelipe Balbi dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
8441ddcb218SFelipe Balbi }
84572246da4SFelipe Balbi
84672246da4SFelipe Balbi if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
84772246da4SFelipe Balbi ret = dwc3_ep0_std_request(dwc, ctrl);
84872246da4SFelipe Balbi else
84972246da4SFelipe Balbi ret = dwc3_ep0_delegate_req(dwc, ctrl);
85072246da4SFelipe Balbi
8515bdb1dccSSebastian Andrzej Siewior if (ret == USB_GADGET_DELAYED_STATUS)
8525bdb1dccSSebastian Andrzej Siewior dwc->delayed_status = true;
8535bdb1dccSSebastian Andrzej Siewior
854ef21ede6SFelipe Balbi out:
855ef21ede6SFelipe Balbi if (ret < 0)
85672246da4SFelipe Balbi dwc3_ep0_stall_and_restart(dwc);
85772246da4SFelipe Balbi }
85872246da4SFelipe Balbi
dwc3_ep0_complete_data(struct dwc3 * dwc,const struct dwc3_event_depevt * event)85972246da4SFelipe Balbi static void dwc3_ep0_complete_data(struct dwc3 *dwc,
86072246da4SFelipe Balbi const struct dwc3_event_depevt *event)
86172246da4SFelipe Balbi {
8627642d838SHeinrich Schuchardt struct dwc3_request *r;
86372246da4SFelipe Balbi struct usb_request *ur;
864f6bafc6aSFelipe Balbi struct dwc3_trb *trb;
865c2da2ff0SSebastian Andrzej Siewior struct dwc3_ep *ep0;
8668a344220SKishon Vijay Abraham I u32 transferred = 0;
867fca8892aSFelipe Balbi u32 status;
868f6bafc6aSFelipe Balbi u32 length;
86972246da4SFelipe Balbi u8 epnum;
87072246da4SFelipe Balbi
87172246da4SFelipe Balbi epnum = event->endpoint_number;
872c2da2ff0SSebastian Andrzej Siewior ep0 = dwc->eps[0];
87372246da4SFelipe Balbi
8741ddcb218SFelipe Balbi dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
875f6bafc6aSFelipe Balbi trb = dwc->ep0_trb;
876ccb072deSFelipe Balbi trace_dwc3_complete_trb(ep0, trb);
877ccb072deSFelipe Balbi
878aa3342c8SFelipe Balbi r = next_request(&ep0->pending_list);
879520fe763SFelipe Balbi if (!r)
880520fe763SFelipe Balbi return;
881520fe763SFelipe Balbi
882fca8892aSFelipe Balbi status = DWC3_TRB_SIZE_TRBSTS(trb->size);
883fca8892aSFelipe Balbi if (status == DWC3_TRBSTS_SETUP_PENDING) {
884b5d335e5SFelipe Balbi dwc->setup_packet_pending = true;
885fca8892aSFelipe Balbi if (r)
886fca8892aSFelipe Balbi dwc3_gadget_giveback(ep0, r, -ECONNRESET);
887fca8892aSFelipe Balbi
888fca8892aSFelipe Balbi return;
889fca8892aSFelipe Balbi }
890fca8892aSFelipe Balbi
8916856d30cSFelipe Balbi ur = &r->request;
8926856d30cSFelipe Balbi
893f6bafc6aSFelipe Balbi length = trb->size & DWC3_TRB_SIZE_MASK;
8944199c5f8SFelipe Balbi transferred = ur->length - length;
8954199c5f8SFelipe Balbi ur->actual += transferred;
8968a344220SKishon Vijay Abraham I
897d6e5a549SFelipe Balbi if ((IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) &&
898d6e5a549SFelipe Balbi ur->length && ur->zero) || dwc->ep0_bounced) {
899c0bd5456SKishon Vijay Abraham I trb++;
9004199c5f8SFelipe Balbi trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
901d6e5a549SFelipe Balbi trace_dwc3_complete_trb(ep0, trb);
902f035d139SThinh Nguyen
903f035d139SThinh Nguyen if (r->direction)
904f035d139SThinh Nguyen dwc->eps[1]->trb_enqueue = 0;
905f035d139SThinh Nguyen else
906f035d139SThinh Nguyen dwc->eps[0]->trb_enqueue = 0;
907f035d139SThinh Nguyen
9084199c5f8SFelipe Balbi dwc->ep0_bounced = false;
909c0bd5456SKishon Vijay Abraham I }
910c0bd5456SKishon Vijay Abraham I
911d6e5a549SFelipe Balbi if ((epnum & 1) && ur->actual < ur->length)
91272246da4SFelipe Balbi dwc3_ep0_stall_and_restart(dwc);
913d6e5a549SFelipe Balbi else
914c2da2ff0SSebastian Andrzej Siewior dwc3_gadget_giveback(ep0, r, 0);
91572246da4SFelipe Balbi }
91672246da4SFelipe Balbi
dwc3_ep0_complete_status(struct dwc3 * dwc,const struct dwc3_event_depevt * event)91785a78101SFelipe Balbi static void dwc3_ep0_complete_status(struct dwc3 *dwc,
91872246da4SFelipe Balbi const struct dwc3_event_depevt *event)
91972246da4SFelipe Balbi {
92072246da4SFelipe Balbi struct dwc3_request *r;
92172246da4SFelipe Balbi struct dwc3_ep *dep;
922fca8892aSFelipe Balbi struct dwc3_trb *trb;
923fca8892aSFelipe Balbi u32 status;
92472246da4SFelipe Balbi
925c7fcdeb2SFelipe Balbi dep = dwc->eps[0];
926fca8892aSFelipe Balbi trb = dwc->ep0_trb;
92772246da4SFelipe Balbi
928ccb072deSFelipe Balbi trace_dwc3_complete_trb(dep, trb);
929ccb072deSFelipe Balbi
930aa3342c8SFelipe Balbi if (!list_empty(&dep->pending_list)) {
931aa3342c8SFelipe Balbi r = next_request(&dep->pending_list);
93272246da4SFelipe Balbi
93372246da4SFelipe Balbi dwc3_gadget_giveback(dep, r, 0);
93472246da4SFelipe Balbi }
93572246da4SFelipe Balbi
9363b637367SGerard Cauvy if (dwc->test_mode) {
9373b637367SGerard Cauvy int ret;
9383b637367SGerard Cauvy
9393b637367SGerard Cauvy ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
9403b637367SGerard Cauvy if (ret < 0) {
9415eb30cedSFelipe Balbi dev_err(dwc->dev, "invalid test #%d\n",
9423b637367SGerard Cauvy dwc->test_mode_nr);
9433b637367SGerard Cauvy dwc3_ep0_stall_and_restart(dwc);
9445c81ababSFelipe Balbi return;
9453b637367SGerard Cauvy }
9463b637367SGerard Cauvy }
9473b637367SGerard Cauvy
948fca8892aSFelipe Balbi status = DWC3_TRB_SIZE_TRBSTS(trb->size);
9495eb30cedSFelipe Balbi if (status == DWC3_TRBSTS_SETUP_PENDING)
950b5d335e5SFelipe Balbi dwc->setup_packet_pending = true;
951fca8892aSFelipe Balbi
952c7fcdeb2SFelipe Balbi dwc->ep0state = EP0_SETUP_PHASE;
95372246da4SFelipe Balbi dwc3_ep0_out_start(dwc);
95472246da4SFelipe Balbi }
95572246da4SFelipe Balbi
dwc3_ep0_xfer_complete(struct dwc3 * dwc,const struct dwc3_event_depevt * event)95672246da4SFelipe Balbi static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
95772246da4SFelipe Balbi const struct dwc3_event_depevt *event)
95872246da4SFelipe Balbi {
959c7fcdeb2SFelipe Balbi struct dwc3_ep *dep = dwc->eps[event->endpoint_number];
960c7fcdeb2SFelipe Balbi
9615f2e7975SFelipe Balbi dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
962b4996a86SFelipe Balbi dep->resource_index = 0;
963df62df56SFelipe Balbi dwc->setup_packet_pending = false;
964c7fcdeb2SFelipe Balbi
96572246da4SFelipe Balbi switch (dwc->ep0state) {
966c7fcdeb2SFelipe Balbi case EP0_SETUP_PHASE:
96772246da4SFelipe Balbi dwc3_ep0_inspect_setup(dwc, event);
96872246da4SFelipe Balbi break;
96972246da4SFelipe Balbi
970c7fcdeb2SFelipe Balbi case EP0_DATA_PHASE:
97172246da4SFelipe Balbi dwc3_ep0_complete_data(dwc, event);
97272246da4SFelipe Balbi break;
97372246da4SFelipe Balbi
974c7fcdeb2SFelipe Balbi case EP0_STATUS_PHASE:
97585a78101SFelipe Balbi dwc3_ep0_complete_status(dwc, event);
97672246da4SFelipe Balbi break;
977c7fcdeb2SFelipe Balbi default:
978c7fcdeb2SFelipe Balbi WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state);
97972246da4SFelipe Balbi }
98072246da4SFelipe Balbi }
98172246da4SFelipe Balbi
__dwc3_ep0_do_control_data(struct dwc3 * dwc,struct dwc3_ep * dep,struct dwc3_request * req)982a0807881SFelipe Balbi static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
983a0807881SFelipe Balbi struct dwc3_ep *dep, struct dwc3_request *req)
984a0807881SFelipe Balbi {
98566706077SThinh Nguyen unsigned int trb_length = 0;
986a0807881SFelipe Balbi int ret;
987a0807881SFelipe Balbi
988a0807881SFelipe Balbi req->direction = !!dep->number;
989a0807881SFelipe Balbi
990a0807881SFelipe Balbi if (req->request.length == 0) {
99166706077SThinh Nguyen if (!req->direction)
99266706077SThinh Nguyen trb_length = dep->endpoint.maxpacket;
99366706077SThinh Nguyen
99466706077SThinh Nguyen dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, trb_length,
995368ca113SKishon Vijay Abraham I DWC3_TRBCTL_CONTROL_DATA, false);
996d686a5ffSFelipe Balbi ret = dwc3_ep0_start_trans(dep);
997c74c6d4aSFelipe Balbi } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
998a0807881SFelipe Balbi && (dep->number == 0)) {
999c390b036SAndrew Morton u32 maxpacket;
10004199c5f8SFelipe Balbi u32 rem;
1001a0807881SFelipe Balbi
1002d64ff406SArnd Bergmann ret = usb_gadget_map_request_by_dev(dwc->sysdev,
1003d64ff406SArnd Bergmann &req->request, dep->number);
10045eb30cedSFelipe Balbi if (ret)
1005a0807881SFelipe Balbi return;
1006a0807881SFelipe Balbi
1007c390b036SAndrew Morton maxpacket = dep->endpoint.maxpacket;
10084199c5f8SFelipe Balbi rem = req->request.length % maxpacket;
1009a0807881SFelipe Balbi dwc->ep0_bounced = true;
1010a0807881SFelipe Balbi
10114199c5f8SFelipe Balbi /* prepare normal TRB */
10124199c5f8SFelipe Balbi dwc3_ep0_prepare_one_trb(dep, req->request.dma,
10134199c5f8SFelipe Balbi req->request.length,
10144199c5f8SFelipe Balbi DWC3_TRBCTL_CONTROL_DATA,
10154199c5f8SFelipe Balbi true);
10164199c5f8SFelipe Balbi
101755168470SFelipe Balbi req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1];
101855168470SFelipe Balbi
10194199c5f8SFelipe Balbi /* Now prepare one extra TRB to align transfer size */
10204199c5f8SFelipe Balbi dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
10214199c5f8SFelipe Balbi maxpacket - rem,
10224199c5f8SFelipe Balbi DWC3_TRBCTL_CONTROL_DATA,
1023d686a5ffSFelipe Balbi false);
1024d686a5ffSFelipe Balbi ret = dwc3_ep0_start_trans(dep);
1025d6e5a549SFelipe Balbi } else if (IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) &&
1026d6e5a549SFelipe Balbi req->request.length && req->request.zero) {
1027d6e5a549SFelipe Balbi
1028d6e5a549SFelipe Balbi ret = usb_gadget_map_request_by_dev(dwc->sysdev,
1029d6e5a549SFelipe Balbi &req->request, dep->number);
1030d6e5a549SFelipe Balbi if (ret)
1031d6e5a549SFelipe Balbi return;
1032d6e5a549SFelipe Balbi
1033d6e5a549SFelipe Balbi /* prepare normal TRB */
1034d6e5a549SFelipe Balbi dwc3_ep0_prepare_one_trb(dep, req->request.dma,
1035d6e5a549SFelipe Balbi req->request.length,
1036d6e5a549SFelipe Balbi DWC3_TRBCTL_CONTROL_DATA,
1037d6e5a549SFelipe Balbi true);
1038d6e5a549SFelipe Balbi
103955168470SFelipe Balbi req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1];
104055168470SFelipe Balbi
104166706077SThinh Nguyen if (!req->direction)
104266706077SThinh Nguyen trb_length = dep->endpoint.maxpacket;
104366706077SThinh Nguyen
1044d6e5a549SFelipe Balbi /* Now prepare one extra TRB to align transfer size */
1045d6e5a549SFelipe Balbi dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
104666706077SThinh Nguyen trb_length, DWC3_TRBCTL_CONTROL_DATA,
1047d6e5a549SFelipe Balbi false);
1048d6e5a549SFelipe Balbi ret = dwc3_ep0_start_trans(dep);
1049a0807881SFelipe Balbi } else {
1050d64ff406SArnd Bergmann ret = usb_gadget_map_request_by_dev(dwc->sysdev,
1051d64ff406SArnd Bergmann &req->request, dep->number);
10525eb30cedSFelipe Balbi if (ret)
1053a0807881SFelipe Balbi return;
1054a0807881SFelipe Balbi
1055d686a5ffSFelipe Balbi dwc3_ep0_prepare_one_trb(dep, req->request.dma,
1056368ca113SKishon Vijay Abraham I req->request.length, DWC3_TRBCTL_CONTROL_DATA,
1057368ca113SKishon Vijay Abraham I false);
105855168470SFelipe Balbi
105955168470SFelipe Balbi req->trb = &dwc->ep0_trb[dep->trb_enqueue];
106055168470SFelipe Balbi
1061d686a5ffSFelipe Balbi ret = dwc3_ep0_start_trans(dep);
1062a0807881SFelipe Balbi }
1063a0807881SFelipe Balbi
1064a0807881SFelipe Balbi WARN_ON(ret < 0);
1065a0807881SFelipe Balbi }
1066a0807881SFelipe Balbi
dwc3_ep0_start_control_status(struct dwc3_ep * dep)1067f0f2b2a2SSebastian Andrzej Siewior static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
1068c7fcdeb2SFelipe Balbi {
1069f0f2b2a2SSebastian Andrzej Siewior struct dwc3 *dwc = dep->dwc;
1070c7fcdeb2SFelipe Balbi u32 type;
1071c7fcdeb2SFelipe Balbi
1072c7fcdeb2SFelipe Balbi type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
1073c7fcdeb2SFelipe Balbi : DWC3_TRBCTL_CONTROL_STATUS2;
1074c7fcdeb2SFelipe Balbi
1075d686a5ffSFelipe Balbi dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0, type, false);
1076d686a5ffSFelipe Balbi return dwc3_ep0_start_trans(dep);
1077f0f2b2a2SSebastian Andrzej Siewior }
1078c7fcdeb2SFelipe Balbi
__dwc3_ep0_do_control_status(struct dwc3 * dwc,struct dwc3_ep * dep)1079788a23f4SFelipe Balbi static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
1080f0f2b2a2SSebastian Andrzej Siewior {
1081f0f2b2a2SSebastian Andrzej Siewior WARN_ON(dwc3_ep0_start_control_status(dep));
1082c7fcdeb2SFelipe Balbi }
1083c7fcdeb2SFelipe Balbi
dwc3_ep0_do_control_status(struct dwc3 * dwc,const struct dwc3_event_depevt * event)1084788a23f4SFelipe Balbi static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
1085788a23f4SFelipe Balbi const struct dwc3_event_depevt *event)
1086788a23f4SFelipe Balbi {
1087788a23f4SFelipe Balbi struct dwc3_ep *dep = dwc->eps[event->endpoint_number];
1088788a23f4SFelipe Balbi
1089788a23f4SFelipe Balbi __dwc3_ep0_do_control_status(dwc, dep);
1090788a23f4SFelipe Balbi }
1091788a23f4SFelipe Balbi
dwc3_ep0_send_delayed_status(struct dwc3 * dwc)1092d97c78a1SThinh Nguyen void dwc3_ep0_send_delayed_status(struct dwc3 *dwc)
1093d97c78a1SThinh Nguyen {
1094d97c78a1SThinh Nguyen unsigned int direction = !dwc->ep0_expect_in;
1095d97c78a1SThinh Nguyen
1096fa27e2f6SThinh Nguyen dwc->delayed_status = false;
10972840d6dfSWesley Cheng dwc->clear_stall_protocol = 0;
1098fa27e2f6SThinh Nguyen
1099d97c78a1SThinh Nguyen if (dwc->ep0state != EP0_STATUS_PHASE)
1100d97c78a1SThinh Nguyen return;
1101d97c78a1SThinh Nguyen
1102d97c78a1SThinh Nguyen __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
1103d97c78a1SThinh Nguyen }
1104d97c78a1SThinh Nguyen
dwc3_ep0_end_control_data(struct dwc3 * dwc,struct dwc3_ep * dep)11059d778f0cSMayank Rana void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
11062e3db064SFelipe Balbi {
11072e3db064SFelipe Balbi struct dwc3_gadget_ep_cmd_params params;
11082e3db064SFelipe Balbi u32 cmd;
11092e3db064SFelipe Balbi int ret;
11102e3db064SFelipe Balbi
11119d778f0cSMayank Rana /*
11129d778f0cSMayank Rana * For status/DATA OUT stage, TRB will be queued on ep0 out
11139d778f0cSMayank Rana * endpoint for which resource index is zero. Hence allow
11149d778f0cSMayank Rana * queuing ENDXFER command for ep0 out endpoint.
11159d778f0cSMayank Rana */
11169d778f0cSMayank Rana if (!dep->resource_index && dep->number)
11172e3db064SFelipe Balbi return;
11182e3db064SFelipe Balbi
11192e3db064SFelipe Balbi cmd = DWC3_DEPCMD_ENDTRANSFER;
11202e3db064SFelipe Balbi cmd |= DWC3_DEPCMD_CMDIOC;
11212e3db064SFelipe Balbi cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
11222e3db064SFelipe Balbi memset(¶ms, 0, sizeof(params));
11232cd4718dSFelipe Balbi ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
11242e3db064SFelipe Balbi WARN_ON_ONCE(ret);
11252e3db064SFelipe Balbi dep->resource_index = 0;
11262e3db064SFelipe Balbi }
11272e3db064SFelipe Balbi
dwc3_ep0_xfernotready(struct dwc3 * dwc,const struct dwc3_event_depevt * event)112872246da4SFelipe Balbi static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
112972246da4SFelipe Balbi const struct dwc3_event_depevt *event)
113072246da4SFelipe Balbi {
11319cc9bcd5SFelipe Balbi switch (event->status) {
1132c7fcdeb2SFelipe Balbi case DEPEVT_STATUS_CONTROL_DATA:
1133359d5a85SWesley Cheng if (!dwc->softconnect || !dwc->connected)
1134359d5a85SWesley Cheng return;
113555f3fba6SFelipe Balbi /*
11362e3db064SFelipe Balbi * We already have a DATA transfer in the controller's cache,
11372e3db064SFelipe Balbi * if we receive a XferNotReady(DATA) we will ignore it, unless
11382e3db064SFelipe Balbi * it's for the wrong direction.
113955f3fba6SFelipe Balbi *
11402e3db064SFelipe Balbi * In that case, we must issue END_TRANSFER command to the Data
11412e3db064SFelipe Balbi * Phase we already have started and issue SetStall on the
11422e3db064SFelipe Balbi * control endpoint.
114355f3fba6SFelipe Balbi */
114455f3fba6SFelipe Balbi if (dwc->ep0_expect_in != event->endpoint_number) {
11452e3db064SFelipe Balbi struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in];
11462e3db064SFelipe Balbi
11475eb30cedSFelipe Balbi dev_err(dwc->dev, "unexpected direction for Data Phase\n");
11482e3db064SFelipe Balbi dwc3_ep0_end_control_data(dwc, dep);
114955f3fba6SFelipe Balbi dwc3_ep0_stall_and_restart(dwc);
115055f3fba6SFelipe Balbi return;
115155f3fba6SFelipe Balbi }
115255f3fba6SFelipe Balbi
115372246da4SFelipe Balbi break;
11541ddcb218SFelipe Balbi
1155c7fcdeb2SFelipe Balbi case DEPEVT_STATUS_CONTROL_STATUS:
115677fa6df8SFelipe Balbi if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS)
115777fa6df8SFelipe Balbi return;
115877fa6df8SFelipe Balbi
11595e76ee96SWesley Cheng if (dwc->setup_packet_pending) {
11605e76ee96SWesley Cheng dwc3_ep0_stall_and_restart(dwc);
11615e76ee96SWesley Cheng return;
11625e76ee96SWesley Cheng }
11635e76ee96SWesley Cheng
1164f0f2b2a2SSebastian Andrzej Siewior dwc->ep0state = EP0_STATUS_PHASE;
1165f0f2b2a2SSebastian Andrzej Siewior
11665bdb1dccSSebastian Andrzej Siewior if (dwc->delayed_status) {
116753896798SBaolin Wang struct dwc3_ep *dep = dwc->eps[0];
116853896798SBaolin Wang
11695bdb1dccSSebastian Andrzej Siewior WARN_ON_ONCE(event->endpoint_number != 1);
117053896798SBaolin Wang /*
117153896798SBaolin Wang * We should handle the delay STATUS phase here if the
117253896798SBaolin Wang * request for handling delay STATUS has been queued
117353896798SBaolin Wang * into the list.
117453896798SBaolin Wang */
117553896798SBaolin Wang if (!list_empty(&dep->pending_list)) {
117653896798SBaolin Wang dwc->delayed_status = false;
1177e81a7018SPeter Chen usb_gadget_set_state(dwc->gadget,
117853896798SBaolin Wang USB_STATE_CONFIGURED);
117953896798SBaolin Wang dwc3_ep0_do_control_status(dwc, event);
118053896798SBaolin Wang }
118153896798SBaolin Wang
11825bdb1dccSSebastian Andrzej Siewior return;
11835bdb1dccSSebastian Andrzej Siewior }
11845bdb1dccSSebastian Andrzej Siewior
1185788a23f4SFelipe Balbi dwc3_ep0_do_control_status(dwc, event);
118672246da4SFelipe Balbi }
118772246da4SFelipe Balbi }
118872246da4SFelipe Balbi
dwc3_ep0_interrupt(struct dwc3 * dwc,const struct dwc3_event_depevt * event)118972246da4SFelipe Balbi void dwc3_ep0_interrupt(struct dwc3 *dwc,
11908becf270SFelipe Balbi const struct dwc3_event_depevt *event)
119172246da4SFelipe Balbi {
11922d7b78f5SThinh Nguyen struct dwc3_ep *dep = dwc->eps[event->endpoint_number];
11932d7b78f5SThinh Nguyen u8 cmd;
11942d7b78f5SThinh Nguyen
119572246da4SFelipe Balbi switch (event->endpoint_event) {
119672246da4SFelipe Balbi case DWC3_DEPEVT_XFERCOMPLETE:
119772246da4SFelipe Balbi dwc3_ep0_xfer_complete(dwc, event);
119872246da4SFelipe Balbi break;
119972246da4SFelipe Balbi
120072246da4SFelipe Balbi case DWC3_DEPEVT_XFERNOTREADY:
120172246da4SFelipe Balbi dwc3_ep0_xfernotready(dwc, event);
120272246da4SFelipe Balbi break;
120372246da4SFelipe Balbi
120472246da4SFelipe Balbi case DWC3_DEPEVT_XFERINPROGRESS:
120572246da4SFelipe Balbi case DWC3_DEPEVT_RXTXFIFOEVT:
120672246da4SFelipe Balbi case DWC3_DEPEVT_STREAMEVT:
12072d7b78f5SThinh Nguyen break;
120872246da4SFelipe Balbi case DWC3_DEPEVT_EPCMDCMPLT:
12092d7b78f5SThinh Nguyen cmd = DEPEVT_PARAMETER_CMD(event->parameters);
12102d7b78f5SThinh Nguyen
1211c58d8bfcSThinh Nguyen if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
1212c58d8bfcSThinh Nguyen dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
12132d7b78f5SThinh Nguyen dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
1214c58d8bfcSThinh Nguyen }
121572246da4SFelipe Balbi break;
12162f28c3c9SRoy Luo default:
12172f28c3c9SRoy Luo dev_err(dwc->dev, "unknown endpoint event %d\n", event->endpoint_event);
12182f28c3c9SRoy Luo break;
121972246da4SFelipe Balbi }
122072246da4SFelipe Balbi }
1221