mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
Three defects that together prevented macOS from ever mounting a composite USBMSC function (Linux was mostly unaffected because its probe sequence and recovery timing never exercised these paths): 1. usbmsc_setup() compared the class-request wIndex against the compile-time constant USBMSC_INTERFACEID (= CONFIG_USBMSC_IFNOBASE, i.e. 0) instead of the composite-assigned priv->devinfo.ifnobase. In composite mode the MSC interface number is nonzero, so GET MAX LUN, Bulk-Only Mass Storage Reset, and GET/SET INTERFACE all failed the index check and stalled EP0. Standalone MSC is unaffected (ifnobase == 0), which is why this went unnoticed. 2. usbmsc_deferredresponse() has its entire body inside #ifndef CONFIG_USBMSC_COMPOSITE, so the deferred EP0 status stage for MSRESET/SETINTERFACE was never sent in composite mode and the host's Bulk-Only reset timed out. (Unreachable before fix 1 -- MSRESET used to stall at the wrong-interface check.) Compile the body in composite mode too, but suppress the worker's deferred response for SETCONFIGURATION there: the composite driver answers that request itself, and a duplicate zero-length packet corrupts the EP0 state. 3. usbmsc_cmdfinishstate() stalled the bulk IN endpoint whenever a device-to-host command left a residue, even when the response had already been sent and terminated by a short packet (or ZLP). The stall is BOT-legal (USB MSC BOT 6.7.2) but gratuitous: the short packet already ended the data phase and the residue is reported in dCSWDataResidue. Hosts such as macOS answer any bulk-IN halt during device probing with a full Bulk-Only reset sequence, which costs seconds per command or aborts the probe entirely (macOS probes MODE SENSE(6) with allocation lengths that exceed the response; Linux's probe does not). Only halt the endpoint when nothing terminated the data phase. Root-cause analysis and host traces in apache/nuttx#19435. Validated on RP2350 silicon (Raspberry Pi Pico 2 W, composite CDC-ACM + CDC-NCM + USBMSC): GET MAX LUN answers 1 LUN (previously EP0 stall and a garbage LUN count on macOS), MSRESET completes 10/10 (previously ETIMEDOUT), MODE SENSE(6) alloc=0xC0 returns short data plus a CSW with dCSWDataResidue and zero bulk-IN stalls across the exact-length suite, and macOS now mounts the volume (together with the companion DCD fixes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Ricard Rosson <ricard@groundbits.com> |
||
|---|---|---|
| .. | ||
| adb.c | ||
| cdcacm.c | ||
| cdcacm.h | ||
| cdcacm_desc.c | ||
| cdcecm.c | ||
| cdcecm.h | ||
| cdcncm.c | ||
| CMakeLists.txt | ||
| composite.c | ||
| composite.h | ||
| composite_desc.c | ||
| dfu.c | ||
| Kconfig | ||
| Make.defs | ||
| mtp.c | ||
| pl2303.c | ||
| rndis.c | ||
| rndis_std.h | ||
| usbdev_desc.c | ||
| usbdev_fs.c | ||
| usbdev_fs.h | ||
| usbdev_req.c | ||
| usbdev_strings.c | ||
| usbdev_trace.c | ||
| usbdev_trprintf.c | ||
| usbmsc.c | ||
| usbmsc.h | ||
| usbmsc_desc.c | ||
| usbmsc_scsi.c | ||
| uvc.c | ||