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(¶ms, 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, ¶ms);
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(¶ms, 0, sizeof(params));
1038*4882a593Smuzhiyun ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
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