fix(host): don't count punktfunk's own virtual Deck as a physical Steam controller
apple / swift (push) Successful in 1m7s
android / android (push) Has been cancelled
apple / screenshots (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / web (push) Has been cancelled
ci / rust (push) Has been cancelled
deb / build-publish (push) Has been cancelled
decky / build-publish (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
windows-host / package (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
apple / swift (push) Successful in 1m7s
android / android (push) Has been cancelled
apple / screenshots (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / web (push) Has been cancelled
ci / rust (push) Has been cancelled
deb / build-publish (push) Has been cancelled
decky / build-publish (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
windows-host / package (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
The Steam-conflict gate scanned /sys/bus/hid/devices for non-virtual 28DE devices, but the usbip/gadget virtual Decks present a REAL USB device (vhci resolves through vhci_hcd, not /devices/virtual/) — so a just-ended session's pad still detaching, or a concurrent session's live one, read as "physical Steam controller attached" and degraded every back-to-back Deck session to DualSense (observed live on Bazzite). Exclude our pads by their PFDK… serial (HID_UNIQ), with the vhci_hcd path as belt and braces. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1911,6 +1911,13 @@ fn degrade_if_no_uhid(chosen: GamepadPref) -> GamepadPref {
|
|||||||
/// two Decks — confirmed conflict-prone on a Deck-as-host (the physical `28DE:1205` + Steam's
|
/// two Decks — confirmed conflict-prone on a Deck-as-host (the physical `28DE:1205` + Steam's
|
||||||
/// `28DE:11FF` XInput output pad are both live). HID device dirs are named `BUS:VID:PID.INST`
|
/// `28DE:11FF` XInput output pad are both live). HID device dirs are named `BUS:VID:PID.INST`
|
||||||
/// (uppercase); a UHID virtual device resolves through `/devices/virtual/…`, a real one does not.
|
/// (uppercase); a UHID virtual device resolves through `/devices/virtual/…`, a real one does not.
|
||||||
|
///
|
||||||
|
/// Punktfunk's OWN virtual Decks must never count: the usbip/gadget transports present a real USB
|
||||||
|
/// device (vhci resolves through `vhci_hcd`, NOT `/devices/virtual/`), so a just-ended session's
|
||||||
|
/// pad still detaching — or a concurrent session's live one — read as "physical" and degraded
|
||||||
|
/// every back-to-back Deck session to DualSense (observed live on Bazzite 2026-07-04). Ours are
|
||||||
|
/// recognizable by the `PFDK…` serial ([`steam_proto::deck_serial`]) in `HID_UNIQ`, with the
|
||||||
|
/// vhci path as belt and braces.
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn physical_steam_controller_present() -> bool {
|
fn physical_steam_controller_present() -> bool {
|
||||||
let Ok(entries) = std::fs::read_dir("/sys/bus/hid/devices") else {
|
let Ok(entries) = std::fs::read_dir("/sys/bus/hid/devices") else {
|
||||||
@@ -1920,8 +1927,16 @@ fn physical_steam_controller_present() -> bool {
|
|||||||
if !e.file_name().to_string_lossy().contains(":28DE:") {
|
if !e.file_name().to_string_lossy().contains(":28DE:") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if std::fs::read_to_string(e.path().join("uevent"))
|
||||||
|
.is_ok_and(|u| u.lines().any(|l| l.starts_with("HID_UNIQ=PFDK")))
|
||||||
|
{
|
||||||
|
return false; // one of our own virtual Decks
|
||||||
|
}
|
||||||
match std::fs::read_link(e.path()) {
|
match std::fs::read_link(e.path()) {
|
||||||
Ok(target) => !target.to_string_lossy().contains("/virtual/"),
|
Ok(target) => {
|
||||||
|
let t = target.to_string_lossy();
|
||||||
|
!t.contains("/virtual/") && !t.contains("vhci_hcd")
|
||||||
|
}
|
||||||
Err(_) => true,
|
Err(_) => true,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user