Skip to content

Pi 5: NCM gadget (usb_f_ncm on dwc2) hard-locks the system during link-up with a macOS host #7622

Description

@JAKONL

Describe the bug

Binding a configfs gadget with a single ncm function on a Raspberry Pi 5 hard-locks the whole system as soon as a macOS host starts enumerating it. The last kernel messages are always the same three dwc2 lines (bound driver, high-speed, new address 1), then nothing: no oops, no soft-lockup report, and oops=panic panic=10 never fires, so the board needs a power cycle. Reproduced three times, identically, including once with RAM capped to 3 GB (mem=3G) to rule out DMA addressing above the controller's 32-bit reach. g_ether (ECM) on the same setup enumerates and passes traffic in both directions, so this is specific to the NCM function on dwc2/BCM2712.

Steps to reproduce the behaviour

  1. dtoverlay=dwc2,dr_mode=peripheral under [all] in config.txt; PSU_MAX_CURRENT=3000 in the EEPROM config so the Mac can see the gadget at all (see USB PD request makes gadgets not work with some hosts #6569).
  2. Boot with the Pi connected to an Apple Silicon Mac (macOS 26.6.2) by USB-C to USB-C, Pi powered by the Mac. g_ether enumerates fine at this point.
  3. Switch to NCM:
modprobe libcomposite usb_f_ncm
modprobe -r g_ether
cd /sys/kernel/config/usb_gadget && mkdir g1 && cd g1
echo 0x2e8a > idVendor; echo 0x0013 > idProduct; echo 0x0200 > bcdUSB
mkdir -p strings/0x409 configs/c.1/strings/0x409 functions/ncm.usb0
echo "Raspberry Pi Ltd." > strings/0x409/manufacturer; echo "Raspberry Pi USB Gadget" > strings/0x409/product
echo NCM > configs/c.1/strings/0x409/configuration; echo 250 > configs/c.1/MaxPower
echo 02:6c:cc:fa:69:4e > functions/ncm.usb0/host_addr; echo 02:6c:cc:fa:69:4f > functions/ncm.usb0/dev_addr
ln -s functions/ncm.usb0 configs/c.1/
echo 1000480000.usb > UDC
  1. The Mac resets the bus, assigns an address, reads descriptors, and shows the "Allow accessory to connect?" prompt (all fine). The Pi locks up hard a moment later, as the NCM function goes live and starts sending link notifications (see Logs). Full system lockup; only a power cycle recovers it.

Device (s)

Raspberry Pi 5

System

Raspberry Pi OS trixie (Debian 13), 8GB board
Linux blackbox 6.18.39+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.18.39-1+rpt1 (2026-07-29) aarch64
(also reproduced on 6.18.34+rpt-rpi-2712)
Bootloader: 2026/05/26 16:01:25
Host: MacBook (Apple M2), macOS 26.6.2

Logs

With tp_printk on the kernel command line and events/gadget/enable=1, the gadget endpoint activity is printed to the kernel log and streamed over netconsole (eth0). This shows the hang is not during enumeration — descriptors are read, the address is set, the config is applied, and the function goes live. The system dies during the NCM link-up notification.

Tail of the capture, right before it goes silent:

usb_gadget_giveback_request: ep0: req ... length 8/8 ... status 0 --> 0
usb_ep_queue:                ep0: req ... length 0/0 ... status -115 --> 0
usb_gadget_giveback_request: ep0: req ... length 0/0 ... status 0 --> 0
usb_gadget_giveback_request: ep2in: req ... length 16/16 ... status 0 --> 0   # NCM notification sent
usb_ep_queue:                ep2in: req ... length 0/16 ... status -115 --> 0
usb_gadget_giveback_request: ep2in: req ... length 16/16 ... status 0 --> 0   # second notification sent
usb_ep_queue:                ep2in: req ... length 0/8  ... status -115 --> 0  # third notification queued
<complete silence, no oops, no further output>

Immediately before this, ep1out (bulk OUT) had ~16 requests queued at 16384 bytes each and ep2in (the interrupt/notification endpoint) was cycling 16-byte then 8-byte transfers — i.e. the CDC-NCM NETWORK_CONNECTION / SPEED_CHANGE notification sequence. The lockup happens as the function transitions to carrying data, not while the host is reading descriptors. g_ether (ECM) on the identical setup gets past this point and passes traffic.

ssh over both Wi-Fi and Ethernet drops at the same instant, so it is a full system lockup. A systemd-fed hardware watchdog (RuntimeWatchdogSec=15, BCM2835 WDT) did not reset the board — the lockup is hard enough that the reset path never runs — so recovery required a manual power cycle. No oops, no soft/hard-lockup report (neither detector is enabled in this kernel config).

Additional context

Motivation: g_ether/ECM is unusable with current macOS because AppleUserECM stops transmitting after ~150 frames per enumeration (Apple FB24614121, see raspberrypi/rpi-usb-gadget#27), and NCM is the only other Ethernet class macOS drives natively. I have not yet been able to test NCM against a Linux host on this board, so I cannot say whether the lockup is host-specific. Happy to test patches or capture more state; netconsole over the dongle is set up.

Full captures (netconsole output from the tracepoint run, and from the earlier mem=3G run): https://gist.github.com/JAKONL/59430a4cc738b689f71e3d225962e904

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions