drivers/usbdev: re-assert soft connect in cdcecm/cdcncm disconnect()
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions

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 <ricard@groundbits.com>
Co-authored-by: Xiang Xiao <xiaoxiang781216@gmail.com>
Assisted-by: Claude (Anthropic Claude Code)
This commit is contained in:
Ricard Rosson 2026-07-29 11:07:18 +01:00 committed by Xiang Xiao
parent a85b28bc2c
commit d6444d0a7b
2 changed files with 22 additions and 0 deletions

View file

@ -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
}
/****************************************************************************

View file

@ -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
}
/****************************************************************************