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