<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tinyusb.git/test/hil/usbtest.py, 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/test/hil/usbtest.py?h=worktree-ch569-hydrausb3</id>
<link rel='self' href='http://cgit.235523.xyz/tinyusb.git/atom/test/hil/usbtest.py?h=worktree-ch569-hydrausb3'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/'/>
<updated>2026-07-09T07:34:13Z</updated>
<entry>
<title>usbtest: skip silicon-impossible cases via bcdDevice quirk flags</title>
<updated>2026-07-09T07:34:13Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-09T07:34:13Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=62175c3e0d6a5cabf3008667eef0638335a69b3b'/>
<id>urn:sha1:62175c3e0d6a5cabf3008667eef0638335a69b3b</id>
<content type='text'>
The CH569 USBSS ctrl_out flakiness (cases 14/21, host -EPROTO) is a
silicon erratum, not a driver bug: EP0 OUT data stages whose wLength
% 4 == 1 are intermittently dropped at 5 Gbps. Proven by A/B against
WCH's own binary USB3 stack (SimulateCDC EVT demo patched to accept
the gadget-zero 0x5b/0x5c requests), which fails identically on the
same board — independent of host LPM (persists with U1/U2 disabled)
and sysclk (80 vs 120 MHz). Bulk OUT at the same lengths is clean.
Document the erratum in the dcd and drop the ineffective zeroed-BOS
workaround.

Rather than letting known-impossible cases flake the battery, the
firmware now advertises quirk flags in bcdDevice bits 4-7 (tier stays
in bits 0-3): 0x10 skips ctrl_out 14/21, 0x20 skips ep-halt 13 (the
previously proven single-STALL limitation). usbtest.py skips flagged
cases visibly at SuperSpeed only (explicit --tests still runs them)
and reports them in the summary/JSON.

Also fix the CH56x USB3 dcd leaving an endpoint halted across
reconfiguration: clear the stalled flag in dcd_edpt_open/close/
close_all (USB 2.0 9.4.5) so a SET_CONFIGURATION recovery of a
halted-then-reopened endpoint does not STALL forever.

Validated on hydrausb3_v1 at 5000M: tier-4 battery x3 = 27/27 passed
+ 3 skipped, full HIL device suite 12/12 green (MSC 160/134 MB/s).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
</content>
</entry>
<entry>
<title>Pass the usbtest battery on CH569 at high and SuperSpeed</title>
<updated>2026-07-08T05:26:08Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-08T05:26:08Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=597f27d0f46d24c276eb00f62aba6efd4199f2ba'/>
<id>urn:sha1:597f27d0f46d24c276eb00f62aba6efd4199f2ba</id>
<content type='text'>
Running the Linux kernel usbtest/testusb battery against the CH569 for
the first time. Results: 30/30 at high speed (4 consecutive reflash
cycles), 25/26 at SuperSpeed.

DCD fixes found by the battery:
- dcd_ch56x_usbhs: clear-halt on an armed bulk-OUT pipe reset the toggle
  but dropped the queued receive, NAKing forever (usbtest case 29 - the
  same defect previously found on rp2040/fsdev/ch32_usbhs/rusb2)
- dcd_ch56x_usb30: endpoint halt is now latched; the endpoint event
  handler used to clear the response field on every completion, wiping a
  just-set STALL while the peer streamed, and clear-halt now re-arms a
  still-armed transfer with the fresh packet sequence (cases 13/29)

usbtest example gains SuperSpeed support: tier 3 on SS builds, a
4-endpoint SS descriptor set with companions, EP0 512 config and
1024-byte receive buffers.

test/hil/usbtest.py gains SuperSpeed-aware case parameters: bulk sizes
and vary steps must be 1024-multiples at SS or the device's whole-packet
source overruns the host request (case 4 EOVERFLOW).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019MRGjBT2NBkCoWwyDT4LaE
</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>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>usbtest: FS-sized ep buffers + host runner hardening</title>
<updated>2026-07-03T01:57:32Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-03T01:57:32Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=556e1bf81f8307d2ba2051de2f547844bc10b121'/>
<id>urn:sha1:556e1bf81f8307d2ba2051de2f547844bc10b121</id>
<content type='text'>
- example: interrupt/iso endpoint buffers track the per-speed max packet
  size instead of a fixed 512, saving ~1.6 KB of USB DMA RAM on FS builds.
- test/hil/usbtest.py: re-resolve the device node after a mid-battery
  re-enumeration (stale node was misreported as NOTRUN); reject an
  out-of-range tier (a tier-0 device would run an empty battery and read
  green); validate --tests case numbers; run cleanup in a try/finally so a
  crash can't leave the dynamic id registered to hijack the next device;
  guard set_pattern and the pci-reset placeholder; report a sudo-password
  failure on the testusb fallback instead of a misleading NOTRUN.
- tinyusb-sudoer: allow the foreign-driver unbind path and the testusb
  fallback used by the runner.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>usbtest: auto-recover via usb_recover.sh pci-reset on kernel-side hang</title>
<updated>2026-07-02T10:40:13Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-02T10:40:13Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=1727156053adf45456b8f93561f680c774f629c4'/>
<id>urn:sha1:1727156053adf45456b8f93561f680c774f629c4</id>
<content type='text'>
A wedged control/bulk pipe leaves testusb in uninterruptible sleep;
FLR is the only lock-free recovery, and it must run before the cleanup
unbind writes or they deadlock the bus (see .claude/skills/usb-recover).

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>usbtest: abandon D-state testusb on timeout; usb-recover: pci-reset + ordering rule</title>
<updated>2026-07-02T08:49:20Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-02T08:49:20Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=d3f9b78c3b6c92f96290f4b4cee164b853b51513'/>
<id>urn:sha1:d3f9b78c3b6c92f96290f4b4cee164b853b51513</id>
<content type='text'>
The runner no longer waits on an unkillable child stuck in a usbfs ioctl:
it marks the case HUNG, aborts the battery, and prints the pci-reset
recovery command. Skill now documents the new usb_recover.sh pci-reset
(FLR) mode and the hard-won ordering rule: on a D-state hang FLR must come
before any rebind attempt, because a blocked rebind holds the PCI device
lock that FLR needs — after that only a reboot recovers.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
</content>
</entry>
<entry>
<title>test/hil: add usbtest.py runner for the kernel usbtest battery</title>
<updated>2026-07-02T07:37:23Z</updated>
<author>
<name>hathach</name>
<email>thach@tinyusb.org</email>
</author>
<published>2026-07-02T07:37:23Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/tinyusb.git/commit/?id=35cf99161efd4598d6ffee8a9ef1d18b19e41654'/>
<id>urn:sha1:35cf99161efd4598d6ffee8a9ef1d18b19e41654</id>
<content type='text'>
Binds the device to the usbtest driver (dynamic id; Gadget-Zero profile
ref-trick for tier&gt;=2), runs the tier-appropriate cases with explicit
packet-aligned parameters, and parses testusb stdout: its exit code is
always 0 and profile-gated cases print nothing, so a missing result line
is reported as a failure rather than a silent pass.

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