Skip to content

Fix Resume() to fully reinitialize USB device after suspend#249

Open
fcatuhe wants to merge 1 commit intouunicorn:masterfrom
fcatuhe:fix/survive-usb-errors
Open

Fix Resume() to fully reinitialize USB device after suspend#249
fcatuhe wants to merge 1 commit intouunicorn:masterfrom
fcatuhe:fix/survive-usb-errors

Conversation

@fcatuhe
Copy link

@fcatuhe fcatuhe commented Mar 17, 2026

Replace the broken Resume() implementation with a proper retry loop that does a full init.open() (USB re-enumeration + sensor init), giving the kernel time to enumerate the USB device after wake.

Motivation

The existing Resume() called init.open_common() which skips usb.open() — it assumes the USB handle is still valid. After suspend, the kernel resets the USB bus and the handle goes stale, causing USBError: [Errno 19] No such device. The original single bare-except retry was also insufficient since the USB device may not be enumerated yet when Resume() is called.

This became visible after open-fprintd PR #24 added PrepareForSleep handling, which now calls Device.Resume() automatically on wake. The hyprlock maintainer rightly pointed out that DBus services should handle suspend internally and stay alive across sleep cycles.

Related issues

This change, together with open-fprintd PR #24, should address:

Related PRs

Changes

Changes to dbus_service/dbus-service and validitysensor/usb.py:

  • Call init.open() instead of init.open_common() to get a fresh USB handle
  • Retry up to 20 times with 100ms delay (2s max) for USB enumeration
  • Change open_dev() to raise USBError instead of a bare Exception when the device is not found, so the retry loop can catch USBError specifically

Testing

Tested on a ThinkPad X1 Carbon 6th Gen (06cb:009a Synaptics reader) running Arch Linux (Omarchy) with open-fprintd + python-validity. Multiple suspend/resume cycles — USB device typically enumerates after 0-2 failed attempts (~0-200ms). Fingerprint verification works reliably after wake. Tested both successful matches and no-match retries across multiple cycles without service crashes.

Replace the broken Resume() with a retry loop that does a full
init.open() (USB re-enumeration + sensor init), giving the kernel
time to enumerate the USB device after wake.

- Call init.open() instead of init.open_common() for fresh USB handle
- Retry up to 20 times with 100ms delay (2s max) for USB enumeration
- Catch Exception since usb.open() raises plain Exception when device
  is not yet enumerated
@NhProGamer
Copy link

I tested this on my T480, it seems to fix issues related, good job

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants