<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tinyusb.git/src/class/vendor, branch worktree-ch569-hydrausb3</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/tinyusb.git/atom/src/class/vendor?h=worktree-ch569-hydrausb3</id>
<link rel='self' href='http://cgit.235523.xyz/tinyusb.git/atom/src/class/vendor?h=worktree-ch569-hydrausb3'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/'/>
<updated>2026-07-07T04:21:06Z</updated>
<entry>
<title>usbtest: address Codex re-review (5 findings)</title>
<updated>2026-07-07T04:21:06Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-07T03:54:31Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=9422d113479cfe36a4915690617c15b7bf617806'/>
<id>urn:sha1:9422d113479cfe36a4915690617c15b7bf617806</id>
<content type='text'>
- rp2040 dcd_edpt_clear_stall: the toggle-reset re-issue rewound remaining_len
  only for IN, but bufctrl_prepare16() pre-subtracts it for OUT too, so an OUT
  re-issue was short by the still-armed buffers. Rewind both directions (user_buf
  only for IN, which advances at DPRAM-copy time). Validated: pico usbtest 30/30.

- usb_recover.sh: refuse pci-rebind/reset/bind on a BDF that is not a USB
  controller (class 0x0c03xx), so a stray/mistyped address can't disturb storage
  or NICs on the shared HIL host. Guard tested against real BDFs.

- ip3511 dcd_edpt_open: make it tolerant of reopening a still-armed endpoint
  instead of asserting it disabled -- retire via EPSKIP (UM11126 41.7.6/41.8.3)
  then force disabled. This is the correct ISO_ALLOC reopen contract, since
  usbd_edpt_close() is a no-op there. NOTE: audio/video streaming EPs already use
  usbd_edpt_iso_activate() on ISO_ALLOC, so there is no in-tree trigger; this is
  defensive hardening for a class that reopens a non-iso EP via usbd_edpt_open
  (e.g. a UVC device with a notification EP + VC SET_INTERFACE). Verified on HW:
  lpc11u37 usbtest 30/30 and video_capture SET_INTERFACE cycling both fine.

- vendor_device set_alt: abort the outgoing altsetting's bulk/interrupt endpoints
  before dropping them, so an endpoint absent from the target altsetting can't
  stay armed and hold its usbd claim. (No in-tree trigger: usbtest uses a single
  non-zero altsetting; defensive robustness for multi-alt vendor devices.)

- vendor_device tud_vendor_n_mounted(): count iso endpoints too, so an iso-only
  altsetting reports mounted. (No in-tree trigger: usbtest alt1 always has bulk.)

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>address review round 2 (4 fixed, 1 answered)</title>
<updated>2026-07-06T18:23:38Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T18:23:38Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=abd8769781e38bb14153dd6f9dedcc5b3c7b7be2'/>
<id>urn:sha1:abd8769781e38bb14153dd6f9dedcc5b3c7b7be2</id>
<content type='text'>
- dcd(nrf5x): dcd_edpt_iso_activate drops a stale armed transfer (started/
  data_received/iso_in_transfer_ready) — there is no dcd close on this port, so
  a transfer armed before SET_INTERFACE would trip TU_ASSERT(!xfer-&gt;started) on
  the class's next arm after usbd reset the endpoint's claim state.
- class(vendor): tud_vendor_n_mounted() counts the interrupt endpoints, so an
  interrupt-only vendor interface (bulk absent) reports mounted.
- example(usbtest): int/iso write lengths follow the negotiated speed
  (tud_speed_get), not the compile-time capability — a high-speed build
  enumerated at full speed serves the FS descriptor (mps 64/128) and must not
  submit HS-sized packets.
- test/hil: test_example() return annotation matches the (err, status, metric)
  3-tuple it returns.

Verified: feather_nrf52840_express and raspberry_pi_pico 30/30 through the HIL
battery; pico/feather/ch32v307-usbhs builds clean.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>address Codex/Copilot review findings (9 fixed, 3 refuted with evidence)</title>
<updated>2026-07-06T17:30:07Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T17:30:07Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=f41c1827b2b59d1a0bdfc28bbe6580e5c44ef961'/>
<id>urn:sha1:f41c1827b2b59d1a0bdfc28bbe6580e5c44ef961</id>
<content type='text'>
- dcd(rp2040): rewind IN staging before the clear-halt re-issue. Staging advances
  user_buf/remaining_len when packets are copied into DPRAM, before the host has
  consumed them; aborting and re-issuing from the advanced pointer silently
  skipped the staged-but-unsent bytes.
- dcd(ip3511): dcd_edpt_iso_activate aborts a transfer still armed from the
  previous altsetting (clear Active on both buffer slots) so the hardware can't
  keep servicing the old descriptor against the class's fresh queueing.
- dcd(rusb2): reuse an endpoint's existing pipe in dcd_edpt_open. usbd_edpt_close
  is a no-op on ISO_ALLOC ports, so a class's close/open across SET_INTERFACE
  would allocate a second pipe with the same EPNUM and leak pipes.
- class(vendor): the buffered-mode free-slot check also tests the interrupt
  endpoints, so an interrupt-only vendor interface isn't clobbered as "free".
- bsp(ch32v30x): board_get_unique_id respects max_len and copies bytes
  (alignment-safe) instead of writing 12 bytes through a uint32_t cast.
- test/hil/usbtest.py: treat same-serial multi-matches as ambiguous and retry
  until the dual-port stale node drops (nanoch32v203/ch32v307 variants); reprobe
  a binding that predates the dynamic-id re-registration so a stale capability
  profile can't survive; skip the remove_id/unbind cleanup after an unrecovered
  kernel-side hang (it would join the D-state convoy and deadlock the bus).
- usbtest skip.txt: add the families whose DCD refuses dcd_edpt_iso_alloc
  (CXD56, FT90X, LPC175X_6X, LPC40XX, NUC100/120/505, PIC32MZ, SAMG, SAMX7X,
  VALENTYUSB_EPTRI) — tier 4 cannot enumerate there.
- test/hil/tinyusb-sudoer: note that '#1000' is a sudoers UID specifier, not a
  comment (the review misread the grants as commented out).

Refuted in review threads: nrf5x ISOSPLIT keeps reserve-max per-configuration
allocation semantics (iso_alloc is per-config, not per-alt); the LPC EP-number
claim (default descriptor uses EP1-3; lpcxpresso11u37 passes 30/30 on HW); the
vendor alt-0 "abort" concern (host cannot address endpoints outside the active
altsetting; usbd_edpt_iso_activate resets state on re-entry).

Verified on hardware: raspberry_pi_pico, lpcxpresso11u37, ra4m1_ek all 30/30
through the HIL battery after the changes; builds clean incl. buffered-mode
vendor (webusb_serial).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>fix CI: clang/IAR unused helpers, LTO-dropped ISR symbol, LPC11/13 USB RAM overflow</title>
<updated>2026-07-06T10:55:26Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T10:55:26Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=59f15ad44d4121630368e54cf52287f5a814e787'/>
<id>urn:sha1:59f15ad44d4121630368e54cf52287f5a814e787</id>
<content type='text'>
Four PR-CI failures, each with a distinct root cause:

- class/vendor: mark the shared non-buffered transfer helpers TU_ATTR_UNUSED.
  In buffered mode with the int/iso endpoint gates off none is referenced, and
  clang (-Wunused-function -Werror) and IAR (Error[Pe177]) reject an unused
  static — gcc does not, which is why only the clang/IAR matrix failed.
- bsp/ch32v20x: keep dcd_int_handler alive under LTO. The `call` sits inside
  naked asm where LTO cannot see it, so -flto make builds internalized the
  symbol and every ch32v20x device example failed to link (cmake has no LTO,
  which masked it). A TU_ATTR_USED function-pointer reference pins it.
- usbtest: LPC11/13 (ip3511 FS) keep endpoint buffers in a dedicated 2 KB USB
  RAM; the 2048 B bulk epbuf overflowed it (RamUsb2 150%) in make builds. Use
  512 B (= 8 FS packets) on those parts; lpcxpresso11u37 still passes 30/30.
- test/hil: skip device/usbtest on lpcxpresso43s67 (hfp rig) — its ip3511 HS
  port wedges from the first control case (1/30) and needs on-rig debugging.

Verified: make builds link for nanoch32v203 (dfu_runtime + usbtest),
lpcxpresso11u37 and lpcxpresso1347 (RamUsb2 75%); buffered-mode webusb_serial
builds; 61/61 unit tests; lpcxpresso11u37 usbtest 30/30 on hardware with the
smaller epbuf.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/master' into usbtest</title>
<updated>2026-07-06T09:17:17Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T09:17:17Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=2d73cf58de9a41278a9c6e1e3c9e5c6626bf95b7'/>
<id>urn:sha1:2d73cf58de9a41278a9c6e1e3c9e5c6626bf95b7</id>
<content type='text'>
# Conflicts:
#	lib/rt-thread/port/msc_device_port.c
#	src/device/usbd.c
</content>
</entry>
<entry>
<title>usbtest: address remaining review findings (rusb2 #11/#12, vendor #15)</title>
<updated>2026-07-06T07:03:10Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T07:03:10Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=3345e80d843a6c13543311bf0eda8cd1bf40604f'/>
<id>urn:sha1:3345e80d843a6c13543311bf0eda8cd1bf40604f</id>
<content type='text'>
#12 dcd(rusb2): key the bulk-OUT clear-stall re-arm on a new per-pipe `queued`
   flag instead of `pipe.buf != NULL`. A zero-length OUT read leaves buf==NULL
   while still armed, so the old test skipped the re-assert and the endpoint
   NAKed forever after CLEAR_FEATURE(HALT). `queued` is set at submit and
   cleared at completion (and on pipe teardown).
#11 dcd(rusb2): retry a zero-length IN packet that couldn't be queued at submit
   (double-buffered pipe full, host not draining). Previously the ZLP was
   dropped and the next BRDY reported a phantom completion for a packet the host
   never received; now it's deferred to BRDY via `zlp_pending` and only
   completes once actually queued and sent.
#15 vendor: collapse the byte-identical bulk/interrupt/isochronous non-buffered
   write / write_available / read_xfer triples into three shared static-inline
   helpers keyed on (endpoint, epbuf, bufsize).

Verified on ra4m1_ek: usbtest tier-4 30/30 (rusb2 + vendor refactor); pre-commit
(format/codespell/unit) clean. The nRF54LM20 DK also passes 30/30 at high speed.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>usbtest: address code-review findings (EP3 iso regression + 9 more)</title>
<updated>2026-07-06T04:53:40Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-06T04:53:40Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=24be2499839538b377927d30d4ab43122f337dff'/>
<id>urn:sha1:24be2499839538b377927d30d4ab43122f337dff</id>
<content type='text'>
Cross-checking the branch against the MCU datasheets surfaced a regression and
several latent defects. Fixes (finding # from the review):

#1 dcd_ch32_usbfs: restore EP3's enlarged iso buffer. CH32V20x/V30x/F20x USBFS
   give endpoint 3 a 1023-byte iso packet (CH32FV2x_V3xRM ch23; 16-bit
   R16_UEP3_T_LEN), unlike every other 64 B endpoint. Commit c05e9313e removed
   that buffer and capped iso at 64 B, breaking &gt;64 B FS iso (UVC/UAC) on EP3.
   Re-add it via CFG_TUD_WCH_USBFS_EP3_BUFSIZE, defaulted to 1023 on those parts
   (CH32_USBFS_EP3_1023_BUFSIZE in ch32_usbfs_reg.h) and 64 elsewhere.
#3 dcd_ch32_usbfs: make data.isochronous[] per-direction and clear it on
   endpoint (re)open, so a reused ep number can't inherit a stale iso response.
#7 dcd_ch32_usbfs: exempt iso from the PID_OUT data-toggle handling too (was
   only done for PID_IN); iso is DATA0-only in both directions.
#13 dcd_ch32_usbfs: bounds-assert ep &lt; EP_MAX in dcd_edpt_iso_alloc.
#2/#6 usbtest descriptors: TUD_OPT_HIGH_SPEED is a compile-time capability, not
   the live speed, so the full-speed config (and OTHER_SPEED) advertised int/iso
   mps 512 on HS boards — illegal at FS / over the 1023 B/frame iso budget. Split
   into FS-legal / HS descriptor sizes; the plain macro tracks operating speed.
#10 vendor: non-alt free-slot detection also checks the int endpoints (a vendor
   interface may now be interrupt-only, no bulk ep).
#14 vendor: replace the order-coupled ITF_MEM_RESET_SIZE ladder (2 unreachable
   branches) with offsetof(vendord_interface_t, tx_stream).
#5 rp2040: clear_stall re-issue preserves the already-transferred count so a
   mid-transfer clear-halt reports the full length, not just the remainder.
#8 rp2040: force single-buffering for iso (only BULK gets a double DPRAM buffer),
   so a multi-packet iso xfer can't spill buffer 1 into the next ep's DPRAM.

Verified: CH32V203 usbfs and CH583 still pass usbtest tier-4 30/30; all board
families build; pre-commit (format/codespell/unit) clean.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>usbd/vendor/usbtest: address second-round review findings</title>
<updated>2026-07-03T02:43:39Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-03T02:43:39Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=fea013861de27da047ca0b0a7f01cb913246ae4b'/>
<id>urn:sha1:fea013861de27da047ca0b0a7f01cb913246ae4b</id>
<content type='text'>
usbd:
- usbd_edpt_clear_stall keeps the long-standing unconditional STALLED|BUSY
  clear (audio's set-interface relies on it to drop a leftover BUSY bit)
  and only gates the new CLAIMED release on the endpoint having been
  stalled — fixes the halt-test starvation without the double-arm race and
  without regressing audio on ports where nothing else zeros ep_status.
- GET_STATUS direction guard + checked return factored into a shared
  process_get_status() and applied to all three recipients (device,
  interface, endpoint); previously only the interface case was hardened,
  leaving the endpoint/device siblings able to hand usbd a stack buffer for
  a malformed OUT request.

vendor:
- vendord_open commits p_itf_desc only after the descriptor parse succeeds,
  so a mid-parse failure no longer marks the interface slot permanently
  occupied (find_vendor_itf keys on p_itf_desc under ALT_SETTINGS).
- vendord_set_alt is a single pass again: the current endpoints are dropped
  only once the target altsetting is confirmed present, dropping the
  redundant vendord_has_alt pre-scan while keeping the invalid-alt rollback.
- CLOSE_API iso re-activation now closes+reopens the endpoint (zeroing
  ep_status) instead of a no-op, so a re-selected altsetting on ip3511/rusb2
  can't starve on stale BUSY/CLAIMED.

test/hil/usbtest.py:
- re-resolve on the concrete serial (never retarget a different device),
  best-effort cleanup that can't mask the original error, set_pattern
  catches PermissionError too, --tier choices derive from TIER_CASES,
  --tests uses isdecimal.

Full 30-case battery passes on all four dwc2 boards; all three GET_STATUS
recipients + invalid SET_INTERFACE + EP0 halt verified via raw usbfs
control transfers; usbtest builds for ip3511/rusb2 (CLOSE_API iso path).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>class/vendor: portability + robustness fixes for int/iso/alt support</title>
<updated>2026-07-03T01:57:29Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-03T01:57:29Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=4f83784b289797b89c88c5748d1d69c119b00561'/>
<id>urn:sha1:4f83784b289797b89c88c5748d1d69c119b00561</id>
<content type='text'>
- Isochronous endpoints are reserved through TUP_DCD_EDPT_ISO_ALLOC-guarded
  helpers with a usbd_edpt_open fallback (mirrors audio), so ports without
  the iso alloc API (lpc_ip3511, rusb2) enumerate instead of failing open.
- #error when EP_ISO_* is set without ALT_SETTINGS (iso must live in a
  non-zero altsetting per USB 2.0 5.6.3); the non-alt open path no longer
  silently treats an iso endpoint as bulk.
- Non-buffered bulk read/write gain the 'ep &gt; 0' guard the int/iso APIs
  have, so they cannot claim EP0 while an altsetting without a bulk ep is
  selected.
- find_vendor_itf uses p_itf_desc (not the ep fields) to detect a free
  slot under ALT_SETTINGS, where an interface parked in the empty alt 0
  has all ep fields 0; fixes slot aliasing with CFG_TUD_VENDOR &gt; 1.
- vendord_set_alt validates the altsetting exists before mutating state
  (rollback safety) and stall/clears interrupt endpoints only for the
  enabled direction.
- vendord_open rejects an endpoint address reused across altsettings with
  a different type/MPS (opened once), closing a misconfig + buffer overflow.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>class/vendor: isochronous endpoints + alternate setting support</title>
<updated>2026-07-02T15:58:36Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-02T15:58:36Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=7040c9b9e25551caa01205389b1fc7b430b77304'/>
<id>urn:sha1:7040c9b9e25551caa01205389b1fc7b430b77304</id>
<content type='text'>
CFG_TUD_VENDOR_EP_ISO_OUT/IN (default 0) add an isochronous endpoint per
direction with the same non-buffered API shape as the interrupt pair
(tud_vendor_n_iso_read_xfer / tud_vendor_n_iso_write + weak iso_rx/tx_cb),
buffers sized by CFG_TUD_VENDOR_EP_ISO_OUT/IN_BUFSIZE.

CFG_TUD_VENDOR_ALT_SETTINGS (default 0, non-buffered mode only) lets the
vendor interface carry multiple altsettings: vendord consumes them all,
answers GET_INTERFACE and performs SET_INTERFACE via a new internal
vendord_control_xfer_cb (registered in usbd's driver table; everything
else still delegates to the app's tud_vendor_control_xfer_cb).

Endpoints are hardware-opened exactly once at vendord_open: dcds with a
linear FIFO allocator (dwc2: TUP_DCD_EDPT_ISO_ALLOC, where
usbd_edpt_close is a no-op and every re-open leaks FIFO space) cannot
close/re-open endpoints dynamically. Selecting an altsetting only
re-targets the API: bulk/interrupt endpoints get a stall+clear-stall
cycle, which portably aborts any in-flight transfer and resets the data
toggle to DATA0 as SET_INTERFACE requires; isochronous endpoints are
FIFO-allocated at open and (re)activated on selection.

Motivated by the usbtest example (Linux usbtest iso cases 15/16/22/23,
which also drives 256 consecutive SET_INTERFACE cycles in its ch9 case);
alt 0 without endpoints satisfies USB 2.0 5.6.3 for iso devices.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
</feed>
