xref: /openbmc/linux/drivers/usb/dwc3/ep0.c (revision 278002edb19bce2c628fafb0af936e77000f3a5b)
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(&params, 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, &params);
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(&params, 0, sizeof(params));
11232cd4718dSFelipe Balbi 	ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
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