
Split out _usb_eth_start() from _usb_eth_init() and usb_eth_stop() from _usb_eth_halt(). Now _usb_eth_init() only initialises and registers the gadget device, which _usb_eth_halt() reverses, and together are used for probing and removing the device. The _usb_eth_start() and _usb_eth_stop() functions connect and disconnect the gadget as expected by the start()/stop() callbacks.
Previously the gadget device was probed on every start() and removed on every stop(), which is inconsistent with other DM_ETH drivers.
Signed-off-by: Niel Fourie lusus@denx.de Cc: Marek Vasut marex@denx.de Cc: Lukasz Majewski lukma@denx.de Cc: Ramon Fried rfried.dev@gmail.com --- Changes for v2: - fixed variable declaration order - removed non-DM_ETH code due to upstream removal during rebasing
drivers/usb/gadget/ether.c | 51 +++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 85c971e4c4..914427eb77 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2274,15 +2274,11 @@ fail:
/*-------------------------------------------------------------------------*/ static void _usb_eth_halt(struct ether_priv *priv); +static void _usb_eth_stop(struct ether_priv *priv);
static int _usb_eth_init(struct ether_priv *priv) { - 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; @@ -2322,14 +2318,26 @@ static int _usb_eth_init(struct ether_priv *priv) priv->eth_driver.resume = eth_resume; if (usb_gadget_register_driver(&priv->eth_driver) < 0) goto fail; + return 0; +fail: + _usb_eth_halt(priv); + return -1; +}
- dev->network_started = 0; +static int _usb_eth_start(struct ether_priv *priv) +{ + unsigned long timeout = USB_CONNECT_TIMEOUT; + struct eth_dev *dev = &priv->ethdev; + unsigned long ts;
+ if (!dev->gadget) + return -1; + + dev->network_started = 0; packet_received = 0; packet_sent = 0;
- gadget = dev->gadget; - usb_gadget_connect(gadget); + usb_gadget_connect(dev->gadget);
if (env_get("cdc_connect_timeout")) timeout = dectoul(env_get("cdc_connect_timeout"), NULL) * CONFIG_SYS_HZ; @@ -2347,6 +2355,7 @@ static int _usb_eth_init(struct ether_priv *priv) rx_submit(dev, dev->rx_req, 0); return 0; fail: + _usb_eth_stop(priv); _usb_eth_halt(priv); return -1; } @@ -2426,11 +2435,10 @@ static int _usb_eth_recv(struct ether_priv *priv) return 0; }
-static void _usb_eth_halt(struct ether_priv *priv) +static void _usb_eth_stop(struct ether_priv *priv) { struct eth_dev *dev = &priv->ethdev;
- /* If the gadget not registered, simple return */ if (!dev->gadget) return;
@@ -2454,6 +2462,14 @@ static void _usb_eth_halt(struct ether_priv *priv) usb_gadget_handle_interrupts(0); dev->network_started = 0; } +} + +static void _usb_eth_halt(struct ether_priv *priv) +{ + struct eth_dev *dev = &priv->ethdev; + + if (!dev->gadget) + return;
usb_gadget_unregister_driver(&priv->eth_driver); usb_gadget_release(0); @@ -2463,7 +2479,7 @@ static int usb_eth_start(struct udevice *dev) { struct ether_priv *priv = dev_get_priv(dev);
- return _usb_eth_init(priv); + return _usb_eth_start(priv); }
static int usb_eth_send(struct udevice *dev, void *packet, int length) @@ -2513,7 +2529,7 @@ static void usb_eth_stop(struct udevice *dev) { struct ether_priv *priv = dev_get_priv(dev);
- _usb_eth_halt(priv); + _usb_eth_stop(priv); }
static int usb_eth_probe(struct udevice *dev) @@ -2527,6 +2543,16 @@ 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);
+ return _usb_eth_init(priv); + + return 0; +} + +static int usb_eth_remove(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + _usb_eth_halt(priv); return 0; }
@@ -2562,6 +2588,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),