Skip to content

embassy-usb-host: stop descriptor retries on disconnect - #7030

Merged
bugadani merged 1 commit into
embassy-rs:mainfrom
ShangYJQ:fix/usb-host-disconnect-retry
Sep 18, 2026
Merged

bugadani merged 1 commit into
embassy-rs:mainfrom
ShangYJQ:fix/usb-host-disconnect-retry

Conversation

@ShangYJQ

Copy link
Copy Markdown
Contributor

Summary

Stop retry_descriptor() from retrying descriptor reads after
PipeError::Disconnected.

A disconnect is terminal: retrying the request starts a new transfer after
the device has already left the bus. Depending on the host driver, that
transfer may never complete.

Problem

I reproduced this with a USB device that disconnects and re-enumerates
during enumeration.

The host driver (embassy-usb-synopsys-otg, ESP32-S3) correctly propagated
the disconnect to the in-flight transfer:

propagate EV_DISCONNECT
→ wait_for_result: EV_DISCONNECT
→ PipeError::Disconnected
→ control transfer returns Disconnected

However, retry_descriptor() treated Disconnected like any other
descriptor-read error. After the 5 ms retry delay it issued the same
GET_DESCRIPTOR request again.

At that point the device was already disconnected, so the new transfer
remained pending indefinitely and enumeration never returned.

Fix

Return Disconnected immediately from retry_descriptor() while preserving
the existing retry behavior for other errors such as Stall.

The helper is used with both PipeError and HostError, so the error is
converted to HostError only for the terminal-disconnect check.

Testing

Added regression coverage verifying that:

  • Disconnected is returned immediately and the operation is attempted
    exactly once (both as PipeError and as HostError::PipeError).
  • Stall remains retryable and can succeed on a subsequent attempt.

Without the fix, the disconnect test fails because the read is attempted
4 times (the initial attempt plus 3 retries).

I also verified the fix on hardware using an ESP32-S3 USB host and a device
that re-enumerates from 04b4:2412 to 045e:028e.

Before the fix, enumeration remained pending after the intermediate device
disconnected.

After the fix:

Device: VID=04b4 PID=2412
port Disconnected
enumerate ERR: Transfer(Disconnected)

port Connected
Device: VID=045e PID=028e
enumerate OK

@embassy-bot

embassy-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

👋 Welcome, @ShangYJQ, and thanks for opening your first pull request here!

If you haven't already, please give the contributor guide a read.

@leftger leftger added the e-usb-host Issues for USB Host label Sep 18, 2026
@leftger
leftger requested a review from bugadani September 18, 2026 21:29
@bugadani
bugadani added this pull request to the merge queue Sep 18, 2026
Merged via the queue into embassy-rs:main with commit a877e95 Sep 18, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e-usb-host Issues for USB Host

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants