[PATCH v3 1/4] cmd: bind: Add unbind command with driver filter

Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de --- Cc: Kevin Hilman khilman@baylibre.com Cc: Lukasz Majewski lukma@denx.de Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Simon Glass sjg@chromium.org --- V2: No change V3: No change --- cmd/bind.c | 10 +++++----- drivers/core/device.c | 20 +++++++++++++++----- include/dm/device.h | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/cmd/bind.c b/cmd/bind.c index 4d1b7885e60..3137cdf6cb5 100644 --- a/cmd/bind.c +++ b/cmd/bind.c @@ -162,7 +162,7 @@ static int bind_by_node_path(const char *path, const char *drv_name) return 0; }
-static int unbind_by_node_path(const char *path) +static int unbind_by_node_path(const char *path, const char *drv_name) { struct udevice *dev; int ret; @@ -174,7 +174,7 @@ static int unbind_by_node_path(const char *path) return -EINVAL; }
- ret = device_find_global_by_ofnode(ofnode, &dev); + ret = device_find_global_by_ofnode_driver(ofnode, drv_name, &dev);
if (!dev || ret) { printf("Cannot find a device with path %s\n", path); @@ -214,9 +214,9 @@ static int do_bind_unbind(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; ret = bind_by_node_path(argv[1], argv[2]); } else if (by_node && !bind) { - if (argc != 2) + if (argc != 2 && argc != 3) return CMD_RET_USAGE; - ret = unbind_by_node_path(argv[1]); + ret = unbind_by_node_path(argv[1], argv[2]); } else if (!by_node && bind) { int index = (argc > 2) ? dectoul(argv[2], NULL) : 0;
@@ -251,7 +251,7 @@ U_BOOT_CMD( U_BOOT_CMD( unbind, 4, 0, do_bind_unbind, "Unbind a device from a driver", - "<node path>\n" + "<node path> [<driver>]\n" "unbind <class> <index>\n" "unbind <class> <index> <driver>\n" ); diff --git a/drivers/core/device.c b/drivers/core/device.c index 6e26b64fb81..52fceb69341 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -877,15 +877,17 @@ int device_get_child_by_of_offset(const struct udevice *parent, int node, }
static struct udevice *_device_find_global_by_ofnode(struct udevice *parent, - ofnode ofnode) + ofnode ofnode, + const char *drv) { struct udevice *dev, *found;
- if (ofnode_equal(dev_ofnode(parent), ofnode)) + if (ofnode_equal(dev_ofnode(parent), ofnode) && + (!drv || (drv && !strcmp(parent->driver->name, drv)))) return parent;
device_foreach_child(dev, parent) { - found = _device_find_global_by_ofnode(dev, ofnode); + found = _device_find_global_by_ofnode(dev, ofnode, drv); if (found) return found; } @@ -895,7 +897,15 @@ static struct udevice *_device_find_global_by_ofnode(struct udevice *parent,
int device_find_global_by_ofnode(ofnode ofnode, struct udevice **devp) { - *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode); + *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL); + + return *devp ? 0 : -ENOENT; +} + +int device_find_global_by_ofnode_driver(ofnode ofnode, const char *drv, + struct udevice **devp) +{ + *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, drv);
return *devp ? 0 : -ENOENT; } @@ -904,7 +914,7 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp) { struct udevice *dev;
- dev = _device_find_global_by_ofnode(gd->dm_root, ofnode); + dev = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL); return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp); }
diff --git a/include/dm/device.h b/include/dm/device.h index b86bf90609b..5f05ae0924f 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -748,6 +748,23 @@ int device_get_child_by_of_offset(const struct udevice *parent, int of_offset,
int device_find_global_by_ofnode(ofnode node, struct udevice **devp);
+/** + * device_find_global_by_ofnode_driver() - Get a device based on ofnode and driver + * + * Locates a device by its device tree ofnode and driver currently bound to + * it, searching globally throughout the all driver model devices. + * + * The device is NOT probed + * + * @node: Device tree ofnode to find + * @drv: Driver name bound to device + * @devp: Returns pointer to device if found, otherwise this is set to NULL + * Return: 0 if OK, -ve on error + */ + +int device_find_global_by_ofnode_driver(ofnode node, const char *drv, + struct udevice **devp); + /** * device_get_global_by_ofnode() - Get a device based on ofnode *

These functions here are only ever called once since drop of non-DM networking code. Inline them. No functional change.
Signed-off-by: Marek Vasut marex@denx.de --- Cc: Kevin Hilman khilman@baylibre.com Cc: Lukasz Majewski lukma@denx.de Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Simon Glass sjg@chromium.org --- V2: No change V3: No change --- drivers/usb/gadget/ether.c | 48 +++++++------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 85c971e4c43..88c656c4dc0 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2273,10 +2273,11 @@ fail: }
/*-------------------------------------------------------------------------*/ -static void _usb_eth_halt(struct ether_priv *priv); +static void usb_eth_stop(struct udevice *dev);
-static int _usb_eth_init(struct ether_priv *priv) +static int usb_eth_start(struct udevice *udev) { + struct ether_priv *priv = dev_get_priv(udev); struct eth_dev *dev = &priv->ethdev; struct usb_gadget *gadget; unsigned long ts; @@ -2347,12 +2348,13 @@ static int _usb_eth_init(struct ether_priv *priv) rx_submit(dev, dev->rx_req, 0); return 0; fail: - _usb_eth_halt(priv); + usb_eth_stop(udev); return -1; }
-static int _usb_eth_send(struct ether_priv *priv, void *packet, int length) +static int usb_eth_send(struct udevice *udev, void *packet, int length) { + struct ether_priv *priv = dev_get_priv(udev); int retval; void *rndis_pkt = NULL; struct eth_dev *dev = &priv->ethdev; @@ -2419,15 +2421,9 @@ drop: return -ENOMEM; }
-static int _usb_eth_recv(struct ether_priv *priv) -{ - usb_gadget_handle_interrupts(0); - - return 0; -} - -static void _usb_eth_halt(struct ether_priv *priv) +static void usb_eth_stop(struct udevice *udev) { + struct ether_priv *priv = dev_get_priv(udev); struct eth_dev *dev = &priv->ethdev;
/* If the gadget not registered, simple return */ @@ -2459,31 +2455,12 @@ static void _usb_eth_halt(struct ether_priv *priv) usb_gadget_release(0); }
-static int usb_eth_start(struct udevice *dev) -{ - struct ether_priv *priv = dev_get_priv(dev); - - return _usb_eth_init(priv); -} - -static int usb_eth_send(struct udevice *dev, void *packet, int length) -{ - struct ether_priv *priv = dev_get_priv(dev); - - return _usb_eth_send(priv, packet, length); -} - static int usb_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct ether_priv *priv = dev_get_priv(dev); struct eth_dev *ethdev = &priv->ethdev; - int ret;
- ret = _usb_eth_recv(priv); - if (ret) { - pr_err("error packet receive\n"); - return ret; - } + usb_gadget_handle_interrupts(0);
if (packet_received) { if (ethdev->rx_req) { @@ -2509,13 +2486,6 @@ static int usb_eth_free_pkt(struct udevice *dev, uchar *packet, return rx_submit(ethdev, ethdev->rx_req, 0); }
-static void usb_eth_stop(struct udevice *dev) -{ - struct ether_priv *priv = dev_get_priv(dev); - - _usb_eth_halt(priv); -} - static int usb_eth_probe(struct udevice *dev) { struct ether_priv *priv = dev_get_priv(dev);

Move the driver probe function above the driver structure, so it can be placed alongside other related functions, like upcoming remove function. No functional change.
Signed-off-by: Marek Vasut marex@denx.de --- Cc: Kevin Hilman khilman@baylibre.com Cc: Lukasz Majewski lukma@denx.de Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Simon Glass sjg@chromium.org --- V2: No change V3: No change --- drivers/usb/gadget/ether.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 88c656c4dc0..2040b5b5081 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2486,20 +2486,6 @@ static int usb_eth_free_pkt(struct udevice *dev, uchar *packet, return rx_submit(ethdev, ethdev->rx_req, 0); }
-static int usb_eth_probe(struct udevice *dev) -{ - struct ether_priv *priv = dev_get_priv(dev); - struct eth_pdata *pdata = dev_get_plat(dev); - - priv->netdev = dev; - l_priv = priv; - - get_ether_addr(CONFIG_USBNET_DEV_ADDR, pdata->enetaddr); - eth_env_set_enetaddr("usbnet_devaddr", pdata->enetaddr); - - return 0; -} - static const struct eth_ops usb_eth_ops = { .start = usb_eth_start, .send = usb_eth_send, @@ -2528,6 +2514,20 @@ int usb_ether_init(void) return 0; }
+static int usb_eth_probe(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + + priv->netdev = dev; + l_priv = priv; + + get_ether_addr(CONFIG_USBNET_DEV_ADDR, pdata->enetaddr); + eth_env_set_enetaddr("usbnet_devaddr", pdata->enetaddr); + + return 0; +} + U_BOOT_DRIVER(eth_usb) = { .name = "usb_ether", .id = UCLASS_ETH,

Move the ethernet gadget driver registration and removal from ethernet bind and unbind callbacks into driver DM probe and remove callbacks. This way, when the driver is bound, which is triggered deliberately using 'bind' command, the USB ethernet gadget driver is instantiated and bound to the matching UDC. In reverse, when the driver is unbound, which is again triggered deliberately using 'unbind' command, the USB ethernet gadget driver instance is removed.
Effectively, this now behaves like running either 'ums' or 'dfu' or any other commands utilizing USB gadget functionality.
This also drops use of usb_gadget_release() and moves the use of usb_gadget_initialize() into usb_ether_init() used only by legacy platforms that do not use 'bind' command properly yet. Those have no place in drivers.
Signed-off-by: Marek Vasut marex@denx.de --- NOTE: This must be thoroughly tested. --- Cc: Kevin Hilman khilman@baylibre.com Cc: Lukasz Majewski lukma@denx.de Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Simon Glass sjg@chromium.org --- V2: Fix up return value handling in probe V3: Reinstate usb_gadget_initialize() in usb_ether_init() to retain this obscure workaround for legacy platforms that fail to use bind command --- drivers/usb/gadget/ether.c | 89 +++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 45 deletions(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 2040b5b5081..ecbae1c83ea 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2281,49 +2281,8 @@ static int usb_eth_start(struct udevice *udev) struct eth_dev *dev = &priv->ethdev; struct usb_gadget *gadget; unsigned long ts; - int ret; unsigned long timeout = USB_CONNECT_TIMEOUT;
- ret = usb_gadget_initialize(0); - if (ret) - return ret; - - /* Configure default mac-addresses for the USB ethernet device */ -#ifdef CONFIG_USBNET_DEV_ADDR - strlcpy(dev_addr, CONFIG_USBNET_DEV_ADDR, sizeof(dev_addr)); -#endif -#ifdef CONFIG_USBNET_HOST_ADDR - strlcpy(host_addr, CONFIG_USBNET_HOST_ADDR, sizeof(host_addr)); -#endif - /* Check if the user overruled the MAC addresses */ - if (env_get("usbnet_devaddr")) - strlcpy(dev_addr, env_get("usbnet_devaddr"), - sizeof(dev_addr)); - - if (env_get("usbnet_hostaddr")) - strlcpy(host_addr, env_get("usbnet_hostaddr"), - sizeof(host_addr)); - - if (!is_eth_addr_valid(dev_addr)) { - pr_err("Need valid 'usbnet_devaddr' to be set"); - goto fail; - } - if (!is_eth_addr_valid(host_addr)) { - pr_err("Need valid 'usbnet_hostaddr' to be set"); - goto fail; - } - - priv->eth_driver.speed = DEVSPEED; - priv->eth_driver.bind = eth_bind; - priv->eth_driver.unbind = eth_unbind; - priv->eth_driver.setup = eth_setup; - priv->eth_driver.reset = eth_disconnect; - priv->eth_driver.disconnect = eth_disconnect; - priv->eth_driver.suspend = eth_suspend; - priv->eth_driver.resume = eth_resume; - if (usb_gadget_register_driver(&priv->eth_driver) < 0) - goto fail; - dev->network_started = 0;
packet_received = 0; @@ -2450,9 +2409,6 @@ static void usb_eth_stop(struct udevice *udev) usb_gadget_handle_interrupts(0); dev->network_started = 0; } - - usb_gadget_unregister_driver(&priv->eth_driver); - usb_gadget_release(0); }
static int usb_eth_recv(struct udevice *dev, int flags, uchar **packetp) @@ -2511,7 +2467,7 @@ int usb_ether_init(void) return ret; }
- return 0; + return usb_gadget_initialize(0); }
static int usb_eth_probe(struct udevice *dev) @@ -2525,6 +2481,48 @@ static int usb_eth_probe(struct udevice *dev) get_ether_addr(CONFIG_USBNET_DEV_ADDR, pdata->enetaddr); eth_env_set_enetaddr("usbnet_devaddr", pdata->enetaddr);
+ /* Configure default mac-addresses for the USB ethernet device */ +#ifdef CONFIG_USBNET_DEV_ADDR + strlcpy(dev_addr, CONFIG_USBNET_DEV_ADDR, sizeof(dev_addr)); +#endif +#ifdef CONFIG_USBNET_HOST_ADDR + strlcpy(host_addr, CONFIG_USBNET_HOST_ADDR, sizeof(host_addr)); +#endif + /* Check if the user overruled the MAC addresses */ + if (env_get("usbnet_devaddr")) + strlcpy(dev_addr, env_get("usbnet_devaddr"), + sizeof(dev_addr)); + + if (env_get("usbnet_hostaddr")) + strlcpy(host_addr, env_get("usbnet_hostaddr"), + sizeof(host_addr)); + + if (!is_eth_addr_valid(dev_addr)) { + pr_err("Need valid 'usbnet_devaddr' to be set"); + return -EINVAL; + } + if (!is_eth_addr_valid(host_addr)) { + pr_err("Need valid 'usbnet_hostaddr' to be set"); + return -EINVAL; + } + + priv->eth_driver.speed = DEVSPEED; + priv->eth_driver.bind = eth_bind; + priv->eth_driver.unbind = eth_unbind; + priv->eth_driver.setup = eth_setup; + priv->eth_driver.reset = eth_disconnect; + priv->eth_driver.disconnect = eth_disconnect; + priv->eth_driver.suspend = eth_suspend; + priv->eth_driver.resume = eth_resume; + return usb_gadget_register_driver(&priv->eth_driver); +} + +static int usb_eth_remove(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + usb_gadget_unregister_driver(&priv->eth_driver); + return 0; }
@@ -2532,6 +2530,7 @@ U_BOOT_DRIVER(eth_usb) = { .name = "usb_ether", .id = UCLASS_ETH, .probe = usb_eth_probe, + .remove = usb_eth_remove, .ops = &usb_eth_ops, .priv_auto = sizeof(struct ether_priv), .plat_auto = sizeof(struct eth_pdata),

Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200:
Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Thanks, Miquèl
Cc: Kevin Hilman khilman@baylibre.com Cc: Lukasz Majewski lukma@denx.de Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Simon Glass sjg@chromium.org
V2: No change V3: No change
cmd/bind.c | 10 +++++----- drivers/core/device.c | 20 +++++++++++++++----- include/dm/device.h | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/cmd/bind.c b/cmd/bind.c index 4d1b7885e60..3137cdf6cb5 100644 --- a/cmd/bind.c +++ b/cmd/bind.c @@ -162,7 +162,7 @@ static int bind_by_node_path(const char *path, const char *drv_name) return 0; }
-static int unbind_by_node_path(const char *path) +static int unbind_by_node_path(const char *path, const char *drv_name) { struct udevice *dev; int ret; @@ -174,7 +174,7 @@ static int unbind_by_node_path(const char *path) return -EINVAL; }
- ret = device_find_global_by_ofnode(ofnode, &dev);
ret = device_find_global_by_ofnode_driver(ofnode, drv_name, &dev);
if (!dev || ret) { printf("Cannot find a device with path %s\n", path);
@@ -214,9 +214,9 @@ static int do_bind_unbind(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; ret = bind_by_node_path(argv[1], argv[2]); } else if (by_node && !bind) {
if (argc != 2)
if (argc != 2 && argc != 3) return CMD_RET_USAGE;
ret = unbind_by_node_path(argv[1]);
} else if (!by_node && bind) { int index = (argc > 2) ? dectoul(argv[2], NULL) : 0;ret = unbind_by_node_path(argv[1], argv[2]);
@@ -251,7 +251,7 @@ U_BOOT_CMD( U_BOOT_CMD( unbind, 4, 0, do_bind_unbind, "Unbind a device from a driver",
- "<node path>\n"
- "<node path> [<driver>]\n" "unbind <class> <index>\n" "unbind <class> <index> <driver>\n"
); diff --git a/drivers/core/device.c b/drivers/core/device.c index 6e26b64fb81..52fceb69341 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -877,15 +877,17 @@ int device_get_child_by_of_offset(const struct udevice *parent, int node, }
static struct udevice *_device_find_global_by_ofnode(struct udevice *parent,
ofnode ofnode)
ofnode ofnode,
const char *drv)
{ struct udevice *dev, *found;
- if (ofnode_equal(dev_ofnode(parent), ofnode))
if (ofnode_equal(dev_ofnode(parent), ofnode) &&
(!drv || (drv && !strcmp(parent->driver->name, drv))))
return parent;
device_foreach_child(dev, parent) {
found = _device_find_global_by_ofnode(dev, ofnode);
if (found) return found; }found = _device_find_global_by_ofnode(dev, ofnode, drv);
@@ -895,7 +897,15 @@ static struct udevice *_device_find_global_by_ofnode(struct udevice *parent,
int device_find_global_by_ofnode(ofnode ofnode, struct udevice **devp) {
- *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode);
- *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL);
- return *devp ? 0 : -ENOENT;
+}
+int device_find_global_by_ofnode_driver(ofnode ofnode, const char *drv,
struct udevice **devp)
+{
*devp = _device_find_global_by_ofnode(gd->dm_root, ofnode, drv);
return *devp ? 0 : -ENOENT;
} @@ -904,7 +914,7 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp) { struct udevice *dev;
- dev = _device_find_global_by_ofnode(gd->dm_root, ofnode);
- dev = _device_find_global_by_ofnode(gd->dm_root, ofnode, NULL); return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}
diff --git a/include/dm/device.h b/include/dm/device.h index b86bf90609b..5f05ae0924f 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -748,6 +748,23 @@ int device_get_child_by_of_offset(const struct udevice *parent, int of_offset,
int device_find_global_by_ofnode(ofnode node, struct udevice **devp);
+/**
- device_find_global_by_ofnode_driver() - Get a device based on ofnode and driver
- Locates a device by its device tree ofnode and driver currently bound to
- it, searching globally throughout the all driver model devices.
- The device is NOT probed
- @node: Device tree ofnode to find
- @drv: Driver name bound to device
- @devp: Returns pointer to device if found, otherwise this is set to NULL
- Return: 0 if OK, -ve on error
- */
+int device_find_global_by_ofnode_driver(ofnode node, const char *drv,
struct udevice **devp);
/**
- device_get_global_by_ofnode() - Get a device based on ofnode

On 7/31/23 11:31, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200:
Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.

Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200:
On 7/31/23 11:31, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200:
Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error:
=> unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Thanks, Miquèl

On 7/31/23 15:36, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200:
On 7/31/23 11:31, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200:
Extend the driver core to perform lookup by both OF node and driver bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error:
=> unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.

Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200:
On 7/31/23 15:36, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200:
On 7/31/23 11:31, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200:
>> Extend the driver core to perform lookup by both OF node and driver
bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is:
> => fastboot usb 0
couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error:
=> unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
CPU : AM335X-GP rev 2.1 Model: TI AM335x BeagleBone Black DRAM: 512 MiB Core: 160 devices, 18 uclasses, devicetree: separate WDT: Started wdt@44e35000 with servicing every 1000ms (60s timeout) NAND: 0 MiB MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 Loading Environment from FAT... Unable to read "uboot.env" from mmc1:1... <ethaddr> not set. Validating first E-fuse MAC Net: Could not get PHY for ethernet@4a100000: addr 0 eth2: ethernet@4a100000using musb-hdrc, OUT ep1out IN ep1in STATUS ep2in MAC de:ad:be:ef:00:01 HOST MAC de:ad:be:ef:00:00 RNDIS ready , eth3: usb_ether => dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver rsa_mod_ex 0 [ ] mod_exp_sw |-- mod_exp_sw simple_bus 0 [ + ] simple_bus |-- ocp simple_bus 1 [ + ] simple_bus | |-- l4_wkup@44c00000 simple_bus 2 [ ] simple_bus | | |-- segment@0 simple_bus 3 [ ] simple_bus | | |-- segment@100000 simple_bus 4 [ + ] simple_bus | | `-- segment@200000 simple_bus 5 [ + ] ti_sysc | | |-- target-module@0 simple_bus 6 [ + ] simple_bus | | | `-- prcm@0 simple_bus 7 [ ] simple_bus | | | |-- clocks clk 0 [ ] fixed_clock | | | | |-- clock-clk-32768 clk 1 [ ] fixed_clock | | | | |-- clock-clk-rc32k clk 2 [ ] fixed_clock | | | | |-- clock-virt-192000 00 clk 3 [ ] fixed_clock | | | | |-- clock-virt-240000 00 clk 4 [ ] fixed_clock | | | | |-- clock-virt-250000 00 clk 5 [ ] fixed_clock | | | | |-- clock-virt-260000 00 clk 6 [ ] fixed_clock | | | | |-- clock-tclkin clk 7 [ ] fixed_factor_clock | | | | |-- clock-dpll-ddr-m2 -div2 clk 8 [ ] fixed_factor_clock | | | | |-- clock-dpll-per-m2 -div4-wkupdm clk 9 [ ] fixed_factor_clock | | | | |-- clock-dpll-per-m2 -div4 clk 10 [ ] fixed_factor_clock | | | | |-- clock-clk-24mhz clk 11 [ ] fixed_factor_clock | | | | |-- clock-clkdiv32k clk 12 [ ] fixed_factor_clock | | | | |-- clock-l3-gclk clk 13 [ ] fixed_factor_clock | | | | |-- clock-dpll-core-m 4-div2 clk 14 [ ] fixed_factor_clock | | | | |-- clock-l4-rtc-gclk clk 15 [ ] fixed_factor_clock | | | | |-- clock-l4hs-gclk clk 16 [ ] fixed_factor_clock | | | | |-- clock-l3s-gclk clk 17 [ ] fixed_factor_clock | | | | |-- clock-l4fw-gclk clk 18 [ ] fixed_factor_clock | | | | |-- clock-l4ls-gclk clk 19 [ ] fixed_factor_clock | | | | |-- clock-sysclk-div clk 20 [ ] fixed_factor_clock | | | | |-- clock-cpsw-125mhz -gclk clk 21 [ ] fixed_factor_clock | | | | `-- clock-mmc simple_bus 8 [ ] ti_omap4_cm | | | |-- clock@0 clk 22 [ ] ti_ctrl_clk | | | | |-- clock@38 clk 23 [ ] ti_ctrl_clk | | | | |-- clock@1c clk 24 [ ] ti_ctrl_clk | | | | |-- clock@24 clk 25 [ ] ti_ctrl_clk | | | | |-- clock@120 clk 26 [ ] ti_ctrl_clk | | | | |-- clock@e8 clk 27 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 28 [ ] ti_ctrl_clk | | | | |-- clock@18 clk 29 [ ] ti_ctrl_clk | | | | |-- clock@14c clk 30 [ ] ti_ctrl_clk | | | | |-- clock@38 clk 31 [ ] ti_ctrl_clk | | | | |-- clock@1c clk 32 [ ] ti_ctrl_clk | | | | |-- clock@24 clk 33 [ ] ti_ctrl_clk | | | | |-- clock@120 clk 34 [ ] ti_ctrl_clk | | | | |-- clock@e8 clk 35 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 36 [ ] ti_ctrl_clk | | | | |-- clock@18 clk 37 [ ] ti_ctrl_clk | | | | `-- clock@14c simple_bus 9 [ + ] ti_omap4_cm | | | |-- clock@400 clk 38 [ + ] ti_ctrl_clk | | | | |-- clock@0 clk 39 [ ] ti_ctrl_clk | | | | |-- clock@14 clk 40 [ ] ti_ctrl_clk | | | | |-- clock@b0 clk 41 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 42 [ ] ti_ctrl_clk | | | | |-- clock@14 clk 43 [ ] ti_ctrl_clk | | | | `-- clock@b0 simple_bus 10 [ ] ti_omap4_cm | | | |-- clock@600 clk 44 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 45 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 11 [ ] ti_omap4_cm | | | |-- clock@800 clk 46 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 47 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 12 [ ] ti_omap4_cm | | | |-- clock@900 clk 48 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 49 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 13 [ ] ti_omap4_cm | | | `-- clock@a00 clk 50 [ ] ti_ctrl_clk | | | |-- clock@0 clk 51 [ ] ti_ctrl_clk | | | `-- clock@0 simple_bus 14 [ + ] ti_sysc | | |-- target-module@7000 gpio 0 [ + ] gpio_omap | | | `-- gpio@0 simple_bus 15 [ + ] ti_sysc | | |-- target-module@9000 serial 0 [ + ] omap_serial | | | `-- serial@0 simple_bus 16 [ ] ti_sysc | | |-- target-module@b000 simple_bus 17 [ ] ti_sysc | | |-- target-module@d000 simple_bus 18 [ ] ti_sysc | | |-- target-module@10000 simple_bus 19 [ ] simple_bus | | | `-- scm@0 simple_bus 20 [ ] simple_bus | | | `-- scm_conf@0 simple_bus 21 [ ] simple_bus | | | `-- clocks clk 52 [ ] fixed_factor_clock | | | |-- clock-adc-tsc -fck clk 53 [ ] fixed_factor_clock | | | |-- clock-dcan0-f ck clk 54 [ ] fixed_factor_clock | | | |-- clock-dcan1-f ck clk 55 [ ] fixed_factor_clock | | | |-- clock-mcasp0- fck clk 56 [ ] fixed_factor_clock | | | |-- clock-mcasp1- fck clk 57 [ ] fixed_factor_clock | | | |-- clock-smartre flex0-fck clk 58 [ ] fixed_factor_clock | | | |-- clock-smartre flex1-fck clk 59 [ ] fixed_factor_clock | | | |-- clock-sha0-fc k clk 60 [ ] fixed_factor_clock | | | |-- clock-aes0-fc k clk 61 [ ] fixed_factor_clock | | | `-- clock-rng-fck simple_bus 22 [ ] ti_sysc | | |-- target-module@35000 simple_bus 23 [ ] ti_sysc | | `-- target-module@3e000 simple_bus 24 [ ] simple_bus | |-- interconnect@48000000 simple_bus 25 [ ] simple_bus | | |-- segment@0 simple_bus 26 [ ] ti_sysc | | | |-- target-module@22000 simple_bus 27 [ ] ti_sysc | | | |-- target-module@24000 simple_bus 28 [ ] ti_sysc | | | |-- target-module@2a000 simple_bus 29 [ ] ti_sysc | | | |-- target-module@30000 simple_bus 30 [ ] ti_sysc | | | |-- target-module@38000 simple_bus 31 [ ] ti_sysc | | | |-- target-module@3c000 simple_bus 32 [ ] ti_sysc | | | |-- target-module@4c000 gpio 1 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 33 [ ] ti_sysc | | | |-- target-module@60000 simple_bus 34 [ ] ti_sysc | | | |-- target-module@80000 simple_bus 35 [ ] ti_sysc | | | |-- target-module@c8000 simple_bus 36 [ ] ti_sysc | | | `-- target-module@ca000 simple_bus 37 [ ] simple_bus | | |-- segment@100000 simple_bus 38 [ ] ti_sysc | | | |-- target-module@9c000 simple_bus 39 [ ] ti_sysc | | | |-- target-module@a0000 simple_bus 40 [ ] ti_sysc | | | |-- target-module@a6000 simple_bus 41 [ ] ti_sysc | | | |-- target-module@a8000 simple_bus 42 [ ] ti_sysc | | | |-- target-module@aa000 simple_bus 43 [ ] ti_sysc | | | |-- target-module@ac000 gpio 2 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 44 [ ] ti_sysc | | | |-- target-module@ae000 gpio 3 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 45 [ ] ti_sysc | | | |-- target-module@cc000 simple_bus 46 [ ] ti_sysc | | | |-- target-module@d0000 simple_bus 47 [ ] ti_sysc | | | `-- target-module@d8000 simple_bus 48 [ ] simple_bus | | |-- segment@200000 simple_bus 49 [ ] simple_bus | | `-- segment@300000 simple_bus 50 [ ] ti_sysc | | |-- target-module@0 simple_bus 51 [ ] ti_sysc | | |-- target-module@2000 simple_bus 52 [ ] ti_sysc | | |-- target-module@4000 simple_bus 53 [ ] ti_sysc | | |-- target-module@e000 simple_bus 54 [ ] ti_sysc | | `-- target-module@10000 simple_bus 55 [ ] simple_bus | |-- interconnect@47c00000 simple_bus 56 [ ] simple_bus | | `-- segment@0 simple_bus 57 [ ] simple_bus | |-- interconnect@4a000000 simple_bus 58 [ ] simple_bus | | `-- segment@0 simple_bus 59 [ ] ti_sysc | | `-- target-module@100000 simple_bus 60 [ ] simple_bus | |-- interconnect@4b140000 simple_bus 61 [ ] simple_bus | | `-- segment@0 simple_bus 62 [ ] ti_sysc | |-- target-module@49000000 simple_bus 63 [ ] ti_sysc | |-- target-module@49800000 simple_bus 64 [ ] ti_sysc | |-- target-module@49900000 simple_bus 65 [ ] ti_sysc | |-- target-module@49a00000 simple_bus 66 [ ] ti_sysc | |-- target-module@47810000 i2c 0 [ ] i2c_omap | |-- i2c@44e0b000 pmic 0 [ ] tps65217 pmic | | `-- tps@24 i2c 1 [ ] i2c_omap | |-- i2c@4819c000 mmc 0 [ + ] omap_hsmmc | |-- mmc@48060000 blk 0 [ ] mmc_blk | | |-- mmc@48060000.blk bootdev 0 [ ] mmc_bootdev | | `-- mmc@48060000.bootdev mmc 1 [ + ] omap_hsmmc | |-- mmc@481d8000 blk 1 [ + ] mmc_blk | | |-- mmc@481d8000.blk partition 0 [ + ] blk_partition | | | `-- mmc@481d8000.blk:1 bootdev 1 [ ] mmc_bootdev | | `-- mmc@481d8000.bootdev watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000 => dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver rsa_mod_ex 0 [ ] mod_exp_sw |-- mod_exp_sw simple_bus 0 [ + ] simple_bus |-- ocp simple_bus 1 [ + ] simple_bus | |-- l4_wkup@44c00000 simple_bus 2 [ ] simple_bus | | |-- segment@0 simple_bus 3 [ ] simple_bus | | |-- segment@100000 simple_bus 4 [ + ] simple_bus | | `-- segment@200000 simple_bus 5 [ + ] ti_sysc | | |-- target-module@0 simple_bus 6 [ + ] simple_bus | | | `-- prcm@0 simple_bus 7 [ ] simple_bus | | | |-- clocks clk 0 [ ] fixed_clock | | | | |-- clock-clk-32768 clk 1 [ ] fixed_clock | | | | |-- clock-clk-rc32k clk 2 [ ] fixed_clock | | | | |-- clock-virt-192000 00 clk 3 [ ] fixed_clock | | | | |-- clock-virt-240000 00 clk 4 [ ] fixed_clock | | | | |-- clock-virt-250000 00 clk 5 [ ] fixed_clock | | | | |-- clock-virt-260000 00 clk 6 [ ] fixed_clock | | | | |-- clock-tclkin clk 7 [ ] fixed_factor_clock | | | | |-- clock-dpll-ddr-m2 -div2 clk 8 [ ] fixed_factor_clock | | | | |-- clock-dpll-per-m2 -div4-wkupdm clk 9 [ ] fixed_factor_clock | | | | |-- clock-dpll-per-m2 -div4 clk 10 [ ] fixed_factor_clock | | | | |-- clock-clk-24mhz clk 11 [ ] fixed_factor_clock | | | | |-- clock-clkdiv32k clk 12 [ ] fixed_factor_clock | | | | |-- clock-l3-gclk clk 13 [ ] fixed_factor_clock | | | | |-- clock-dpll-core-m 4-div2 clk 14 [ ] fixed_factor_clock | | | | |-- clock-l4-rtc-gclk clk 15 [ ] fixed_factor_clock | | | | |-- clock-l4hs-gclk clk 16 [ ] fixed_factor_clock | | | | |-- clock-l3s-gclk clk 17 [ ] fixed_factor_clock | | | | |-- clock-l4fw-gclk clk 18 [ ] fixed_factor_clock | | | | |-- clock-l4ls-gclk clk 19 [ ] fixed_factor_clock | | | | |-- clock-sysclk-div clk 20 [ ] fixed_factor_clock | | | | |-- clock-cpsw-125mhz -gclk clk 21 [ ] fixed_factor_clock | | | | `-- clock-mmc simple_bus 8 [ ] ti_omap4_cm | | | |-- clock@0 clk 22 [ ] ti_ctrl_clk | | | | |-- clock@38 clk 23 [ ] ti_ctrl_clk | | | | |-- clock@1c clk 24 [ ] ti_ctrl_clk | | | | |-- clock@24 clk 25 [ ] ti_ctrl_clk | | | | |-- clock@120 clk 26 [ ] ti_ctrl_clk | | | | |-- clock@e8 clk 27 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 28 [ ] ti_ctrl_clk | | | | |-- clock@18 clk 29 [ ] ti_ctrl_clk | | | | |-- clock@14c clk 30 [ ] ti_ctrl_clk | | | | |-- clock@38 clk 31 [ ] ti_ctrl_clk | | | | |-- clock@1c clk 32 [ ] ti_ctrl_clk | | | | |-- clock@24 clk 33 [ ] ti_ctrl_clk | | | | |-- clock@120 clk 34 [ ] ti_ctrl_clk | | | | |-- clock@e8 clk 35 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 36 [ ] ti_ctrl_clk | | | | |-- clock@18 clk 37 [ ] ti_ctrl_clk | | | | `-- clock@14c simple_bus 9 [ + ] ti_omap4_cm | | | |-- clock@400 clk 38 [ + ] ti_ctrl_clk | | | | |-- clock@0 clk 39 [ ] ti_ctrl_clk | | | | |-- clock@14 clk 40 [ ] ti_ctrl_clk | | | | |-- clock@b0 clk 41 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 42 [ ] ti_ctrl_clk | | | | |-- clock@14 clk 43 [ ] ti_ctrl_clk | | | | `-- clock@b0 simple_bus 10 [ ] ti_omap4_cm | | | |-- clock@600 clk 44 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 45 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 11 [ ] ti_omap4_cm | | | |-- clock@800 clk 46 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 47 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 12 [ ] ti_omap4_cm | | | |-- clock@900 clk 48 [ ] ti_ctrl_clk | | | | |-- clock@0 clk 49 [ ] ti_ctrl_clk | | | | `-- clock@0 simple_bus 13 [ ] ti_omap4_cm | | | `-- clock@a00 clk 50 [ ] ti_ctrl_clk | | | |-- clock@0 clk 51 [ ] ti_ctrl_clk | | | `-- clock@0 simple_bus 14 [ + ] ti_sysc | | |-- target-module@7000 gpio 0 [ + ] gpio_omap | | | `-- gpio@0 simple_bus 15 [ + ] ti_sysc | | |-- target-module@9000 serial 0 [ + ] omap_serial | | | `-- serial@0 simple_bus 16 [ ] ti_sysc | | |-- target-module@b000 simple_bus 17 [ ] ti_sysc | | |-- target-module@d000 simple_bus 18 [ ] ti_sysc | | |-- target-module@10000 simple_bus 19 [ ] simple_bus | | | `-- scm@0 simple_bus 20 [ ] simple_bus | | | `-- scm_conf@0 simple_bus 21 [ ] simple_bus | | | `-- clocks clk 52 [ ] fixed_factor_clock | | | |-- clock-adc-tsc -fck clk 53 [ ] fixed_factor_clock | | | |-- clock-dcan0-f ck clk 54 [ ] fixed_factor_clock | | | |-- clock-dcan1-f ck clk 55 [ ] fixed_factor_clock | | | |-- clock-mcasp0- fck clk 56 [ ] fixed_factor_clock | | | |-- clock-mcasp1- fck clk 57 [ ] fixed_factor_clock | | | |-- clock-smartre flex0-fck clk 58 [ ] fixed_factor_clock | | | |-- clock-smartre flex1-fck clk 59 [ ] fixed_factor_clock | | | |-- clock-sha0-fc k clk 60 [ ] fixed_factor_clock | | | |-- clock-aes0-fc k clk 61 [ ] fixed_factor_clock | | | `-- clock-rng-fck simple_bus 22 [ ] ti_sysc | | |-- target-module@35000 simple_bus 23 [ ] ti_sysc | | `-- target-module@3e000 simple_bus 24 [ ] simple_bus | |-- interconnect@48000000 simple_bus 25 [ ] simple_bus | | |-- segment@0 simple_bus 26 [ ] ti_sysc | | | |-- target-module@22000 simple_bus 27 [ ] ti_sysc | | | |-- target-module@24000 simple_bus 28 [ ] ti_sysc | | | |-- target-module@2a000 simple_bus 29 [ ] ti_sysc | | | |-- target-module@30000 simple_bus 30 [ ] ti_sysc | | | |-- target-module@38000 simple_bus 31 [ ] ti_sysc | | | |-- target-module@3c000 simple_bus 32 [ ] ti_sysc | | | |-- target-module@4c000 gpio 1 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 33 [ ] ti_sysc | | | |-- target-module@60000 simple_bus 34 [ ] ti_sysc | | | |-- target-module@80000 simple_bus 35 [ ] ti_sysc | | | |-- target-module@c8000 simple_bus 36 [ ] ti_sysc | | | `-- target-module@ca000 simple_bus 37 [ ] simple_bus | | |-- segment@100000 simple_bus 38 [ ] ti_sysc | | | |-- target-module@9c000 simple_bus 39 [ ] ti_sysc | | | |-- target-module@a0000 simple_bus 40 [ ] ti_sysc | | | |-- target-module@a6000 simple_bus 41 [ ] ti_sysc | | | |-- target-module@a8000 simple_bus 42 [ ] ti_sysc | | | |-- target-module@aa000 simple_bus 43 [ ] ti_sysc | | | |-- target-module@ac000 gpio 2 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 44 [ ] ti_sysc | | | |-- target-module@ae000 gpio 3 [ ] gpio_omap | | | | `-- gpio@0 simple_bus 45 [ ] ti_sysc | | | |-- target-module@cc000 simple_bus 46 [ ] ti_sysc | | | |-- target-module@d0000 simple_bus 47 [ ] ti_sysc | | | `-- target-module@d8000 simple_bus 48 [ ] simple_bus | | |-- segment@200000 simple_bus 49 [ ] simple_bus | | `-- segment@300000 simple_bus 50 [ ] ti_sysc | | |-- target-module@0 simple_bus 51 [ ] ti_sysc | | |-- target-module@2000 simple_bus 52 [ ] ti_sysc | | |-- target-module@4000 simple_bus 53 [ ] ti_sysc | | |-- target-module@e000 simple_bus 54 [ ] ti_sysc | | `-- target-module@10000 simple_bus 55 [ ] simple_bus | |-- interconnect@47c00000 simple_bus 56 [ ] simple_bus | | `-- segment@0 simple_bus 57 [ ] simple_bus | |-- interconnect@4a000000 simple_bus 58 [ ] simple_bus | | `-- segment@0 simple_bus 59 [ ] ti_sysc | | `-- target-module@100000 simple_bus 60 [ ] simple_bus | |-- interconnect@4b140000 simple_bus 61 [ ] simple_bus | | `-- segment@0 simple_bus 62 [ ] ti_sysc | |-- target-module@49000000 simple_bus 63 [ ] ti_sysc | |-- target-module@49800000 simple_bus 64 [ ] ti_sysc | |-- target-module@49900000 simple_bus 65 [ ] ti_sysc | |-- target-module@49a00000 simple_bus 66 [ ] ti_sysc | |-- target-module@47810000 i2c 0 [ ] i2c_omap | |-- i2c@44e0b000 pmic 0 [ ] tps65217 pmic | | `-- tps@24 i2c 1 [ ] i2c_omap | |-- i2c@4819c000 mmc 0 [ + ] omap_hsmmc | |-- mmc@48060000 blk 0 [ ] mmc_blk | | |-- mmc@48060000.blk bootdev 0 [ ] mmc_bootdev | | `-- mmc@48060000.bootdev mmc 1 [ + ] omap_hsmmc | |-- mmc@481d8000 blk 1 [ + ] mmc_blk | | |-- mmc@481d8000.blk partition 0 [ + ] blk_partition | | | `-- mmc@481d8000.blk:1 bootdev 1 [ ] mmc_bootdev | | `-- mmc@481d8000.bootdev watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0
Thanks, Miquèl

On 7/31/23 15:58, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200:
On 7/31/23 15:36, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200:
On 7/31/23 11:31, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>>> Extend the driver core to perform lookup by both OF node and driver
bound to the node. Use this to look up specific device instances to unbind from nodes in the unbind command. One example where this is needed is USB peripheral controller, which may have multiple gadget drivers bound to it. The unbind command has to select that specific gadget driver instance to unbind from the controller, not unbind the controller driver itself from the controller.
USB ethernet gadget usage looks as follows with this change. Notice the extra 'usb_ether' addition in the 'unbind' command at the end. " bind /soc/usb-otg@49000000 usb_ether setenv ethact usb_ether setenv loadaddr 0xc2000000 setenv ipaddr 10.0.0.2 setenv serverip 10.0.0.1 setenv netmask 255.255.255.0 tftpboot 0xc2000000 10.0.0.1:test.file unbind /soc/usb-otg@49000000 usb_ether "
Signed-off-by: Marek Vasut marex@denx.de
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is: >>> => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error:
=> unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether

Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200:
On 7/31/23 15:58, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200:
On 7/31/23 15:36, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200:
>> On 7/31/23 11:31, Miquel Raynal wrote: Hi Marek,
marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>>> Extend the driver core to perform lookup by both OF node and driver > bound to the node. Use this to look up specific device instances to > unbind from nodes in the unbind command. One example where this is > needed is USB peripheral controller, which may have multiple gadget > drivers bound to it. The unbind command has to select that specific > gadget driver instance to unbind from the controller, not unbind the > controller driver itself from the controller. > > USB ethernet gadget usage looks as follows with this change. Notice > the extra 'usb_ether' addition in the 'unbind' command at the end. > " > bind /soc/usb-otg@49000000 usb_ether > setenv ethact usb_ether > setenv loadaddr 0xc2000000 > setenv ipaddr 10.0.0.2 > setenv serverip 10.0.0.1 > setenv netmask 255.255.255.0 > tftpboot 0xc2000000 10.0.0.1:test.file > unbind /soc/usb-otg@49000000 usb_ether > " > > Signed-off-by: Marek Vasut marex@denx.de > ---
I am no longer getting wrong pointer dereferences, the SPL is working in recovery mode, TFTP "File not found" errors are no longer a problem and I did not experience any reset while tftp'ing regular files.
One last remaining request on my side is the need for using fastboot as well which does no longer work as-is: >>> => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error:
> => unbind /ocp/usb@47400000/usb@47401000
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000 =>

On 7/31/23 16:25, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200:
On 7/31/23 15:58, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200:
On 7/31/23 15:36, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: >>>> On 7/31/23 11:31, Miquel Raynal wrote:
> Hi Marek, > > marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: > >>>> Extend the driver core to perform lookup by both OF node and driver >> bound to the node. Use this to look up specific device instances to >> unbind from nodes in the unbind command. One example where this is >> needed is USB peripheral controller, which may have multiple gadget >> drivers bound to it. The unbind command has to select that specific >> gadget driver instance to unbind from the controller, not unbind the >> controller driver itself from the controller. >> >> USB ethernet gadget usage looks as follows with this change. Notice >> the extra 'usb_ether' addition in the 'unbind' command at the end. >> " >> bind /soc/usb-otg@49000000 usb_ether >> setenv ethact usb_ether >> setenv loadaddr 0xc2000000 >> setenv ipaddr 10.0.0.2 >> setenv serverip 10.0.0.1 >> setenv netmask 255.255.255.0 >> tftpboot 0xc2000000 10.0.0.1:test.file >> unbind /soc/usb-otg@49000000 usb_ether >> " >> >> Signed-off-by: Marek Vasut marex@denx.de >> --- > > I am no longer getting wrong pointer dereferences, the SPL is working in > recovery mode, TFTP "File not found" errors are no longer a problem and > I did not experience any reset while tftp'ing regular files. > > One last remaining request on my side is the need for using fastboot as > well which does no longer work as-is: > >>> => fastboot usb 0 > couldn't find an available UDC > g_dnl_register: failed!, error: -19 > exit not allowed from main input shell. > > Can you advise what bind/unbind command would be necessary here?
Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error: >>> => unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Can you debug this ? Basically the problem that happens is that if you run: unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
Maybe just try unbind usb_ether or unbind usb_ether usb_ether
ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral and then the fastboot thing

Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:40:04 +0200:
On 7/31/23 16:25, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200:
On 7/31/23 15:58, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200:
>> On 7/31/23 15:36, Miquel Raynal wrote: Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: >>>> On 7/31/23 11:31, Miquel Raynal wrote: >> Hi Marek, >> >> marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >> >>>> Extend the driver core to perform lookup by both OF node and driver >>> bound to the node. Use this to look up specific device instances to >>> unbind from nodes in the unbind command. One example where this is >>> needed is USB peripheral controller, which may have multiple gadget >>> drivers bound to it. The unbind command has to select that specific >>> gadget driver instance to unbind from the controller, not unbind the >>> controller driver itself from the controller. >>> >>> USB ethernet gadget usage looks as follows with this change. Notice >>> the extra 'usb_ether' addition in the 'unbind' command at the end. >>> " >>> bind /soc/usb-otg@49000000 usb_ether >>> setenv ethact usb_ether >>> setenv loadaddr 0xc2000000 >>> setenv ipaddr 10.0.0.2 >>> setenv serverip 10.0.0.1 >>> setenv netmask 255.255.255.0 >>> tftpboot 0xc2000000 10.0.0.1:test.file >>> unbind /soc/usb-otg@49000000 usb_ether >>> " >>> >>> Signed-off-by: Marek Vasut marex@denx.de >>> --- >> >> I am no longer getting wrong pointer dereferences, the SPL is working in >> recovery mode, TFTP "File not found" errors are no longer a problem and >> I did not experience any reset while tftp'ing regular files. >> >> One last remaining request on my side is the need for using fastboot as >> well which does no longer work as-is: >> >>> => fastboot usb 0 >> couldn't find an available UDC >> g_dnl_register: failed!, error: -19 >> exit not allowed from main input shell. >> >> Can you advise what bind/unbind command would be necessary here? > > Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'.
Nice `dm tree` command, never used it before.
Even when I unbind usb_ether I still get the same error: >>> => unbind /ocp/usb@47400000/usb@47401000 => fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Yes it did.
Can you debug this ? Basically the problem that happens is that if you run: unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
True.
Maybe just try unbind usb_ether
=> unbind usb_ether unbind - Unbind a device from a driver
Usage: unbind <node path> [<driver>] unbind <class> <index> unbind <class> <index> <driver>
or unbind usb_ether usb_ether
=> unbind usb_ether usb_ether usb_ether is not a valid uclass
ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral
Indeed when we perform the unbind, ti-musb-peripheral is removed. Yes, binding it again like you advise makes it come back.
and then the fastboot thing
Unfortunately after binding it again, so with the following dm tree snippet:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | |-- usb@47401800 usb 0 [ ] ti-musb-peripheral | | `-- usb@47401000
It still fails:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Without this series, this works: => unbind /ocp/usb@47400000/usb@47401000 => bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral => fastboot usb 0
Thanks, Miquèl

On 8/1/23 20:53, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:40:04 +0200:
On 7/31/23 16:25, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200:
On 7/31/23 15:58, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200: >>>> On 7/31/23 15:36, Miquel Raynal wrote:
> Hi Marek, > > marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: > >>>> On 7/31/23 11:31, Miquel Raynal wrote: >>> Hi Marek, >>> >>> marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>> >>>> Extend the driver core to perform lookup by both OF node and driver >>>> bound to the node. Use this to look up specific device instances to >>>> unbind from nodes in the unbind command. One example where this is >>>> needed is USB peripheral controller, which may have multiple gadget >>>> drivers bound to it. The unbind command has to select that specific >>>> gadget driver instance to unbind from the controller, not unbind the >>>> controller driver itself from the controller. >>>> >>>> USB ethernet gadget usage looks as follows with this change. Notice >>>> the extra 'usb_ether' addition in the 'unbind' command at the end. >>>> " >>>> bind /soc/usb-otg@49000000 usb_ether >>>> setenv ethact usb_ether >>>> setenv loadaddr 0xc2000000 >>>> setenv ipaddr 10.0.0.2 >>>> setenv serverip 10.0.0.1 >>>> setenv netmask 255.255.255.0 >>>> tftpboot 0xc2000000 10.0.0.1:test.file >>>> unbind /soc/usb-otg@49000000 usb_ether >>>> " >>>> >>>> Signed-off-by: Marek Vasut marex@denx.de >>>> --- >>> >>> I am no longer getting wrong pointer dereferences, the SPL is working in >>> recovery mode, TFTP "File not found" errors are no longer a problem and >>> I did not experience any reset while tftp'ing regular files. >>> >>> One last remaining request on my side is the need for using fastboot as >>> well which does no longer work as-is: >>> >>> => fastboot usb 0 >>> couldn't find an available UDC >>> g_dnl_register: failed!, error: -19 >>> exit not allowed from main input shell. >>> >>> Can you advise what bind/unbind command would be necessary here? >> >> Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'. > > Nice `dm tree` command, never used it before. > > Even when I unbind usb_ether I still get the same error: > >>> => unbind /ocp/usb@47400000/usb@47401000 > => fastboot usb 0 > couldn't find an available UDC > g_dnl_register: failed!, error: -19 > exit not allowed from main input shell. > > Is there a specific gadget driver which I should bind again manually?
Can you share the output of dm tree before/after unbind ?
fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0
=> unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Yes it did.
Can you debug this ? Basically the problem that happens is that if you run: unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
True.
Maybe just try unbind usb_ether
=> unbind usb_ether unbind - Unbind a device from a driver
Usage: unbind <node path> [<driver>] unbind <class> <index> unbind <class> <index> <driver>
or unbind usb_ether usb_ether
=> unbind usb_ether usb_ether usb_ether is not a valid uclass
ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral
Indeed when we perform the unbind, ti-musb-peripheral is removed. Yes, binding it again like you advise makes it come back.
and then the fastboot thing
Unfortunately after binding it again, so with the following dm tree snippet:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | |-- usb@47401800 usb 0 [ ] ti-musb-peripheral | | `-- usb@47401000
It still fails:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Without this series, this works: => unbind /ocp/usb@47400000/usb@47401000 => bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral => fastboot usb 0
OK, so fastboot did not work even without this series without obscure workarounds ?
Can you try and debug this ?
Does 'fastboot usb 1' work with this series by any chance ?

Hi Marek,
marex@denx.de wrote on Wed, 2 Aug 2023 01:07:46 +0200:
On 8/1/23 20:53, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:40:04 +0200:
On 7/31/23 16:25, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200:
>> On 7/31/23 15:58, Miquel Raynal wrote: Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200: >>>> On 7/31/23 15:36, Miquel Raynal wrote: >> Hi Marek, >> >> marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: >> >>>> On 7/31/23 11:31, Miquel Raynal wrote: >>>> Hi Marek, >>>> >>>> marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>>> >>>> Extend the driver core to perform lookup by both OF node and driver >>>>> bound to the node. Use this to look up specific device instances to >>>>> unbind from nodes in the unbind command. One example where this is >>>>> needed is USB peripheral controller, which may have multiple gadget >>>>> drivers bound to it. The unbind command has to select that specific >>>>> gadget driver instance to unbind from the controller, not unbind the >>>>> controller driver itself from the controller. >>>>> >>>>> USB ethernet gadget usage looks as follows with this change. Notice >>>>> the extra 'usb_ether' addition in the 'unbind' command at the end. >>>>> " >>>>> bind /soc/usb-otg@49000000 usb_ether >>>>> setenv ethact usb_ether >>>>> setenv loadaddr 0xc2000000 >>>>> setenv ipaddr 10.0.0.2 >>>>> setenv serverip 10.0.0.1 >>>>> setenv netmask 255.255.255.0 >>>>> tftpboot 0xc2000000 10.0.0.1:test.file >>>>> unbind /soc/usb-otg@49000000 usb_ether >>>>> " >>>>> >>>>> Signed-off-by: Marek Vasut marex@denx.de >>>>> --- >>>> >>>> I am no longer getting wrong pointer dereferences, the SPL is working in >>>> recovery mode, TFTP "File not found" errors are no longer a problem and >>>> I did not experience any reset while tftp'ing regular files. >>>> >>>> One last remaining request on my side is the need for using fastboot as >>>> well which does no longer work as-is: >>>> >>> => fastboot usb 0 >>>> couldn't find an available UDC >>>> g_dnl_register: failed!, error: -19 >>>> exit not allowed from main input shell. >>>> >>>> Can you advise what bind/unbind command would be necessary here? >>> >>> Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'. >> >> Nice `dm tree` command, never used it before. >> >> Even when I unbind usb_ether I still get the same error: >> >>> => unbind /ocp/usb@47400000/usb@47401000 >> => fastboot usb 0 >> couldn't find an available UDC >> g_dnl_register: failed!, error: -19 >> exit not allowed from main input shell. >> >> Is there a specific gadget driver which I should bind again manually? > > Can you share the output of dm tree before/after unbind ? > > fastboot should auto-bind to the right thing.
Ok. Apparently it does not, but I don't have any clue why. If you want me to check something else I will. Here is the output:
U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...]
>>>> watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 ethernet 1 [ + ] usb_ether | | | `-- usb_ether bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev usb 0 [ ] ti-musb-host | | `-- usb@47401800 ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed bootstd 0 [ ] bootstd_drv |-- bootstd bootmeth 0 [ ] bootmeth_efi | |-- efi bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux bootmeth 2 [ ] bootmeth_pxe | |-- pxe bootmeth 3 [ ] vbe_simple | `-- vbe_simple timer 0 [ + ] omap_timer `-- timer@0 => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Yes it did.
Can you debug this ? Basically the problem that happens is that if you run: unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
True.
Maybe just try unbind usb_ether
=> unbind usb_ether unbind - Unbind a device from a driver
Usage: unbind <node path> [<driver>] unbind <class> <index> unbind <class> <index> <driver>
or unbind usb_ether usb_ether
=> unbind usb_ether usb_ether usb_ether is not a valid uclass
ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral
Indeed when we perform the unbind, ti-musb-peripheral is removed. Yes, binding it again like you advise makes it come back.
and then the fastboot thing
Unfortunately after binding it again, so with the following dm tree snippet:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | |-- usb@47401800 usb 0 [ ] ti-musb-peripheral | | `-- usb@47401000
It still fails:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Without this series, this works: => unbind /ocp/usb@47400000/usb@47401000 => bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral => fastboot usb 0
OK, so fastboot did not work even without this series without obscure workarounds ?
I'm happy you call the unbind/bind sequence an "obscure workaround" ;-)
The command "fastboot usb 0" works without your series, before tftp or after tftp, it does not matter, it used to work. Applying this series makes it always fail.
I was just reporting that, before your series, calling unbind would also remove ti-musb-peripheral, but calling bind again with the above line makes the usb_ether gadget and fastboot work again. Whereas with your series the unbind behaves identically but the bind command does not "fix" fastboot (tftp works fine in v3).
Can you try and debug this ?
The breakage is not part of the existing code base, it was introduced by the series. Maybe you can try with any other board with USB peripheral and see if the behavior is identical?
Does 'fastboot usb 1' work with this series by any chance ?
When fastboot works, starting it "blocks" the CLI. When I unbind the peripheral driver on USB 0, the fastboot command does not block any more and yet does not print anything, it just returns "immediately" without any log.
When I run 'fastboot usb 1' it acts like that as well, nothing happens, without error. It acts identically before and after this series.
Thanks, Miquèl

On 8/2/23 09:48, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Wed, 2 Aug 2023 01:07:46 +0200:
On 8/1/23 20:53, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:40:04 +0200:
On 7/31/23 16:25, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200: >>>> On 7/31/23 15:58, Miquel Raynal wrote:
> Hi Marek, > > marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200: > >>>> On 7/31/23 15:36, Miquel Raynal wrote: >>> Hi Marek, >>> >>> marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: >>> >>>> On 7/31/23 11:31, Miquel Raynal wrote: >>>>> Hi Marek, >>>>> >>>>> marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>>>> >>>> Extend the driver core to perform lookup by both OF node and driver >>>>>> bound to the node. Use this to look up specific device instances to >>>>>> unbind from nodes in the unbind command. One example where this is >>>>>> needed is USB peripheral controller, which may have multiple gadget >>>>>> drivers bound to it. The unbind command has to select that specific >>>>>> gadget driver instance to unbind from the controller, not unbind the >>>>>> controller driver itself from the controller. >>>>>> >>>>>> USB ethernet gadget usage looks as follows with this change. Notice >>>>>> the extra 'usb_ether' addition in the 'unbind' command at the end. >>>>>> " >>>>>> bind /soc/usb-otg@49000000 usb_ether >>>>>> setenv ethact usb_ether >>>>>> setenv loadaddr 0xc2000000 >>>>>> setenv ipaddr 10.0.0.2 >>>>>> setenv serverip 10.0.0.1 >>>>>> setenv netmask 255.255.255.0 >>>>>> tftpboot 0xc2000000 10.0.0.1:test.file >>>>>> unbind /soc/usb-otg@49000000 usb_ether >>>>>> " >>>>>> >>>>>> Signed-off-by: Marek Vasut marex@denx.de >>>>>> --- >>>>> >>>>> I am no longer getting wrong pointer dereferences, the SPL is working in >>>>> recovery mode, TFTP "File not found" errors are no longer a problem and >>>>> I did not experience any reset while tftp'ing regular files. >>>>> >>>>> One last remaining request on my side is the need for using fastboot as >>>>> well which does no longer work as-is: >>>>> >>> => fastboot usb 0 >>>>> couldn't find an available UDC >>>>> g_dnl_register: failed!, error: -19 >>>>> exit not allowed from main input shell. >>>>> >>>>> Can you advise what bind/unbind command would be necessary here? >>>> >>>> Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'. >>> >>> Nice `dm tree` command, never used it before. >>> >>> Even when I unbind usb_ether I still get the same error: >>> >>> => unbind /ocp/usb@47400000/usb@47401000 >>> => fastboot usb 0 >>> couldn't find an available UDC >>> g_dnl_register: failed!, error: -19 >>> exit not allowed from main input shell. >>> >>> Is there a specific gadget driver which I should bind again manually? >> >> Can you share the output of dm tree before/after unbind ? >> >> fastboot should auto-bind to the right thing. > > Ok. Apparently it does not, but I don't have any clue why. If you want > me to check something else I will. Here is the output: > > U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200)
[...] >>>>> watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 > misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 > usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 > ethernet 1 [ + ] usb_ether | | | `-- usb_ether > bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev > usb 0 [ ] ti-musb-host | | `-- usb@47401800 > ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 > bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev > simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 > simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 > simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 > clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed > bootstd 0 [ ] bootstd_drv |-- bootstd > bootmeth 0 [ ] bootmeth_efi | |-- efi > bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux > bootmeth 2 [ ] bootmeth_pxe | |-- pxe > bootmeth 3 [ ] vbe_simple | `-- vbe_simple > timer 0 [ + ] omap_timer `-- timer@0 > => unbind /ocp/usb@47400000/usb@47401000
The commit message of this patch contains the following example: unbind /soc/usb-otg@49000000 usb_ether so in your case, try unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Yes it did.
Can you debug this ? Basically the problem that happens is that if you run: unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
True.
Maybe just try unbind usb_ether
=> unbind usb_ether unbind - Unbind a device from a driver
Usage: unbind <node path> [<driver>] unbind <class> <index> unbind <class> <index> <driver>
or unbind usb_ether usb_ether
=> unbind usb_ether usb_ether usb_ether is not a valid uclass
ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral
Indeed when we perform the unbind, ti-musb-peripheral is removed. Yes, binding it again like you advise makes it come back.
and then the fastboot thing
Unfortunately after binding it again, so with the following dm tree snippet:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | |-- usb@47401800 usb 0 [ ] ti-musb-peripheral | | `-- usb@47401000
It still fails:
=> fastboot usb 0 couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Without this series, this works: => unbind /ocp/usb@47400000/usb@47401000 => bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral => fastboot usb 0
OK, so fastboot did not work even without this series without obscure workarounds ?
I'm happy you call the unbind/bind sequence an "obscure workaround" ;-)
The command "fastboot usb 0" works without your series, before tftp or after tftp, it does not matter, it used to work. Applying this series makes it always fail.
I was just reporting that, before your series, calling unbind would also remove ti-musb-peripheral, but calling bind again with the above line makes the usb_ether gadget and fastboot work again. Whereas with your series the unbind behaves identically but the bind command does not "fix" fastboot (tftp works fine in v3).
Can you try and debug this ?
The breakage is not part of the existing code base, it was introduced by the series. Maybe you can try with any other board with USB peripheral and see if the behavior is identical?
Does 'fastboot usb 1' work with this series by any chance ?
When fastboot works, starting it "blocks" the CLI. When I unbind the peripheral driver on USB 0, the fastboot command does not block any more and yet does not print anything, it just returns "immediately" without any log.
When I run 'fastboot usb 1' it acts like that as well, nothing happens, without error. It acts identically before and after this series.
Please test v4

Hi Marek,
marex@denx.de wrote on Wed, 2 Aug 2023 16:38:47 +0200:
On 8/2/23 09:48, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Wed, 2 Aug 2023 01:07:46 +0200:
On 8/1/23 20:53, Miquel Raynal wrote:
Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:40:04 +0200:
>> On 7/31/23 16:25, Miquel Raynal wrote: Hi Marek,
marex@denx.de wrote on Mon, 31 Jul 2023 16:08:19 +0200: >>>> On 7/31/23 15:58, Miquel Raynal wrote: >> Hi Marek, >> >> marex@denx.de wrote on Mon, 31 Jul 2023 15:50:58 +0200: >> >>>> On 7/31/23 15:36, Miquel Raynal wrote: >>>> Hi Marek, >>>> >>>> marex@denx.de wrote on Mon, 31 Jul 2023 13:44:25 +0200: >>>> >>>> On 7/31/23 11:31, Miquel Raynal wrote: >>>>>> Hi Marek, >>>>>> >>>>>> marex@denx.de wrote on Sat, 29 Jul 2023 16:57:09 +0200: >>>>>> >>>> Extend the driver core to perform lookup by both OF node and driver >>>>>>> bound to the node. Use this to look up specific device instances to >>>>>>> unbind from nodes in the unbind command. One example where this is >>>>>>> needed is USB peripheral controller, which may have multiple gadget >>>>>>> drivers bound to it. The unbind command has to select that specific >>>>>>> gadget driver instance to unbind from the controller, not unbind the >>>>>>> controller driver itself from the controller. >>>>>>> >>>>>>> USB ethernet gadget usage looks as follows with this change. Notice >>>>>>> the extra 'usb_ether' addition in the 'unbind' command at the end. >>>>>>> " >>>>>>> bind /soc/usb-otg@49000000 usb_ether >>>>>>> setenv ethact usb_ether >>>>>>> setenv loadaddr 0xc2000000 >>>>>>> setenv ipaddr 10.0.0.2 >>>>>>> setenv serverip 10.0.0.1 >>>>>>> setenv netmask 255.255.255.0 >>>>>>> tftpboot 0xc2000000 10.0.0.1:test.file >>>>>>> unbind /soc/usb-otg@49000000 usb_ether >>>>>>> " >>>>>>> >>>>>>> Signed-off-by: Marek Vasut marex@denx.de >>>>>>> --- >>>>>> >>>>>> I am no longer getting wrong pointer dereferences, the SPL is working in >>>>>> recovery mode, TFTP "File not found" errors are no longer a problem and >>>>>> I did not experience any reset while tftp'ing regular files. >>>>>> >>>>>> One last remaining request on my side is the need for using fastboot as >>>>>> well which does no longer work as-is: >>>>>> >>> => fastboot usb 0 >>>>>> couldn't find an available UDC >>>>>> g_dnl_register: failed!, error: -19 >>>>>> exit not allowed from main input shell. >>>>>> >>>>>> Can you advise what bind/unbind command would be necessary here? >>>>> >>>>> Either 'unbind usb_ether' or run 'dm tree' -> look up the path to usb_ether in the tree (it will be hanging under usb_peripheral or some such), and then use 'unbind <that path>'. >>>> >>>> Nice `dm tree` command, never used it before. >>>> >>>> Even when I unbind usb_ether I still get the same error: >>>> >>> => unbind /ocp/usb@47400000/usb@47401000 >>>> => fastboot usb 0 >>>> couldn't find an available UDC >>>> g_dnl_register: failed!, error: -19 >>>> exit not allowed from main input shell. >>>> >>>> Is there a specific gadget driver which I should bind again manually? >>> >>> Can you share the output of dm tree before/after unbind ? >>> >>> fastboot should auto-bind to the right thing. >> >> Ok. Apparently it does not, but I don't have any clue why. If you want >> me to check something else I will. Here is the output: >> >> U-Boot 2023.07-00806-g979e7443428 (Jul 31 2023 - 11:17:06 +0200) > > [...] > >>>>> watchdog 0 [ + ] omap3_wdt | |-- wdt@44e35000 >> misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 >> usb 0 [ + ] ti-musb-peripheral | | |-- usb@47401000 >> ethernet 1 [ + ] usb_ether | | | `-- usb_ether >> bootdev 3 [ ] eth_bootdev | | | `-- usb_ether.bootdev >> usb 0 [ ] ti-musb-host | | `-- usb@47401800 >> ethernet 0 [ + ] eth_cpsw | |-- ethernet@4a100000 >> bootdev 2 [ ] eth_bootdev | | `-- ethernet@4a100000.bootdev >> simple_bus 67 [ ] ti_sysc | |-- target-module@53100000 >> simple_bus 68 [ ] ti_sysc | |-- target-module@53500000 >> simple_bus 69 [ ] ti_sysc | `-- target-module@56000000 >> clk 62 [ ] fixed_clock |-- clk_mcasp0_fixed >> bootstd 0 [ ] bootstd_drv |-- bootstd >> bootmeth 0 [ ] bootmeth_efi | |-- efi >> bootmeth 1 [ ] bootmeth_extlinux | |-- extlinux >> bootmeth 2 [ ] bootmeth_pxe | |-- pxe >> bootmeth 3 [ ] vbe_simple | `-- vbe_simple >> timer 0 [ + ] omap_timer `-- timer@0 >> => unbind /ocp/usb@47400000/usb@47401000 > > The commit message of this patch contains the following example: > unbind /soc/usb-otg@49000000 usb_ether > so in your case, try > unbind /ocp/usb@47400000/usb@47401000 usb_ether
Does not work, unfortunately: => unbind /ocp/usb@47400000/usb@47401000 usb_ether Cannot find a device with path /ocp/usb@47400000/usb@47401000 => unbind /ocp/usb@47400000/usb@47401000
Did this even work before , i.e. without this series, if you were to use USB ethernet first and then fastboot second (that sequence is important) ?
Yes it did.
>> Can you debug this ? Basically the problem that happens is that if you run:
unbind /ocp/usb@47400000/usb@47401000 this unbind ti-musb-peripheral usb@47401000 instead of just unbinding usb_ether usb_ether
True.
>> Maybe just try
unbind usb_ether
> => unbind usb_ether
unbind - Unbind a device from a driver
Usage: unbind <node path> [<driver>] unbind <class> <index> unbind <class> <index> <driver>
>> or
unbind usb_ether usb_ether
> => unbind usb_ether usb_ether
usb_ether is not a valid uclass
>> ti-musb-peripheral usb@47401000 has to stay in the dm tree output after the unbind. Or maybe try
bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral
Indeed when we perform the unbind, ti-musb-peripheral is removed. Yes, binding it again like you advise makes it come back.
>> and then the fastboot thing
Unfortunately after binding it again, so with the following dm tree snippet:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000 usb 0 [ ] ti-musb-host | | |-- usb@47401800 usb 0 [ ] ti-musb-peripheral | | `-- usb@47401000
It still fails:
> => fastboot usb 0
couldn't find an available UDC g_dnl_register: failed!, error: -19 exit not allowed from main input shell.
Without this series, this works: => unbind /ocp/usb@47400000/usb@47401000 => bind /ocp/usb@47400000/usb@47401000 ti-musb-peripheral => fastboot usb 0
OK, so fastboot did not work even without this series without obscure workarounds ?
I'm happy you call the unbind/bind sequence an "obscure workaround" ;-)
The command "fastboot usb 0" works without your series, before tftp or after tftp, it does not matter, it used to work. Applying this series makes it always fail.
I was just reporting that, before your series, calling unbind would also remove ti-musb-peripheral, but calling bind again with the above line makes the usb_ether gadget and fastboot work again. Whereas with your series the unbind behaves identically but the bind command does not "fix" fastboot (tftp works fine in v3).
Can you try and debug this ?
The breakage is not part of the existing code base, it was introduced by the series. Maybe you can try with any other board with USB peripheral and see if the behavior is identical?
Does 'fastboot usb 1' work with this series by any chance ?
When fastboot works, starting it "blocks" the CLI. When I unbind the peripheral driver on USB 0, the fastboot command does not block any more and yet does not print anything, it just returns "immediately" without any log.
When I run 'fastboot usb 1' it acts like that as well, nothing happens, without error. It acts identically before and after this series.
Please test v4
I will.
Thanks, Miquèl
participants (2)
-
Marek Vasut
-
Miquel Raynal