bind/unbind command not working for usb_ether
Tim Harvey
tharvey at gateworks.com
Tue Feb 15 19:28:57 CET 2022
On Tue, Feb 15, 2022 at 9:36 AM Patrice CHOTARD
<patrice.chotard at foss.st.com> wrote:
>
> Hi Tim
>
> On 2/15/22 17:09, Tim Harvey wrote:
> > On Tue, Feb 15, 2022 at 5:29 AM Patrice CHOTARD
> > <patrice.chotard at foss.st.com> wrote:
> >>
> >> Hi Tim
> >>
> >> On 2/10/22 18:04, Tim Harvey wrote:
> >>> 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")
> >>>
> >>
> >> For example, i made some trial on STM32MP1 platform:
> >>
> >> At boot, we got :
> >>
> >> STM32MP> dm tree
> >> Class Index Probed Driver Name
> >> -----------------------------------------------------------
> >> root 0 [ + ] root_driver root_driver
> >> firmware 0 [ ] psci |-- psci
> >> sysreset 0 [ ] psci-sysreset | `-- psci-sysreset
> >> .....
> >> blk 0 [ + ] mmc_blk | | `-- mmc at 58005000.blk
> >> ethernet 0 [ + ] eth_eqos | |-- ethernet at 5800a000
> >> eth_phy_ge 0 [ + ] eth_phy_generic_drv | | `-- ethernet-phy at 0
> >> usb 0 [ ] ehci_generic | |-- usb at 5800d000
> >> video 0 [ ] stm32_display | |-- display-controller at 5a001000
> >> .....
> >>
> >>
> >> As you can see, there is already an ethernet interface used.
> >> We unbind the ethernet interface before binding the usb_ether gadget to the usb class.
> >> First unbind the generic ethernet phy (eth_phy_generic_drv) and the ethernet driver
> >> (eth_eqos).
> >>
> >>
> >> STM32MP> unbind eth_phy_generic 0
> >> STM32MP> unbind ethernet 0
> >> STM32MP> dm tree
> >> Class Index Probed Driver Name
> >> -----------------------------------------------------------
> >> root 0 [ + ] root_driver root_driver
> >> firmware 0 [ ] psci |-- psci
> >> sysreset 0 [ ] psci-sysreset | `-- psci-sysreset
> >> ....
> >> blk 0 [ + ] mmc_blk | | `-- mmc at 58005000.blk
> >> usb 0 [ ] ehci_generic | |-- usb at 5800d000
> >> video 0 [ ] stm32_display | |-- display-controller at 5a001000
> >> ....
> >>
> >> Ethernet and phy driver are both unbinded.
> >> Now we can bind the usb_eher to the usb class
> >>
> >> STM32MP> bind usb 0 usb_ether
> >> STM32MP> dm tree
> >> Class Index Probed Driver Name
> >> -----------------------------------------------------------
> >> root 0 [ + ] root_driver root_driver
> >> firmware 0 [ ] psci |-- psci
> >> sysreset 0 [ ] psci-sysreset | `-- psci-sysreset
> >> ....
> >> blk 0 [ + ] mmc_blk | | `-- mmc at 58005000.blk
> >> usb 0 [ ] ehci_generic | |-- usb at 5800d000
> >> ethernet 0 [ ] usb_ether | | `-- usb_ether
> >> video 0 [ ] stm32_display | |-- display-controller at 5a001000
> >> ....
> >>
> >> usb_ether is now binded.
> >> As example, if you can then use some ethernet command as dhcp or ping :
> >>
> >> STM32MP> dhcp
> >> using dwc2-udc, OUT ep2out-bulk IN ep1in-bulk STATUS ep3in-int
> >> MAC de:ad:be:ef:00:01
> >> HOST MAC de:ad:be:ef:00:00
> >> RNDIS ready
> >> high speed config #2: 2 mA, Ethernet Gadget, using RNDIS
> >> USB RNDIS network up!
> >> BOOTP broadcast 1
> >>
> >>> I have enabled:
> >>> CONFIG_DM_USB=y
> >>> CONFIG_USB_GADGET=y
> >>> CONFIG_USB_ETHER=y
> >>>
> >> In my case i enabled also CONFIG_USB_ETH_RNDIS=y
> >>
> >
> > Patrice,
> >
> > In my case when I try to bind to usb_ether the device can not be found
> > (as it is never registered in the first place):
> > Ventana > unbind ethernet 0
> > Ventana > bind usb 0 usb_ether
> > Cannot find device 0 of class usb
>
> weird, because below, in the dm tree output, we can see :
>
> > usb 0 [ ] ehci_mx6 | | |-- usb at 2184000
> > usb 1 [ ] ehci_mx6 | | |-- usb at 2184200
>
> so it should find a usb class device .....
>
Patrice,
I added some debugging and found that 'bind usb 0 usb_ether' does the following:
bind_by_class_index(class="usb" index=0 drv="usb_ether")
uclass_get_by_name(name="usb")
uclass_get_by_name_len(name="usb" len=3)
^^^ does a strncmp with name=usb and len=3 so it matches the first
driver with a class name starting with 'usb' and in this case matches
usb_mass_storage instead of 'usb'
Simon, this behavior comes from commit 4b030177b660 ("dm: core: Allow
finding children / uclasses by partial name"). Why would
device_find_child_by_name() want to use a substring match? I suppose
if there is a valid reason for this such as your commit logs describe
then those functions should directly call uclass_get_by_name_len() and
uclass_get_by_name() should be doing a full name match correct?
Patrice, if I make uclass_get_by_name match the full string with the
below patch then 'bind usb 0 usb_ether' indeed works as planned:
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 2578803b7a4d..33dbca544574 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -196,7 +196,16 @@ enum uclass_id uclass_get_by_name_len(const char
*name, int len)
enum uclass_id uclass_get_by_name(const char *name)
{
- return uclass_get_by_name_len(name, strlen(name));
+ int i;
+
+ for (i = 0; i < UCLASS_COUNT; i++) {
+ struct uclass_driver *uc_drv = lists_uclass_lookup(i);
+
+ if (uc_drv && !strcmp(uc_drv->name, name))
+ return i;
+ }
+
+ return UCLASS_INVALID;
}
int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp)
I don't see the need to unbind 'ethernet' as you can select the active
network device with 'ethact':
Ventana > net list
eth0 : ethernet at 2188000 00:d0:12:f3:f2:f5 active
Ventana > bind usb 0 usb_ether
Ventana > net list
eth0 : ethernet at 2188000 00:d0:12:f3:f2:f5 active
eth1 : usb_ether 00:00:00:00:00:00
Ventana > setenv ethact eth1
Ventana > ping 192.168.1.146
^^^ but now we run into the issue Heiko discovered where the
usb_gadget_register_driver() call from ether.c ends up removing usb
and usb_ether and without his hack to return from device-remove if
device is usb_ether we hang:
@@ -201,12 +202,16 @@ int device_remove(struct udevice *dev, uint flags)
const struct driver *drv;
int ret;
+printf("%s %s\n", __func__, dev->name);
if (!dev)
return -EINVAL;
if (!(dev_get_flags(dev) & DM_FLAG_ACTIVATED))
return 0;
+ if (!strncmp(dev->name, "usb_ether", 8))
+ return 0;
+
/*
* If the child returns EKEYREJECTED, continue. It just means that it
* didn't match the flags.
Best Regards,
Tim
More information about the U-Boot
mailing list