From 746458f4ab3d611718facb599666baac0a6b9d59 Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Wed, 8 Jul 2026 14:43:04 +0100 Subject: [PATCH 1/2] 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. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01AHJRvWeBMTHwzpwjaUg4HW --- 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 2ce7e93cadf8e..c39f84d422871 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 d528d8f0da4c2..2aa84e5325e0d 100644 --- a/drivers/usbdev/cdcncm.c +++ b/drivers/usbdev/cdcncm.c @@ -2868,6 +2868,17 @@ static void cdcncm_disconnect(FAR struct usbdevclass_driver_s *driver, cdcncm_resetconfig(self); 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_CDCNCM_COMPOSITE + DEV_CONNECT(dev); +#endif } /**************************************************************************** From 4e3426e5523c62ea806781a1d47a95f580a2f5ae Mon Sep 17 00:00:00 2001 From: ricardgb <73692159+ricardgb@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:14:57 +0100 Subject: [PATCH 2/2] Update drivers/usbdev/cdcncm.c Co-authored-by: Xiang Xiao --- drivers/usbdev/cdcncm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usbdev/cdcncm.c b/drivers/usbdev/cdcncm.c index 2aa84e5325e0d..3358d261ce6cd 100644 --- a/drivers/usbdev/cdcncm.c +++ b/drivers/usbdev/cdcncm.c @@ -2869,7 +2869,7 @@ static void cdcncm_disconnect(FAR struct usbdevclass_driver_s *driver, cdcncm_resetconfig(self); uinfo("\n"); - /* Perform the soft connect function so that we will we can be + /* 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