ricardgb opened a new pull request, #19451:
URL: https://github.com/apache/nuttx/pull/19451

   # PR 2 — usbmsc: fix composite-mode class requests and Hi>Di stall behavior
   
   Branch: `usbmsc-composite-bot-fixes` (worktree `~/nuttxspace/wt-pr-usbmsc`)
   Base: apache/nuttx master (1b6f918c3f)
   References: #19435 (bugs 1-3 of that report)
   
   ## Summary
   
   Three usbmsc defects that together prevent macOS from ever mounting a
   composite USBMSC function (and degrade any host that probes with allocation
   lengths larger than the response). Linux is mostly unaffected because its
   probe sequence and recovery timing never exercise these paths — which is why
   they survived so long.
   
   ## The three fixes
   
   1. **wIndex checked against a compile-time constant instead of the assigned
      interface number.** `usbmsc_setup()` compared the class-request `wIndex`
      with `USBMSC_INTERFACEID` (= `CONFIG_USBMSC_IFNOBASE` + 0 = 0) instead of
      the composite-assigned `priv->devinfo.ifnobase`. In composite mode the MSC
      interface is nonzero, so GET MAX LUN, Bulk-Only Mass Storage Reset, and
      GET/SET INTERFACE failed the check and stalled EP0 (macOS then read a
      garbage LUN count — "Max LUNs reported as 28" — off the stalled transfer
      and probed phantom LUNs). Standalone MSC is unaffected (ifnobase == 0).
      Four call sites fixed.
   
   2. **`usbmsc_deferredresponse()` is a no-op in composite mode** — its whole
      body was inside `#ifndef CONFIG_USBMSC_COMPOSITE`, so the deferred EP0
      status stage for MSRESET/SETINTERFACE was never sent and the host's
      Bulk-Only reset timed out. (Unreachable before fix 1: MSRESET used to
      stall at the wrong-interface check.) The body is now compiled in composite
      mode too; the worker's deferred response for SETCONFIGURATION is
      suppressed there, because the composite driver answers that request itself
      and a duplicate ZLP corrupts EP0.
   
   3. **Gratuitous bulk-IN stall on Hi>Di residue.** `usbmsc_cmdfinishstate()`
      stalled bulk-IN 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 pointless — the
      short packet already ended the data phase and the residue is reported in
      `dCSWDataResidue` — and macOS answers any bulk-IN halt during probing with
      a full Bulk-Only reset sequence (macOS probes MODE SENSE(6) with
      allocation lengths exceeding the response; Linux's probe does not). Only
      halt the endpoint when nothing terminated the data phase.
   
   ## Validation
   
   - **RP2350 (Raspberry Pi Pico 2 W) hardware, composite CDC-ACM + CDC-NCM +
     USBMSC (MSC at interface 4), Linux host with usbmon + raw-usbfs traces:**
     - GET MAX LUN: EP0 stall (`-EPIPE`) before → 1 byte (1 LUN) after.
     - MSRESET: `ETIMEDOUT` before → completes 10/10 after, including MSRESET
       arriving mid-command with an immediate bus reset after it.
     - MODE SENSE(6) alloc=0xC0: short data then CSW-read stall + clear-halt
       before → short data then immediate CSW with `dCSWDataResidue=0xB0` and
       zero bulk-IN stalls across the exact-length suite after.
     - No regressions: FAT volume mounts/full-reads, NCM + ACM unaffected, warm
       reboots clean.
     - End-to-end: macOS now mounts the volume (together with the companion DCD
       fixes in the separate rp2040/rp23xx PR).
   - **Build-tested** on `raspberrypi-pico:composite` (composite MSC) and
     `pimoroni-pico-2-plus:usbmsc` (standalone MSC — exercises the unchanged
     `#ifndef CONFIG_USBMSC_COMPOSITE` paths).
   
   Full host traces and the failure chronology are in #19435.
   
   ## Impact
   
   Every composite configuration containing USBMSC where the MSC interface
   number is nonzero (i.e. essentially all of them). Standalone MSC behavior is
   unchanged except fix 3 (fewer gratuitous stalls; hosts see a CSW with
   residue instead of stall/clear-halt/retry).
   
   ## AI disclosure
   
   This investigation and the fixes were performed by an AI agent (Claude Code),
   operated and directed by the submitter, and reviewed by the submitter before
   posting.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to