1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2015 Google, Inc
3*4882a593Smuzhiyun * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * usb_match_device() modified from Linux kernel v4.0.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <errno.h>
13*4882a593Smuzhiyun #include <memalign.h>
14*4882a593Smuzhiyun #include <usb.h>
15*4882a593Smuzhiyun #include <dm/device-internal.h>
16*4882a593Smuzhiyun #include <dm/lists.h>
17*4882a593Smuzhiyun #include <dm/uclass-internal.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun extern bool usb_started; /* flag for the started/stopped USB status */
22*4882a593Smuzhiyun static bool asynch_allowed;
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun struct usb_uclass_priv {
25*4882a593Smuzhiyun int companion_device_count;
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun
usb_disable_asynch(int disable)28*4882a593Smuzhiyun int usb_disable_asynch(int disable)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun int old_value = asynch_allowed;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun asynch_allowed = !disable;
33*4882a593Smuzhiyun return old_value;
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun
submit_int_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length,int interval,bool nonblock)36*4882a593Smuzhiyun int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
37*4882a593Smuzhiyun int length, int interval, bool nonblock)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
40*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun if (!ops->interrupt)
43*4882a593Smuzhiyun return -ENOSYS;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun return ops->interrupt(bus, udev, pipe, buffer, length, interval,
46*4882a593Smuzhiyun nonblock);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
submit_control_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length,struct devrequest * setup)49*4882a593Smuzhiyun int submit_control_msg(struct usb_device *udev, unsigned long pipe,
50*4882a593Smuzhiyun void *buffer, int length, struct devrequest *setup)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
53*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
54*4882a593Smuzhiyun struct usb_uclass_priv *uc_priv = bus->uclass->priv;
55*4882a593Smuzhiyun int err;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun if (!ops->control)
58*4882a593Smuzhiyun return -ENOSYS;
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun err = ops->control(bus, udev, pipe, buffer, length, setup);
61*4882a593Smuzhiyun if (setup->request == USB_REQ_SET_FEATURE &&
62*4882a593Smuzhiyun setup->requesttype == USB_RT_PORT &&
63*4882a593Smuzhiyun setup->value == cpu_to_le16(USB_PORT_FEAT_RESET) &&
64*4882a593Smuzhiyun err == -ENXIO) {
65*4882a593Smuzhiyun /* Device handed over to companion after port reset */
66*4882a593Smuzhiyun uc_priv->companion_device_count++;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun return err;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
submit_bulk_msg(struct usb_device * udev,unsigned long pipe,void * buffer,int length)72*4882a593Smuzhiyun int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
73*4882a593Smuzhiyun int length)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
76*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun if (!ops->bulk)
79*4882a593Smuzhiyun return -ENOSYS;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun return ops->bulk(bus, udev, pipe, buffer, length);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
create_int_queue(struct usb_device * udev,unsigned long pipe,int queuesize,int elementsize,void * buffer,int interval)84*4882a593Smuzhiyun struct int_queue *create_int_queue(struct usb_device *udev,
85*4882a593Smuzhiyun unsigned long pipe, int queuesize, int elementsize,
86*4882a593Smuzhiyun void *buffer, int interval)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
89*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun if (!ops->create_int_queue)
92*4882a593Smuzhiyun return NULL;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun return ops->create_int_queue(bus, udev, pipe, queuesize, elementsize,
95*4882a593Smuzhiyun buffer, interval);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
poll_int_queue(struct usb_device * udev,struct int_queue * queue)98*4882a593Smuzhiyun void *poll_int_queue(struct usb_device *udev, struct int_queue *queue)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
101*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun if (!ops->poll_int_queue)
104*4882a593Smuzhiyun return NULL;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun return ops->poll_int_queue(bus, udev, queue);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
destroy_int_queue(struct usb_device * udev,struct int_queue * queue)109*4882a593Smuzhiyun int destroy_int_queue(struct usb_device *udev, struct int_queue *queue)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
112*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun if (!ops->destroy_int_queue)
115*4882a593Smuzhiyun return -ENOSYS;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun return ops->destroy_int_queue(bus, udev, queue);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
usb_alloc_device(struct usb_device * udev)120*4882a593Smuzhiyun int usb_alloc_device(struct usb_device *udev)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
123*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* This is only requird by some controllers - current XHCI */
126*4882a593Smuzhiyun if (!ops->alloc_device)
127*4882a593Smuzhiyun return 0;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun return ops->alloc_device(bus, udev);
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
usb_reset_root_port(struct usb_device * udev)132*4882a593Smuzhiyun int usb_reset_root_port(struct usb_device *udev)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
135*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (!ops->reset_root_port)
138*4882a593Smuzhiyun return -ENOSYS;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun return ops->reset_root_port(bus, udev);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
usb_update_hub_device(struct usb_device * udev)143*4882a593Smuzhiyun int usb_update_hub_device(struct usb_device *udev)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
146*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun if (!ops->update_hub_device)
149*4882a593Smuzhiyun return -ENOSYS;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun return ops->update_hub_device(bus, udev);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
usb_get_max_xfer_size(struct usb_device * udev,size_t * size)154*4882a593Smuzhiyun int usb_get_max_xfer_size(struct usb_device *udev, size_t *size)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun struct udevice *bus = udev->controller_dev;
157*4882a593Smuzhiyun struct dm_usb_ops *ops = usb_get_ops(bus);
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun if (!ops->get_max_xfer_size)
160*4882a593Smuzhiyun return -ENOSYS;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun return ops->get_max_xfer_size(bus, size);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
usb_stop(void)165*4882a593Smuzhiyun int usb_stop(void)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun struct udevice *bus;
168*4882a593Smuzhiyun struct udevice *rh;
169*4882a593Smuzhiyun struct uclass *uc;
170*4882a593Smuzhiyun struct usb_uclass_priv *uc_priv;
171*4882a593Smuzhiyun int err = 0, ret;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* De-activate any devices that have been activated */
174*4882a593Smuzhiyun ret = uclass_get(UCLASS_USB, &uc);
175*4882a593Smuzhiyun if (ret)
176*4882a593Smuzhiyun return ret;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun uc_priv = uc->priv;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun uclass_foreach_dev(bus, uc) {
181*4882a593Smuzhiyun ret = device_remove(bus, DM_REMOVE_NORMAL);
182*4882a593Smuzhiyun if (ret && !err)
183*4882a593Smuzhiyun err = ret;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /* Locate root hub device */
186*4882a593Smuzhiyun device_find_first_child(bus, &rh);
187*4882a593Smuzhiyun if (rh) {
188*4882a593Smuzhiyun /*
189*4882a593Smuzhiyun * All USB devices are children of root hub.
190*4882a593Smuzhiyun * Unbinding root hub will unbind all of its children.
191*4882a593Smuzhiyun */
192*4882a593Smuzhiyun ret = device_unbind(rh);
193*4882a593Smuzhiyun if (ret && !err)
194*4882a593Smuzhiyun err = ret;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun #ifdef CONFIG_USB_STORAGE
199*4882a593Smuzhiyun usb_stor_reset();
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun uc_priv->companion_device_count = 0;
202*4882a593Smuzhiyun usb_started = 0;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun return err;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
usb_scan_bus(struct udevice * bus,bool recurse)207*4882a593Smuzhiyun static void usb_scan_bus(struct udevice *bus, bool recurse)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun struct usb_bus_priv *priv;
210*4882a593Smuzhiyun struct udevice *dev;
211*4882a593Smuzhiyun int ret;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun priv = dev_get_uclass_priv(bus);
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun assert(recurse); /* TODO: Support non-recusive */
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun printf("scanning bus %s for devices... ", bus->name);
218*4882a593Smuzhiyun debug("\n");
219*4882a593Smuzhiyun ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev);
220*4882a593Smuzhiyun if (ret)
221*4882a593Smuzhiyun printf("failed, error %d\n", ret);
222*4882a593Smuzhiyun else if (priv->next_addr == 0)
223*4882a593Smuzhiyun printf("No USB Device found\n");
224*4882a593Smuzhiyun else
225*4882a593Smuzhiyun printf("%d USB Device(s) found\n", priv->next_addr);
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
remove_inactive_children(struct uclass * uc,struct udevice * bus)228*4882a593Smuzhiyun static void remove_inactive_children(struct uclass *uc, struct udevice *bus)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun uclass_foreach_dev(bus, uc) {
231*4882a593Smuzhiyun struct udevice *dev, *next;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun if (!device_active(bus))
234*4882a593Smuzhiyun continue;
235*4882a593Smuzhiyun device_foreach_child_safe(dev, next, bus) {
236*4882a593Smuzhiyun if (!device_active(dev))
237*4882a593Smuzhiyun device_unbind(dev);
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
usb_init(void)242*4882a593Smuzhiyun int usb_init(void)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun int controllers_initialized = 0;
245*4882a593Smuzhiyun struct usb_uclass_priv *uc_priv;
246*4882a593Smuzhiyun struct usb_bus_priv *priv;
247*4882a593Smuzhiyun struct udevice *bus;
248*4882a593Smuzhiyun struct uclass *uc;
249*4882a593Smuzhiyun int ret;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun asynch_allowed = 1;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun ret = uclass_get(UCLASS_USB, &uc);
254*4882a593Smuzhiyun if (ret)
255*4882a593Smuzhiyun return ret;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun uc_priv = uc->priv;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun uclass_foreach_dev(bus, uc) {
260*4882a593Smuzhiyun /* init low_level USB */
261*4882a593Smuzhiyun printf("Bus %s: ", bus->name);
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun #ifdef CONFIG_SANDBOX
264*4882a593Smuzhiyun /*
265*4882a593Smuzhiyun * For Sandbox, we need scan the device tree each time when we
266*4882a593Smuzhiyun * start the USB stack, in order to re-create the emulated USB
267*4882a593Smuzhiyun * devices and bind drivers for them before we actually do the
268*4882a593Smuzhiyun * driver probe.
269*4882a593Smuzhiyun */
270*4882a593Smuzhiyun ret = dm_scan_fdt_dev(bus);
271*4882a593Smuzhiyun if (ret) {
272*4882a593Smuzhiyun printf("Sandbox USB device scan failed (%d)\n", ret);
273*4882a593Smuzhiyun continue;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun #endif
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun ret = device_probe(bus);
278*4882a593Smuzhiyun if (ret == -ENODEV) { /* No such device. */
279*4882a593Smuzhiyun puts("Port not available.\n");
280*4882a593Smuzhiyun controllers_initialized++;
281*4882a593Smuzhiyun continue;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (ret) { /* Other error. */
285*4882a593Smuzhiyun printf("probe failed, error %d\n", ret);
286*4882a593Smuzhiyun continue;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun controllers_initialized++;
289*4882a593Smuzhiyun usb_started = true;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /*
293*4882a593Smuzhiyun * lowlevel init done, now scan the bus for devices i.e. search HUBs
294*4882a593Smuzhiyun * and configure them, first scan primary controllers.
295*4882a593Smuzhiyun */
296*4882a593Smuzhiyun uclass_foreach_dev(bus, uc) {
297*4882a593Smuzhiyun if (!device_active(bus))
298*4882a593Smuzhiyun continue;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun priv = dev_get_uclass_priv(bus);
301*4882a593Smuzhiyun if (!priv->companion)
302*4882a593Smuzhiyun usb_scan_bus(bus, true);
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun /*
306*4882a593Smuzhiyun * Now that the primary controllers have been scanned and have handed
307*4882a593Smuzhiyun * over any devices they do not understand to their companions, scan
308*4882a593Smuzhiyun * the companions if necessary.
309*4882a593Smuzhiyun */
310*4882a593Smuzhiyun if (uc_priv->companion_device_count) {
311*4882a593Smuzhiyun uclass_foreach_dev(bus, uc) {
312*4882a593Smuzhiyun if (!device_active(bus))
313*4882a593Smuzhiyun continue;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun priv = dev_get_uclass_priv(bus);
316*4882a593Smuzhiyun if (priv->companion)
317*4882a593Smuzhiyun usb_scan_bus(bus, true);
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun debug("scan end\n");
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /* Remove any devices that were not found on this scan */
324*4882a593Smuzhiyun remove_inactive_children(uc, bus);
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun ret = uclass_get(UCLASS_USB_HUB, &uc);
327*4882a593Smuzhiyun if (ret)
328*4882a593Smuzhiyun return ret;
329*4882a593Smuzhiyun remove_inactive_children(uc, bus);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /* if we were not able to find at least one working bus, bail out */
332*4882a593Smuzhiyun if (controllers_initialized == 0)
333*4882a593Smuzhiyun printf("No working controllers found\n");
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun return usb_started ? 0 : -1;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /*
339*4882a593Smuzhiyun * TODO(sjg@chromium.org): Remove this legacy function. At present it is needed
340*4882a593Smuzhiyun * to support boards which use driver model for USB but not Ethernet, and want
341*4882a593Smuzhiyun * to use USB Ethernet.
342*4882a593Smuzhiyun *
343*4882a593Smuzhiyun * The #if clause is here to ensure that remains the only case.
344*4882a593Smuzhiyun */
345*4882a593Smuzhiyun #if !defined(CONFIG_DM_ETH) && defined(CONFIG_USB_HOST_ETHER)
find_child_devnum(struct udevice * parent,int devnum)346*4882a593Smuzhiyun static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun struct usb_device *udev;
349*4882a593Smuzhiyun struct udevice *dev;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun if (!device_active(parent))
352*4882a593Smuzhiyun return NULL;
353*4882a593Smuzhiyun udev = dev_get_parent_priv(parent);
354*4882a593Smuzhiyun if (udev->devnum == devnum)
355*4882a593Smuzhiyun return udev;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun for (device_find_first_child(parent, &dev);
358*4882a593Smuzhiyun dev;
359*4882a593Smuzhiyun device_find_next_child(&dev)) {
360*4882a593Smuzhiyun udev = find_child_devnum(dev, devnum);
361*4882a593Smuzhiyun if (udev)
362*4882a593Smuzhiyun return udev;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun return NULL;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
usb_get_dev_index(struct udevice * bus,int index)368*4882a593Smuzhiyun struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun struct udevice *dev;
371*4882a593Smuzhiyun int devnum = index + 1; /* Addresses are allocated from 1 on USB */
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun device_find_first_child(bus, &dev);
374*4882a593Smuzhiyun if (!dev)
375*4882a593Smuzhiyun return NULL;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun return find_child_devnum(dev, devnum);
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun #endif
380*4882a593Smuzhiyun
usb_setup_ehci_gadget(struct ehci_ctrl ** ctlrp)381*4882a593Smuzhiyun int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun struct usb_platdata *plat;
384*4882a593Smuzhiyun struct udevice *dev;
385*4882a593Smuzhiyun int ret;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /* Find the old device and remove it */
388*4882a593Smuzhiyun ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
389*4882a593Smuzhiyun if (ret)
390*4882a593Smuzhiyun return ret;
391*4882a593Smuzhiyun ret = device_remove(dev, DM_REMOVE_NORMAL);
392*4882a593Smuzhiyun if (ret)
393*4882a593Smuzhiyun return ret;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun plat = dev_get_platdata(dev);
396*4882a593Smuzhiyun plat->init_type = USB_INIT_DEVICE;
397*4882a593Smuzhiyun ret = device_probe(dev);
398*4882a593Smuzhiyun if (ret)
399*4882a593Smuzhiyun return ret;
400*4882a593Smuzhiyun *ctlrp = dev_get_priv(dev);
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun return 0;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_device(const struct usb_device_descriptor * desc,const struct usb_device_id * id)406*4882a593Smuzhiyun static int usb_match_device(const struct usb_device_descriptor *desc,
407*4882a593Smuzhiyun const struct usb_device_id *id)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
410*4882a593Smuzhiyun id->idVendor != le16_to_cpu(desc->idVendor))
411*4882a593Smuzhiyun return 0;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
414*4882a593Smuzhiyun id->idProduct != le16_to_cpu(desc->idProduct))
415*4882a593Smuzhiyun return 0;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun /* No need to test id->bcdDevice_lo != 0, since 0 is never
418*4882a593Smuzhiyun greater than any unsigned number. */
419*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
420*4882a593Smuzhiyun (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice)))
421*4882a593Smuzhiyun return 0;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
424*4882a593Smuzhiyun (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice)))
425*4882a593Smuzhiyun return 0;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
428*4882a593Smuzhiyun (id->bDeviceClass != desc->bDeviceClass))
429*4882a593Smuzhiyun return 0;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
432*4882a593Smuzhiyun (id->bDeviceSubClass != desc->bDeviceSubClass))
433*4882a593Smuzhiyun return 0;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
436*4882a593Smuzhiyun (id->bDeviceProtocol != desc->bDeviceProtocol))
437*4882a593Smuzhiyun return 0;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun return 1;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_one_id_intf(const struct usb_device_descriptor * desc,const struct usb_interface_descriptor * int_desc,const struct usb_device_id * id)443*4882a593Smuzhiyun static int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
444*4882a593Smuzhiyun const struct usb_interface_descriptor *int_desc,
445*4882a593Smuzhiyun const struct usb_device_id *id)
446*4882a593Smuzhiyun {
447*4882a593Smuzhiyun /* The interface class, subclass, protocol and number should never be
448*4882a593Smuzhiyun * checked for a match if the device class is Vendor Specific,
449*4882a593Smuzhiyun * unless the match record specifies the Vendor ID. */
450*4882a593Smuzhiyun if (desc->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
451*4882a593Smuzhiyun !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
452*4882a593Smuzhiyun (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
453*4882a593Smuzhiyun USB_DEVICE_ID_MATCH_INT_SUBCLASS |
454*4882a593Smuzhiyun USB_DEVICE_ID_MATCH_INT_PROTOCOL |
455*4882a593Smuzhiyun USB_DEVICE_ID_MATCH_INT_NUMBER)))
456*4882a593Smuzhiyun return 0;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
459*4882a593Smuzhiyun (id->bInterfaceClass != int_desc->bInterfaceClass))
460*4882a593Smuzhiyun return 0;
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
463*4882a593Smuzhiyun (id->bInterfaceSubClass != int_desc->bInterfaceSubClass))
464*4882a593Smuzhiyun return 0;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
467*4882a593Smuzhiyun (id->bInterfaceProtocol != int_desc->bInterfaceProtocol))
468*4882a593Smuzhiyun return 0;
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
471*4882a593Smuzhiyun (id->bInterfaceNumber != int_desc->bInterfaceNumber))
472*4882a593Smuzhiyun return 0;
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun return 1;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun /* returns 0 if no match, 1 if match */
usb_match_one_id(struct usb_device_descriptor * desc,struct usb_interface_descriptor * int_desc,const struct usb_device_id * id)478*4882a593Smuzhiyun static int usb_match_one_id(struct usb_device_descriptor *desc,
479*4882a593Smuzhiyun struct usb_interface_descriptor *int_desc,
480*4882a593Smuzhiyun const struct usb_device_id *id)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun if (!usb_match_device(desc, id))
483*4882a593Smuzhiyun return 0;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun return usb_match_one_id_intf(desc, int_desc, id);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /**
489*4882a593Smuzhiyun * usb_find_and_bind_driver() - Find and bind the right USB driver
490*4882a593Smuzhiyun *
491*4882a593Smuzhiyun * This only looks at certain fields in the descriptor.
492*4882a593Smuzhiyun */
usb_find_and_bind_driver(struct udevice * parent,struct usb_device_descriptor * desc,struct usb_interface_descriptor * iface,int bus_seq,int devnum,struct udevice ** devp)493*4882a593Smuzhiyun static int usb_find_and_bind_driver(struct udevice *parent,
494*4882a593Smuzhiyun struct usb_device_descriptor *desc,
495*4882a593Smuzhiyun struct usb_interface_descriptor *iface,
496*4882a593Smuzhiyun int bus_seq, int devnum,
497*4882a593Smuzhiyun struct udevice **devp)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun struct usb_driver_entry *start, *entry;
500*4882a593Smuzhiyun int n_ents;
501*4882a593Smuzhiyun int ret;
502*4882a593Smuzhiyun char name[30], *str;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun *devp = NULL;
505*4882a593Smuzhiyun debug("%s: Searching for driver\n", __func__);
506*4882a593Smuzhiyun start = ll_entry_start(struct usb_driver_entry, usb_driver_entry);
507*4882a593Smuzhiyun n_ents = ll_entry_count(struct usb_driver_entry, usb_driver_entry);
508*4882a593Smuzhiyun for (entry = start; entry != start + n_ents; entry++) {
509*4882a593Smuzhiyun const struct usb_device_id *id;
510*4882a593Smuzhiyun struct udevice *dev;
511*4882a593Smuzhiyun const struct driver *drv;
512*4882a593Smuzhiyun struct usb_dev_platdata *plat;
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun for (id = entry->match; id->match_flags; id++) {
515*4882a593Smuzhiyun if (!usb_match_one_id(desc, iface, id))
516*4882a593Smuzhiyun continue;
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun drv = entry->driver;
519*4882a593Smuzhiyun /*
520*4882a593Smuzhiyun * We could pass the descriptor to the driver as
521*4882a593Smuzhiyun * platdata (instead of NULL) and allow its bind()
522*4882a593Smuzhiyun * method to return -ENOENT if it doesn't support this
523*4882a593Smuzhiyun * device. That way we could continue the search to
524*4882a593Smuzhiyun * find another driver. For now this doesn't seem
525*4882a593Smuzhiyun * necesssary, so just bind the first match.
526*4882a593Smuzhiyun */
527*4882a593Smuzhiyun ret = device_bind(parent, drv, drv->name, NULL, -1,
528*4882a593Smuzhiyun &dev);
529*4882a593Smuzhiyun if (ret)
530*4882a593Smuzhiyun goto error;
531*4882a593Smuzhiyun debug("%s: Match found: %s\n", __func__, drv->name);
532*4882a593Smuzhiyun dev->driver_data = id->driver_info;
533*4882a593Smuzhiyun plat = dev_get_parent_platdata(dev);
534*4882a593Smuzhiyun plat->id = *id;
535*4882a593Smuzhiyun *devp = dev;
536*4882a593Smuzhiyun return 0;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* Bind a generic driver so that the device can be used */
541*4882a593Smuzhiyun snprintf(name, sizeof(name), "generic_bus_%x_dev_%x", bus_seq, devnum);
542*4882a593Smuzhiyun str = strdup(name);
543*4882a593Smuzhiyun if (!str)
544*4882a593Smuzhiyun return -ENOMEM;
545*4882a593Smuzhiyun ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun error:
548*4882a593Smuzhiyun debug("%s: No match found: %d\n", __func__, ret);
549*4882a593Smuzhiyun return ret;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /**
553*4882a593Smuzhiyun * usb_find_child() - Find an existing device which matches our needs
554*4882a593Smuzhiyun *
555*4882a593Smuzhiyun *
556*4882a593Smuzhiyun */
usb_find_child(struct udevice * parent,struct usb_device_descriptor * desc,struct usb_interface_descriptor * iface,struct udevice ** devp)557*4882a593Smuzhiyun static int usb_find_child(struct udevice *parent,
558*4882a593Smuzhiyun struct usb_device_descriptor *desc,
559*4882a593Smuzhiyun struct usb_interface_descriptor *iface,
560*4882a593Smuzhiyun struct udevice **devp)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun struct udevice *dev;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun *devp = NULL;
565*4882a593Smuzhiyun for (device_find_first_child(parent, &dev);
566*4882a593Smuzhiyun dev;
567*4882a593Smuzhiyun device_find_next_child(&dev)) {
568*4882a593Smuzhiyun struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun /* If this device is already in use, skip it */
571*4882a593Smuzhiyun if (device_active(dev))
572*4882a593Smuzhiyun continue;
573*4882a593Smuzhiyun debug(" %s: name='%s', plat=%d, desc=%d\n", __func__,
574*4882a593Smuzhiyun dev->name, plat->id.bDeviceClass, desc->bDeviceClass);
575*4882a593Smuzhiyun if (usb_match_one_id(desc, iface, &plat->id)) {
576*4882a593Smuzhiyun *devp = dev;
577*4882a593Smuzhiyun return 0;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun return -ENOENT;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
usb_scan_device(struct udevice * parent,int port,enum usb_device_speed speed,struct udevice ** devp)584*4882a593Smuzhiyun int usb_scan_device(struct udevice *parent, int port,
585*4882a593Smuzhiyun enum usb_device_speed speed, struct udevice **devp)
586*4882a593Smuzhiyun {
587*4882a593Smuzhiyun struct udevice *dev;
588*4882a593Smuzhiyun bool created = false;
589*4882a593Smuzhiyun struct usb_dev_platdata *plat;
590*4882a593Smuzhiyun struct usb_bus_priv *priv;
591*4882a593Smuzhiyun struct usb_device *parent_udev;
592*4882a593Smuzhiyun int ret;
593*4882a593Smuzhiyun ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1);
594*4882a593Smuzhiyun struct usb_interface_descriptor *iface = &udev->config.if_desc[0].desc;
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun *devp = NULL;
597*4882a593Smuzhiyun memset(udev, '\0', sizeof(*udev));
598*4882a593Smuzhiyun udev->controller_dev = usb_get_bus(parent);
599*4882a593Smuzhiyun priv = dev_get_uclass_priv(udev->controller_dev);
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun /*
602*4882a593Smuzhiyun * Somewhat nasty, this. We create a local device and use the normal
603*4882a593Smuzhiyun * USB stack to read its descriptor. Then we know what type of device
604*4882a593Smuzhiyun * to create for real.
605*4882a593Smuzhiyun *
606*4882a593Smuzhiyun * udev->dev is set to the parent, since we don't have a real device
607*4882a593Smuzhiyun * yet. The USB stack should not access udev.dev anyway, except perhaps
608*4882a593Smuzhiyun * to find the controller, and the controller will either be @parent,
609*4882a593Smuzhiyun * or some parent of @parent.
610*4882a593Smuzhiyun *
611*4882a593Smuzhiyun * Another option might be to create the device as a generic USB
612*4882a593Smuzhiyun * device, then morph it into the correct one when we know what it
613*4882a593Smuzhiyun * should be. This means that a generic USB device would morph into
614*4882a593Smuzhiyun * a network controller, or a USB flash stick, for example. However,
615*4882a593Smuzhiyun * we don't support such morphing and it isn't clear that it would
616*4882a593Smuzhiyun * be easy to do.
617*4882a593Smuzhiyun *
618*4882a593Smuzhiyun * Yet another option is to split out the USB stack parts of udev
619*4882a593Smuzhiyun * into something like a 'struct urb' (as Linux does) which can exist
620*4882a593Smuzhiyun * independently of any device. This feels cleaner, but calls for quite
621*4882a593Smuzhiyun * a big change to the USB stack.
622*4882a593Smuzhiyun *
623*4882a593Smuzhiyun * For now, the approach is to set up an empty udev, read its
624*4882a593Smuzhiyun * descriptor and assign it an address, then bind a real device and
625*4882a593Smuzhiyun * stash the resulting information into the device's parent
626*4882a593Smuzhiyun * platform data. Then when we probe it, usb_child_pre_probe() is called
627*4882a593Smuzhiyun * and it will pull the information out of the stash.
628*4882a593Smuzhiyun */
629*4882a593Smuzhiyun udev->dev = parent;
630*4882a593Smuzhiyun udev->speed = speed;
631*4882a593Smuzhiyun udev->devnum = priv->next_addr + 1;
632*4882a593Smuzhiyun udev->portnr = port;
633*4882a593Smuzhiyun debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr);
634*4882a593Smuzhiyun parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ?
635*4882a593Smuzhiyun dev_get_parent_priv(parent) : NULL;
636*4882a593Smuzhiyun ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev);
637*4882a593Smuzhiyun debug("read_descriptor for '%s': ret=%d\n", parent->name, ret);
638*4882a593Smuzhiyun if (ret)
639*4882a593Smuzhiyun return ret;
640*4882a593Smuzhiyun ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
641*4882a593Smuzhiyun debug("** usb_find_child returns %d\n", ret);
642*4882a593Smuzhiyun if (ret) {
643*4882a593Smuzhiyun if (ret != -ENOENT)
644*4882a593Smuzhiyun return ret;
645*4882a593Smuzhiyun ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface,
646*4882a593Smuzhiyun udev->controller_dev->seq,
647*4882a593Smuzhiyun udev->devnum, &dev);
648*4882a593Smuzhiyun if (ret)
649*4882a593Smuzhiyun return ret;
650*4882a593Smuzhiyun created = true;
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun plat = dev_get_parent_platdata(dev);
653*4882a593Smuzhiyun debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat);
654*4882a593Smuzhiyun plat->devnum = udev->devnum;
655*4882a593Smuzhiyun plat->udev = udev;
656*4882a593Smuzhiyun priv->next_addr++;
657*4882a593Smuzhiyun ret = device_probe(dev);
658*4882a593Smuzhiyun if (ret) {
659*4882a593Smuzhiyun debug("%s: Device '%s' probe failed\n", __func__, dev->name);
660*4882a593Smuzhiyun priv->next_addr--;
661*4882a593Smuzhiyun if (created)
662*4882a593Smuzhiyun device_unbind(dev);
663*4882a593Smuzhiyun return ret;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun *devp = dev;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun return 0;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun /*
671*4882a593Smuzhiyun * Detect if a USB device has been plugged or unplugged.
672*4882a593Smuzhiyun */
usb_detect_change(void)673*4882a593Smuzhiyun int usb_detect_change(void)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun struct udevice *hub;
676*4882a593Smuzhiyun struct uclass *uc;
677*4882a593Smuzhiyun int change = 0;
678*4882a593Smuzhiyun int ret;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun ret = uclass_get(UCLASS_USB_HUB, &uc);
681*4882a593Smuzhiyun if (ret)
682*4882a593Smuzhiyun return ret;
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun uclass_foreach_dev(hub, uc) {
685*4882a593Smuzhiyun struct usb_device *udev;
686*4882a593Smuzhiyun struct udevice *dev;
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun if (!device_active(hub))
689*4882a593Smuzhiyun continue;
690*4882a593Smuzhiyun for (device_find_first_child(hub, &dev);
691*4882a593Smuzhiyun dev;
692*4882a593Smuzhiyun device_find_next_child(&dev)) {
693*4882a593Smuzhiyun struct usb_port_status status;
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun if (!device_active(dev))
696*4882a593Smuzhiyun continue;
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun udev = dev_get_parent_priv(dev);
699*4882a593Smuzhiyun if (usb_get_port_status(udev, udev->portnr, &status)
700*4882a593Smuzhiyun < 0)
701*4882a593Smuzhiyun /* USB request failed */
702*4882a593Smuzhiyun continue;
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun if (le16_to_cpu(status.wPortChange) &
705*4882a593Smuzhiyun USB_PORT_STAT_C_CONNECTION)
706*4882a593Smuzhiyun change++;
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun return change;
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun
usb_child_post_bind(struct udevice * dev)713*4882a593Smuzhiyun static int usb_child_post_bind(struct udevice *dev)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
716*4882a593Smuzhiyun int val;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun if (!dev_of_valid(dev))
719*4882a593Smuzhiyun return 0;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun /* We only support matching a few things */
722*4882a593Smuzhiyun val = dev_read_u32_default(dev, "usb,device-class", -1);
723*4882a593Smuzhiyun if (val != -1) {
724*4882a593Smuzhiyun plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
725*4882a593Smuzhiyun plat->id.bDeviceClass = val;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun val = dev_read_u32_default(dev, "usb,interface-class", -1);
728*4882a593Smuzhiyun if (val != -1) {
729*4882a593Smuzhiyun plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
730*4882a593Smuzhiyun plat->id.bInterfaceClass = val;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun return 0;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun
usb_get_bus(struct udevice * dev)736*4882a593Smuzhiyun struct udevice *usb_get_bus(struct udevice *dev)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun struct udevice *bus;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; )
741*4882a593Smuzhiyun bus = bus->parent;
742*4882a593Smuzhiyun if (!bus) {
743*4882a593Smuzhiyun /* By design this cannot happen */
744*4882a593Smuzhiyun assert(bus);
745*4882a593Smuzhiyun debug("USB HUB '%s' does not have a controller\n", dev->name);
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun return bus;
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun
usb_child_pre_probe(struct udevice * dev)751*4882a593Smuzhiyun int usb_child_pre_probe(struct udevice *dev)
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun struct usb_device *udev = dev_get_parent_priv(dev);
754*4882a593Smuzhiyun struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
755*4882a593Smuzhiyun int ret;
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun if (plat->udev) {
758*4882a593Smuzhiyun /*
759*4882a593Smuzhiyun * Copy over all the values set in the on stack struct
760*4882a593Smuzhiyun * usb_device in usb_scan_device() to our final struct
761*4882a593Smuzhiyun * usb_device for this dev.
762*4882a593Smuzhiyun */
763*4882a593Smuzhiyun *udev = *(plat->udev);
764*4882a593Smuzhiyun /* And clear plat->udev as it will not be valid for long */
765*4882a593Smuzhiyun plat->udev = NULL;
766*4882a593Smuzhiyun udev->dev = dev;
767*4882a593Smuzhiyun } else {
768*4882a593Smuzhiyun /*
769*4882a593Smuzhiyun * This happens with devices which are explicitly bound
770*4882a593Smuzhiyun * instead of being discovered through usb_scan_device()
771*4882a593Smuzhiyun * such as sandbox emul devices.
772*4882a593Smuzhiyun */
773*4882a593Smuzhiyun udev->dev = dev;
774*4882a593Smuzhiyun udev->controller_dev = usb_get_bus(dev);
775*4882a593Smuzhiyun udev->devnum = plat->devnum;
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun /*
778*4882a593Smuzhiyun * udev did not go through usb_scan_device(), so we need to
779*4882a593Smuzhiyun * select the config and read the config descriptors.
780*4882a593Smuzhiyun */
781*4882a593Smuzhiyun ret = usb_select_config(udev);
782*4882a593Smuzhiyun if (ret)
783*4882a593Smuzhiyun return ret;
784*4882a593Smuzhiyun }
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun return 0;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun
789*4882a593Smuzhiyun UCLASS_DRIVER(usb) = {
790*4882a593Smuzhiyun .id = UCLASS_USB,
791*4882a593Smuzhiyun .name = "usb",
792*4882a593Smuzhiyun .flags = DM_UC_FLAG_SEQ_ALIAS,
793*4882a593Smuzhiyun .post_bind = dm_scan_fdt_dev,
794*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct usb_uclass_priv),
795*4882a593Smuzhiyun .per_child_auto_alloc_size = sizeof(struct usb_device),
796*4882a593Smuzhiyun .per_device_auto_alloc_size = sizeof(struct usb_bus_priv),
797*4882a593Smuzhiyun .child_post_bind = usb_child_post_bind,
798*4882a593Smuzhiyun .child_pre_probe = usb_child_pre_probe,
799*4882a593Smuzhiyun .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
800*4882a593Smuzhiyun };
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun UCLASS_DRIVER(usb_dev_generic) = {
803*4882a593Smuzhiyun .id = UCLASS_USB_DEV_GENERIC,
804*4882a593Smuzhiyun .name = "usb_dev_generic",
805*4882a593Smuzhiyun };
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun U_BOOT_DRIVER(usb_dev_generic_drv) = {
808*4882a593Smuzhiyun .id = UCLASS_USB_DEV_GENERIC,
809*4882a593Smuzhiyun .name = "usb_dev_generic_drv",
810*4882a593Smuzhiyun };
811