bind/unbind command not working for usb_ether

Tim Harvey tharvey at gateworks.com
Thu Feb 10 18:04:50 CET 2022


Greetings,

I'm trying to understand how to use the U-Boot bind command to bind
the usb_ether driver to the usb class to register a USB ethernet
gadget network device as referenced in:
commit 02291d83fdaaf ("doc: add bind/unbind command documentation")
commit 49c752c93a78 ("cmd: Add bind/unbind commands to bind a device
to a driver from the command line")

I have enabled:
CONFIG_DM_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETHER=y

However the 'usb_ether' driver is never registered and thus doesn't
appear in a 'dm tree' list and can't be bound to the usb controller.

With the help of Heiko I've found two ways to get the usb_ether driver
to register:

dt-way:
- add of match in ether.c:
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 63d552bc8b..8e2a05a5af 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2690,10 +2690,16 @@ int usb_ether_init(void)
        return 0;
 }

+static const struct udevice_id usb_ether_ids[] = {
+       { .compatible = "gadget,usb_ether" },
+       { }
+};
+
 U_BOOT_DRIVER(eth_usb) = {
        .name   = "usb_ether",
        .id     = UCLASS_ETH,
        .probe  = usb_eth_probe,
+       .of_match = usb_ether_ids,
        .ops    = &usb_eth_ops,
        .priv_auto_alloc_size = sizeof(struct ether_priv),
        .platdata_auto_alloc_size = sizeof(struct eth_pdata),
- then add it directly in your board u-boot.dts:
+&usbotg1 {
+       usb_ether0 {
+               compatible = "gadget,usb_ether";
+               status = "okay";
+       };
+};


The non-dt way:
- bind it manually in board code with:
{
        struct udevice *dev;
        struct udevice *usb_dev;
        int ret;

        ret = uclass_first_device(UCLASS_USB, &usb_dev);
        if (!usb_dev || ret)
                printf("%s: No USB device found\n", __func__);

        ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev);
        if (!dev || ret)
                printf("%s: usb - not able to bind usb_ether
device\n", __func__);
}
- Note that this is the same code from usb_ether_init() but with
UCLASS_USB instead of UCLASS_USB_GADGET_GENERIC

What is the intended way to bind the usb_ether gadget device at runtime?

Additionally Heiko found that once bound and usb_ether is registered
as a network device using a network command like ping/tftpboot calls
usb_setup_ehci_gadget() which removes the USB driver ... and so also
the child usb ethernet gadget device then re-probes only the usb
driver and not the gadget thus fails. I compared this to how the 'ums'
command works and that also removes the usb driver and child nodes but
because ums isn't a gadget driver it doesn't get removed and works.

Best Regards,

Tim


More information about the U-Boot mailing list