Skip to content

host: fix enumerate racing #3080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 23, 2025
Merged

host: fix enumerate racing #3080

merged 6 commits into from
Apr 23, 2025

Conversation

HiFiPhile
Copy link
Collaborator

@HiFiPhile HiFiPhile commented Apr 12, 2025

Describe the PR

Move _dev0.enumerating into event queue

  • if a previous enumeration failed _ctrl_xfer status could stuck, it needs to be cleared before next attempt.
  • after _dev0.enumerating is reset in hcd_event_handler(), if an attach event arrived before _ctrl_xfer clean up in remove event, a racing condition will happen.

Move decouncing delay before USB reset.

Chirp K for HS detection happens within 7ms of the start of reset, to make speed detection reliable the debouncing delay need to be placed before reset.

image

image

Windows 10 does this:

  1. Vbus detected
  2. Delay 100ms
  3. Bus reset + chirp 50ms
  4. Delay 33ms
  5. Start setup

- if a previous enumeration failed _ctrl_xfer status could stuck, it needs to be cleared before next attempt.
- after _dev0.enumerating is reset in hcd_event_handler(), if an attach event arrived before _ctrl_xfer clean up in remove event, a racing condition will happen.

Signed-off-by: HiFiPhile <[email protected]>
src/host/usbh.c Outdated
Comment on lines 566 to 569
if ((event.rhport == _dev0.rhport) && (event.connection.hub_addr == _dev0.hub_addr) &&
(event.connection.hub_port == _dev0.hub_port)) {
_dev0.enumerating = 0;
hcd_device_close(_dev0.rhport, _dev0.hub_addr);
Copy link
Owner

@hathach hathach Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank yo, we should include _dev0.enumerating == 1 since other value has obsolete (for new device) after enumerated successfully. The isr blindly set the flag, but we need to check since we do more than that here. Also hcd_device_close(_dev0.rhport, 0) instead of using hub_addr

I have rebased and fix this, also move this snippet into process_removing_device() since there is a TODO for dev0 there.

Copy link
Collaborator Author

@HiFiPhile HiFiPhile Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested, is hcd_device_close(_dev0.rhport, 0) works with device under a hub ?

I need to read more how hub is handled ;)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should, the 2nd argument is the device addres that is removed. Otherwise, it will try to remove the hub that attached the rhport.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a loophole with early return. If set address is done _dev0.enumerating is still true but _usbh_devices also needs to be cleaned.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah you are right, putting enumerating in dev0 is confusing. Let me revise and fix this.

replace dev0.enumerating by enumerating_daddr for better clean up on unplugging while enumerating
move controller_id & enumerating_daddr into _usbh_data struct
Copy link
Owner

@hathach hathach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made an improvement from just a flag enumerating to actual enumerating_daddr to make it easier to clean up when device unplugged while enumerating not completed yet. @HiFiPhile please let me know if this make sense to you.

After this merged, I will make PR similar to the #3075 for ignoring attach/detach on the same rhport/hub/port while debouncing to usbh to make it generic for all host controller. This seems to work rathe well.

Signed-off-by: HiFiPhile <[email protected]>
@HiFiPhile
Copy link
Collaborator Author

It works pretty well in my side, tried some quick action and no assert happened :)

@hathach hathach merged commit b632686 into hathach:master Apr 23, 2025
108 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants