xref: /OK3568_Linux_fs/kernel/drivers/usb/gadget/udc/dummy_hcd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * dummy_hcd.c -- Dummy/Loopback USB host and device emulator driver.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Maintainer: Alan Stern <stern@rowland.harvard.edu>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (C) 2003 David Brownell
8*4882a593Smuzhiyun  * Copyright (C) 2003-2005 Alan Stern
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /*
13*4882a593Smuzhiyun  * This exposes a device side "USB gadget" API, driven by requests to a
14*4882a593Smuzhiyun  * Linux-USB host controller driver.  USB traffic is simulated; there's
15*4882a593Smuzhiyun  * no need for USB hardware.  Use this with two other drivers:
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  *  - Gadget driver, responding to requests (device);
18*4882a593Smuzhiyun  *  - Host-side device driver, as already familiar in Linux.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * Having this all in one kernel can help some stages of development,
21*4882a593Smuzhiyun  * bypassing some hardware (and driver) issues.  UML could help too.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * Note: The emulation does not include isochronous transfers!
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include <linux/module.h>
27*4882a593Smuzhiyun #include <linux/kernel.h>
28*4882a593Smuzhiyun #include <linux/delay.h>
29*4882a593Smuzhiyun #include <linux/ioport.h>
30*4882a593Smuzhiyun #include <linux/slab.h>
31*4882a593Smuzhiyun #include <linux/errno.h>
32*4882a593Smuzhiyun #include <linux/init.h>
33*4882a593Smuzhiyun #include <linux/timer.h>
34*4882a593Smuzhiyun #include <linux/list.h>
35*4882a593Smuzhiyun #include <linux/interrupt.h>
36*4882a593Smuzhiyun #include <linux/platform_device.h>
37*4882a593Smuzhiyun #include <linux/usb.h>
38*4882a593Smuzhiyun #include <linux/usb/gadget.h>
39*4882a593Smuzhiyun #include <linux/usb/hcd.h>
40*4882a593Smuzhiyun #include <linux/scatterlist.h>
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #include <asm/byteorder.h>
43*4882a593Smuzhiyun #include <linux/io.h>
44*4882a593Smuzhiyun #include <asm/irq.h>
45*4882a593Smuzhiyun #include <asm/unaligned.h>
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define DRIVER_DESC	"USB Host+Gadget Emulator"
48*4882a593Smuzhiyun #define DRIVER_VERSION	"02 May 2005"
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define POWER_BUDGET	500	/* in mA; use 8 for low-power port testing */
51*4882a593Smuzhiyun #define POWER_BUDGET_3	900	/* in mA */
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun static const char	driver_name[] = "dummy_hcd";
54*4882a593Smuzhiyun static const char	driver_desc[] = "USB Host+Gadget Emulator";
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun static const char	gadget_name[] = "dummy_udc";
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
59*4882a593Smuzhiyun MODULE_AUTHOR("David Brownell");
60*4882a593Smuzhiyun MODULE_LICENSE("GPL");
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun struct dummy_hcd_module_parameters {
63*4882a593Smuzhiyun 	bool is_super_speed;
64*4882a593Smuzhiyun 	bool is_high_speed;
65*4882a593Smuzhiyun 	unsigned int num;
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun static struct dummy_hcd_module_parameters mod_data = {
69*4882a593Smuzhiyun 	.is_super_speed = false,
70*4882a593Smuzhiyun 	.is_high_speed = true,
71*4882a593Smuzhiyun 	.num = 1,
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
74*4882a593Smuzhiyun MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
75*4882a593Smuzhiyun module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
76*4882a593Smuzhiyun MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
77*4882a593Smuzhiyun module_param_named(num, mod_data.num, uint, S_IRUGO);
78*4882a593Smuzhiyun MODULE_PARM_DESC(num, "number of emulated controllers");
79*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /* gadget side driver data structres */
82*4882a593Smuzhiyun struct dummy_ep {
83*4882a593Smuzhiyun 	struct list_head		queue;
84*4882a593Smuzhiyun 	unsigned long			last_io;	/* jiffies timestamp */
85*4882a593Smuzhiyun 	struct usb_gadget		*gadget;
86*4882a593Smuzhiyun 	const struct usb_endpoint_descriptor *desc;
87*4882a593Smuzhiyun 	struct usb_ep			ep;
88*4882a593Smuzhiyun 	unsigned			halted:1;
89*4882a593Smuzhiyun 	unsigned			wedged:1;
90*4882a593Smuzhiyun 	unsigned			already_seen:1;
91*4882a593Smuzhiyun 	unsigned			setup_stage:1;
92*4882a593Smuzhiyun 	unsigned			stream_en:1;
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun struct dummy_request {
96*4882a593Smuzhiyun 	struct list_head		queue;		/* ep's requests */
97*4882a593Smuzhiyun 	struct usb_request		req;
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun 
usb_ep_to_dummy_ep(struct usb_ep * _ep)100*4882a593Smuzhiyun static inline struct dummy_ep *usb_ep_to_dummy_ep(struct usb_ep *_ep)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	return container_of(_ep, struct dummy_ep, ep);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun 
usb_request_to_dummy_request(struct usb_request * _req)105*4882a593Smuzhiyun static inline struct dummy_request *usb_request_to_dummy_request
106*4882a593Smuzhiyun 		(struct usb_request *_req)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	return container_of(_req, struct dummy_request, req);
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun  * Every device has ep0 for control requests, plus up to 30 more endpoints,
115*4882a593Smuzhiyun  * in one of two types:
116*4882a593Smuzhiyun  *
117*4882a593Smuzhiyun  *   - Configurable:  direction (in/out), type (bulk, iso, etc), and endpoint
118*4882a593Smuzhiyun  *     number can be changed.  Names like "ep-a" are used for this type.
119*4882a593Smuzhiyun  *
120*4882a593Smuzhiyun  *   - Fixed Function:  in other cases.  some characteristics may be mutable;
121*4882a593Smuzhiyun  *     that'd be hardware-specific.  Names like "ep12out-bulk" are used.
122*4882a593Smuzhiyun  *
123*4882a593Smuzhiyun  * Gadget drivers are responsible for not setting up conflicting endpoint
124*4882a593Smuzhiyun  * configurations, illegal or unsupported packet lengths, and so on.
125*4882a593Smuzhiyun  */
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun static const char ep0name[] = "ep0";
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun static const struct {
130*4882a593Smuzhiyun 	const char *name;
131*4882a593Smuzhiyun 	const struct usb_ep_caps caps;
132*4882a593Smuzhiyun } ep_info[] = {
133*4882a593Smuzhiyun #define EP_INFO(_name, _caps) \
134*4882a593Smuzhiyun 	{ \
135*4882a593Smuzhiyun 		.name = _name, \
136*4882a593Smuzhiyun 		.caps = _caps, \
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /* we don't provide isochronous endpoints since we don't support them */
140*4882a593Smuzhiyun #define TYPE_BULK_OR_INT	(USB_EP_CAPS_TYPE_BULK | USB_EP_CAPS_TYPE_INT)
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/* everyone has ep0 */
143*4882a593Smuzhiyun 	EP_INFO(ep0name,
144*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)),
145*4882a593Smuzhiyun 	/* act like a pxa250: fifteen fixed function endpoints */
146*4882a593Smuzhiyun 	EP_INFO("ep1in-bulk",
147*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
148*4882a593Smuzhiyun 	EP_INFO("ep2out-bulk",
149*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
150*4882a593Smuzhiyun /*
151*4882a593Smuzhiyun 	EP_INFO("ep3in-iso",
152*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
153*4882a593Smuzhiyun 	EP_INFO("ep4out-iso",
154*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun 	EP_INFO("ep5in-int",
157*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
158*4882a593Smuzhiyun 	EP_INFO("ep6in-bulk",
159*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
160*4882a593Smuzhiyun 	EP_INFO("ep7out-bulk",
161*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun 	EP_INFO("ep8in-iso",
164*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
165*4882a593Smuzhiyun 	EP_INFO("ep9out-iso",
166*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
167*4882a593Smuzhiyun */
168*4882a593Smuzhiyun 	EP_INFO("ep10in-int",
169*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
170*4882a593Smuzhiyun 	EP_INFO("ep11in-bulk",
171*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
172*4882a593Smuzhiyun 	EP_INFO("ep12out-bulk",
173*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
174*4882a593Smuzhiyun /*
175*4882a593Smuzhiyun 	EP_INFO("ep13in-iso",
176*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)),
177*4882a593Smuzhiyun 	EP_INFO("ep14out-iso",
178*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)),
179*4882a593Smuzhiyun */
180*4882a593Smuzhiyun 	EP_INFO("ep15in-int",
181*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)),
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	/* or like sa1100: two fixed function endpoints */
184*4882a593Smuzhiyun 	EP_INFO("ep1out-bulk",
185*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)),
186*4882a593Smuzhiyun 	EP_INFO("ep2in-bulk",
187*4882a593Smuzhiyun 		USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)),
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	/* and now some generic EPs so we have enough in multi config */
190*4882a593Smuzhiyun 	EP_INFO("ep-aout",
191*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
192*4882a593Smuzhiyun 	EP_INFO("ep-bin",
193*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)),
194*4882a593Smuzhiyun 	EP_INFO("ep-cout",
195*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
196*4882a593Smuzhiyun 	EP_INFO("ep-dout",
197*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
198*4882a593Smuzhiyun 	EP_INFO("ep-ein",
199*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)),
200*4882a593Smuzhiyun 	EP_INFO("ep-fout",
201*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
202*4882a593Smuzhiyun 	EP_INFO("ep-gin",
203*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)),
204*4882a593Smuzhiyun 	EP_INFO("ep-hout",
205*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
206*4882a593Smuzhiyun 	EP_INFO("ep-iout",
207*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
208*4882a593Smuzhiyun 	EP_INFO("ep-jin",
209*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)),
210*4882a593Smuzhiyun 	EP_INFO("ep-kout",
211*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
212*4882a593Smuzhiyun 	EP_INFO("ep-lin",
213*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)),
214*4882a593Smuzhiyun 	EP_INFO("ep-mout",
215*4882a593Smuzhiyun 		USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)),
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun #undef EP_INFO
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun #define DUMMY_ENDPOINTS	ARRAY_SIZE(ep_info)
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun #define FIFO_SIZE		64
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun struct urbp {
227*4882a593Smuzhiyun 	struct urb		*urb;
228*4882a593Smuzhiyun 	struct list_head	urbp_list;
229*4882a593Smuzhiyun 	struct sg_mapping_iter	miter;
230*4882a593Smuzhiyun 	u32			miter_started;
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun enum dummy_rh_state {
235*4882a593Smuzhiyun 	DUMMY_RH_RESET,
236*4882a593Smuzhiyun 	DUMMY_RH_SUSPENDED,
237*4882a593Smuzhiyun 	DUMMY_RH_RUNNING
238*4882a593Smuzhiyun };
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun struct dummy_hcd {
241*4882a593Smuzhiyun 	struct dummy			*dum;
242*4882a593Smuzhiyun 	enum dummy_rh_state		rh_state;
243*4882a593Smuzhiyun 	struct timer_list		timer;
244*4882a593Smuzhiyun 	u32				port_status;
245*4882a593Smuzhiyun 	u32				old_status;
246*4882a593Smuzhiyun 	unsigned long			re_timeout;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	struct usb_device		*udev;
249*4882a593Smuzhiyun 	struct list_head		urbp_list;
250*4882a593Smuzhiyun 	struct urbp			*next_frame_urbp;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	u32				stream_en_ep;
253*4882a593Smuzhiyun 	u8				num_stream[30 / 2];
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	unsigned			active:1;
256*4882a593Smuzhiyun 	unsigned			old_active:1;
257*4882a593Smuzhiyun 	unsigned			resuming:1;
258*4882a593Smuzhiyun };
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun struct dummy {
261*4882a593Smuzhiyun 	spinlock_t			lock;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	/*
264*4882a593Smuzhiyun 	 * DEVICE/GADGET side support
265*4882a593Smuzhiyun 	 */
266*4882a593Smuzhiyun 	struct dummy_ep			ep[DUMMY_ENDPOINTS];
267*4882a593Smuzhiyun 	int				address;
268*4882a593Smuzhiyun 	int				callback_usage;
269*4882a593Smuzhiyun 	struct usb_gadget		gadget;
270*4882a593Smuzhiyun 	struct usb_gadget_driver	*driver;
271*4882a593Smuzhiyun 	struct dummy_request		fifo_req;
272*4882a593Smuzhiyun 	u8				fifo_buf[FIFO_SIZE];
273*4882a593Smuzhiyun 	u16				devstatus;
274*4882a593Smuzhiyun 	unsigned			ints_enabled:1;
275*4882a593Smuzhiyun 	unsigned			udc_suspended:1;
276*4882a593Smuzhiyun 	unsigned			pullup:1;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	/*
279*4882a593Smuzhiyun 	 * HOST side support
280*4882a593Smuzhiyun 	 */
281*4882a593Smuzhiyun 	struct dummy_hcd		*hs_hcd;
282*4882a593Smuzhiyun 	struct dummy_hcd		*ss_hcd;
283*4882a593Smuzhiyun };
284*4882a593Smuzhiyun 
hcd_to_dummy_hcd(struct usb_hcd * hcd)285*4882a593Smuzhiyun static inline struct dummy_hcd *hcd_to_dummy_hcd(struct usb_hcd *hcd)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	return (struct dummy_hcd *) (hcd->hcd_priv);
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun 
dummy_hcd_to_hcd(struct dummy_hcd * dum)290*4882a593Smuzhiyun static inline struct usb_hcd *dummy_hcd_to_hcd(struct dummy_hcd *dum)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	return container_of((void *) dum, struct usb_hcd, hcd_priv);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
dummy_dev(struct dummy_hcd * dum)295*4882a593Smuzhiyun static inline struct device *dummy_dev(struct dummy_hcd *dum)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	return dummy_hcd_to_hcd(dum)->self.controller;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
udc_dev(struct dummy * dum)300*4882a593Smuzhiyun static inline struct device *udc_dev(struct dummy *dum)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	return dum->gadget.dev.parent;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
ep_to_dummy(struct dummy_ep * ep)305*4882a593Smuzhiyun static inline struct dummy *ep_to_dummy(struct dummy_ep *ep)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	return container_of(ep->gadget, struct dummy, gadget);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
gadget_to_dummy_hcd(struct usb_gadget * gadget)310*4882a593Smuzhiyun static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	struct dummy *dum = container_of(gadget, struct dummy, gadget);
313*4882a593Smuzhiyun 	if (dum->gadget.speed == USB_SPEED_SUPER)
314*4882a593Smuzhiyun 		return dum->ss_hcd;
315*4882a593Smuzhiyun 	else
316*4882a593Smuzhiyun 		return dum->hs_hcd;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
gadget_dev_to_dummy(struct device * dev)319*4882a593Smuzhiyun static inline struct dummy *gadget_dev_to_dummy(struct device *dev)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun 	return container_of(dev, struct dummy, gadget.dev);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /* DEVICE/GADGET SIDE UTILITY ROUTINES */
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun /* called with spinlock held */
nuke(struct dummy * dum,struct dummy_ep * ep)329*4882a593Smuzhiyun static void nuke(struct dummy *dum, struct dummy_ep *ep)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	while (!list_empty(&ep->queue)) {
332*4882a593Smuzhiyun 		struct dummy_request	*req;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 		req = list_entry(ep->queue.next, struct dummy_request, queue);
335*4882a593Smuzhiyun 		list_del_init(&req->queue);
336*4882a593Smuzhiyun 		req->req.status = -ESHUTDOWN;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 		spin_unlock(&dum->lock);
339*4882a593Smuzhiyun 		usb_gadget_giveback_request(&ep->ep, &req->req);
340*4882a593Smuzhiyun 		spin_lock(&dum->lock);
341*4882a593Smuzhiyun 	}
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun /* caller must hold lock */
stop_activity(struct dummy * dum)345*4882a593Smuzhiyun static void stop_activity(struct dummy *dum)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	int i;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	/* prevent any more requests */
350*4882a593Smuzhiyun 	dum->address = 0;
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	/* The timer is left running so that outstanding URBs can fail */
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	/* nuke any pending requests first, so driver i/o is quiesced */
355*4882a593Smuzhiyun 	for (i = 0; i < DUMMY_ENDPOINTS; ++i)
356*4882a593Smuzhiyun 		nuke(dum, &dum->ep[i]);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	/* driver now does any non-usb quiescing necessary */
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun /**
362*4882a593Smuzhiyun  * set_link_state_by_speed() - Sets the current state of the link according to
363*4882a593Smuzhiyun  *	the hcd speed
364*4882a593Smuzhiyun  * @dum_hcd: pointer to the dummy_hcd structure to update the link state for
365*4882a593Smuzhiyun  *
366*4882a593Smuzhiyun  * This function updates the port_status according to the link state and the
367*4882a593Smuzhiyun  * speed of the hcd.
368*4882a593Smuzhiyun  */
set_link_state_by_speed(struct dummy_hcd * dum_hcd)369*4882a593Smuzhiyun static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	struct dummy *dum = dum_hcd->dum;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	if (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3) {
374*4882a593Smuzhiyun 		if ((dum_hcd->port_status & USB_SS_PORT_STAT_POWER) == 0) {
375*4882a593Smuzhiyun 			dum_hcd->port_status = 0;
376*4882a593Smuzhiyun 		} else if (!dum->pullup || dum->udc_suspended) {
377*4882a593Smuzhiyun 			/* UDC suspend must cause a disconnect */
378*4882a593Smuzhiyun 			dum_hcd->port_status &= ~(USB_PORT_STAT_CONNECTION |
379*4882a593Smuzhiyun 						USB_PORT_STAT_ENABLE);
380*4882a593Smuzhiyun 			if ((dum_hcd->old_status &
381*4882a593Smuzhiyun 			     USB_PORT_STAT_CONNECTION) != 0)
382*4882a593Smuzhiyun 				dum_hcd->port_status |=
383*4882a593Smuzhiyun 					(USB_PORT_STAT_C_CONNECTION << 16);
384*4882a593Smuzhiyun 		} else {
385*4882a593Smuzhiyun 			/* device is connected and not suspended */
386*4882a593Smuzhiyun 			dum_hcd->port_status |= (USB_PORT_STAT_CONNECTION |
387*4882a593Smuzhiyun 						 USB_PORT_STAT_SPEED_5GBPS) ;
388*4882a593Smuzhiyun 			if ((dum_hcd->old_status &
389*4882a593Smuzhiyun 			     USB_PORT_STAT_CONNECTION) == 0)
390*4882a593Smuzhiyun 				dum_hcd->port_status |=
391*4882a593Smuzhiyun 					(USB_PORT_STAT_C_CONNECTION << 16);
392*4882a593Smuzhiyun 			if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) &&
393*4882a593Smuzhiyun 			    (dum_hcd->port_status &
394*4882a593Smuzhiyun 			     USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 &&
395*4882a593Smuzhiyun 			    dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
396*4882a593Smuzhiyun 				dum_hcd->active = 1;
397*4882a593Smuzhiyun 		}
398*4882a593Smuzhiyun 	} else {
399*4882a593Smuzhiyun 		if ((dum_hcd->port_status & USB_PORT_STAT_POWER) == 0) {
400*4882a593Smuzhiyun 			dum_hcd->port_status = 0;
401*4882a593Smuzhiyun 		} else if (!dum->pullup || dum->udc_suspended) {
402*4882a593Smuzhiyun 			/* UDC suspend must cause a disconnect */
403*4882a593Smuzhiyun 			dum_hcd->port_status &= ~(USB_PORT_STAT_CONNECTION |
404*4882a593Smuzhiyun 						USB_PORT_STAT_ENABLE |
405*4882a593Smuzhiyun 						USB_PORT_STAT_LOW_SPEED |
406*4882a593Smuzhiyun 						USB_PORT_STAT_HIGH_SPEED |
407*4882a593Smuzhiyun 						USB_PORT_STAT_SUSPEND);
408*4882a593Smuzhiyun 			if ((dum_hcd->old_status &
409*4882a593Smuzhiyun 			     USB_PORT_STAT_CONNECTION) != 0)
410*4882a593Smuzhiyun 				dum_hcd->port_status |=
411*4882a593Smuzhiyun 					(USB_PORT_STAT_C_CONNECTION << 16);
412*4882a593Smuzhiyun 		} else {
413*4882a593Smuzhiyun 			dum_hcd->port_status |= USB_PORT_STAT_CONNECTION;
414*4882a593Smuzhiyun 			if ((dum_hcd->old_status &
415*4882a593Smuzhiyun 			     USB_PORT_STAT_CONNECTION) == 0)
416*4882a593Smuzhiyun 				dum_hcd->port_status |=
417*4882a593Smuzhiyun 					(USB_PORT_STAT_C_CONNECTION << 16);
418*4882a593Smuzhiyun 			if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0)
419*4882a593Smuzhiyun 				dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND;
420*4882a593Smuzhiyun 			else if ((dum_hcd->port_status &
421*4882a593Smuzhiyun 				  USB_PORT_STAT_SUSPEND) == 0 &&
422*4882a593Smuzhiyun 					dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
423*4882a593Smuzhiyun 				dum_hcd->active = 1;
424*4882a593Smuzhiyun 		}
425*4882a593Smuzhiyun 	}
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun /* caller must hold lock */
set_link_state(struct dummy_hcd * dum_hcd)429*4882a593Smuzhiyun static void set_link_state(struct dummy_hcd *dum_hcd)
430*4882a593Smuzhiyun 	__must_hold(&dum->lock)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun 	struct dummy *dum = dum_hcd->dum;
433*4882a593Smuzhiyun 	unsigned int power_bit;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	dum_hcd->active = 0;
436*4882a593Smuzhiyun 	if (dum->pullup)
437*4882a593Smuzhiyun 		if ((dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 &&
438*4882a593Smuzhiyun 		     dum->gadget.speed != USB_SPEED_SUPER) ||
439*4882a593Smuzhiyun 		    (dummy_hcd_to_hcd(dum_hcd)->speed != HCD_USB3 &&
440*4882a593Smuzhiyun 		     dum->gadget.speed == USB_SPEED_SUPER))
441*4882a593Smuzhiyun 			return;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	set_link_state_by_speed(dum_hcd);
444*4882a593Smuzhiyun 	power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ?
445*4882a593Smuzhiyun 			USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 ||
448*4882a593Smuzhiyun 	     dum_hcd->active)
449*4882a593Smuzhiyun 		dum_hcd->resuming = 0;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	/* Currently !connected or in reset */
452*4882a593Smuzhiyun 	if ((dum_hcd->port_status & power_bit) == 0 ||
453*4882a593Smuzhiyun 			(dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) {
454*4882a593Smuzhiyun 		unsigned int disconnect = power_bit &
455*4882a593Smuzhiyun 				dum_hcd->old_status & (~dum_hcd->port_status);
456*4882a593Smuzhiyun 		unsigned int reset = USB_PORT_STAT_RESET &
457*4882a593Smuzhiyun 				(~dum_hcd->old_status) & dum_hcd->port_status;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 		/* Report reset and disconnect events to the driver */
460*4882a593Smuzhiyun 		if (dum->ints_enabled && (disconnect || reset)) {
461*4882a593Smuzhiyun 			stop_activity(dum);
462*4882a593Smuzhiyun 			++dum->callback_usage;
463*4882a593Smuzhiyun 			spin_unlock(&dum->lock);
464*4882a593Smuzhiyun 			if (reset)
465*4882a593Smuzhiyun 				usb_gadget_udc_reset(&dum->gadget, dum->driver);
466*4882a593Smuzhiyun 			else
467*4882a593Smuzhiyun 				dum->driver->disconnect(&dum->gadget);
468*4882a593Smuzhiyun 			spin_lock(&dum->lock);
469*4882a593Smuzhiyun 			--dum->callback_usage;
470*4882a593Smuzhiyun 		}
471*4882a593Smuzhiyun 	} else if (dum_hcd->active != dum_hcd->old_active &&
472*4882a593Smuzhiyun 			dum->ints_enabled) {
473*4882a593Smuzhiyun 		++dum->callback_usage;
474*4882a593Smuzhiyun 		spin_unlock(&dum->lock);
475*4882a593Smuzhiyun 		if (dum_hcd->old_active && dum->driver->suspend)
476*4882a593Smuzhiyun 			dum->driver->suspend(&dum->gadget);
477*4882a593Smuzhiyun 		else if (!dum_hcd->old_active &&  dum->driver->resume)
478*4882a593Smuzhiyun 			dum->driver->resume(&dum->gadget);
479*4882a593Smuzhiyun 		spin_lock(&dum->lock);
480*4882a593Smuzhiyun 		--dum->callback_usage;
481*4882a593Smuzhiyun 	}
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	dum_hcd->old_status = dum_hcd->port_status;
484*4882a593Smuzhiyun 	dum_hcd->old_active = dum_hcd->active;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun /* DEVICE/GADGET SIDE DRIVER
490*4882a593Smuzhiyun  *
491*4882a593Smuzhiyun  * This only tracks gadget state.  All the work is done when the host
492*4882a593Smuzhiyun  * side tries some (emulated) i/o operation.  Real device controller
493*4882a593Smuzhiyun  * drivers would do real i/o using dma, fifos, irqs, timers, etc.
494*4882a593Smuzhiyun  */
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun #define is_enabled(dum) \
497*4882a593Smuzhiyun 	(dum->port_status & USB_PORT_STAT_ENABLE)
498*4882a593Smuzhiyun 
dummy_enable(struct usb_ep * _ep,const struct usb_endpoint_descriptor * desc)499*4882a593Smuzhiyun static int dummy_enable(struct usb_ep *_ep,
500*4882a593Smuzhiyun 		const struct usb_endpoint_descriptor *desc)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	struct dummy		*dum;
503*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd;
504*4882a593Smuzhiyun 	struct dummy_ep		*ep;
505*4882a593Smuzhiyun 	unsigned		max;
506*4882a593Smuzhiyun 	int			retval;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	ep = usb_ep_to_dummy_ep(_ep);
509*4882a593Smuzhiyun 	if (!_ep || !desc || ep->desc || _ep->name == ep0name
510*4882a593Smuzhiyun 			|| desc->bDescriptorType != USB_DT_ENDPOINT)
511*4882a593Smuzhiyun 		return -EINVAL;
512*4882a593Smuzhiyun 	dum = ep_to_dummy(ep);
513*4882a593Smuzhiyun 	if (!dum->driver)
514*4882a593Smuzhiyun 		return -ESHUTDOWN;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	dum_hcd = gadget_to_dummy_hcd(&dum->gadget);
517*4882a593Smuzhiyun 	if (!is_enabled(dum_hcd))
518*4882a593Smuzhiyun 		return -ESHUTDOWN;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	/*
521*4882a593Smuzhiyun 	 * For HS/FS devices only bits 0..10 of the wMaxPacketSize represent the
522*4882a593Smuzhiyun 	 * maximum packet size.
523*4882a593Smuzhiyun 	 * For SS devices the wMaxPacketSize is limited by 1024.
524*4882a593Smuzhiyun 	 */
525*4882a593Smuzhiyun 	max = usb_endpoint_maxp(desc);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	/* drivers must not request bad settings, since lower levels
528*4882a593Smuzhiyun 	 * (hardware or its drivers) may not check.  some endpoints
529*4882a593Smuzhiyun 	 * can't do iso, many have maxpacket limitations, etc.
530*4882a593Smuzhiyun 	 *
531*4882a593Smuzhiyun 	 * since this "hardware" driver is here to help debugging, we
532*4882a593Smuzhiyun 	 * have some extra sanity checks.  (there could be more though,
533*4882a593Smuzhiyun 	 * especially for "ep9out" style fixed function ones.)
534*4882a593Smuzhiyun 	 */
535*4882a593Smuzhiyun 	retval = -EINVAL;
536*4882a593Smuzhiyun 	switch (usb_endpoint_type(desc)) {
537*4882a593Smuzhiyun 	case USB_ENDPOINT_XFER_BULK:
538*4882a593Smuzhiyun 		if (strstr(ep->ep.name, "-iso")
539*4882a593Smuzhiyun 				|| strstr(ep->ep.name, "-int")) {
540*4882a593Smuzhiyun 			goto done;
541*4882a593Smuzhiyun 		}
542*4882a593Smuzhiyun 		switch (dum->gadget.speed) {
543*4882a593Smuzhiyun 		case USB_SPEED_SUPER:
544*4882a593Smuzhiyun 			if (max == 1024)
545*4882a593Smuzhiyun 				break;
546*4882a593Smuzhiyun 			goto done;
547*4882a593Smuzhiyun 		case USB_SPEED_HIGH:
548*4882a593Smuzhiyun 			if (max == 512)
549*4882a593Smuzhiyun 				break;
550*4882a593Smuzhiyun 			goto done;
551*4882a593Smuzhiyun 		case USB_SPEED_FULL:
552*4882a593Smuzhiyun 			if (max == 8 || max == 16 || max == 32 || max == 64)
553*4882a593Smuzhiyun 				/* we'll fake any legal size */
554*4882a593Smuzhiyun 				break;
555*4882a593Smuzhiyun 			/* save a return statement */
556*4882a593Smuzhiyun 		default:
557*4882a593Smuzhiyun 			goto done;
558*4882a593Smuzhiyun 		}
559*4882a593Smuzhiyun 		break;
560*4882a593Smuzhiyun 	case USB_ENDPOINT_XFER_INT:
561*4882a593Smuzhiyun 		if (strstr(ep->ep.name, "-iso")) /* bulk is ok */
562*4882a593Smuzhiyun 			goto done;
563*4882a593Smuzhiyun 		/* real hardware might not handle all packet sizes */
564*4882a593Smuzhiyun 		switch (dum->gadget.speed) {
565*4882a593Smuzhiyun 		case USB_SPEED_SUPER:
566*4882a593Smuzhiyun 		case USB_SPEED_HIGH:
567*4882a593Smuzhiyun 			if (max <= 1024)
568*4882a593Smuzhiyun 				break;
569*4882a593Smuzhiyun 			/* save a return statement */
570*4882a593Smuzhiyun 			fallthrough;
571*4882a593Smuzhiyun 		case USB_SPEED_FULL:
572*4882a593Smuzhiyun 			if (max <= 64)
573*4882a593Smuzhiyun 				break;
574*4882a593Smuzhiyun 			/* save a return statement */
575*4882a593Smuzhiyun 			fallthrough;
576*4882a593Smuzhiyun 		default:
577*4882a593Smuzhiyun 			if (max <= 8)
578*4882a593Smuzhiyun 				break;
579*4882a593Smuzhiyun 			goto done;
580*4882a593Smuzhiyun 		}
581*4882a593Smuzhiyun 		break;
582*4882a593Smuzhiyun 	case USB_ENDPOINT_XFER_ISOC:
583*4882a593Smuzhiyun 		if (strstr(ep->ep.name, "-bulk")
584*4882a593Smuzhiyun 				|| strstr(ep->ep.name, "-int"))
585*4882a593Smuzhiyun 			goto done;
586*4882a593Smuzhiyun 		/* real hardware might not handle all packet sizes */
587*4882a593Smuzhiyun 		switch (dum->gadget.speed) {
588*4882a593Smuzhiyun 		case USB_SPEED_SUPER:
589*4882a593Smuzhiyun 		case USB_SPEED_HIGH:
590*4882a593Smuzhiyun 			if (max <= 1024)
591*4882a593Smuzhiyun 				break;
592*4882a593Smuzhiyun 			/* save a return statement */
593*4882a593Smuzhiyun 			fallthrough;
594*4882a593Smuzhiyun 		case USB_SPEED_FULL:
595*4882a593Smuzhiyun 			if (max <= 1023)
596*4882a593Smuzhiyun 				break;
597*4882a593Smuzhiyun 			/* save a return statement */
598*4882a593Smuzhiyun 		default:
599*4882a593Smuzhiyun 			goto done;
600*4882a593Smuzhiyun 		}
601*4882a593Smuzhiyun 		break;
602*4882a593Smuzhiyun 	default:
603*4882a593Smuzhiyun 		/* few chips support control except on ep0 */
604*4882a593Smuzhiyun 		goto done;
605*4882a593Smuzhiyun 	}
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun 	_ep->maxpacket = max;
608*4882a593Smuzhiyun 	if (usb_ss_max_streams(_ep->comp_desc)) {
609*4882a593Smuzhiyun 		if (!usb_endpoint_xfer_bulk(desc)) {
610*4882a593Smuzhiyun 			dev_err(udc_dev(dum), "Can't enable stream support on "
611*4882a593Smuzhiyun 					"non-bulk ep %s\n", _ep->name);
612*4882a593Smuzhiyun 			return -EINVAL;
613*4882a593Smuzhiyun 		}
614*4882a593Smuzhiyun 		ep->stream_en = 1;
615*4882a593Smuzhiyun 	}
616*4882a593Smuzhiyun 	ep->desc = desc;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	dev_dbg(udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d stream %s\n",
619*4882a593Smuzhiyun 		_ep->name,
620*4882a593Smuzhiyun 		desc->bEndpointAddress & 0x0f,
621*4882a593Smuzhiyun 		(desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
622*4882a593Smuzhiyun 		usb_ep_type_string(usb_endpoint_type(desc)),
623*4882a593Smuzhiyun 		max, ep->stream_en ? "enabled" : "disabled");
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	/* at this point real hardware should be NAKing transfers
626*4882a593Smuzhiyun 	 * to that endpoint, until a buffer is queued to it.
627*4882a593Smuzhiyun 	 */
628*4882a593Smuzhiyun 	ep->halted = ep->wedged = 0;
629*4882a593Smuzhiyun 	retval = 0;
630*4882a593Smuzhiyun done:
631*4882a593Smuzhiyun 	return retval;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun 
dummy_disable(struct usb_ep * _ep)634*4882a593Smuzhiyun static int dummy_disable(struct usb_ep *_ep)
635*4882a593Smuzhiyun {
636*4882a593Smuzhiyun 	struct dummy_ep		*ep;
637*4882a593Smuzhiyun 	struct dummy		*dum;
638*4882a593Smuzhiyun 	unsigned long		flags;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	ep = usb_ep_to_dummy_ep(_ep);
641*4882a593Smuzhiyun 	if (!_ep || !ep->desc || _ep->name == ep0name)
642*4882a593Smuzhiyun 		return -EINVAL;
643*4882a593Smuzhiyun 	dum = ep_to_dummy(ep);
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	spin_lock_irqsave(&dum->lock, flags);
646*4882a593Smuzhiyun 	ep->desc = NULL;
647*4882a593Smuzhiyun 	ep->stream_en = 0;
648*4882a593Smuzhiyun 	nuke(dum, ep);
649*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum->lock, flags);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	dev_dbg(udc_dev(dum), "disabled %s\n", _ep->name);
652*4882a593Smuzhiyun 	return 0;
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun 
dummy_alloc_request(struct usb_ep * _ep,gfp_t mem_flags)655*4882a593Smuzhiyun static struct usb_request *dummy_alloc_request(struct usb_ep *_ep,
656*4882a593Smuzhiyun 		gfp_t mem_flags)
657*4882a593Smuzhiyun {
658*4882a593Smuzhiyun 	struct dummy_request	*req;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	if (!_ep)
661*4882a593Smuzhiyun 		return NULL;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	req = kzalloc(sizeof(*req), mem_flags);
664*4882a593Smuzhiyun 	if (!req)
665*4882a593Smuzhiyun 		return NULL;
666*4882a593Smuzhiyun 	INIT_LIST_HEAD(&req->queue);
667*4882a593Smuzhiyun 	return &req->req;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun 
dummy_free_request(struct usb_ep * _ep,struct usb_request * _req)670*4882a593Smuzhiyun static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req)
671*4882a593Smuzhiyun {
672*4882a593Smuzhiyun 	struct dummy_request	*req;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	if (!_ep || !_req) {
675*4882a593Smuzhiyun 		WARN_ON(1);
676*4882a593Smuzhiyun 		return;
677*4882a593Smuzhiyun 	}
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	req = usb_request_to_dummy_request(_req);
680*4882a593Smuzhiyun 	WARN_ON(!list_empty(&req->queue));
681*4882a593Smuzhiyun 	kfree(req);
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun 
fifo_complete(struct usb_ep * ep,struct usb_request * req)684*4882a593Smuzhiyun static void fifo_complete(struct usb_ep *ep, struct usb_request *req)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun 
dummy_queue(struct usb_ep * _ep,struct usb_request * _req,gfp_t mem_flags)688*4882a593Smuzhiyun static int dummy_queue(struct usb_ep *_ep, struct usb_request *_req,
689*4882a593Smuzhiyun 		gfp_t mem_flags)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun 	struct dummy_ep		*ep;
692*4882a593Smuzhiyun 	struct dummy_request	*req;
693*4882a593Smuzhiyun 	struct dummy		*dum;
694*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd;
695*4882a593Smuzhiyun 	unsigned long		flags;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	req = usb_request_to_dummy_request(_req);
698*4882a593Smuzhiyun 	if (!_req || !list_empty(&req->queue) || !_req->complete)
699*4882a593Smuzhiyun 		return -EINVAL;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	ep = usb_ep_to_dummy_ep(_ep);
702*4882a593Smuzhiyun 	if (!_ep || (!ep->desc && _ep->name != ep0name))
703*4882a593Smuzhiyun 		return -EINVAL;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	dum = ep_to_dummy(ep);
706*4882a593Smuzhiyun 	dum_hcd = gadget_to_dummy_hcd(&dum->gadget);
707*4882a593Smuzhiyun 	if (!dum->driver || !is_enabled(dum_hcd))
708*4882a593Smuzhiyun 		return -ESHUTDOWN;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun #if 0
711*4882a593Smuzhiyun 	dev_dbg(udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
712*4882a593Smuzhiyun 			ep, _req, _ep->name, _req->length, _req->buf);
713*4882a593Smuzhiyun #endif
714*4882a593Smuzhiyun 	_req->status = -EINPROGRESS;
715*4882a593Smuzhiyun 	_req->actual = 0;
716*4882a593Smuzhiyun 	spin_lock_irqsave(&dum->lock, flags);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	/* implement an emulated single-request FIFO */
719*4882a593Smuzhiyun 	if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
720*4882a593Smuzhiyun 			list_empty(&dum->fifo_req.queue) &&
721*4882a593Smuzhiyun 			list_empty(&ep->queue) &&
722*4882a593Smuzhiyun 			_req->length <= FIFO_SIZE) {
723*4882a593Smuzhiyun 		req = &dum->fifo_req;
724*4882a593Smuzhiyun 		req->req = *_req;
725*4882a593Smuzhiyun 		req->req.buf = dum->fifo_buf;
726*4882a593Smuzhiyun 		memcpy(dum->fifo_buf, _req->buf, _req->length);
727*4882a593Smuzhiyun 		req->req.context = dum;
728*4882a593Smuzhiyun 		req->req.complete = fifo_complete;
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun 		list_add_tail(&req->queue, &ep->queue);
731*4882a593Smuzhiyun 		spin_unlock(&dum->lock);
732*4882a593Smuzhiyun 		_req->actual = _req->length;
733*4882a593Smuzhiyun 		_req->status = 0;
734*4882a593Smuzhiyun 		usb_gadget_giveback_request(_ep, _req);
735*4882a593Smuzhiyun 		spin_lock(&dum->lock);
736*4882a593Smuzhiyun 	}  else
737*4882a593Smuzhiyun 		list_add_tail(&req->queue, &ep->queue);
738*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum->lock, flags);
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	/* real hardware would likely enable transfers here, in case
741*4882a593Smuzhiyun 	 * it'd been left NAKing.
742*4882a593Smuzhiyun 	 */
743*4882a593Smuzhiyun 	return 0;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun 
dummy_dequeue(struct usb_ep * _ep,struct usb_request * _req)746*4882a593Smuzhiyun static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	struct dummy_ep		*ep;
749*4882a593Smuzhiyun 	struct dummy		*dum;
750*4882a593Smuzhiyun 	int			retval = -EINVAL;
751*4882a593Smuzhiyun 	unsigned long		flags;
752*4882a593Smuzhiyun 	struct dummy_request	*req = NULL;
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	if (!_ep || !_req)
755*4882a593Smuzhiyun 		return retval;
756*4882a593Smuzhiyun 	ep = usb_ep_to_dummy_ep(_ep);
757*4882a593Smuzhiyun 	dum = ep_to_dummy(ep);
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	if (!dum->driver)
760*4882a593Smuzhiyun 		return -ESHUTDOWN;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	local_irq_save(flags);
763*4882a593Smuzhiyun 	spin_lock(&dum->lock);
764*4882a593Smuzhiyun 	list_for_each_entry(req, &ep->queue, queue) {
765*4882a593Smuzhiyun 		if (&req->req == _req) {
766*4882a593Smuzhiyun 			list_del_init(&req->queue);
767*4882a593Smuzhiyun 			_req->status = -ECONNRESET;
768*4882a593Smuzhiyun 			retval = 0;
769*4882a593Smuzhiyun 			break;
770*4882a593Smuzhiyun 		}
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 	spin_unlock(&dum->lock);
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	if (retval == 0) {
775*4882a593Smuzhiyun 		dev_dbg(udc_dev(dum),
776*4882a593Smuzhiyun 				"dequeued req %p from %s, len %d buf %p\n",
777*4882a593Smuzhiyun 				req, _ep->name, _req->length, _req->buf);
778*4882a593Smuzhiyun 		usb_gadget_giveback_request(_ep, _req);
779*4882a593Smuzhiyun 	}
780*4882a593Smuzhiyun 	local_irq_restore(flags);
781*4882a593Smuzhiyun 	return retval;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun static int
dummy_set_halt_and_wedge(struct usb_ep * _ep,int value,int wedged)785*4882a593Smuzhiyun dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	struct dummy_ep		*ep;
788*4882a593Smuzhiyun 	struct dummy		*dum;
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	if (!_ep)
791*4882a593Smuzhiyun 		return -EINVAL;
792*4882a593Smuzhiyun 	ep = usb_ep_to_dummy_ep(_ep);
793*4882a593Smuzhiyun 	dum = ep_to_dummy(ep);
794*4882a593Smuzhiyun 	if (!dum->driver)
795*4882a593Smuzhiyun 		return -ESHUTDOWN;
796*4882a593Smuzhiyun 	if (!value)
797*4882a593Smuzhiyun 		ep->halted = ep->wedged = 0;
798*4882a593Smuzhiyun 	else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
799*4882a593Smuzhiyun 			!list_empty(&ep->queue))
800*4882a593Smuzhiyun 		return -EAGAIN;
801*4882a593Smuzhiyun 	else {
802*4882a593Smuzhiyun 		ep->halted = 1;
803*4882a593Smuzhiyun 		if (wedged)
804*4882a593Smuzhiyun 			ep->wedged = 1;
805*4882a593Smuzhiyun 	}
806*4882a593Smuzhiyun 	/* FIXME clear emulated data toggle too */
807*4882a593Smuzhiyun 	return 0;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun static int
dummy_set_halt(struct usb_ep * _ep,int value)811*4882a593Smuzhiyun dummy_set_halt(struct usb_ep *_ep, int value)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun 	return dummy_set_halt_and_wedge(_ep, value, 0);
814*4882a593Smuzhiyun }
815*4882a593Smuzhiyun 
dummy_set_wedge(struct usb_ep * _ep)816*4882a593Smuzhiyun static int dummy_set_wedge(struct usb_ep *_ep)
817*4882a593Smuzhiyun {
818*4882a593Smuzhiyun 	if (!_ep || _ep->name == ep0name)
819*4882a593Smuzhiyun 		return -EINVAL;
820*4882a593Smuzhiyun 	return dummy_set_halt_and_wedge(_ep, 1, 1);
821*4882a593Smuzhiyun }
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun static const struct usb_ep_ops dummy_ep_ops = {
824*4882a593Smuzhiyun 	.enable		= dummy_enable,
825*4882a593Smuzhiyun 	.disable	= dummy_disable,
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	.alloc_request	= dummy_alloc_request,
828*4882a593Smuzhiyun 	.free_request	= dummy_free_request,
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	.queue		= dummy_queue,
831*4882a593Smuzhiyun 	.dequeue	= dummy_dequeue,
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	.set_halt	= dummy_set_halt,
834*4882a593Smuzhiyun 	.set_wedge	= dummy_set_wedge,
835*4882a593Smuzhiyun };
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
838*4882a593Smuzhiyun 
839*4882a593Smuzhiyun /* there are both host and device side versions of this call ... */
dummy_g_get_frame(struct usb_gadget * _gadget)840*4882a593Smuzhiyun static int dummy_g_get_frame(struct usb_gadget *_gadget)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun 	struct timespec64 ts64;
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 	ktime_get_ts64(&ts64);
845*4882a593Smuzhiyun 	return ts64.tv_nsec / NSEC_PER_MSEC;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun 
dummy_wakeup(struct usb_gadget * _gadget)848*4882a593Smuzhiyun static int dummy_wakeup(struct usb_gadget *_gadget)
849*4882a593Smuzhiyun {
850*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd;
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	dum_hcd = gadget_to_dummy_hcd(_gadget);
853*4882a593Smuzhiyun 	if (!(dum_hcd->dum->devstatus & ((1 << USB_DEVICE_B_HNP_ENABLE)
854*4882a593Smuzhiyun 				| (1 << USB_DEVICE_REMOTE_WAKEUP))))
855*4882a593Smuzhiyun 		return -EINVAL;
856*4882a593Smuzhiyun 	if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0)
857*4882a593Smuzhiyun 		return -ENOLINK;
858*4882a593Smuzhiyun 	if ((dum_hcd->port_status & USB_PORT_STAT_SUSPEND) == 0 &&
859*4882a593Smuzhiyun 			 dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
860*4882a593Smuzhiyun 		return -EIO;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	/* FIXME: What if the root hub is suspended but the port isn't? */
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 	/* hub notices our request, issues downstream resume, etc */
865*4882a593Smuzhiyun 	dum_hcd->resuming = 1;
866*4882a593Smuzhiyun 	dum_hcd->re_timeout = jiffies + msecs_to_jiffies(20);
867*4882a593Smuzhiyun 	mod_timer(&dummy_hcd_to_hcd(dum_hcd)->rh_timer, dum_hcd->re_timeout);
868*4882a593Smuzhiyun 	return 0;
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun 
dummy_set_selfpowered(struct usb_gadget * _gadget,int value)871*4882a593Smuzhiyun static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value)
872*4882a593Smuzhiyun {
873*4882a593Smuzhiyun 	struct dummy	*dum;
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun 	_gadget->is_selfpowered = (value != 0);
876*4882a593Smuzhiyun 	dum = gadget_to_dummy_hcd(_gadget)->dum;
877*4882a593Smuzhiyun 	if (value)
878*4882a593Smuzhiyun 		dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
879*4882a593Smuzhiyun 	else
880*4882a593Smuzhiyun 		dum->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
881*4882a593Smuzhiyun 	return 0;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun 
dummy_udc_update_ep0(struct dummy * dum)884*4882a593Smuzhiyun static void dummy_udc_update_ep0(struct dummy *dum)
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun 	if (dum->gadget.speed == USB_SPEED_SUPER)
887*4882a593Smuzhiyun 		dum->ep[0].ep.maxpacket = 9;
888*4882a593Smuzhiyun 	else
889*4882a593Smuzhiyun 		dum->ep[0].ep.maxpacket = 64;
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun 
dummy_pullup(struct usb_gadget * _gadget,int value)892*4882a593Smuzhiyun static int dummy_pullup(struct usb_gadget *_gadget, int value)
893*4882a593Smuzhiyun {
894*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd;
895*4882a593Smuzhiyun 	struct dummy	*dum;
896*4882a593Smuzhiyun 	unsigned long	flags;
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun 	dum = gadget_dev_to_dummy(&_gadget->dev);
899*4882a593Smuzhiyun 	dum_hcd = gadget_to_dummy_hcd(_gadget);
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	spin_lock_irqsave(&dum->lock, flags);
902*4882a593Smuzhiyun 	dum->pullup = (value != 0);
903*4882a593Smuzhiyun 	set_link_state(dum_hcd);
904*4882a593Smuzhiyun 	if (value == 0) {
905*4882a593Smuzhiyun 		/*
906*4882a593Smuzhiyun 		 * Emulate synchronize_irq(): wait for callbacks to finish.
907*4882a593Smuzhiyun 		 * This seems to be the best place to emulate the call to
908*4882a593Smuzhiyun 		 * synchronize_irq() that's in usb_gadget_remove_driver().
909*4882a593Smuzhiyun 		 * Doing it in dummy_udc_stop() would be too late since it
910*4882a593Smuzhiyun 		 * is called after the unbind callback and unbind shouldn't
911*4882a593Smuzhiyun 		 * be invoked until all the other callbacks are finished.
912*4882a593Smuzhiyun 		 */
913*4882a593Smuzhiyun 		while (dum->callback_usage > 0) {
914*4882a593Smuzhiyun 			spin_unlock_irqrestore(&dum->lock, flags);
915*4882a593Smuzhiyun 			usleep_range(1000, 2000);
916*4882a593Smuzhiyun 			spin_lock_irqsave(&dum->lock, flags);
917*4882a593Smuzhiyun 		}
918*4882a593Smuzhiyun 	}
919*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum->lock, flags);
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd));
922*4882a593Smuzhiyun 	return 0;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun 
dummy_udc_set_speed(struct usb_gadget * _gadget,enum usb_device_speed speed)925*4882a593Smuzhiyun static void dummy_udc_set_speed(struct usb_gadget *_gadget,
926*4882a593Smuzhiyun 		enum usb_device_speed speed)
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun 	struct dummy	*dum;
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	dum = gadget_dev_to_dummy(&_gadget->dev);
931*4882a593Smuzhiyun 	dum->gadget.speed = speed;
932*4882a593Smuzhiyun 	dummy_udc_update_ep0(dum);
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun static int dummy_udc_start(struct usb_gadget *g,
936*4882a593Smuzhiyun 		struct usb_gadget_driver *driver);
937*4882a593Smuzhiyun static int dummy_udc_stop(struct usb_gadget *g);
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun static const struct usb_gadget_ops dummy_ops = {
940*4882a593Smuzhiyun 	.get_frame	= dummy_g_get_frame,
941*4882a593Smuzhiyun 	.wakeup		= dummy_wakeup,
942*4882a593Smuzhiyun 	.set_selfpowered = dummy_set_selfpowered,
943*4882a593Smuzhiyun 	.pullup		= dummy_pullup,
944*4882a593Smuzhiyun 	.udc_start	= dummy_udc_start,
945*4882a593Smuzhiyun 	.udc_stop	= dummy_udc_stop,
946*4882a593Smuzhiyun 	.udc_set_speed	= dummy_udc_set_speed,
947*4882a593Smuzhiyun };
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun /* "function" sysfs attribute */
function_show(struct device * dev,struct device_attribute * attr,char * buf)952*4882a593Smuzhiyun static ssize_t function_show(struct device *dev, struct device_attribute *attr,
953*4882a593Smuzhiyun 		char *buf)
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun 	struct dummy	*dum = gadget_dev_to_dummy(dev);
956*4882a593Smuzhiyun 
957*4882a593Smuzhiyun 	if (!dum->driver || !dum->driver->function)
958*4882a593Smuzhiyun 		return 0;
959*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%s\n", dum->driver->function);
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun static DEVICE_ATTR_RO(function);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun /*
966*4882a593Smuzhiyun  * Driver registration/unregistration.
967*4882a593Smuzhiyun  *
968*4882a593Smuzhiyun  * This is basically hardware-specific; there's usually only one real USB
969*4882a593Smuzhiyun  * device (not host) controller since that's how USB devices are intended
970*4882a593Smuzhiyun  * to work.  So most implementations of these api calls will rely on the
971*4882a593Smuzhiyun  * fact that only one driver will ever bind to the hardware.  But curious
972*4882a593Smuzhiyun  * hardware can be built with discrete components, so the gadget API doesn't
973*4882a593Smuzhiyun  * require that assumption.
974*4882a593Smuzhiyun  *
975*4882a593Smuzhiyun  * For this emulator, it might be convenient to create a usb device
976*4882a593Smuzhiyun  * for each driver that registers:  just add to a big root hub.
977*4882a593Smuzhiyun  */
978*4882a593Smuzhiyun 
dummy_udc_start(struct usb_gadget * g,struct usb_gadget_driver * driver)979*4882a593Smuzhiyun static int dummy_udc_start(struct usb_gadget *g,
980*4882a593Smuzhiyun 		struct usb_gadget_driver *driver)
981*4882a593Smuzhiyun {
982*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(g);
983*4882a593Smuzhiyun 	struct dummy		*dum = dum_hcd->dum;
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun 	switch (g->speed) {
986*4882a593Smuzhiyun 	/* All the speeds we support */
987*4882a593Smuzhiyun 	case USB_SPEED_LOW:
988*4882a593Smuzhiyun 	case USB_SPEED_FULL:
989*4882a593Smuzhiyun 	case USB_SPEED_HIGH:
990*4882a593Smuzhiyun 	case USB_SPEED_SUPER:
991*4882a593Smuzhiyun 		break;
992*4882a593Smuzhiyun 	default:
993*4882a593Smuzhiyun 		dev_err(dummy_dev(dum_hcd), "Unsupported driver max speed %d\n",
994*4882a593Smuzhiyun 				driver->max_speed);
995*4882a593Smuzhiyun 		return -EINVAL;
996*4882a593Smuzhiyun 	}
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	/*
999*4882a593Smuzhiyun 	 * DEVICE side init ... the layer above hardware, which
1000*4882a593Smuzhiyun 	 * can't enumerate without help from the driver we're binding.
1001*4882a593Smuzhiyun 	 */
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun 	spin_lock_irq(&dum->lock);
1004*4882a593Smuzhiyun 	dum->devstatus = 0;
1005*4882a593Smuzhiyun 	dum->driver = driver;
1006*4882a593Smuzhiyun 	dum->ints_enabled = 1;
1007*4882a593Smuzhiyun 	spin_unlock_irq(&dum->lock);
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 	return 0;
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun 
dummy_udc_stop(struct usb_gadget * g)1012*4882a593Smuzhiyun static int dummy_udc_stop(struct usb_gadget *g)
1013*4882a593Smuzhiyun {
1014*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(g);
1015*4882a593Smuzhiyun 	struct dummy		*dum = dum_hcd->dum;
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun 	spin_lock_irq(&dum->lock);
1018*4882a593Smuzhiyun 	dum->ints_enabled = 0;
1019*4882a593Smuzhiyun 	stop_activity(dum);
1020*4882a593Smuzhiyun 	dum->driver = NULL;
1021*4882a593Smuzhiyun 	spin_unlock_irq(&dum->lock);
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun 	return 0;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun #undef is_enabled
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun /* The gadget structure is stored inside the hcd structure and will be
1029*4882a593Smuzhiyun  * released along with it. */
init_dummy_udc_hw(struct dummy * dum)1030*4882a593Smuzhiyun static void init_dummy_udc_hw(struct dummy *dum)
1031*4882a593Smuzhiyun {
1032*4882a593Smuzhiyun 	int i;
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dum->gadget.ep_list);
1035*4882a593Smuzhiyun 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
1036*4882a593Smuzhiyun 		struct dummy_ep	*ep = &dum->ep[i];
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 		if (!ep_info[i].name)
1039*4882a593Smuzhiyun 			break;
1040*4882a593Smuzhiyun 		ep->ep.name = ep_info[i].name;
1041*4882a593Smuzhiyun 		ep->ep.caps = ep_info[i].caps;
1042*4882a593Smuzhiyun 		ep->ep.ops = &dummy_ep_ops;
1043*4882a593Smuzhiyun 		list_add_tail(&ep->ep.ep_list, &dum->gadget.ep_list);
1044*4882a593Smuzhiyun 		ep->halted = ep->wedged = ep->already_seen =
1045*4882a593Smuzhiyun 				ep->setup_stage = 0;
1046*4882a593Smuzhiyun 		usb_ep_set_maxpacket_limit(&ep->ep, ~0);
1047*4882a593Smuzhiyun 		ep->ep.max_streams = 16;
1048*4882a593Smuzhiyun 		ep->last_io = jiffies;
1049*4882a593Smuzhiyun 		ep->gadget = &dum->gadget;
1050*4882a593Smuzhiyun 		ep->desc = NULL;
1051*4882a593Smuzhiyun 		INIT_LIST_HEAD(&ep->queue);
1052*4882a593Smuzhiyun 	}
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	dum->gadget.ep0 = &dum->ep[0].ep;
1055*4882a593Smuzhiyun 	list_del_init(&dum->ep[0].ep.ep_list);
1056*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dum->fifo_req.queue);
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun #ifdef CONFIG_USB_OTG
1059*4882a593Smuzhiyun 	dum->gadget.is_otg = 1;
1060*4882a593Smuzhiyun #endif
1061*4882a593Smuzhiyun }
1062*4882a593Smuzhiyun 
dummy_udc_probe(struct platform_device * pdev)1063*4882a593Smuzhiyun static int dummy_udc_probe(struct platform_device *pdev)
1064*4882a593Smuzhiyun {
1065*4882a593Smuzhiyun 	struct dummy	*dum;
1066*4882a593Smuzhiyun 	int		rc;
1067*4882a593Smuzhiyun 
1068*4882a593Smuzhiyun 	dum = *((void **)dev_get_platdata(&pdev->dev));
1069*4882a593Smuzhiyun 	/* Clear usb_gadget region for new registration to udc-core */
1070*4882a593Smuzhiyun 	memzero_explicit(&dum->gadget, sizeof(struct usb_gadget));
1071*4882a593Smuzhiyun 	dum->gadget.name = gadget_name;
1072*4882a593Smuzhiyun 	dum->gadget.ops = &dummy_ops;
1073*4882a593Smuzhiyun 	if (mod_data.is_super_speed)
1074*4882a593Smuzhiyun 		dum->gadget.max_speed = USB_SPEED_SUPER;
1075*4882a593Smuzhiyun 	else if (mod_data.is_high_speed)
1076*4882a593Smuzhiyun 		dum->gadget.max_speed = USB_SPEED_HIGH;
1077*4882a593Smuzhiyun 	else
1078*4882a593Smuzhiyun 		dum->gadget.max_speed = USB_SPEED_FULL;
1079*4882a593Smuzhiyun 
1080*4882a593Smuzhiyun 	dum->gadget.dev.parent = &pdev->dev;
1081*4882a593Smuzhiyun 	init_dummy_udc_hw(dum);
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget);
1084*4882a593Smuzhiyun 	if (rc < 0)
1085*4882a593Smuzhiyun 		goto err_udc;
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 	rc = device_create_file(&dum->gadget.dev, &dev_attr_function);
1088*4882a593Smuzhiyun 	if (rc < 0)
1089*4882a593Smuzhiyun 		goto err_dev;
1090*4882a593Smuzhiyun 	platform_set_drvdata(pdev, dum);
1091*4882a593Smuzhiyun 	return rc;
1092*4882a593Smuzhiyun 
1093*4882a593Smuzhiyun err_dev:
1094*4882a593Smuzhiyun 	usb_del_gadget_udc(&dum->gadget);
1095*4882a593Smuzhiyun err_udc:
1096*4882a593Smuzhiyun 	return rc;
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun 
dummy_udc_remove(struct platform_device * pdev)1099*4882a593Smuzhiyun static int dummy_udc_remove(struct platform_device *pdev)
1100*4882a593Smuzhiyun {
1101*4882a593Smuzhiyun 	struct dummy	*dum = platform_get_drvdata(pdev);
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 	device_remove_file(&dum->gadget.dev, &dev_attr_function);
1104*4882a593Smuzhiyun 	usb_del_gadget_udc(&dum->gadget);
1105*4882a593Smuzhiyun 	return 0;
1106*4882a593Smuzhiyun }
1107*4882a593Smuzhiyun 
dummy_udc_pm(struct dummy * dum,struct dummy_hcd * dum_hcd,int suspend)1108*4882a593Smuzhiyun static void dummy_udc_pm(struct dummy *dum, struct dummy_hcd *dum_hcd,
1109*4882a593Smuzhiyun 		int suspend)
1110*4882a593Smuzhiyun {
1111*4882a593Smuzhiyun 	spin_lock_irq(&dum->lock);
1112*4882a593Smuzhiyun 	dum->udc_suspended = suspend;
1113*4882a593Smuzhiyun 	set_link_state(dum_hcd);
1114*4882a593Smuzhiyun 	spin_unlock_irq(&dum->lock);
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun 
dummy_udc_suspend(struct platform_device * pdev,pm_message_t state)1117*4882a593Smuzhiyun static int dummy_udc_suspend(struct platform_device *pdev, pm_message_t state)
1118*4882a593Smuzhiyun {
1119*4882a593Smuzhiyun 	struct dummy		*dum = platform_get_drvdata(pdev);
1120*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(&dum->gadget);
1121*4882a593Smuzhiyun 
1122*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "%s\n", __func__);
1123*4882a593Smuzhiyun 	dummy_udc_pm(dum, dum_hcd, 1);
1124*4882a593Smuzhiyun 	usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd));
1125*4882a593Smuzhiyun 	return 0;
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun 
dummy_udc_resume(struct platform_device * pdev)1128*4882a593Smuzhiyun static int dummy_udc_resume(struct platform_device *pdev)
1129*4882a593Smuzhiyun {
1130*4882a593Smuzhiyun 	struct dummy		*dum = platform_get_drvdata(pdev);
1131*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(&dum->gadget);
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "%s\n", __func__);
1134*4882a593Smuzhiyun 	dummy_udc_pm(dum, dum_hcd, 0);
1135*4882a593Smuzhiyun 	usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd));
1136*4882a593Smuzhiyun 	return 0;
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun static struct platform_driver dummy_udc_driver = {
1140*4882a593Smuzhiyun 	.probe		= dummy_udc_probe,
1141*4882a593Smuzhiyun 	.remove		= dummy_udc_remove,
1142*4882a593Smuzhiyun 	.suspend	= dummy_udc_suspend,
1143*4882a593Smuzhiyun 	.resume		= dummy_udc_resume,
1144*4882a593Smuzhiyun 	.driver		= {
1145*4882a593Smuzhiyun 		.name	= gadget_name,
1146*4882a593Smuzhiyun 	},
1147*4882a593Smuzhiyun };
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
1150*4882a593Smuzhiyun 
dummy_get_ep_idx(const struct usb_endpoint_descriptor * desc)1151*4882a593Smuzhiyun static unsigned int dummy_get_ep_idx(const struct usb_endpoint_descriptor *desc)
1152*4882a593Smuzhiyun {
1153*4882a593Smuzhiyun 	unsigned int index;
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	index = usb_endpoint_num(desc) << 1;
1156*4882a593Smuzhiyun 	if (usb_endpoint_dir_in(desc))
1157*4882a593Smuzhiyun 		index |= 1;
1158*4882a593Smuzhiyun 	return index;
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun 
1161*4882a593Smuzhiyun /* HOST SIDE DRIVER
1162*4882a593Smuzhiyun  *
1163*4882a593Smuzhiyun  * this uses the hcd framework to hook up to host side drivers.
1164*4882a593Smuzhiyun  * its root hub will only have one device, otherwise it acts like
1165*4882a593Smuzhiyun  * a normal host controller.
1166*4882a593Smuzhiyun  *
1167*4882a593Smuzhiyun  * when urbs are queued, they're just stuck on a list that we
1168*4882a593Smuzhiyun  * scan in a timer callback.  that callback connects writes from
1169*4882a593Smuzhiyun  * the host with reads from the device, and so on, based on the
1170*4882a593Smuzhiyun  * usb 2.0 rules.
1171*4882a593Smuzhiyun  */
1172*4882a593Smuzhiyun 
dummy_ep_stream_en(struct dummy_hcd * dum_hcd,struct urb * urb)1173*4882a593Smuzhiyun static int dummy_ep_stream_en(struct dummy_hcd *dum_hcd, struct urb *urb)
1174*4882a593Smuzhiyun {
1175*4882a593Smuzhiyun 	const struct usb_endpoint_descriptor *desc = &urb->ep->desc;
1176*4882a593Smuzhiyun 	u32 index;
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun 	if (!usb_endpoint_xfer_bulk(desc))
1179*4882a593Smuzhiyun 		return 0;
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun 	index = dummy_get_ep_idx(desc);
1182*4882a593Smuzhiyun 	return (1 << index) & dum_hcd->stream_en_ep;
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun /*
1186*4882a593Smuzhiyun  * The max stream number is saved as a nibble so for the 30 possible endpoints
1187*4882a593Smuzhiyun  * we only 15 bytes of memory. Therefore we are limited to max 16 streams (0
1188*4882a593Smuzhiyun  * means we use only 1 stream). The maximum according to the spec is 16bit so
1189*4882a593Smuzhiyun  * if the 16 stream limit is about to go, the array size should be incremented
1190*4882a593Smuzhiyun  * to 30 elements of type u16.
1191*4882a593Smuzhiyun  */
get_max_streams_for_pipe(struct dummy_hcd * dum_hcd,unsigned int pipe)1192*4882a593Smuzhiyun static int get_max_streams_for_pipe(struct dummy_hcd *dum_hcd,
1193*4882a593Smuzhiyun 		unsigned int pipe)
1194*4882a593Smuzhiyun {
1195*4882a593Smuzhiyun 	int max_streams;
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 	max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)];
1198*4882a593Smuzhiyun 	if (usb_pipeout(pipe))
1199*4882a593Smuzhiyun 		max_streams >>= 4;
1200*4882a593Smuzhiyun 	else
1201*4882a593Smuzhiyun 		max_streams &= 0xf;
1202*4882a593Smuzhiyun 	max_streams++;
1203*4882a593Smuzhiyun 	return max_streams;
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun 
set_max_streams_for_pipe(struct dummy_hcd * dum_hcd,unsigned int pipe,unsigned int streams)1206*4882a593Smuzhiyun static void set_max_streams_for_pipe(struct dummy_hcd *dum_hcd,
1207*4882a593Smuzhiyun 		unsigned int pipe, unsigned int streams)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun 	int max_streams;
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	streams--;
1212*4882a593Smuzhiyun 	max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)];
1213*4882a593Smuzhiyun 	if (usb_pipeout(pipe)) {
1214*4882a593Smuzhiyun 		streams <<= 4;
1215*4882a593Smuzhiyun 		max_streams &= 0xf;
1216*4882a593Smuzhiyun 	} else {
1217*4882a593Smuzhiyun 		max_streams &= 0xf0;
1218*4882a593Smuzhiyun 	}
1219*4882a593Smuzhiyun 	max_streams |= streams;
1220*4882a593Smuzhiyun 	dum_hcd->num_stream[usb_pipeendpoint(pipe)] = max_streams;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun 
dummy_validate_stream(struct dummy_hcd * dum_hcd,struct urb * urb)1223*4882a593Smuzhiyun static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb)
1224*4882a593Smuzhiyun {
1225*4882a593Smuzhiyun 	unsigned int max_streams;
1226*4882a593Smuzhiyun 	int enabled;
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	enabled = dummy_ep_stream_en(dum_hcd, urb);
1229*4882a593Smuzhiyun 	if (!urb->stream_id) {
1230*4882a593Smuzhiyun 		if (enabled)
1231*4882a593Smuzhiyun 			return -EINVAL;
1232*4882a593Smuzhiyun 		return 0;
1233*4882a593Smuzhiyun 	}
1234*4882a593Smuzhiyun 	if (!enabled)
1235*4882a593Smuzhiyun 		return -EINVAL;
1236*4882a593Smuzhiyun 
1237*4882a593Smuzhiyun 	max_streams = get_max_streams_for_pipe(dum_hcd,
1238*4882a593Smuzhiyun 			usb_pipeendpoint(urb->pipe));
1239*4882a593Smuzhiyun 	if (urb->stream_id > max_streams) {
1240*4882a593Smuzhiyun 		dev_err(dummy_dev(dum_hcd), "Stream id %d is out of range.\n",
1241*4882a593Smuzhiyun 				urb->stream_id);
1242*4882a593Smuzhiyun 		BUG();
1243*4882a593Smuzhiyun 		return -EINVAL;
1244*4882a593Smuzhiyun 	}
1245*4882a593Smuzhiyun 	return 0;
1246*4882a593Smuzhiyun }
1247*4882a593Smuzhiyun 
dummy_urb_enqueue(struct usb_hcd * hcd,struct urb * urb,gfp_t mem_flags)1248*4882a593Smuzhiyun static int dummy_urb_enqueue(
1249*4882a593Smuzhiyun 	struct usb_hcd			*hcd,
1250*4882a593Smuzhiyun 	struct urb			*urb,
1251*4882a593Smuzhiyun 	gfp_t				mem_flags
1252*4882a593Smuzhiyun ) {
1253*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd;
1254*4882a593Smuzhiyun 	struct urbp	*urbp;
1255*4882a593Smuzhiyun 	unsigned long	flags;
1256*4882a593Smuzhiyun 	int		rc;
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	urbp = kmalloc(sizeof *urbp, mem_flags);
1259*4882a593Smuzhiyun 	if (!urbp)
1260*4882a593Smuzhiyun 		return -ENOMEM;
1261*4882a593Smuzhiyun 	urbp->urb = urb;
1262*4882a593Smuzhiyun 	urbp->miter_started = 0;
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 	dum_hcd = hcd_to_dummy_hcd(hcd);
1265*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
1266*4882a593Smuzhiyun 
1267*4882a593Smuzhiyun 	rc = dummy_validate_stream(dum_hcd, urb);
1268*4882a593Smuzhiyun 	if (rc) {
1269*4882a593Smuzhiyun 		kfree(urbp);
1270*4882a593Smuzhiyun 		goto done;
1271*4882a593Smuzhiyun 	}
1272*4882a593Smuzhiyun 
1273*4882a593Smuzhiyun 	rc = usb_hcd_link_urb_to_ep(hcd, urb);
1274*4882a593Smuzhiyun 	if (rc) {
1275*4882a593Smuzhiyun 		kfree(urbp);
1276*4882a593Smuzhiyun 		goto done;
1277*4882a593Smuzhiyun 	}
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	if (!dum_hcd->udev) {
1280*4882a593Smuzhiyun 		dum_hcd->udev = urb->dev;
1281*4882a593Smuzhiyun 		usb_get_dev(dum_hcd->udev);
1282*4882a593Smuzhiyun 	} else if (unlikely(dum_hcd->udev != urb->dev))
1283*4882a593Smuzhiyun 		dev_err(dummy_dev(dum_hcd), "usb_device address has changed!\n");
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list);
1286*4882a593Smuzhiyun 	urb->hcpriv = urbp;
1287*4882a593Smuzhiyun 	if (!dum_hcd->next_frame_urbp)
1288*4882a593Smuzhiyun 		dum_hcd->next_frame_urbp = urbp;
1289*4882a593Smuzhiyun 	if (usb_pipetype(urb->pipe) == PIPE_CONTROL)
1290*4882a593Smuzhiyun 		urb->error_count = 1;		/* mark as a new urb */
1291*4882a593Smuzhiyun 
1292*4882a593Smuzhiyun 	/* kick the scheduler, it'll do the rest */
1293*4882a593Smuzhiyun 	if (!timer_pending(&dum_hcd->timer))
1294*4882a593Smuzhiyun 		mod_timer(&dum_hcd->timer, jiffies + 1);
1295*4882a593Smuzhiyun 
1296*4882a593Smuzhiyun  done:
1297*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
1298*4882a593Smuzhiyun 	return rc;
1299*4882a593Smuzhiyun }
1300*4882a593Smuzhiyun 
dummy_urb_dequeue(struct usb_hcd * hcd,struct urb * urb,int status)1301*4882a593Smuzhiyun static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1302*4882a593Smuzhiyun {
1303*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd;
1304*4882a593Smuzhiyun 	unsigned long	flags;
1305*4882a593Smuzhiyun 	int		rc;
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun 	/* giveback happens automatically in timer callback,
1308*4882a593Smuzhiyun 	 * so make sure the callback happens */
1309*4882a593Smuzhiyun 	dum_hcd = hcd_to_dummy_hcd(hcd);
1310*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
1311*4882a593Smuzhiyun 
1312*4882a593Smuzhiyun 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
1313*4882a593Smuzhiyun 	if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
1314*4882a593Smuzhiyun 			!list_empty(&dum_hcd->urbp_list))
1315*4882a593Smuzhiyun 		mod_timer(&dum_hcd->timer, jiffies);
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
1318*4882a593Smuzhiyun 	return rc;
1319*4882a593Smuzhiyun }
1320*4882a593Smuzhiyun 
dummy_perform_transfer(struct urb * urb,struct dummy_request * req,u32 len)1321*4882a593Smuzhiyun static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req,
1322*4882a593Smuzhiyun 		u32 len)
1323*4882a593Smuzhiyun {
1324*4882a593Smuzhiyun 	void *ubuf, *rbuf;
1325*4882a593Smuzhiyun 	struct urbp *urbp = urb->hcpriv;
1326*4882a593Smuzhiyun 	int to_host;
1327*4882a593Smuzhiyun 	struct sg_mapping_iter *miter = &urbp->miter;
1328*4882a593Smuzhiyun 	u32 trans = 0;
1329*4882a593Smuzhiyun 	u32 this_sg;
1330*4882a593Smuzhiyun 	bool next_sg;
1331*4882a593Smuzhiyun 
1332*4882a593Smuzhiyun 	to_host = usb_urb_dir_in(urb);
1333*4882a593Smuzhiyun 	rbuf = req->req.buf + req->req.actual;
1334*4882a593Smuzhiyun 
1335*4882a593Smuzhiyun 	if (!urb->num_sgs) {
1336*4882a593Smuzhiyun 		ubuf = urb->transfer_buffer + urb->actual_length;
1337*4882a593Smuzhiyun 		if (to_host)
1338*4882a593Smuzhiyun 			memcpy(ubuf, rbuf, len);
1339*4882a593Smuzhiyun 		else
1340*4882a593Smuzhiyun 			memcpy(rbuf, ubuf, len);
1341*4882a593Smuzhiyun 		return len;
1342*4882a593Smuzhiyun 	}
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun 	if (!urbp->miter_started) {
1345*4882a593Smuzhiyun 		u32 flags = SG_MITER_ATOMIC;
1346*4882a593Smuzhiyun 
1347*4882a593Smuzhiyun 		if (to_host)
1348*4882a593Smuzhiyun 			flags |= SG_MITER_TO_SG;
1349*4882a593Smuzhiyun 		else
1350*4882a593Smuzhiyun 			flags |= SG_MITER_FROM_SG;
1351*4882a593Smuzhiyun 
1352*4882a593Smuzhiyun 		sg_miter_start(miter, urb->sg, urb->num_sgs, flags);
1353*4882a593Smuzhiyun 		urbp->miter_started = 1;
1354*4882a593Smuzhiyun 	}
1355*4882a593Smuzhiyun 	next_sg = sg_miter_next(miter);
1356*4882a593Smuzhiyun 	if (next_sg == false) {
1357*4882a593Smuzhiyun 		WARN_ON_ONCE(1);
1358*4882a593Smuzhiyun 		return -EINVAL;
1359*4882a593Smuzhiyun 	}
1360*4882a593Smuzhiyun 	do {
1361*4882a593Smuzhiyun 		ubuf = miter->addr;
1362*4882a593Smuzhiyun 		this_sg = min_t(u32, len, miter->length);
1363*4882a593Smuzhiyun 		miter->consumed = this_sg;
1364*4882a593Smuzhiyun 		trans += this_sg;
1365*4882a593Smuzhiyun 
1366*4882a593Smuzhiyun 		if (to_host)
1367*4882a593Smuzhiyun 			memcpy(ubuf, rbuf, this_sg);
1368*4882a593Smuzhiyun 		else
1369*4882a593Smuzhiyun 			memcpy(rbuf, ubuf, this_sg);
1370*4882a593Smuzhiyun 		len -= this_sg;
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 		if (!len)
1373*4882a593Smuzhiyun 			break;
1374*4882a593Smuzhiyun 		next_sg = sg_miter_next(miter);
1375*4882a593Smuzhiyun 		if (next_sg == false) {
1376*4882a593Smuzhiyun 			WARN_ON_ONCE(1);
1377*4882a593Smuzhiyun 			return -EINVAL;
1378*4882a593Smuzhiyun 		}
1379*4882a593Smuzhiyun 
1380*4882a593Smuzhiyun 		rbuf += this_sg;
1381*4882a593Smuzhiyun 	} while (1);
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	sg_miter_stop(miter);
1384*4882a593Smuzhiyun 	return trans;
1385*4882a593Smuzhiyun }
1386*4882a593Smuzhiyun 
1387*4882a593Smuzhiyun /* transfer up to a frame's worth; caller must own lock */
transfer(struct dummy_hcd * dum_hcd,struct urb * urb,struct dummy_ep * ep,int limit,int * status)1388*4882a593Smuzhiyun static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb,
1389*4882a593Smuzhiyun 		struct dummy_ep *ep, int limit, int *status)
1390*4882a593Smuzhiyun {
1391*4882a593Smuzhiyun 	struct dummy		*dum = dum_hcd->dum;
1392*4882a593Smuzhiyun 	struct dummy_request	*req;
1393*4882a593Smuzhiyun 	int			sent = 0;
1394*4882a593Smuzhiyun 
1395*4882a593Smuzhiyun top:
1396*4882a593Smuzhiyun 	/* if there's no request queued, the device is NAKing; return */
1397*4882a593Smuzhiyun 	list_for_each_entry(req, &ep->queue, queue) {
1398*4882a593Smuzhiyun 		unsigned	host_len, dev_len, len;
1399*4882a593Smuzhiyun 		int		is_short, to_host;
1400*4882a593Smuzhiyun 		int		rescan = 0;
1401*4882a593Smuzhiyun 
1402*4882a593Smuzhiyun 		if (dummy_ep_stream_en(dum_hcd, urb)) {
1403*4882a593Smuzhiyun 			if ((urb->stream_id != req->req.stream_id))
1404*4882a593Smuzhiyun 				continue;
1405*4882a593Smuzhiyun 		}
1406*4882a593Smuzhiyun 
1407*4882a593Smuzhiyun 		/* 1..N packets of ep->ep.maxpacket each ... the last one
1408*4882a593Smuzhiyun 		 * may be short (including zero length).
1409*4882a593Smuzhiyun 		 *
1410*4882a593Smuzhiyun 		 * writer can send a zlp explicitly (length 0) or implicitly
1411*4882a593Smuzhiyun 		 * (length mod maxpacket zero, and 'zero' flag); they always
1412*4882a593Smuzhiyun 		 * terminate reads.
1413*4882a593Smuzhiyun 		 */
1414*4882a593Smuzhiyun 		host_len = urb->transfer_buffer_length - urb->actual_length;
1415*4882a593Smuzhiyun 		dev_len = req->req.length - req->req.actual;
1416*4882a593Smuzhiyun 		len = min(host_len, dev_len);
1417*4882a593Smuzhiyun 
1418*4882a593Smuzhiyun 		/* FIXME update emulated data toggle too */
1419*4882a593Smuzhiyun 
1420*4882a593Smuzhiyun 		to_host = usb_urb_dir_in(urb);
1421*4882a593Smuzhiyun 		if (unlikely(len == 0))
1422*4882a593Smuzhiyun 			is_short = 1;
1423*4882a593Smuzhiyun 		else {
1424*4882a593Smuzhiyun 			/* not enough bandwidth left? */
1425*4882a593Smuzhiyun 			if (limit < ep->ep.maxpacket && limit < len)
1426*4882a593Smuzhiyun 				break;
1427*4882a593Smuzhiyun 			len = min_t(unsigned, len, limit);
1428*4882a593Smuzhiyun 			if (len == 0)
1429*4882a593Smuzhiyun 				break;
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 			/* send multiple of maxpacket first, then remainder */
1432*4882a593Smuzhiyun 			if (len >= ep->ep.maxpacket) {
1433*4882a593Smuzhiyun 				is_short = 0;
1434*4882a593Smuzhiyun 				if (len % ep->ep.maxpacket)
1435*4882a593Smuzhiyun 					rescan = 1;
1436*4882a593Smuzhiyun 				len -= len % ep->ep.maxpacket;
1437*4882a593Smuzhiyun 			} else {
1438*4882a593Smuzhiyun 				is_short = 1;
1439*4882a593Smuzhiyun 			}
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun 			len = dummy_perform_transfer(urb, req, len);
1442*4882a593Smuzhiyun 
1443*4882a593Smuzhiyun 			ep->last_io = jiffies;
1444*4882a593Smuzhiyun 			if ((int)len < 0) {
1445*4882a593Smuzhiyun 				req->req.status = len;
1446*4882a593Smuzhiyun 			} else {
1447*4882a593Smuzhiyun 				limit -= len;
1448*4882a593Smuzhiyun 				sent += len;
1449*4882a593Smuzhiyun 				urb->actual_length += len;
1450*4882a593Smuzhiyun 				req->req.actual += len;
1451*4882a593Smuzhiyun 			}
1452*4882a593Smuzhiyun 		}
1453*4882a593Smuzhiyun 
1454*4882a593Smuzhiyun 		/* short packets terminate, maybe with overflow/underflow.
1455*4882a593Smuzhiyun 		 * it's only really an error to write too much.
1456*4882a593Smuzhiyun 		 *
1457*4882a593Smuzhiyun 		 * partially filling a buffer optionally blocks queue advances
1458*4882a593Smuzhiyun 		 * (so completion handlers can clean up the queue) but we don't
1459*4882a593Smuzhiyun 		 * need to emulate such data-in-flight.
1460*4882a593Smuzhiyun 		 */
1461*4882a593Smuzhiyun 		if (is_short) {
1462*4882a593Smuzhiyun 			if (host_len == dev_len) {
1463*4882a593Smuzhiyun 				req->req.status = 0;
1464*4882a593Smuzhiyun 				*status = 0;
1465*4882a593Smuzhiyun 			} else if (to_host) {
1466*4882a593Smuzhiyun 				req->req.status = 0;
1467*4882a593Smuzhiyun 				if (dev_len > host_len)
1468*4882a593Smuzhiyun 					*status = -EOVERFLOW;
1469*4882a593Smuzhiyun 				else
1470*4882a593Smuzhiyun 					*status = 0;
1471*4882a593Smuzhiyun 			} else {
1472*4882a593Smuzhiyun 				*status = 0;
1473*4882a593Smuzhiyun 				if (host_len > dev_len)
1474*4882a593Smuzhiyun 					req->req.status = -EOVERFLOW;
1475*4882a593Smuzhiyun 				else
1476*4882a593Smuzhiyun 					req->req.status = 0;
1477*4882a593Smuzhiyun 			}
1478*4882a593Smuzhiyun 
1479*4882a593Smuzhiyun 		/*
1480*4882a593Smuzhiyun 		 * many requests terminate without a short packet.
1481*4882a593Smuzhiyun 		 * send a zlp if demanded by flags.
1482*4882a593Smuzhiyun 		 */
1483*4882a593Smuzhiyun 		} else {
1484*4882a593Smuzhiyun 			if (req->req.length == req->req.actual) {
1485*4882a593Smuzhiyun 				if (req->req.zero && to_host)
1486*4882a593Smuzhiyun 					rescan = 1;
1487*4882a593Smuzhiyun 				else
1488*4882a593Smuzhiyun 					req->req.status = 0;
1489*4882a593Smuzhiyun 			}
1490*4882a593Smuzhiyun 			if (urb->transfer_buffer_length == urb->actual_length) {
1491*4882a593Smuzhiyun 				if (urb->transfer_flags & URB_ZERO_PACKET &&
1492*4882a593Smuzhiyun 				    !to_host)
1493*4882a593Smuzhiyun 					rescan = 1;
1494*4882a593Smuzhiyun 				else
1495*4882a593Smuzhiyun 					*status = 0;
1496*4882a593Smuzhiyun 			}
1497*4882a593Smuzhiyun 		}
1498*4882a593Smuzhiyun 
1499*4882a593Smuzhiyun 		/* device side completion --> continuable */
1500*4882a593Smuzhiyun 		if (req->req.status != -EINPROGRESS) {
1501*4882a593Smuzhiyun 			list_del_init(&req->queue);
1502*4882a593Smuzhiyun 
1503*4882a593Smuzhiyun 			spin_unlock(&dum->lock);
1504*4882a593Smuzhiyun 			usb_gadget_giveback_request(&ep->ep, &req->req);
1505*4882a593Smuzhiyun 			spin_lock(&dum->lock);
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun 			/* requests might have been unlinked... */
1508*4882a593Smuzhiyun 			rescan = 1;
1509*4882a593Smuzhiyun 		}
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 		/* host side completion --> terminate */
1512*4882a593Smuzhiyun 		if (*status != -EINPROGRESS)
1513*4882a593Smuzhiyun 			break;
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 		/* rescan to continue with any other queued i/o */
1516*4882a593Smuzhiyun 		if (rescan)
1517*4882a593Smuzhiyun 			goto top;
1518*4882a593Smuzhiyun 	}
1519*4882a593Smuzhiyun 	return sent;
1520*4882a593Smuzhiyun }
1521*4882a593Smuzhiyun 
periodic_bytes(struct dummy * dum,struct dummy_ep * ep)1522*4882a593Smuzhiyun static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep)
1523*4882a593Smuzhiyun {
1524*4882a593Smuzhiyun 	int	limit = ep->ep.maxpacket;
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun 	if (dum->gadget.speed == USB_SPEED_HIGH) {
1527*4882a593Smuzhiyun 		int	tmp;
1528*4882a593Smuzhiyun 
1529*4882a593Smuzhiyun 		/* high bandwidth mode */
1530*4882a593Smuzhiyun 		tmp = usb_endpoint_maxp_mult(ep->desc);
1531*4882a593Smuzhiyun 		tmp *= 8 /* applies to entire frame */;
1532*4882a593Smuzhiyun 		limit += limit * tmp;
1533*4882a593Smuzhiyun 	}
1534*4882a593Smuzhiyun 	if (dum->gadget.speed == USB_SPEED_SUPER) {
1535*4882a593Smuzhiyun 		switch (usb_endpoint_type(ep->desc)) {
1536*4882a593Smuzhiyun 		case USB_ENDPOINT_XFER_ISOC:
1537*4882a593Smuzhiyun 			/* Sec. 4.4.8.2 USB3.0 Spec */
1538*4882a593Smuzhiyun 			limit = 3 * 16 * 1024 * 8;
1539*4882a593Smuzhiyun 			break;
1540*4882a593Smuzhiyun 		case USB_ENDPOINT_XFER_INT:
1541*4882a593Smuzhiyun 			/* Sec. 4.4.7.2 USB3.0 Spec */
1542*4882a593Smuzhiyun 			limit = 3 * 1024 * 8;
1543*4882a593Smuzhiyun 			break;
1544*4882a593Smuzhiyun 		case USB_ENDPOINT_XFER_BULK:
1545*4882a593Smuzhiyun 		default:
1546*4882a593Smuzhiyun 			break;
1547*4882a593Smuzhiyun 		}
1548*4882a593Smuzhiyun 	}
1549*4882a593Smuzhiyun 	return limit;
1550*4882a593Smuzhiyun }
1551*4882a593Smuzhiyun 
1552*4882a593Smuzhiyun #define is_active(dum_hcd)	((dum_hcd->port_status & \
1553*4882a593Smuzhiyun 		(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \
1554*4882a593Smuzhiyun 			USB_PORT_STAT_SUSPEND)) \
1555*4882a593Smuzhiyun 		== (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE))
1556*4882a593Smuzhiyun 
find_endpoint(struct dummy * dum,u8 address)1557*4882a593Smuzhiyun static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address)
1558*4882a593Smuzhiyun {
1559*4882a593Smuzhiyun 	int		i;
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun 	if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ?
1562*4882a593Smuzhiyun 			dum->ss_hcd : dum->hs_hcd)))
1563*4882a593Smuzhiyun 		return NULL;
1564*4882a593Smuzhiyun 	if (!dum->ints_enabled)
1565*4882a593Smuzhiyun 		return NULL;
1566*4882a593Smuzhiyun 	if ((address & ~USB_DIR_IN) == 0)
1567*4882a593Smuzhiyun 		return &dum->ep[0];
1568*4882a593Smuzhiyun 	for (i = 1; i < DUMMY_ENDPOINTS; i++) {
1569*4882a593Smuzhiyun 		struct dummy_ep	*ep = &dum->ep[i];
1570*4882a593Smuzhiyun 
1571*4882a593Smuzhiyun 		if (!ep->desc)
1572*4882a593Smuzhiyun 			continue;
1573*4882a593Smuzhiyun 		if (ep->desc->bEndpointAddress == address)
1574*4882a593Smuzhiyun 			return ep;
1575*4882a593Smuzhiyun 	}
1576*4882a593Smuzhiyun 	return NULL;
1577*4882a593Smuzhiyun }
1578*4882a593Smuzhiyun 
1579*4882a593Smuzhiyun #undef is_active
1580*4882a593Smuzhiyun 
1581*4882a593Smuzhiyun #define Dev_Request	(USB_TYPE_STANDARD | USB_RECIP_DEVICE)
1582*4882a593Smuzhiyun #define Dev_InRequest	(Dev_Request | USB_DIR_IN)
1583*4882a593Smuzhiyun #define Intf_Request	(USB_TYPE_STANDARD | USB_RECIP_INTERFACE)
1584*4882a593Smuzhiyun #define Intf_InRequest	(Intf_Request | USB_DIR_IN)
1585*4882a593Smuzhiyun #define Ep_Request	(USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)
1586*4882a593Smuzhiyun #define Ep_InRequest	(Ep_Request | USB_DIR_IN)
1587*4882a593Smuzhiyun 
1588*4882a593Smuzhiyun 
1589*4882a593Smuzhiyun /**
1590*4882a593Smuzhiyun  * handle_control_request() - handles all control transfers
1591*4882a593Smuzhiyun  * @dum_hcd: pointer to dummy (the_controller)
1592*4882a593Smuzhiyun  * @urb: the urb request to handle
1593*4882a593Smuzhiyun  * @setup: pointer to the setup data for a USB device control
1594*4882a593Smuzhiyun  *	 request
1595*4882a593Smuzhiyun  * @status: pointer to request handling status
1596*4882a593Smuzhiyun  *
1597*4882a593Smuzhiyun  * Return 0 - if the request was handled
1598*4882a593Smuzhiyun  *	  1 - if the request wasn't handles
1599*4882a593Smuzhiyun  *	  error code on error
1600*4882a593Smuzhiyun  */
handle_control_request(struct dummy_hcd * dum_hcd,struct urb * urb,struct usb_ctrlrequest * setup,int * status)1601*4882a593Smuzhiyun static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,
1602*4882a593Smuzhiyun 				  struct usb_ctrlrequest *setup,
1603*4882a593Smuzhiyun 				  int *status)
1604*4882a593Smuzhiyun {
1605*4882a593Smuzhiyun 	struct dummy_ep		*ep2;
1606*4882a593Smuzhiyun 	struct dummy		*dum = dum_hcd->dum;
1607*4882a593Smuzhiyun 	int			ret_val = 1;
1608*4882a593Smuzhiyun 	unsigned	w_index;
1609*4882a593Smuzhiyun 	unsigned	w_value;
1610*4882a593Smuzhiyun 
1611*4882a593Smuzhiyun 	w_index = le16_to_cpu(setup->wIndex);
1612*4882a593Smuzhiyun 	w_value = le16_to_cpu(setup->wValue);
1613*4882a593Smuzhiyun 	switch (setup->bRequest) {
1614*4882a593Smuzhiyun 	case USB_REQ_SET_ADDRESS:
1615*4882a593Smuzhiyun 		if (setup->bRequestType != Dev_Request)
1616*4882a593Smuzhiyun 			break;
1617*4882a593Smuzhiyun 		dum->address = w_value;
1618*4882a593Smuzhiyun 		*status = 0;
1619*4882a593Smuzhiyun 		dev_dbg(udc_dev(dum), "set_address = %d\n",
1620*4882a593Smuzhiyun 				w_value);
1621*4882a593Smuzhiyun 		ret_val = 0;
1622*4882a593Smuzhiyun 		break;
1623*4882a593Smuzhiyun 	case USB_REQ_SET_FEATURE:
1624*4882a593Smuzhiyun 		if (setup->bRequestType == Dev_Request) {
1625*4882a593Smuzhiyun 			ret_val = 0;
1626*4882a593Smuzhiyun 			switch (w_value) {
1627*4882a593Smuzhiyun 			case USB_DEVICE_REMOTE_WAKEUP:
1628*4882a593Smuzhiyun 				break;
1629*4882a593Smuzhiyun 			case USB_DEVICE_B_HNP_ENABLE:
1630*4882a593Smuzhiyun 				dum->gadget.b_hnp_enable = 1;
1631*4882a593Smuzhiyun 				break;
1632*4882a593Smuzhiyun 			case USB_DEVICE_A_HNP_SUPPORT:
1633*4882a593Smuzhiyun 				dum->gadget.a_hnp_support = 1;
1634*4882a593Smuzhiyun 				break;
1635*4882a593Smuzhiyun 			case USB_DEVICE_A_ALT_HNP_SUPPORT:
1636*4882a593Smuzhiyun 				dum->gadget.a_alt_hnp_support = 1;
1637*4882a593Smuzhiyun 				break;
1638*4882a593Smuzhiyun 			case USB_DEVICE_U1_ENABLE:
1639*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1640*4882a593Smuzhiyun 				    HCD_USB3)
1641*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_U1_ENABLED;
1642*4882a593Smuzhiyun 				else
1643*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1644*4882a593Smuzhiyun 				break;
1645*4882a593Smuzhiyun 			case USB_DEVICE_U2_ENABLE:
1646*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1647*4882a593Smuzhiyun 				    HCD_USB3)
1648*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_U2_ENABLED;
1649*4882a593Smuzhiyun 				else
1650*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1651*4882a593Smuzhiyun 				break;
1652*4882a593Smuzhiyun 			case USB_DEVICE_LTM_ENABLE:
1653*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1654*4882a593Smuzhiyun 				    HCD_USB3)
1655*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_LTM_ENABLED;
1656*4882a593Smuzhiyun 				else
1657*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1658*4882a593Smuzhiyun 				break;
1659*4882a593Smuzhiyun 			default:
1660*4882a593Smuzhiyun 				ret_val = -EOPNOTSUPP;
1661*4882a593Smuzhiyun 			}
1662*4882a593Smuzhiyun 			if (ret_val == 0) {
1663*4882a593Smuzhiyun 				dum->devstatus |= (1 << w_value);
1664*4882a593Smuzhiyun 				*status = 0;
1665*4882a593Smuzhiyun 			}
1666*4882a593Smuzhiyun 		} else if (setup->bRequestType == Ep_Request) {
1667*4882a593Smuzhiyun 			/* endpoint halt */
1668*4882a593Smuzhiyun 			ep2 = find_endpoint(dum, w_index);
1669*4882a593Smuzhiyun 			if (!ep2 || ep2->ep.name == ep0name) {
1670*4882a593Smuzhiyun 				ret_val = -EOPNOTSUPP;
1671*4882a593Smuzhiyun 				break;
1672*4882a593Smuzhiyun 			}
1673*4882a593Smuzhiyun 			ep2->halted = 1;
1674*4882a593Smuzhiyun 			ret_val = 0;
1675*4882a593Smuzhiyun 			*status = 0;
1676*4882a593Smuzhiyun 		}
1677*4882a593Smuzhiyun 		break;
1678*4882a593Smuzhiyun 	case USB_REQ_CLEAR_FEATURE:
1679*4882a593Smuzhiyun 		if (setup->bRequestType == Dev_Request) {
1680*4882a593Smuzhiyun 			ret_val = 0;
1681*4882a593Smuzhiyun 			switch (w_value) {
1682*4882a593Smuzhiyun 			case USB_DEVICE_REMOTE_WAKEUP:
1683*4882a593Smuzhiyun 				w_value = USB_DEVICE_REMOTE_WAKEUP;
1684*4882a593Smuzhiyun 				break;
1685*4882a593Smuzhiyun 			case USB_DEVICE_U1_ENABLE:
1686*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1687*4882a593Smuzhiyun 				    HCD_USB3)
1688*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_U1_ENABLED;
1689*4882a593Smuzhiyun 				else
1690*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1691*4882a593Smuzhiyun 				break;
1692*4882a593Smuzhiyun 			case USB_DEVICE_U2_ENABLE:
1693*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1694*4882a593Smuzhiyun 				    HCD_USB3)
1695*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_U2_ENABLED;
1696*4882a593Smuzhiyun 				else
1697*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1698*4882a593Smuzhiyun 				break;
1699*4882a593Smuzhiyun 			case USB_DEVICE_LTM_ENABLE:
1700*4882a593Smuzhiyun 				if (dummy_hcd_to_hcd(dum_hcd)->speed ==
1701*4882a593Smuzhiyun 				    HCD_USB3)
1702*4882a593Smuzhiyun 					w_value = USB_DEV_STAT_LTM_ENABLED;
1703*4882a593Smuzhiyun 				else
1704*4882a593Smuzhiyun 					ret_val = -EOPNOTSUPP;
1705*4882a593Smuzhiyun 				break;
1706*4882a593Smuzhiyun 			default:
1707*4882a593Smuzhiyun 				ret_val = -EOPNOTSUPP;
1708*4882a593Smuzhiyun 				break;
1709*4882a593Smuzhiyun 			}
1710*4882a593Smuzhiyun 			if (ret_val == 0) {
1711*4882a593Smuzhiyun 				dum->devstatus &= ~(1 << w_value);
1712*4882a593Smuzhiyun 				*status = 0;
1713*4882a593Smuzhiyun 			}
1714*4882a593Smuzhiyun 		} else if (setup->bRequestType == Ep_Request) {
1715*4882a593Smuzhiyun 			/* endpoint halt */
1716*4882a593Smuzhiyun 			ep2 = find_endpoint(dum, w_index);
1717*4882a593Smuzhiyun 			if (!ep2) {
1718*4882a593Smuzhiyun 				ret_val = -EOPNOTSUPP;
1719*4882a593Smuzhiyun 				break;
1720*4882a593Smuzhiyun 			}
1721*4882a593Smuzhiyun 			if (!ep2->wedged)
1722*4882a593Smuzhiyun 				ep2->halted = 0;
1723*4882a593Smuzhiyun 			ret_val = 0;
1724*4882a593Smuzhiyun 			*status = 0;
1725*4882a593Smuzhiyun 		}
1726*4882a593Smuzhiyun 		break;
1727*4882a593Smuzhiyun 	case USB_REQ_GET_STATUS:
1728*4882a593Smuzhiyun 		if (setup->bRequestType == Dev_InRequest
1729*4882a593Smuzhiyun 				|| setup->bRequestType == Intf_InRequest
1730*4882a593Smuzhiyun 				|| setup->bRequestType == Ep_InRequest) {
1731*4882a593Smuzhiyun 			char *buf;
1732*4882a593Smuzhiyun 			/*
1733*4882a593Smuzhiyun 			 * device: remote wakeup, selfpowered
1734*4882a593Smuzhiyun 			 * interface: nothing
1735*4882a593Smuzhiyun 			 * endpoint: halt
1736*4882a593Smuzhiyun 			 */
1737*4882a593Smuzhiyun 			buf = (char *)urb->transfer_buffer;
1738*4882a593Smuzhiyun 			if (urb->transfer_buffer_length > 0) {
1739*4882a593Smuzhiyun 				if (setup->bRequestType == Ep_InRequest) {
1740*4882a593Smuzhiyun 					ep2 = find_endpoint(dum, w_index);
1741*4882a593Smuzhiyun 					if (!ep2) {
1742*4882a593Smuzhiyun 						ret_val = -EOPNOTSUPP;
1743*4882a593Smuzhiyun 						break;
1744*4882a593Smuzhiyun 					}
1745*4882a593Smuzhiyun 					buf[0] = ep2->halted;
1746*4882a593Smuzhiyun 				} else if (setup->bRequestType ==
1747*4882a593Smuzhiyun 					   Dev_InRequest) {
1748*4882a593Smuzhiyun 					buf[0] = (u8)dum->devstatus;
1749*4882a593Smuzhiyun 				} else
1750*4882a593Smuzhiyun 					buf[0] = 0;
1751*4882a593Smuzhiyun 			}
1752*4882a593Smuzhiyun 			if (urb->transfer_buffer_length > 1)
1753*4882a593Smuzhiyun 				buf[1] = 0;
1754*4882a593Smuzhiyun 			urb->actual_length = min_t(u32, 2,
1755*4882a593Smuzhiyun 				urb->transfer_buffer_length);
1756*4882a593Smuzhiyun 			ret_val = 0;
1757*4882a593Smuzhiyun 			*status = 0;
1758*4882a593Smuzhiyun 		}
1759*4882a593Smuzhiyun 		break;
1760*4882a593Smuzhiyun 	}
1761*4882a593Smuzhiyun 	return ret_val;
1762*4882a593Smuzhiyun }
1763*4882a593Smuzhiyun 
1764*4882a593Smuzhiyun /* drive both sides of the transfers; looks like irq handlers to
1765*4882a593Smuzhiyun  * both drivers except the callbacks aren't in_irq().
1766*4882a593Smuzhiyun  */
dummy_timer(struct timer_list * t)1767*4882a593Smuzhiyun static void dummy_timer(struct timer_list *t)
1768*4882a593Smuzhiyun {
1769*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = from_timer(dum_hcd, t, timer);
1770*4882a593Smuzhiyun 	struct dummy		*dum = dum_hcd->dum;
1771*4882a593Smuzhiyun 	struct urbp		*urbp, *tmp;
1772*4882a593Smuzhiyun 	unsigned long		flags;
1773*4882a593Smuzhiyun 	int			limit, total;
1774*4882a593Smuzhiyun 	int			i;
1775*4882a593Smuzhiyun 
1776*4882a593Smuzhiyun 	/* simplistic model for one frame's bandwidth */
1777*4882a593Smuzhiyun 	/* FIXME: account for transaction and packet overhead */
1778*4882a593Smuzhiyun 	switch (dum->gadget.speed) {
1779*4882a593Smuzhiyun 	case USB_SPEED_LOW:
1780*4882a593Smuzhiyun 		total = 8/*bytes*/ * 12/*packets*/;
1781*4882a593Smuzhiyun 		break;
1782*4882a593Smuzhiyun 	case USB_SPEED_FULL:
1783*4882a593Smuzhiyun 		total = 64/*bytes*/ * 19/*packets*/;
1784*4882a593Smuzhiyun 		break;
1785*4882a593Smuzhiyun 	case USB_SPEED_HIGH:
1786*4882a593Smuzhiyun 		total = 512/*bytes*/ * 13/*packets*/ * 8/*uframes*/;
1787*4882a593Smuzhiyun 		break;
1788*4882a593Smuzhiyun 	case USB_SPEED_SUPER:
1789*4882a593Smuzhiyun 		/* Bus speed is 500000 bytes/ms, so use a little less */
1790*4882a593Smuzhiyun 		total = 490000;
1791*4882a593Smuzhiyun 		break;
1792*4882a593Smuzhiyun 	default:	/* Can't happen */
1793*4882a593Smuzhiyun 		dev_err(dummy_dev(dum_hcd), "bogus device speed\n");
1794*4882a593Smuzhiyun 		total = 0;
1795*4882a593Smuzhiyun 		break;
1796*4882a593Smuzhiyun 	}
1797*4882a593Smuzhiyun 
1798*4882a593Smuzhiyun 	/* FIXME if HZ != 1000 this will probably misbehave ... */
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun 	/* look at each urb queued by the host side driver */
1801*4882a593Smuzhiyun 	spin_lock_irqsave(&dum->lock, flags);
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun 	if (!dum_hcd->udev) {
1804*4882a593Smuzhiyun 		dev_err(dummy_dev(dum_hcd),
1805*4882a593Smuzhiyun 				"timer fired with no URBs pending?\n");
1806*4882a593Smuzhiyun 		spin_unlock_irqrestore(&dum->lock, flags);
1807*4882a593Smuzhiyun 		return;
1808*4882a593Smuzhiyun 	}
1809*4882a593Smuzhiyun 	dum_hcd->next_frame_urbp = NULL;
1810*4882a593Smuzhiyun 
1811*4882a593Smuzhiyun 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
1812*4882a593Smuzhiyun 		if (!ep_info[i].name)
1813*4882a593Smuzhiyun 			break;
1814*4882a593Smuzhiyun 		dum->ep[i].already_seen = 0;
1815*4882a593Smuzhiyun 	}
1816*4882a593Smuzhiyun 
1817*4882a593Smuzhiyun restart:
1818*4882a593Smuzhiyun 	list_for_each_entry_safe(urbp, tmp, &dum_hcd->urbp_list, urbp_list) {
1819*4882a593Smuzhiyun 		struct urb		*urb;
1820*4882a593Smuzhiyun 		struct dummy_request	*req;
1821*4882a593Smuzhiyun 		u8			address;
1822*4882a593Smuzhiyun 		struct dummy_ep		*ep = NULL;
1823*4882a593Smuzhiyun 		int			status = -EINPROGRESS;
1824*4882a593Smuzhiyun 
1825*4882a593Smuzhiyun 		/* stop when we reach URBs queued after the timer interrupt */
1826*4882a593Smuzhiyun 		if (urbp == dum_hcd->next_frame_urbp)
1827*4882a593Smuzhiyun 			break;
1828*4882a593Smuzhiyun 
1829*4882a593Smuzhiyun 		urb = urbp->urb;
1830*4882a593Smuzhiyun 		if (urb->unlinked)
1831*4882a593Smuzhiyun 			goto return_urb;
1832*4882a593Smuzhiyun 		else if (dum_hcd->rh_state != DUMMY_RH_RUNNING)
1833*4882a593Smuzhiyun 			continue;
1834*4882a593Smuzhiyun 
1835*4882a593Smuzhiyun 		/* Used up this frame's bandwidth? */
1836*4882a593Smuzhiyun 		if (total <= 0)
1837*4882a593Smuzhiyun 			continue;
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun 		/* find the gadget's ep for this request (if configured) */
1840*4882a593Smuzhiyun 		address = usb_pipeendpoint (urb->pipe);
1841*4882a593Smuzhiyun 		if (usb_urb_dir_in(urb))
1842*4882a593Smuzhiyun 			address |= USB_DIR_IN;
1843*4882a593Smuzhiyun 		ep = find_endpoint(dum, address);
1844*4882a593Smuzhiyun 		if (!ep) {
1845*4882a593Smuzhiyun 			/* set_configuration() disagreement */
1846*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd),
1847*4882a593Smuzhiyun 				"no ep configured for urb %p\n",
1848*4882a593Smuzhiyun 				urb);
1849*4882a593Smuzhiyun 			status = -EPROTO;
1850*4882a593Smuzhiyun 			goto return_urb;
1851*4882a593Smuzhiyun 		}
1852*4882a593Smuzhiyun 
1853*4882a593Smuzhiyun 		if (ep->already_seen)
1854*4882a593Smuzhiyun 			continue;
1855*4882a593Smuzhiyun 		ep->already_seen = 1;
1856*4882a593Smuzhiyun 		if (ep == &dum->ep[0] && urb->error_count) {
1857*4882a593Smuzhiyun 			ep->setup_stage = 1;	/* a new urb */
1858*4882a593Smuzhiyun 			urb->error_count = 0;
1859*4882a593Smuzhiyun 		}
1860*4882a593Smuzhiyun 		if (ep->halted && !ep->setup_stage) {
1861*4882a593Smuzhiyun 			/* NOTE: must not be iso! */
1862*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd), "ep %s halted, urb %p\n",
1863*4882a593Smuzhiyun 					ep->ep.name, urb);
1864*4882a593Smuzhiyun 			status = -EPIPE;
1865*4882a593Smuzhiyun 			goto return_urb;
1866*4882a593Smuzhiyun 		}
1867*4882a593Smuzhiyun 		/* FIXME make sure both ends agree on maxpacket */
1868*4882a593Smuzhiyun 
1869*4882a593Smuzhiyun 		/* handle control requests */
1870*4882a593Smuzhiyun 		if (ep == &dum->ep[0] && ep->setup_stage) {
1871*4882a593Smuzhiyun 			struct usb_ctrlrequest		setup;
1872*4882a593Smuzhiyun 			int				value = 1;
1873*4882a593Smuzhiyun 
1874*4882a593Smuzhiyun 			setup = *(struct usb_ctrlrequest *) urb->setup_packet;
1875*4882a593Smuzhiyun 			/* paranoia, in case of stale queued data */
1876*4882a593Smuzhiyun 			list_for_each_entry(req, &ep->queue, queue) {
1877*4882a593Smuzhiyun 				list_del_init(&req->queue);
1878*4882a593Smuzhiyun 				req->req.status = -EOVERFLOW;
1879*4882a593Smuzhiyun 				dev_dbg(udc_dev(dum), "stale req = %p\n",
1880*4882a593Smuzhiyun 						req);
1881*4882a593Smuzhiyun 
1882*4882a593Smuzhiyun 				spin_unlock(&dum->lock);
1883*4882a593Smuzhiyun 				usb_gadget_giveback_request(&ep->ep, &req->req);
1884*4882a593Smuzhiyun 				spin_lock(&dum->lock);
1885*4882a593Smuzhiyun 				ep->already_seen = 0;
1886*4882a593Smuzhiyun 				goto restart;
1887*4882a593Smuzhiyun 			}
1888*4882a593Smuzhiyun 
1889*4882a593Smuzhiyun 			/* gadget driver never sees set_address or operations
1890*4882a593Smuzhiyun 			 * on standard feature flags.  some hardware doesn't
1891*4882a593Smuzhiyun 			 * even expose them.
1892*4882a593Smuzhiyun 			 */
1893*4882a593Smuzhiyun 			ep->last_io = jiffies;
1894*4882a593Smuzhiyun 			ep->setup_stage = 0;
1895*4882a593Smuzhiyun 			ep->halted = 0;
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 			value = handle_control_request(dum_hcd, urb, &setup,
1898*4882a593Smuzhiyun 						       &status);
1899*4882a593Smuzhiyun 
1900*4882a593Smuzhiyun 			/* gadget driver handles all other requests.  block
1901*4882a593Smuzhiyun 			 * until setup() returns; no reentrancy issues etc.
1902*4882a593Smuzhiyun 			 */
1903*4882a593Smuzhiyun 			if (value > 0) {
1904*4882a593Smuzhiyun 				++dum->callback_usage;
1905*4882a593Smuzhiyun 				spin_unlock(&dum->lock);
1906*4882a593Smuzhiyun 				value = dum->driver->setup(&dum->gadget,
1907*4882a593Smuzhiyun 						&setup);
1908*4882a593Smuzhiyun 				spin_lock(&dum->lock);
1909*4882a593Smuzhiyun 				--dum->callback_usage;
1910*4882a593Smuzhiyun 
1911*4882a593Smuzhiyun 				if (value >= 0) {
1912*4882a593Smuzhiyun 					/* no delays (max 64KB data stage) */
1913*4882a593Smuzhiyun 					limit = 64*1024;
1914*4882a593Smuzhiyun 					goto treat_control_like_bulk;
1915*4882a593Smuzhiyun 				}
1916*4882a593Smuzhiyun 				/* error, see below */
1917*4882a593Smuzhiyun 			}
1918*4882a593Smuzhiyun 
1919*4882a593Smuzhiyun 			if (value < 0) {
1920*4882a593Smuzhiyun 				if (value != -EOPNOTSUPP)
1921*4882a593Smuzhiyun 					dev_dbg(udc_dev(dum),
1922*4882a593Smuzhiyun 						"setup --> %d\n",
1923*4882a593Smuzhiyun 						value);
1924*4882a593Smuzhiyun 				status = -EPIPE;
1925*4882a593Smuzhiyun 				urb->actual_length = 0;
1926*4882a593Smuzhiyun 			}
1927*4882a593Smuzhiyun 
1928*4882a593Smuzhiyun 			goto return_urb;
1929*4882a593Smuzhiyun 		}
1930*4882a593Smuzhiyun 
1931*4882a593Smuzhiyun 		/* non-control requests */
1932*4882a593Smuzhiyun 		limit = total;
1933*4882a593Smuzhiyun 		switch (usb_pipetype(urb->pipe)) {
1934*4882a593Smuzhiyun 		case PIPE_ISOCHRONOUS:
1935*4882a593Smuzhiyun 			/*
1936*4882a593Smuzhiyun 			 * We don't support isochronous.  But if we did,
1937*4882a593Smuzhiyun 			 * here are some of the issues we'd have to face:
1938*4882a593Smuzhiyun 			 *
1939*4882a593Smuzhiyun 			 * Is it urb->interval since the last xfer?
1940*4882a593Smuzhiyun 			 * Use urb->iso_frame_desc[i].
1941*4882a593Smuzhiyun 			 * Complete whether or not ep has requests queued.
1942*4882a593Smuzhiyun 			 * Report random errors, to debug drivers.
1943*4882a593Smuzhiyun 			 */
1944*4882a593Smuzhiyun 			limit = max(limit, periodic_bytes(dum, ep));
1945*4882a593Smuzhiyun 			status = -EINVAL;	/* fail all xfers */
1946*4882a593Smuzhiyun 			break;
1947*4882a593Smuzhiyun 
1948*4882a593Smuzhiyun 		case PIPE_INTERRUPT:
1949*4882a593Smuzhiyun 			/* FIXME is it urb->interval since the last xfer?
1950*4882a593Smuzhiyun 			 * this almost certainly polls too fast.
1951*4882a593Smuzhiyun 			 */
1952*4882a593Smuzhiyun 			limit = max(limit, periodic_bytes(dum, ep));
1953*4882a593Smuzhiyun 			fallthrough;
1954*4882a593Smuzhiyun 
1955*4882a593Smuzhiyun 		default:
1956*4882a593Smuzhiyun treat_control_like_bulk:
1957*4882a593Smuzhiyun 			ep->last_io = jiffies;
1958*4882a593Smuzhiyun 			total -= transfer(dum_hcd, urb, ep, limit, &status);
1959*4882a593Smuzhiyun 			break;
1960*4882a593Smuzhiyun 		}
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun 		/* incomplete transfer? */
1963*4882a593Smuzhiyun 		if (status == -EINPROGRESS)
1964*4882a593Smuzhiyun 			continue;
1965*4882a593Smuzhiyun 
1966*4882a593Smuzhiyun return_urb:
1967*4882a593Smuzhiyun 		list_del(&urbp->urbp_list);
1968*4882a593Smuzhiyun 		kfree(urbp);
1969*4882a593Smuzhiyun 		if (ep)
1970*4882a593Smuzhiyun 			ep->already_seen = ep->setup_stage = 0;
1971*4882a593Smuzhiyun 
1972*4882a593Smuzhiyun 		usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb);
1973*4882a593Smuzhiyun 		spin_unlock(&dum->lock);
1974*4882a593Smuzhiyun 		usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status);
1975*4882a593Smuzhiyun 		spin_lock(&dum->lock);
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun 		goto restart;
1978*4882a593Smuzhiyun 	}
1979*4882a593Smuzhiyun 
1980*4882a593Smuzhiyun 	if (list_empty(&dum_hcd->urbp_list)) {
1981*4882a593Smuzhiyun 		usb_put_dev(dum_hcd->udev);
1982*4882a593Smuzhiyun 		dum_hcd->udev = NULL;
1983*4882a593Smuzhiyun 	} else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
1984*4882a593Smuzhiyun 		/* want a 1 msec delay here */
1985*4882a593Smuzhiyun 		mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1));
1986*4882a593Smuzhiyun 	}
1987*4882a593Smuzhiyun 
1988*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum->lock, flags);
1989*4882a593Smuzhiyun }
1990*4882a593Smuzhiyun 
1991*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
1992*4882a593Smuzhiyun 
1993*4882a593Smuzhiyun #define PORT_C_MASK \
1994*4882a593Smuzhiyun 	((USB_PORT_STAT_C_CONNECTION \
1995*4882a593Smuzhiyun 	| USB_PORT_STAT_C_ENABLE \
1996*4882a593Smuzhiyun 	| USB_PORT_STAT_C_SUSPEND \
1997*4882a593Smuzhiyun 	| USB_PORT_STAT_C_OVERCURRENT \
1998*4882a593Smuzhiyun 	| USB_PORT_STAT_C_RESET) << 16)
1999*4882a593Smuzhiyun 
dummy_hub_status(struct usb_hcd * hcd,char * buf)2000*4882a593Smuzhiyun static int dummy_hub_status(struct usb_hcd *hcd, char *buf)
2001*4882a593Smuzhiyun {
2002*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd;
2003*4882a593Smuzhiyun 	unsigned long		flags;
2004*4882a593Smuzhiyun 	int			retval = 0;
2005*4882a593Smuzhiyun 
2006*4882a593Smuzhiyun 	dum_hcd = hcd_to_dummy_hcd(hcd);
2007*4882a593Smuzhiyun 
2008*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
2009*4882a593Smuzhiyun 	if (!HCD_HW_ACCESSIBLE(hcd))
2010*4882a593Smuzhiyun 		goto done;
2011*4882a593Smuzhiyun 
2012*4882a593Smuzhiyun 	if (dum_hcd->resuming && time_after_eq(jiffies, dum_hcd->re_timeout)) {
2013*4882a593Smuzhiyun 		dum_hcd->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
2014*4882a593Smuzhiyun 		dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND;
2015*4882a593Smuzhiyun 		set_link_state(dum_hcd);
2016*4882a593Smuzhiyun 	}
2017*4882a593Smuzhiyun 
2018*4882a593Smuzhiyun 	if ((dum_hcd->port_status & PORT_C_MASK) != 0) {
2019*4882a593Smuzhiyun 		*buf = (1 << 1);
2020*4882a593Smuzhiyun 		dev_dbg(dummy_dev(dum_hcd), "port status 0x%08x has changes\n",
2021*4882a593Smuzhiyun 				dum_hcd->port_status);
2022*4882a593Smuzhiyun 		retval = 1;
2023*4882a593Smuzhiyun 		if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED)
2024*4882a593Smuzhiyun 			usb_hcd_resume_root_hub(hcd);
2025*4882a593Smuzhiyun 	}
2026*4882a593Smuzhiyun done:
2027*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
2028*4882a593Smuzhiyun 	return retval;
2029*4882a593Smuzhiyun }
2030*4882a593Smuzhiyun 
2031*4882a593Smuzhiyun /* usb 3.0 root hub device descriptor */
2032*4882a593Smuzhiyun static struct {
2033*4882a593Smuzhiyun 	struct usb_bos_descriptor bos;
2034*4882a593Smuzhiyun 	struct usb_ss_cap_descriptor ss_cap;
2035*4882a593Smuzhiyun } __packed usb3_bos_desc = {
2036*4882a593Smuzhiyun 
2037*4882a593Smuzhiyun 	.bos = {
2038*4882a593Smuzhiyun 		.bLength		= USB_DT_BOS_SIZE,
2039*4882a593Smuzhiyun 		.bDescriptorType	= USB_DT_BOS,
2040*4882a593Smuzhiyun 		.wTotalLength		= cpu_to_le16(sizeof(usb3_bos_desc)),
2041*4882a593Smuzhiyun 		.bNumDeviceCaps		= 1,
2042*4882a593Smuzhiyun 	},
2043*4882a593Smuzhiyun 	.ss_cap = {
2044*4882a593Smuzhiyun 		.bLength		= USB_DT_USB_SS_CAP_SIZE,
2045*4882a593Smuzhiyun 		.bDescriptorType	= USB_DT_DEVICE_CAPABILITY,
2046*4882a593Smuzhiyun 		.bDevCapabilityType	= USB_SS_CAP_TYPE,
2047*4882a593Smuzhiyun 		.wSpeedSupported	= cpu_to_le16(USB_5GBPS_OPERATION),
2048*4882a593Smuzhiyun 		.bFunctionalitySupport	= ilog2(USB_5GBPS_OPERATION),
2049*4882a593Smuzhiyun 	},
2050*4882a593Smuzhiyun };
2051*4882a593Smuzhiyun 
2052*4882a593Smuzhiyun static inline void
ss_hub_descriptor(struct usb_hub_descriptor * desc)2053*4882a593Smuzhiyun ss_hub_descriptor(struct usb_hub_descriptor *desc)
2054*4882a593Smuzhiyun {
2055*4882a593Smuzhiyun 	memset(desc, 0, sizeof *desc);
2056*4882a593Smuzhiyun 	desc->bDescriptorType = USB_DT_SS_HUB;
2057*4882a593Smuzhiyun 	desc->bDescLength = 12;
2058*4882a593Smuzhiyun 	desc->wHubCharacteristics = cpu_to_le16(
2059*4882a593Smuzhiyun 			HUB_CHAR_INDV_PORT_LPSM |
2060*4882a593Smuzhiyun 			HUB_CHAR_COMMON_OCPM);
2061*4882a593Smuzhiyun 	desc->bNbrPorts = 1;
2062*4882a593Smuzhiyun 	desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
2063*4882a593Smuzhiyun 	desc->u.ss.DeviceRemovable = 0;
2064*4882a593Smuzhiyun }
2065*4882a593Smuzhiyun 
hub_descriptor(struct usb_hub_descriptor * desc)2066*4882a593Smuzhiyun static inline void hub_descriptor(struct usb_hub_descriptor *desc)
2067*4882a593Smuzhiyun {
2068*4882a593Smuzhiyun 	memset(desc, 0, sizeof *desc);
2069*4882a593Smuzhiyun 	desc->bDescriptorType = USB_DT_HUB;
2070*4882a593Smuzhiyun 	desc->bDescLength = 9;
2071*4882a593Smuzhiyun 	desc->wHubCharacteristics = cpu_to_le16(
2072*4882a593Smuzhiyun 			HUB_CHAR_INDV_PORT_LPSM |
2073*4882a593Smuzhiyun 			HUB_CHAR_COMMON_OCPM);
2074*4882a593Smuzhiyun 	desc->bNbrPorts = 1;
2075*4882a593Smuzhiyun 	desc->u.hs.DeviceRemovable[0] = 0;
2076*4882a593Smuzhiyun 	desc->u.hs.DeviceRemovable[1] = 0xff;	/* PortPwrCtrlMask */
2077*4882a593Smuzhiyun }
2078*4882a593Smuzhiyun 
dummy_hub_control(struct usb_hcd * hcd,u16 typeReq,u16 wValue,u16 wIndex,char * buf,u16 wLength)2079*4882a593Smuzhiyun static int dummy_hub_control(
2080*4882a593Smuzhiyun 	struct usb_hcd	*hcd,
2081*4882a593Smuzhiyun 	u16		typeReq,
2082*4882a593Smuzhiyun 	u16		wValue,
2083*4882a593Smuzhiyun 	u16		wIndex,
2084*4882a593Smuzhiyun 	char		*buf,
2085*4882a593Smuzhiyun 	u16		wLength
2086*4882a593Smuzhiyun ) {
2087*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd;
2088*4882a593Smuzhiyun 	int		retval = 0;
2089*4882a593Smuzhiyun 	unsigned long	flags;
2090*4882a593Smuzhiyun 
2091*4882a593Smuzhiyun 	if (!HCD_HW_ACCESSIBLE(hcd))
2092*4882a593Smuzhiyun 		return -ETIMEDOUT;
2093*4882a593Smuzhiyun 
2094*4882a593Smuzhiyun 	dum_hcd = hcd_to_dummy_hcd(hcd);
2095*4882a593Smuzhiyun 
2096*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
2097*4882a593Smuzhiyun 	switch (typeReq) {
2098*4882a593Smuzhiyun 	case ClearHubFeature:
2099*4882a593Smuzhiyun 		break;
2100*4882a593Smuzhiyun 	case ClearPortFeature:
2101*4882a593Smuzhiyun 		switch (wValue) {
2102*4882a593Smuzhiyun 		case USB_PORT_FEAT_SUSPEND:
2103*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3) {
2104*4882a593Smuzhiyun 				dev_dbg(dummy_dev(dum_hcd),
2105*4882a593Smuzhiyun 					 "USB_PORT_FEAT_SUSPEND req not "
2106*4882a593Smuzhiyun 					 "supported for USB 3.0 roothub\n");
2107*4882a593Smuzhiyun 				goto error;
2108*4882a593Smuzhiyun 			}
2109*4882a593Smuzhiyun 			if (dum_hcd->port_status & USB_PORT_STAT_SUSPEND) {
2110*4882a593Smuzhiyun 				/* 20msec resume signaling */
2111*4882a593Smuzhiyun 				dum_hcd->resuming = 1;
2112*4882a593Smuzhiyun 				dum_hcd->re_timeout = jiffies +
2113*4882a593Smuzhiyun 						msecs_to_jiffies(20);
2114*4882a593Smuzhiyun 			}
2115*4882a593Smuzhiyun 			break;
2116*4882a593Smuzhiyun 		case USB_PORT_FEAT_POWER:
2117*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd), "power-off\n");
2118*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3)
2119*4882a593Smuzhiyun 				dum_hcd->port_status &= ~USB_SS_PORT_STAT_POWER;
2120*4882a593Smuzhiyun 			else
2121*4882a593Smuzhiyun 				dum_hcd->port_status &= ~USB_PORT_STAT_POWER;
2122*4882a593Smuzhiyun 			set_link_state(dum_hcd);
2123*4882a593Smuzhiyun 			break;
2124*4882a593Smuzhiyun 		case USB_PORT_FEAT_ENABLE:
2125*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_ENABLE:
2126*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_SUSPEND:
2127*4882a593Smuzhiyun 			/* Not allowed for USB-3 */
2128*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3)
2129*4882a593Smuzhiyun 				goto error;
2130*4882a593Smuzhiyun 			fallthrough;
2131*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_CONNECTION:
2132*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_RESET:
2133*4882a593Smuzhiyun 			dum_hcd->port_status &= ~(1 << wValue);
2134*4882a593Smuzhiyun 			set_link_state(dum_hcd);
2135*4882a593Smuzhiyun 			break;
2136*4882a593Smuzhiyun 		default:
2137*4882a593Smuzhiyun 		/* Disallow INDICATOR and C_OVER_CURRENT */
2138*4882a593Smuzhiyun 			goto error;
2139*4882a593Smuzhiyun 		}
2140*4882a593Smuzhiyun 		break;
2141*4882a593Smuzhiyun 	case GetHubDescriptor:
2142*4882a593Smuzhiyun 		if (hcd->speed == HCD_USB3 &&
2143*4882a593Smuzhiyun 				(wLength < USB_DT_SS_HUB_SIZE ||
2144*4882a593Smuzhiyun 				 wValue != (USB_DT_SS_HUB << 8))) {
2145*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd),
2146*4882a593Smuzhiyun 				"Wrong hub descriptor type for "
2147*4882a593Smuzhiyun 				"USB 3.0 roothub.\n");
2148*4882a593Smuzhiyun 			goto error;
2149*4882a593Smuzhiyun 		}
2150*4882a593Smuzhiyun 		if (hcd->speed == HCD_USB3)
2151*4882a593Smuzhiyun 			ss_hub_descriptor((struct usb_hub_descriptor *) buf);
2152*4882a593Smuzhiyun 		else
2153*4882a593Smuzhiyun 			hub_descriptor((struct usb_hub_descriptor *) buf);
2154*4882a593Smuzhiyun 		break;
2155*4882a593Smuzhiyun 
2156*4882a593Smuzhiyun 	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
2157*4882a593Smuzhiyun 		if (hcd->speed != HCD_USB3)
2158*4882a593Smuzhiyun 			goto error;
2159*4882a593Smuzhiyun 
2160*4882a593Smuzhiyun 		if ((wValue >> 8) != USB_DT_BOS)
2161*4882a593Smuzhiyun 			goto error;
2162*4882a593Smuzhiyun 
2163*4882a593Smuzhiyun 		memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc));
2164*4882a593Smuzhiyun 		retval = sizeof(usb3_bos_desc);
2165*4882a593Smuzhiyun 		break;
2166*4882a593Smuzhiyun 
2167*4882a593Smuzhiyun 	case GetHubStatus:
2168*4882a593Smuzhiyun 		*(__le32 *) buf = cpu_to_le32(0);
2169*4882a593Smuzhiyun 		break;
2170*4882a593Smuzhiyun 	case GetPortStatus:
2171*4882a593Smuzhiyun 		if (wIndex != 1)
2172*4882a593Smuzhiyun 			retval = -EPIPE;
2173*4882a593Smuzhiyun 
2174*4882a593Smuzhiyun 		/* whoever resets or resumes must GetPortStatus to
2175*4882a593Smuzhiyun 		 * complete it!!
2176*4882a593Smuzhiyun 		 */
2177*4882a593Smuzhiyun 		if (dum_hcd->resuming &&
2178*4882a593Smuzhiyun 				time_after_eq(jiffies, dum_hcd->re_timeout)) {
2179*4882a593Smuzhiyun 			dum_hcd->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
2180*4882a593Smuzhiyun 			dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND;
2181*4882a593Smuzhiyun 		}
2182*4882a593Smuzhiyun 		if ((dum_hcd->port_status & USB_PORT_STAT_RESET) != 0 &&
2183*4882a593Smuzhiyun 				time_after_eq(jiffies, dum_hcd->re_timeout)) {
2184*4882a593Smuzhiyun 			dum_hcd->port_status |= (USB_PORT_STAT_C_RESET << 16);
2185*4882a593Smuzhiyun 			dum_hcd->port_status &= ~USB_PORT_STAT_RESET;
2186*4882a593Smuzhiyun 			if (dum_hcd->dum->pullup) {
2187*4882a593Smuzhiyun 				dum_hcd->port_status |= USB_PORT_STAT_ENABLE;
2188*4882a593Smuzhiyun 
2189*4882a593Smuzhiyun 				if (hcd->speed < HCD_USB3) {
2190*4882a593Smuzhiyun 					switch (dum_hcd->dum->gadget.speed) {
2191*4882a593Smuzhiyun 					case USB_SPEED_HIGH:
2192*4882a593Smuzhiyun 						dum_hcd->port_status |=
2193*4882a593Smuzhiyun 						      USB_PORT_STAT_HIGH_SPEED;
2194*4882a593Smuzhiyun 						break;
2195*4882a593Smuzhiyun 					case USB_SPEED_LOW:
2196*4882a593Smuzhiyun 						dum_hcd->dum->gadget.ep0->
2197*4882a593Smuzhiyun 							maxpacket = 8;
2198*4882a593Smuzhiyun 						dum_hcd->port_status |=
2199*4882a593Smuzhiyun 							USB_PORT_STAT_LOW_SPEED;
2200*4882a593Smuzhiyun 						break;
2201*4882a593Smuzhiyun 					default:
2202*4882a593Smuzhiyun 						break;
2203*4882a593Smuzhiyun 					}
2204*4882a593Smuzhiyun 				}
2205*4882a593Smuzhiyun 			}
2206*4882a593Smuzhiyun 		}
2207*4882a593Smuzhiyun 		set_link_state(dum_hcd);
2208*4882a593Smuzhiyun 		((__le16 *) buf)[0] = cpu_to_le16(dum_hcd->port_status);
2209*4882a593Smuzhiyun 		((__le16 *) buf)[1] = cpu_to_le16(dum_hcd->port_status >> 16);
2210*4882a593Smuzhiyun 		break;
2211*4882a593Smuzhiyun 	case SetHubFeature:
2212*4882a593Smuzhiyun 		retval = -EPIPE;
2213*4882a593Smuzhiyun 		break;
2214*4882a593Smuzhiyun 	case SetPortFeature:
2215*4882a593Smuzhiyun 		switch (wValue) {
2216*4882a593Smuzhiyun 		case USB_PORT_FEAT_LINK_STATE:
2217*4882a593Smuzhiyun 			if (hcd->speed != HCD_USB3) {
2218*4882a593Smuzhiyun 				dev_dbg(dummy_dev(dum_hcd),
2219*4882a593Smuzhiyun 					 "USB_PORT_FEAT_LINK_STATE req not "
2220*4882a593Smuzhiyun 					 "supported for USB 2.0 roothub\n");
2221*4882a593Smuzhiyun 				goto error;
2222*4882a593Smuzhiyun 			}
2223*4882a593Smuzhiyun 			/*
2224*4882a593Smuzhiyun 			 * Since this is dummy we don't have an actual link so
2225*4882a593Smuzhiyun 			 * there is nothing to do for the SET_LINK_STATE cmd
2226*4882a593Smuzhiyun 			 */
2227*4882a593Smuzhiyun 			break;
2228*4882a593Smuzhiyun 		case USB_PORT_FEAT_U1_TIMEOUT:
2229*4882a593Smuzhiyun 		case USB_PORT_FEAT_U2_TIMEOUT:
2230*4882a593Smuzhiyun 			/* TODO: add suspend/resume support! */
2231*4882a593Smuzhiyun 			if (hcd->speed != HCD_USB3) {
2232*4882a593Smuzhiyun 				dev_dbg(dummy_dev(dum_hcd),
2233*4882a593Smuzhiyun 					 "USB_PORT_FEAT_U1/2_TIMEOUT req not "
2234*4882a593Smuzhiyun 					 "supported for USB 2.0 roothub\n");
2235*4882a593Smuzhiyun 				goto error;
2236*4882a593Smuzhiyun 			}
2237*4882a593Smuzhiyun 			break;
2238*4882a593Smuzhiyun 		case USB_PORT_FEAT_SUSPEND:
2239*4882a593Smuzhiyun 			/* Applicable only for USB2.0 hub */
2240*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3) {
2241*4882a593Smuzhiyun 				dev_dbg(dummy_dev(dum_hcd),
2242*4882a593Smuzhiyun 					 "USB_PORT_FEAT_SUSPEND req not "
2243*4882a593Smuzhiyun 					 "supported for USB 3.0 roothub\n");
2244*4882a593Smuzhiyun 				goto error;
2245*4882a593Smuzhiyun 			}
2246*4882a593Smuzhiyun 			if (dum_hcd->active) {
2247*4882a593Smuzhiyun 				dum_hcd->port_status |= USB_PORT_STAT_SUSPEND;
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun 				/* HNP would happen here; for now we
2250*4882a593Smuzhiyun 				 * assume b_bus_req is always true.
2251*4882a593Smuzhiyun 				 */
2252*4882a593Smuzhiyun 				set_link_state(dum_hcd);
2253*4882a593Smuzhiyun 				if (((1 << USB_DEVICE_B_HNP_ENABLE)
2254*4882a593Smuzhiyun 						& dum_hcd->dum->devstatus) != 0)
2255*4882a593Smuzhiyun 					dev_dbg(dummy_dev(dum_hcd),
2256*4882a593Smuzhiyun 							"no HNP yet!\n");
2257*4882a593Smuzhiyun 			}
2258*4882a593Smuzhiyun 			break;
2259*4882a593Smuzhiyun 		case USB_PORT_FEAT_POWER:
2260*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3)
2261*4882a593Smuzhiyun 				dum_hcd->port_status |= USB_SS_PORT_STAT_POWER;
2262*4882a593Smuzhiyun 			else
2263*4882a593Smuzhiyun 				dum_hcd->port_status |= USB_PORT_STAT_POWER;
2264*4882a593Smuzhiyun 			set_link_state(dum_hcd);
2265*4882a593Smuzhiyun 			break;
2266*4882a593Smuzhiyun 		case USB_PORT_FEAT_BH_PORT_RESET:
2267*4882a593Smuzhiyun 			/* Applicable only for USB3.0 hub */
2268*4882a593Smuzhiyun 			if (hcd->speed != HCD_USB3) {
2269*4882a593Smuzhiyun 				dev_dbg(dummy_dev(dum_hcd),
2270*4882a593Smuzhiyun 					 "USB_PORT_FEAT_BH_PORT_RESET req not "
2271*4882a593Smuzhiyun 					 "supported for USB 2.0 roothub\n");
2272*4882a593Smuzhiyun 				goto error;
2273*4882a593Smuzhiyun 			}
2274*4882a593Smuzhiyun 			fallthrough;
2275*4882a593Smuzhiyun 		case USB_PORT_FEAT_RESET:
2276*4882a593Smuzhiyun 			if (!(dum_hcd->port_status & USB_PORT_STAT_CONNECTION))
2277*4882a593Smuzhiyun 				break;
2278*4882a593Smuzhiyun 			/* if it's already enabled, disable */
2279*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3) {
2280*4882a593Smuzhiyun 				dum_hcd->port_status =
2281*4882a593Smuzhiyun 					(USB_SS_PORT_STAT_POWER |
2282*4882a593Smuzhiyun 					 USB_PORT_STAT_CONNECTION |
2283*4882a593Smuzhiyun 					 USB_PORT_STAT_RESET);
2284*4882a593Smuzhiyun 			} else {
2285*4882a593Smuzhiyun 				dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE
2286*4882a593Smuzhiyun 					| USB_PORT_STAT_LOW_SPEED
2287*4882a593Smuzhiyun 					| USB_PORT_STAT_HIGH_SPEED);
2288*4882a593Smuzhiyun 				dum_hcd->port_status |= USB_PORT_STAT_RESET;
2289*4882a593Smuzhiyun 			}
2290*4882a593Smuzhiyun 			/*
2291*4882a593Smuzhiyun 			 * We want to reset device status. All but the
2292*4882a593Smuzhiyun 			 * Self powered feature
2293*4882a593Smuzhiyun 			 */
2294*4882a593Smuzhiyun 			dum_hcd->dum->devstatus &=
2295*4882a593Smuzhiyun 				(1 << USB_DEVICE_SELF_POWERED);
2296*4882a593Smuzhiyun 			/*
2297*4882a593Smuzhiyun 			 * FIXME USB3.0: what is the correct reset signaling
2298*4882a593Smuzhiyun 			 * interval? Is it still 50msec as for HS?
2299*4882a593Smuzhiyun 			 */
2300*4882a593Smuzhiyun 			dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
2301*4882a593Smuzhiyun 			set_link_state(dum_hcd);
2302*4882a593Smuzhiyun 			break;
2303*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_CONNECTION:
2304*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_RESET:
2305*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_ENABLE:
2306*4882a593Smuzhiyun 		case USB_PORT_FEAT_C_SUSPEND:
2307*4882a593Smuzhiyun 			/* Not allowed for USB-3, and ignored for USB-2 */
2308*4882a593Smuzhiyun 			if (hcd->speed == HCD_USB3)
2309*4882a593Smuzhiyun 				goto error;
2310*4882a593Smuzhiyun 			break;
2311*4882a593Smuzhiyun 		default:
2312*4882a593Smuzhiyun 		/* Disallow TEST, INDICATOR, and C_OVER_CURRENT */
2313*4882a593Smuzhiyun 			goto error;
2314*4882a593Smuzhiyun 		}
2315*4882a593Smuzhiyun 		break;
2316*4882a593Smuzhiyun 	case GetPortErrorCount:
2317*4882a593Smuzhiyun 		if (hcd->speed != HCD_USB3) {
2318*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd),
2319*4882a593Smuzhiyun 				 "GetPortErrorCount req not "
2320*4882a593Smuzhiyun 				 "supported for USB 2.0 roothub\n");
2321*4882a593Smuzhiyun 			goto error;
2322*4882a593Smuzhiyun 		}
2323*4882a593Smuzhiyun 		/* We'll always return 0 since this is a dummy hub */
2324*4882a593Smuzhiyun 		*(__le32 *) buf = cpu_to_le32(0);
2325*4882a593Smuzhiyun 		break;
2326*4882a593Smuzhiyun 	case SetHubDepth:
2327*4882a593Smuzhiyun 		if (hcd->speed != HCD_USB3) {
2328*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd),
2329*4882a593Smuzhiyun 				 "SetHubDepth req not supported for "
2330*4882a593Smuzhiyun 				 "USB 2.0 roothub\n");
2331*4882a593Smuzhiyun 			goto error;
2332*4882a593Smuzhiyun 		}
2333*4882a593Smuzhiyun 		break;
2334*4882a593Smuzhiyun 	default:
2335*4882a593Smuzhiyun 		dev_dbg(dummy_dev(dum_hcd),
2336*4882a593Smuzhiyun 			"hub control req%04x v%04x i%04x l%d\n",
2337*4882a593Smuzhiyun 			typeReq, wValue, wIndex, wLength);
2338*4882a593Smuzhiyun error:
2339*4882a593Smuzhiyun 		/* "protocol stall" on error */
2340*4882a593Smuzhiyun 		retval = -EPIPE;
2341*4882a593Smuzhiyun 	}
2342*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
2343*4882a593Smuzhiyun 
2344*4882a593Smuzhiyun 	if ((dum_hcd->port_status & PORT_C_MASK) != 0)
2345*4882a593Smuzhiyun 		usb_hcd_poll_rh_status(hcd);
2346*4882a593Smuzhiyun 	return retval;
2347*4882a593Smuzhiyun }
2348*4882a593Smuzhiyun 
dummy_bus_suspend(struct usb_hcd * hcd)2349*4882a593Smuzhiyun static int dummy_bus_suspend(struct usb_hcd *hcd)
2350*4882a593Smuzhiyun {
2351*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
2352*4882a593Smuzhiyun 
2353*4882a593Smuzhiyun 	dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 	spin_lock_irq(&dum_hcd->dum->lock);
2356*4882a593Smuzhiyun 	dum_hcd->rh_state = DUMMY_RH_SUSPENDED;
2357*4882a593Smuzhiyun 	set_link_state(dum_hcd);
2358*4882a593Smuzhiyun 	hcd->state = HC_STATE_SUSPENDED;
2359*4882a593Smuzhiyun 	spin_unlock_irq(&dum_hcd->dum->lock);
2360*4882a593Smuzhiyun 	return 0;
2361*4882a593Smuzhiyun }
2362*4882a593Smuzhiyun 
dummy_bus_resume(struct usb_hcd * hcd)2363*4882a593Smuzhiyun static int dummy_bus_resume(struct usb_hcd *hcd)
2364*4882a593Smuzhiyun {
2365*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
2366*4882a593Smuzhiyun 	int rc = 0;
2367*4882a593Smuzhiyun 
2368*4882a593Smuzhiyun 	dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
2369*4882a593Smuzhiyun 
2370*4882a593Smuzhiyun 	spin_lock_irq(&dum_hcd->dum->lock);
2371*4882a593Smuzhiyun 	if (!HCD_HW_ACCESSIBLE(hcd)) {
2372*4882a593Smuzhiyun 		rc = -ESHUTDOWN;
2373*4882a593Smuzhiyun 	} else {
2374*4882a593Smuzhiyun 		dum_hcd->rh_state = DUMMY_RH_RUNNING;
2375*4882a593Smuzhiyun 		set_link_state(dum_hcd);
2376*4882a593Smuzhiyun 		if (!list_empty(&dum_hcd->urbp_list))
2377*4882a593Smuzhiyun 			mod_timer(&dum_hcd->timer, jiffies);
2378*4882a593Smuzhiyun 		hcd->state = HC_STATE_RUNNING;
2379*4882a593Smuzhiyun 	}
2380*4882a593Smuzhiyun 	spin_unlock_irq(&dum_hcd->dum->lock);
2381*4882a593Smuzhiyun 	return rc;
2382*4882a593Smuzhiyun }
2383*4882a593Smuzhiyun 
2384*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
2385*4882a593Smuzhiyun 
show_urb(char * buf,size_t size,struct urb * urb)2386*4882a593Smuzhiyun static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb)
2387*4882a593Smuzhiyun {
2388*4882a593Smuzhiyun 	int ep = usb_pipeendpoint(urb->pipe);
2389*4882a593Smuzhiyun 
2390*4882a593Smuzhiyun 	return scnprintf(buf, size,
2391*4882a593Smuzhiyun 		"urb/%p %s ep%d%s%s len %d/%d\n",
2392*4882a593Smuzhiyun 		urb,
2393*4882a593Smuzhiyun 		({ char *s;
2394*4882a593Smuzhiyun 		switch (urb->dev->speed) {
2395*4882a593Smuzhiyun 		case USB_SPEED_LOW:
2396*4882a593Smuzhiyun 			s = "ls";
2397*4882a593Smuzhiyun 			break;
2398*4882a593Smuzhiyun 		case USB_SPEED_FULL:
2399*4882a593Smuzhiyun 			s = "fs";
2400*4882a593Smuzhiyun 			break;
2401*4882a593Smuzhiyun 		case USB_SPEED_HIGH:
2402*4882a593Smuzhiyun 			s = "hs";
2403*4882a593Smuzhiyun 			break;
2404*4882a593Smuzhiyun 		case USB_SPEED_SUPER:
2405*4882a593Smuzhiyun 			s = "ss";
2406*4882a593Smuzhiyun 			break;
2407*4882a593Smuzhiyun 		default:
2408*4882a593Smuzhiyun 			s = "?";
2409*4882a593Smuzhiyun 			break;
2410*4882a593Smuzhiyun 		 } s; }),
2411*4882a593Smuzhiyun 		ep, ep ? (usb_urb_dir_in(urb) ? "in" : "out") : "",
2412*4882a593Smuzhiyun 		({ char *s; \
2413*4882a593Smuzhiyun 		switch (usb_pipetype(urb->pipe)) { \
2414*4882a593Smuzhiyun 		case PIPE_CONTROL: \
2415*4882a593Smuzhiyun 			s = ""; \
2416*4882a593Smuzhiyun 			break; \
2417*4882a593Smuzhiyun 		case PIPE_BULK: \
2418*4882a593Smuzhiyun 			s = "-bulk"; \
2419*4882a593Smuzhiyun 			break; \
2420*4882a593Smuzhiyun 		case PIPE_INTERRUPT: \
2421*4882a593Smuzhiyun 			s = "-int"; \
2422*4882a593Smuzhiyun 			break; \
2423*4882a593Smuzhiyun 		default: \
2424*4882a593Smuzhiyun 			s = "-iso"; \
2425*4882a593Smuzhiyun 			break; \
2426*4882a593Smuzhiyun 		} s; }),
2427*4882a593Smuzhiyun 		urb->actual_length, urb->transfer_buffer_length);
2428*4882a593Smuzhiyun }
2429*4882a593Smuzhiyun 
urbs_show(struct device * dev,struct device_attribute * attr,char * buf)2430*4882a593Smuzhiyun static ssize_t urbs_show(struct device *dev, struct device_attribute *attr,
2431*4882a593Smuzhiyun 		char *buf)
2432*4882a593Smuzhiyun {
2433*4882a593Smuzhiyun 	struct usb_hcd		*hcd = dev_get_drvdata(dev);
2434*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = hcd_to_dummy_hcd(hcd);
2435*4882a593Smuzhiyun 	struct urbp		*urbp;
2436*4882a593Smuzhiyun 	size_t			size = 0;
2437*4882a593Smuzhiyun 	unsigned long		flags;
2438*4882a593Smuzhiyun 
2439*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
2440*4882a593Smuzhiyun 	list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) {
2441*4882a593Smuzhiyun 		size_t		temp;
2442*4882a593Smuzhiyun 
2443*4882a593Smuzhiyun 		temp = show_urb(buf, PAGE_SIZE - size, urbp->urb);
2444*4882a593Smuzhiyun 		buf += temp;
2445*4882a593Smuzhiyun 		size += temp;
2446*4882a593Smuzhiyun 	}
2447*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
2448*4882a593Smuzhiyun 
2449*4882a593Smuzhiyun 	return size;
2450*4882a593Smuzhiyun }
2451*4882a593Smuzhiyun static DEVICE_ATTR_RO(urbs);
2452*4882a593Smuzhiyun 
dummy_start_ss(struct dummy_hcd * dum_hcd)2453*4882a593Smuzhiyun static int dummy_start_ss(struct dummy_hcd *dum_hcd)
2454*4882a593Smuzhiyun {
2455*4882a593Smuzhiyun 	timer_setup(&dum_hcd->timer, dummy_timer, 0);
2456*4882a593Smuzhiyun 	dum_hcd->rh_state = DUMMY_RH_RUNNING;
2457*4882a593Smuzhiyun 	dum_hcd->stream_en_ep = 0;
2458*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dum_hcd->urbp_list);
2459*4882a593Smuzhiyun 	dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET_3;
2460*4882a593Smuzhiyun 	dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING;
2461*4882a593Smuzhiyun 	dummy_hcd_to_hcd(dum_hcd)->uses_new_polling = 1;
2462*4882a593Smuzhiyun #ifdef CONFIG_USB_OTG
2463*4882a593Smuzhiyun 	dummy_hcd_to_hcd(dum_hcd)->self.otg_port = 1;
2464*4882a593Smuzhiyun #endif
2465*4882a593Smuzhiyun 	return 0;
2466*4882a593Smuzhiyun 
2467*4882a593Smuzhiyun 	/* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
2468*4882a593Smuzhiyun 	return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs);
2469*4882a593Smuzhiyun }
2470*4882a593Smuzhiyun 
dummy_start(struct usb_hcd * hcd)2471*4882a593Smuzhiyun static int dummy_start(struct usb_hcd *hcd)
2472*4882a593Smuzhiyun {
2473*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd = hcd_to_dummy_hcd(hcd);
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	/*
2476*4882a593Smuzhiyun 	 * HOST side init ... we emulate a root hub that'll only ever
2477*4882a593Smuzhiyun 	 * talk to one device (the gadget side).  Also appears in sysfs,
2478*4882a593Smuzhiyun 	 * just like more familiar pci-based HCDs.
2479*4882a593Smuzhiyun 	 */
2480*4882a593Smuzhiyun 	if (!usb_hcd_is_primary_hcd(hcd))
2481*4882a593Smuzhiyun 		return dummy_start_ss(dum_hcd);
2482*4882a593Smuzhiyun 
2483*4882a593Smuzhiyun 	spin_lock_init(&dum_hcd->dum->lock);
2484*4882a593Smuzhiyun 	timer_setup(&dum_hcd->timer, dummy_timer, 0);
2485*4882a593Smuzhiyun 	dum_hcd->rh_state = DUMMY_RH_RUNNING;
2486*4882a593Smuzhiyun 
2487*4882a593Smuzhiyun 	INIT_LIST_HEAD(&dum_hcd->urbp_list);
2488*4882a593Smuzhiyun 
2489*4882a593Smuzhiyun 	hcd->power_budget = POWER_BUDGET;
2490*4882a593Smuzhiyun 	hcd->state = HC_STATE_RUNNING;
2491*4882a593Smuzhiyun 	hcd->uses_new_polling = 1;
2492*4882a593Smuzhiyun 
2493*4882a593Smuzhiyun #ifdef CONFIG_USB_OTG
2494*4882a593Smuzhiyun 	hcd->self.otg_port = 1;
2495*4882a593Smuzhiyun #endif
2496*4882a593Smuzhiyun 
2497*4882a593Smuzhiyun 	/* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
2498*4882a593Smuzhiyun 	return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs);
2499*4882a593Smuzhiyun }
2500*4882a593Smuzhiyun 
dummy_stop(struct usb_hcd * hcd)2501*4882a593Smuzhiyun static void dummy_stop(struct usb_hcd *hcd)
2502*4882a593Smuzhiyun {
2503*4882a593Smuzhiyun 	device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs);
2504*4882a593Smuzhiyun 	dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n");
2505*4882a593Smuzhiyun }
2506*4882a593Smuzhiyun 
2507*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
2508*4882a593Smuzhiyun 
dummy_h_get_frame(struct usb_hcd * hcd)2509*4882a593Smuzhiyun static int dummy_h_get_frame(struct usb_hcd *hcd)
2510*4882a593Smuzhiyun {
2511*4882a593Smuzhiyun 	return dummy_g_get_frame(NULL);
2512*4882a593Smuzhiyun }
2513*4882a593Smuzhiyun 
dummy_setup(struct usb_hcd * hcd)2514*4882a593Smuzhiyun static int dummy_setup(struct usb_hcd *hcd)
2515*4882a593Smuzhiyun {
2516*4882a593Smuzhiyun 	struct dummy *dum;
2517*4882a593Smuzhiyun 
2518*4882a593Smuzhiyun 	dum = *((void **)dev_get_platdata(hcd->self.controller));
2519*4882a593Smuzhiyun 	hcd->self.sg_tablesize = ~0;
2520*4882a593Smuzhiyun 	if (usb_hcd_is_primary_hcd(hcd)) {
2521*4882a593Smuzhiyun 		dum->hs_hcd = hcd_to_dummy_hcd(hcd);
2522*4882a593Smuzhiyun 		dum->hs_hcd->dum = dum;
2523*4882a593Smuzhiyun 		/*
2524*4882a593Smuzhiyun 		 * Mark the first roothub as being USB 2.0.
2525*4882a593Smuzhiyun 		 * The USB 3.0 roothub will be registered later by
2526*4882a593Smuzhiyun 		 * dummy_hcd_probe()
2527*4882a593Smuzhiyun 		 */
2528*4882a593Smuzhiyun 		hcd->speed = HCD_USB2;
2529*4882a593Smuzhiyun 		hcd->self.root_hub->speed = USB_SPEED_HIGH;
2530*4882a593Smuzhiyun 	} else {
2531*4882a593Smuzhiyun 		dum->ss_hcd = hcd_to_dummy_hcd(hcd);
2532*4882a593Smuzhiyun 		dum->ss_hcd->dum = dum;
2533*4882a593Smuzhiyun 		hcd->speed = HCD_USB3;
2534*4882a593Smuzhiyun 		hcd->self.root_hub->speed = USB_SPEED_SUPER;
2535*4882a593Smuzhiyun 	}
2536*4882a593Smuzhiyun 	return 0;
2537*4882a593Smuzhiyun }
2538*4882a593Smuzhiyun 
2539*4882a593Smuzhiyun /* Change a group of bulk endpoints to support multiple stream IDs */
dummy_alloc_streams(struct usb_hcd * hcd,struct usb_device * udev,struct usb_host_endpoint ** eps,unsigned int num_eps,unsigned int num_streams,gfp_t mem_flags)2540*4882a593Smuzhiyun static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
2541*4882a593Smuzhiyun 	struct usb_host_endpoint **eps, unsigned int num_eps,
2542*4882a593Smuzhiyun 	unsigned int num_streams, gfp_t mem_flags)
2543*4882a593Smuzhiyun {
2544*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
2545*4882a593Smuzhiyun 	unsigned long flags;
2546*4882a593Smuzhiyun 	int max_stream;
2547*4882a593Smuzhiyun 	int ret_streams = num_streams;
2548*4882a593Smuzhiyun 	unsigned int index;
2549*4882a593Smuzhiyun 	unsigned int i;
2550*4882a593Smuzhiyun 
2551*4882a593Smuzhiyun 	if (!num_eps)
2552*4882a593Smuzhiyun 		return -EINVAL;
2553*4882a593Smuzhiyun 
2554*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
2555*4882a593Smuzhiyun 	for (i = 0; i < num_eps; i++) {
2556*4882a593Smuzhiyun 		index = dummy_get_ep_idx(&eps[i]->desc);
2557*4882a593Smuzhiyun 		if ((1 << index) & dum_hcd->stream_en_ep) {
2558*4882a593Smuzhiyun 			ret_streams = -EINVAL;
2559*4882a593Smuzhiyun 			goto out;
2560*4882a593Smuzhiyun 		}
2561*4882a593Smuzhiyun 		max_stream = usb_ss_max_streams(&eps[i]->ss_ep_comp);
2562*4882a593Smuzhiyun 		if (!max_stream) {
2563*4882a593Smuzhiyun 			ret_streams = -EINVAL;
2564*4882a593Smuzhiyun 			goto out;
2565*4882a593Smuzhiyun 		}
2566*4882a593Smuzhiyun 		if (max_stream < ret_streams) {
2567*4882a593Smuzhiyun 			dev_dbg(dummy_dev(dum_hcd), "Ep 0x%x only supports %u "
2568*4882a593Smuzhiyun 					"stream IDs.\n",
2569*4882a593Smuzhiyun 					eps[i]->desc.bEndpointAddress,
2570*4882a593Smuzhiyun 					max_stream);
2571*4882a593Smuzhiyun 			ret_streams = max_stream;
2572*4882a593Smuzhiyun 		}
2573*4882a593Smuzhiyun 	}
2574*4882a593Smuzhiyun 
2575*4882a593Smuzhiyun 	for (i = 0; i < num_eps; i++) {
2576*4882a593Smuzhiyun 		index = dummy_get_ep_idx(&eps[i]->desc);
2577*4882a593Smuzhiyun 		dum_hcd->stream_en_ep |= 1 << index;
2578*4882a593Smuzhiyun 		set_max_streams_for_pipe(dum_hcd,
2579*4882a593Smuzhiyun 				usb_endpoint_num(&eps[i]->desc), ret_streams);
2580*4882a593Smuzhiyun 	}
2581*4882a593Smuzhiyun out:
2582*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
2583*4882a593Smuzhiyun 	return ret_streams;
2584*4882a593Smuzhiyun }
2585*4882a593Smuzhiyun 
2586*4882a593Smuzhiyun /* Reverts a group of bulk endpoints back to not using stream IDs. */
dummy_free_streams(struct usb_hcd * hcd,struct usb_device * udev,struct usb_host_endpoint ** eps,unsigned int num_eps,gfp_t mem_flags)2587*4882a593Smuzhiyun static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
2588*4882a593Smuzhiyun 	struct usb_host_endpoint **eps, unsigned int num_eps,
2589*4882a593Smuzhiyun 	gfp_t mem_flags)
2590*4882a593Smuzhiyun {
2591*4882a593Smuzhiyun 	struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd);
2592*4882a593Smuzhiyun 	unsigned long flags;
2593*4882a593Smuzhiyun 	int ret;
2594*4882a593Smuzhiyun 	unsigned int index;
2595*4882a593Smuzhiyun 	unsigned int i;
2596*4882a593Smuzhiyun 
2597*4882a593Smuzhiyun 	spin_lock_irqsave(&dum_hcd->dum->lock, flags);
2598*4882a593Smuzhiyun 	for (i = 0; i < num_eps; i++) {
2599*4882a593Smuzhiyun 		index = dummy_get_ep_idx(&eps[i]->desc);
2600*4882a593Smuzhiyun 		if (!((1 << index) & dum_hcd->stream_en_ep)) {
2601*4882a593Smuzhiyun 			ret = -EINVAL;
2602*4882a593Smuzhiyun 			goto out;
2603*4882a593Smuzhiyun 		}
2604*4882a593Smuzhiyun 	}
2605*4882a593Smuzhiyun 
2606*4882a593Smuzhiyun 	for (i = 0; i < num_eps; i++) {
2607*4882a593Smuzhiyun 		index = dummy_get_ep_idx(&eps[i]->desc);
2608*4882a593Smuzhiyun 		dum_hcd->stream_en_ep &= ~(1 << index);
2609*4882a593Smuzhiyun 		set_max_streams_for_pipe(dum_hcd,
2610*4882a593Smuzhiyun 				usb_endpoint_num(&eps[i]->desc), 0);
2611*4882a593Smuzhiyun 	}
2612*4882a593Smuzhiyun 	ret = 0;
2613*4882a593Smuzhiyun out:
2614*4882a593Smuzhiyun 	spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
2615*4882a593Smuzhiyun 	return ret;
2616*4882a593Smuzhiyun }
2617*4882a593Smuzhiyun 
2618*4882a593Smuzhiyun static struct hc_driver dummy_hcd = {
2619*4882a593Smuzhiyun 	.description =		(char *) driver_name,
2620*4882a593Smuzhiyun 	.product_desc =		"Dummy host controller",
2621*4882a593Smuzhiyun 	.hcd_priv_size =	sizeof(struct dummy_hcd),
2622*4882a593Smuzhiyun 
2623*4882a593Smuzhiyun 	.reset =		dummy_setup,
2624*4882a593Smuzhiyun 	.start =		dummy_start,
2625*4882a593Smuzhiyun 	.stop =			dummy_stop,
2626*4882a593Smuzhiyun 
2627*4882a593Smuzhiyun 	.urb_enqueue =		dummy_urb_enqueue,
2628*4882a593Smuzhiyun 	.urb_dequeue =		dummy_urb_dequeue,
2629*4882a593Smuzhiyun 
2630*4882a593Smuzhiyun 	.get_frame_number =	dummy_h_get_frame,
2631*4882a593Smuzhiyun 
2632*4882a593Smuzhiyun 	.hub_status_data =	dummy_hub_status,
2633*4882a593Smuzhiyun 	.hub_control =		dummy_hub_control,
2634*4882a593Smuzhiyun 	.bus_suspend =		dummy_bus_suspend,
2635*4882a593Smuzhiyun 	.bus_resume =		dummy_bus_resume,
2636*4882a593Smuzhiyun 
2637*4882a593Smuzhiyun 	.alloc_streams =	dummy_alloc_streams,
2638*4882a593Smuzhiyun 	.free_streams =		dummy_free_streams,
2639*4882a593Smuzhiyun };
2640*4882a593Smuzhiyun 
dummy_hcd_probe(struct platform_device * pdev)2641*4882a593Smuzhiyun static int dummy_hcd_probe(struct platform_device *pdev)
2642*4882a593Smuzhiyun {
2643*4882a593Smuzhiyun 	struct dummy		*dum;
2644*4882a593Smuzhiyun 	struct usb_hcd		*hs_hcd;
2645*4882a593Smuzhiyun 	struct usb_hcd		*ss_hcd;
2646*4882a593Smuzhiyun 	int			retval;
2647*4882a593Smuzhiyun 
2648*4882a593Smuzhiyun 	dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
2649*4882a593Smuzhiyun 	dum = *((void **)dev_get_platdata(&pdev->dev));
2650*4882a593Smuzhiyun 
2651*4882a593Smuzhiyun 	if (mod_data.is_super_speed)
2652*4882a593Smuzhiyun 		dummy_hcd.flags = HCD_USB3 | HCD_SHARED;
2653*4882a593Smuzhiyun 	else if (mod_data.is_high_speed)
2654*4882a593Smuzhiyun 		dummy_hcd.flags = HCD_USB2;
2655*4882a593Smuzhiyun 	else
2656*4882a593Smuzhiyun 		dummy_hcd.flags = HCD_USB11;
2657*4882a593Smuzhiyun 	hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev));
2658*4882a593Smuzhiyun 	if (!hs_hcd)
2659*4882a593Smuzhiyun 		return -ENOMEM;
2660*4882a593Smuzhiyun 	hs_hcd->has_tt = 1;
2661*4882a593Smuzhiyun 
2662*4882a593Smuzhiyun 	retval = usb_add_hcd(hs_hcd, 0, 0);
2663*4882a593Smuzhiyun 	if (retval)
2664*4882a593Smuzhiyun 		goto put_usb2_hcd;
2665*4882a593Smuzhiyun 
2666*4882a593Smuzhiyun 	if (mod_data.is_super_speed) {
2667*4882a593Smuzhiyun 		ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev,
2668*4882a593Smuzhiyun 					dev_name(&pdev->dev), hs_hcd);
2669*4882a593Smuzhiyun 		if (!ss_hcd) {
2670*4882a593Smuzhiyun 			retval = -ENOMEM;
2671*4882a593Smuzhiyun 			goto dealloc_usb2_hcd;
2672*4882a593Smuzhiyun 		}
2673*4882a593Smuzhiyun 
2674*4882a593Smuzhiyun 		retval = usb_add_hcd(ss_hcd, 0, 0);
2675*4882a593Smuzhiyun 		if (retval)
2676*4882a593Smuzhiyun 			goto put_usb3_hcd;
2677*4882a593Smuzhiyun 	}
2678*4882a593Smuzhiyun 	return 0;
2679*4882a593Smuzhiyun 
2680*4882a593Smuzhiyun put_usb3_hcd:
2681*4882a593Smuzhiyun 	usb_put_hcd(ss_hcd);
2682*4882a593Smuzhiyun dealloc_usb2_hcd:
2683*4882a593Smuzhiyun 	usb_remove_hcd(hs_hcd);
2684*4882a593Smuzhiyun put_usb2_hcd:
2685*4882a593Smuzhiyun 	usb_put_hcd(hs_hcd);
2686*4882a593Smuzhiyun 	dum->hs_hcd = dum->ss_hcd = NULL;
2687*4882a593Smuzhiyun 	return retval;
2688*4882a593Smuzhiyun }
2689*4882a593Smuzhiyun 
dummy_hcd_remove(struct platform_device * pdev)2690*4882a593Smuzhiyun static int dummy_hcd_remove(struct platform_device *pdev)
2691*4882a593Smuzhiyun {
2692*4882a593Smuzhiyun 	struct dummy		*dum;
2693*4882a593Smuzhiyun 
2694*4882a593Smuzhiyun 	dum = hcd_to_dummy_hcd(platform_get_drvdata(pdev))->dum;
2695*4882a593Smuzhiyun 
2696*4882a593Smuzhiyun 	if (dum->ss_hcd) {
2697*4882a593Smuzhiyun 		usb_remove_hcd(dummy_hcd_to_hcd(dum->ss_hcd));
2698*4882a593Smuzhiyun 		usb_put_hcd(dummy_hcd_to_hcd(dum->ss_hcd));
2699*4882a593Smuzhiyun 	}
2700*4882a593Smuzhiyun 
2701*4882a593Smuzhiyun 	usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
2702*4882a593Smuzhiyun 	usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd));
2703*4882a593Smuzhiyun 
2704*4882a593Smuzhiyun 	dum->hs_hcd = NULL;
2705*4882a593Smuzhiyun 	dum->ss_hcd = NULL;
2706*4882a593Smuzhiyun 
2707*4882a593Smuzhiyun 	return 0;
2708*4882a593Smuzhiyun }
2709*4882a593Smuzhiyun 
dummy_hcd_suspend(struct platform_device * pdev,pm_message_t state)2710*4882a593Smuzhiyun static int dummy_hcd_suspend(struct platform_device *pdev, pm_message_t state)
2711*4882a593Smuzhiyun {
2712*4882a593Smuzhiyun 	struct usb_hcd		*hcd;
2713*4882a593Smuzhiyun 	struct dummy_hcd	*dum_hcd;
2714*4882a593Smuzhiyun 	int			rc = 0;
2715*4882a593Smuzhiyun 
2716*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "%s\n", __func__);
2717*4882a593Smuzhiyun 
2718*4882a593Smuzhiyun 	hcd = platform_get_drvdata(pdev);
2719*4882a593Smuzhiyun 	dum_hcd = hcd_to_dummy_hcd(hcd);
2720*4882a593Smuzhiyun 	if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
2721*4882a593Smuzhiyun 		dev_warn(&pdev->dev, "Root hub isn't suspended!\n");
2722*4882a593Smuzhiyun 		rc = -EBUSY;
2723*4882a593Smuzhiyun 	} else
2724*4882a593Smuzhiyun 		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
2725*4882a593Smuzhiyun 	return rc;
2726*4882a593Smuzhiyun }
2727*4882a593Smuzhiyun 
dummy_hcd_resume(struct platform_device * pdev)2728*4882a593Smuzhiyun static int dummy_hcd_resume(struct platform_device *pdev)
2729*4882a593Smuzhiyun {
2730*4882a593Smuzhiyun 	struct usb_hcd		*hcd;
2731*4882a593Smuzhiyun 
2732*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "%s\n", __func__);
2733*4882a593Smuzhiyun 
2734*4882a593Smuzhiyun 	hcd = platform_get_drvdata(pdev);
2735*4882a593Smuzhiyun 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
2736*4882a593Smuzhiyun 	usb_hcd_poll_rh_status(hcd);
2737*4882a593Smuzhiyun 	return 0;
2738*4882a593Smuzhiyun }
2739*4882a593Smuzhiyun 
2740*4882a593Smuzhiyun static struct platform_driver dummy_hcd_driver = {
2741*4882a593Smuzhiyun 	.probe		= dummy_hcd_probe,
2742*4882a593Smuzhiyun 	.remove		= dummy_hcd_remove,
2743*4882a593Smuzhiyun 	.suspend	= dummy_hcd_suspend,
2744*4882a593Smuzhiyun 	.resume		= dummy_hcd_resume,
2745*4882a593Smuzhiyun 	.driver		= {
2746*4882a593Smuzhiyun 		.name	= driver_name,
2747*4882a593Smuzhiyun 	},
2748*4882a593Smuzhiyun };
2749*4882a593Smuzhiyun 
2750*4882a593Smuzhiyun /*-------------------------------------------------------------------------*/
2751*4882a593Smuzhiyun #define MAX_NUM_UDC	32
2752*4882a593Smuzhiyun static struct platform_device *the_udc_pdev[MAX_NUM_UDC];
2753*4882a593Smuzhiyun static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
2754*4882a593Smuzhiyun 
init(void)2755*4882a593Smuzhiyun static int __init init(void)
2756*4882a593Smuzhiyun {
2757*4882a593Smuzhiyun 	int	retval = -ENOMEM;
2758*4882a593Smuzhiyun 	int	i;
2759*4882a593Smuzhiyun 	struct	dummy *dum[MAX_NUM_UDC] = {};
2760*4882a593Smuzhiyun 
2761*4882a593Smuzhiyun 	if (usb_disabled())
2762*4882a593Smuzhiyun 		return -ENODEV;
2763*4882a593Smuzhiyun 
2764*4882a593Smuzhiyun 	if (!mod_data.is_high_speed && mod_data.is_super_speed)
2765*4882a593Smuzhiyun 		return -EINVAL;
2766*4882a593Smuzhiyun 
2767*4882a593Smuzhiyun 	if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) {
2768*4882a593Smuzhiyun 		pr_err("Number of emulated UDC must be in range of 1...%d\n",
2769*4882a593Smuzhiyun 				MAX_NUM_UDC);
2770*4882a593Smuzhiyun 		return -EINVAL;
2771*4882a593Smuzhiyun 	}
2772*4882a593Smuzhiyun 
2773*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2774*4882a593Smuzhiyun 		the_hcd_pdev[i] = platform_device_alloc(driver_name, i);
2775*4882a593Smuzhiyun 		if (!the_hcd_pdev[i]) {
2776*4882a593Smuzhiyun 			i--;
2777*4882a593Smuzhiyun 			while (i >= 0)
2778*4882a593Smuzhiyun 				platform_device_put(the_hcd_pdev[i--]);
2779*4882a593Smuzhiyun 			return retval;
2780*4882a593Smuzhiyun 		}
2781*4882a593Smuzhiyun 	}
2782*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2783*4882a593Smuzhiyun 		the_udc_pdev[i] = platform_device_alloc(gadget_name, i);
2784*4882a593Smuzhiyun 		if (!the_udc_pdev[i]) {
2785*4882a593Smuzhiyun 			i--;
2786*4882a593Smuzhiyun 			while (i >= 0)
2787*4882a593Smuzhiyun 				platform_device_put(the_udc_pdev[i--]);
2788*4882a593Smuzhiyun 			goto err_alloc_udc;
2789*4882a593Smuzhiyun 		}
2790*4882a593Smuzhiyun 	}
2791*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2792*4882a593Smuzhiyun 		dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL);
2793*4882a593Smuzhiyun 		if (!dum[i]) {
2794*4882a593Smuzhiyun 			retval = -ENOMEM;
2795*4882a593Smuzhiyun 			goto err_add_pdata;
2796*4882a593Smuzhiyun 		}
2797*4882a593Smuzhiyun 		retval = platform_device_add_data(the_hcd_pdev[i], &dum[i],
2798*4882a593Smuzhiyun 				sizeof(void *));
2799*4882a593Smuzhiyun 		if (retval)
2800*4882a593Smuzhiyun 			goto err_add_pdata;
2801*4882a593Smuzhiyun 		retval = platform_device_add_data(the_udc_pdev[i], &dum[i],
2802*4882a593Smuzhiyun 				sizeof(void *));
2803*4882a593Smuzhiyun 		if (retval)
2804*4882a593Smuzhiyun 			goto err_add_pdata;
2805*4882a593Smuzhiyun 	}
2806*4882a593Smuzhiyun 
2807*4882a593Smuzhiyun 	retval = platform_driver_register(&dummy_hcd_driver);
2808*4882a593Smuzhiyun 	if (retval < 0)
2809*4882a593Smuzhiyun 		goto err_add_pdata;
2810*4882a593Smuzhiyun 	retval = platform_driver_register(&dummy_udc_driver);
2811*4882a593Smuzhiyun 	if (retval < 0)
2812*4882a593Smuzhiyun 		goto err_register_udc_driver;
2813*4882a593Smuzhiyun 
2814*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2815*4882a593Smuzhiyun 		retval = platform_device_add(the_hcd_pdev[i]);
2816*4882a593Smuzhiyun 		if (retval < 0) {
2817*4882a593Smuzhiyun 			i--;
2818*4882a593Smuzhiyun 			while (i >= 0)
2819*4882a593Smuzhiyun 				platform_device_del(the_hcd_pdev[i--]);
2820*4882a593Smuzhiyun 			goto err_add_hcd;
2821*4882a593Smuzhiyun 		}
2822*4882a593Smuzhiyun 	}
2823*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2824*4882a593Smuzhiyun 		if (!dum[i]->hs_hcd ||
2825*4882a593Smuzhiyun 				(!dum[i]->ss_hcd && mod_data.is_super_speed)) {
2826*4882a593Smuzhiyun 			/*
2827*4882a593Smuzhiyun 			 * The hcd was added successfully but its probe
2828*4882a593Smuzhiyun 			 * function failed for some reason.
2829*4882a593Smuzhiyun 			 */
2830*4882a593Smuzhiyun 			retval = -EINVAL;
2831*4882a593Smuzhiyun 			goto err_add_udc;
2832*4882a593Smuzhiyun 		}
2833*4882a593Smuzhiyun 	}
2834*4882a593Smuzhiyun 
2835*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2836*4882a593Smuzhiyun 		retval = platform_device_add(the_udc_pdev[i]);
2837*4882a593Smuzhiyun 		if (retval < 0) {
2838*4882a593Smuzhiyun 			i--;
2839*4882a593Smuzhiyun 			while (i >= 0)
2840*4882a593Smuzhiyun 				platform_device_del(the_udc_pdev[i--]);
2841*4882a593Smuzhiyun 			goto err_add_udc;
2842*4882a593Smuzhiyun 		}
2843*4882a593Smuzhiyun 	}
2844*4882a593Smuzhiyun 
2845*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2846*4882a593Smuzhiyun 		if (!platform_get_drvdata(the_udc_pdev[i])) {
2847*4882a593Smuzhiyun 			/*
2848*4882a593Smuzhiyun 			 * The udc was added successfully but its probe
2849*4882a593Smuzhiyun 			 * function failed for some reason.
2850*4882a593Smuzhiyun 			 */
2851*4882a593Smuzhiyun 			retval = -EINVAL;
2852*4882a593Smuzhiyun 			goto err_probe_udc;
2853*4882a593Smuzhiyun 		}
2854*4882a593Smuzhiyun 	}
2855*4882a593Smuzhiyun 	return retval;
2856*4882a593Smuzhiyun 
2857*4882a593Smuzhiyun err_probe_udc:
2858*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++)
2859*4882a593Smuzhiyun 		platform_device_del(the_udc_pdev[i]);
2860*4882a593Smuzhiyun err_add_udc:
2861*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++)
2862*4882a593Smuzhiyun 		platform_device_del(the_hcd_pdev[i]);
2863*4882a593Smuzhiyun err_add_hcd:
2864*4882a593Smuzhiyun 	platform_driver_unregister(&dummy_udc_driver);
2865*4882a593Smuzhiyun err_register_udc_driver:
2866*4882a593Smuzhiyun 	platform_driver_unregister(&dummy_hcd_driver);
2867*4882a593Smuzhiyun err_add_pdata:
2868*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++)
2869*4882a593Smuzhiyun 		kfree(dum[i]);
2870*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++)
2871*4882a593Smuzhiyun 		platform_device_put(the_udc_pdev[i]);
2872*4882a593Smuzhiyun err_alloc_udc:
2873*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++)
2874*4882a593Smuzhiyun 		platform_device_put(the_hcd_pdev[i]);
2875*4882a593Smuzhiyun 	return retval;
2876*4882a593Smuzhiyun }
2877*4882a593Smuzhiyun module_init(init);
2878*4882a593Smuzhiyun 
cleanup(void)2879*4882a593Smuzhiyun static void __exit cleanup(void)
2880*4882a593Smuzhiyun {
2881*4882a593Smuzhiyun 	int i;
2882*4882a593Smuzhiyun 
2883*4882a593Smuzhiyun 	for (i = 0; i < mod_data.num; i++) {
2884*4882a593Smuzhiyun 		struct dummy *dum;
2885*4882a593Smuzhiyun 
2886*4882a593Smuzhiyun 		dum = *((void **)dev_get_platdata(&the_udc_pdev[i]->dev));
2887*4882a593Smuzhiyun 
2888*4882a593Smuzhiyun 		platform_device_unregister(the_udc_pdev[i]);
2889*4882a593Smuzhiyun 		platform_device_unregister(the_hcd_pdev[i]);
2890*4882a593Smuzhiyun 		kfree(dum);
2891*4882a593Smuzhiyun 	}
2892*4882a593Smuzhiyun 	platform_driver_unregister(&dummy_udc_driver);
2893*4882a593Smuzhiyun 	platform_driver_unregister(&dummy_hcd_driver);
2894*4882a593Smuzhiyun }
2895*4882a593Smuzhiyun module_exit(cleanup);
2896