diff options
Diffstat (limited to 'drivers/usb/host/usb-uclass.c')
-rw-r--r-- | drivers/usb/host/usb-uclass.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 7f6a9a6d054..50538e0bd76 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -158,9 +158,6 @@ int usb_stop(void) ret = device_remove(bus); if (ret && !err) err = ret; - ret = device_unbind_children(bus); - if (ret && !err) - err = ret; } #ifdef CONFIG_SANDBOX @@ -205,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children(struct uclass *uc, struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { + struct udevice *dev, *next; + + if (!device_active(bus)) + continue; + device_foreach_child_safe(dev, next, bus) { + if (!device_active(dev)) + device_unbind(dev); + } + } +} + int usb_init(void) { int controllers_initialized = 0; @@ -273,6 +284,15 @@ int usb_init(void) } debug("scan end\n"); + + /* Remove any devices that were not found on this scan */ + remove_inactive_children(uc, bus); + + ret = uclass_get(UCLASS_USB_HUB, &uc); + if (ret) + return ret; + remove_inactive_children(uc, bus); + /* if we were not able to find at least one working bus, bail out */ if (!count) printf("No controllers found\n"); @@ -282,6 +302,14 @@ int usb_init(void) return usb_started ? 0 : -1; } +/* + * TODO(sjg@chromium.org): Remove this legacy function. At present it is needed + * to support boards which use driver model for USB but not Ethernet, and want + * to use USB Ethernet. + * + * The #if clause is here to ensure that remains the only case. + */ +#if !defined(CONFIG_DM_ETH) && defined(CONFIG_USB_HOST_ETHER) static struct usb_device *find_child_devnum(struct udevice *parent, int devnum) { struct usb_device *udev; @@ -315,6 +343,7 @@ struct usb_device *usb_get_dev_index(struct udevice *bus, int index) return find_child_devnum(dev, devnum); } +#endif int usb_post_bind(struct udevice *dev) { @@ -494,14 +523,15 @@ error: } /** - * usb_find_emul_child() - Find an existing device for emulated devices + * usb_find_child() - Find an existing device which matches our needs + * + * */ -static int usb_find_emul_child(struct udevice *parent, - struct usb_device_descriptor *desc, - struct usb_interface_descriptor *iface, - struct udevice **devp) +static int usb_find_child(struct udevice *parent, + struct usb_device_descriptor *desc, + struct usb_interface_descriptor *iface, + struct udevice **devp) { -#ifdef CONFIG_SANDBOX struct udevice *dev; *devp = NULL; @@ -520,7 +550,7 @@ static int usb_find_emul_child(struct udevice *parent, return 0; } } -#endif + return -ENOENT; } @@ -580,8 +610,8 @@ int usb_scan_device(struct udevice *parent, int port, debug("read_descriptor for '%s': ret=%d\n", parent->name, ret); if (ret) return ret; - ret = usb_find_emul_child(parent, &udev->descriptor, iface, &dev); - debug("** usb_find_emul_child returns %d\n", ret); + ret = usb_find_child(parent, &udev->descriptor, iface, &dev); + debug("** usb_find_child returns %d\n", ret); if (ret) { if (ret != -ENOENT) return ret; |