This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new d6444d0a7bd drivers/usbdev: re-assert soft connect in cdcecm/cdcncm 
disconnect()
d6444d0a7bd is described below

commit d6444d0a7bd15c266b715e371b0ba520e7a8bc10
Author: Ricard Rosson <[email protected]>
AuthorDate: Wed Jul 29 11:07:18 2026 +0100

    drivers/usbdev: re-assert soft connect in cdcecm/cdcncm disconnect()
    
    The USB device controller drivers invoke CLASS_DISCONNECT() on every
    USB bus reset, and a bus reset is the first step of normal host
    enumeration.  Every other class driver (cdcacm, usbmsc, rndis)
    re-asserts DEV_CONNECT() at the end of its disconnect() handler so
    that the device remains attached; cdcecm and cdcncm did not, so on
    controllers that soft-disconnect around bus reset (e.g. rp2040, which
    drops the pull-up in its bus-reset handler) a standalone CDC-ECM or
    CDC-NCM device is left soft-disconnected by the first bus reset and
    never enumerates on the host.
    
    Mirror the cdcacm behavior and perform the soft connect in the
    disconnect() methods, unless part of a composite device (composite.c
    already re-connects in its own disconnect handler).
    
    Fixes the standalone CDC-ECM case of issue #15880.
    
    Validated on raspberrypi-pico (RP2040): with this change a standalone
    CONFIG_NET_CDCECM device that previously never appeared on the host
    enumerates via cdc_ether and pings with 0% loss.  cdcncm has the
    identical defect and receives the identical fix.
    
    Signed-off-by: Ricard Rosson <[email protected]>
    Co-authored-by: Xiang Xiao <[email protected]>
    Assisted-by: Claude (Anthropic Claude Code)
---
 drivers/usbdev/cdcecm.c | 11 +++++++++++
 drivers/usbdev/cdcncm.c | 11 +++++++++++
 2 files changed, 22 insertions(+)

diff --git a/drivers/usbdev/cdcecm.c b/drivers/usbdev/cdcecm.c
index 2ce7e93cadf..c39f84d4228 100644
--- a/drivers/usbdev/cdcecm.c
+++ b/drivers/usbdev/cdcecm.c
@@ -1916,6 +1916,17 @@ static void cdcecm_disconnect(FAR struct 
usbdevclass_driver_s *driver,
                               FAR struct usbdev_s *dev)
 {
   uinfo("\n");
+
+  /* Perform the soft connect function so that we will we can be
+   * re-enumerated (unless we are part of a composite device).  The USB
+   * device controller calls CLASS_DISCONNECT() on every bus reset, which
+   * is the first step of any enumeration, so without this the device is
+   * left soft-disconnected and never enumerates on the host.
+   */
+
+#ifndef CONFIG_CDCECM_COMPOSITE
+  DEV_CONNECT(dev);
+#endif
 }
 
 /****************************************************************************
diff --git a/drivers/usbdev/cdcncm.c b/drivers/usbdev/cdcncm.c
index 7f10e5355e3..c7046c4ca74 100644
--- a/drivers/usbdev/cdcncm.c
+++ b/drivers/usbdev/cdcncm.c
@@ -2902,6 +2902,17 @@ static void cdcncm_disconnect(FAR struct 
usbdevclass_driver_s *driver,
 
   cdcncm_resetconfig(self);
   uinfo("\n");
+
+  /* Perform the soft connect function so that we can be
+   * re-enumerated (unless we are part of a composite device).  The USB
+   * device controller calls CLASS_DISCONNECT() on every bus reset, which
+   * is the first step of any enumeration, so without this the device is
+   * left soft-disconnected and never enumerates on the host.
+   */
+
+#ifndef CONFIG_CDCNCM_COMPOSITE
+  DEV_CONNECT(dev);
+#endif
 }
 
 /****************************************************************************

Reply via email to