fix(host/steam): load vhci_hcd at boot on sysext hosts so the Deck pad is Steam-Input-promotable
ci / web (push) Successful in 1m2s
ci / docs-site (push) Successful in 1m9s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 8s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 8s
decky / build-publish (push) Successful in 30s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 8s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 8s
apple / swift (push) Successful in 4m25s
ci / bench (push) Successful in 6m50s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5m49s
docker / deploy-docs (push) Successful in 26s
windows-host / package (push) Successful in 8m40s
arch / build-publish (push) Successful in 11m22s
deb / build-publish (push) Successful in 12m27s
android / android (push) Successful in 16m50s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 19m19s
apple / screenshots (push) Successful in 19m19s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 17m14s
ci / rust (push) Successful in 25m14s
ci / web (push) Successful in 1m2s
ci / docs-site (push) Successful in 1m9s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 8s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 8s
decky / build-publish (push) Successful in 30s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 8s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 8s
apple / swift (push) Successful in 4m25s
ci / bench (push) Successful in 6m50s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5m49s
docker / deploy-docs (push) Successful in 26s
windows-host / package (push) Successful in 8m40s
arch / build-publish (push) Successful in 11m22s
deb / build-publish (push) Successful in 12m27s
android / android (push) Successful in 16m50s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 19m19s
apple / screenshots (push) Successful in 19m19s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 17m14s
ci / rust (push) Successful in 25m14s
The virtual Steam Deck pad only appears in the host's Game Mode (and is navigable) when it arrives as a real USB device via the usbip/vhci_hcd transport — Steam Input won't promote the UHID hid-steam fallback (Interface: -1). The host runs as an unprivileged --user service, so it cannot modprobe vhci_hcd itself; the module must be loaded at boot and the vhci attach/detach sysfs files chgrp'd to the `input` group by the udev rule. Packaging ships modules-load.d/punktfunk.conf + 60-punktfunk.rules under the sysext's /usr/lib, but a systemd-sysext image MERGES after systemd-modules-load and early udev have already run, so on a plain reboot of a sysext host (e.g. Bazzite) those files are read too late: vhci_hcd is never loaded, usbip fails, and the pad silently degrades to non-promoted UHID — the controller vanishes from Game Mode. (deb/arch/rpm are unaffected: real /usr is present at early boot.) Fix: sysext post_merge now mirrors BOTH files into real /etc (read at the normal early-boot time, shadowing the /usr copies by filename; refreshed every merge since neither is user config), then reloads udev, modprobes vhci-hcd, and re-triggers the vhci platform device for the live session. Also raise the UHID-fallback log INFO->WARN with an actionable hint. Verified on the .41 sysext host: after the /etc mirror, unloading vhci_hcd and restarting systemd-modules-load (the real reader of /etc/modules-load.d) reloads the module; a udev coldplug trigger makes attach/detach root:input 0660; the unprivileged host user can then write attach — the exact working precondition for the usbip transport, now durable across reboot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -339,11 +339,18 @@ fn open_transport(idx: u8) -> Result<DeckTransport> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 3. UHID — universal fallback (works everywhere; Steam Input won't promote it).
|
// 3. UHID — universal fallback (works everywhere; Steam Input won't promote it). This is a
|
||||||
|
// DEGRADED outcome, not a normal one: a UHID device has no USB interface number (Interface: -1),
|
||||||
|
// so Steam Input ignores it and the controller never appears in Game Mode / can't navigate.
|
||||||
|
// Reaching here almost always means `vhci_hcd` isn't loaded (the host runs unprivileged and
|
||||||
|
// can't modprobe it) — load it at boot (packaging ships modules-load.d/punktfunk.conf +
|
||||||
|
// 60-punktfunk.rules; on a systemd-sysext host `punktfunk-sysext` mirrors both into /etc).
|
||||||
let p = SteamDeckPad::open(idx)?;
|
let p = SteamDeckPad::open(idx)?;
|
||||||
tracing::info!(
|
tracing::warn!(
|
||||||
index = idx,
|
index = idx,
|
||||||
"virtual Steam Deck created (UHID hid-steam — not Steam-Input-promoted)"
|
"virtual Steam Deck created as UHID hid-steam — Steam Input WON'T promote it (no USB \
|
||||||
|
interface), so it won't appear in Game Mode. Load vhci_hcd (usbip) so the pad arrives as a \
|
||||||
|
real USB device: `sudo modprobe vhci_hcd`, and ensure it loads at boot."
|
||||||
);
|
);
|
||||||
Ok(DeckTransport::Uhid(p))
|
Ok(DeckTransport::Uhid(p))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,10 +77,26 @@ post_merge() {
|
|||||||
for f in /usr/lib/sysctl.d/99-punktfunk-net.conf /usr/lib/sysctl.d/99-punktfunk-client-net.conf; do
|
for f in /usr/lib/sysctl.d/99-punktfunk-net.conf /usr/lib/sysctl.d/99-punktfunk-client-net.conf; do
|
||||||
[ -f "$f" ] && sysctl -q -p "$f" 2>/dev/null || :
|
[ -f "$f" ] && sysctl -q -p "$f" 2>/dev/null || :
|
||||||
done
|
done
|
||||||
# vhci-hcd now, no reboot (modules-load.d/punktfunk.conf covers boot): the usbip transport
|
# vhci-hcd: the usbip transport that makes the virtual Steam Deck pad a real USB device Steam
|
||||||
# that makes the virtual Steam Deck pad a real USB device Steam Input adopts. The udev add
|
# Input adopts. Without it the pad falls back to plain UHID hid-steam, which Steam Input won't
|
||||||
# event fires the 60-punktfunk.rules vhci rule, opening the attach files to the input group.
|
# promote (Interface: -1) — so on a host in Game Mode the controller never appears and you can't
|
||||||
[ -f /usr/lib/modules-load.d/punktfunk.conf ] && modprobe vhci-hcd 2>/dev/null || :
|
# navigate. Two things must be true at boot: the module loaded, and the vhci `attach`/`detach`
|
||||||
|
# sysfs files opened to the `input` group (the host runs unprivileged and can't modprobe/chown).
|
||||||
|
#
|
||||||
|
# A sysext CANNOT rely on its own /usr/lib/modules-load.d + /usr/lib/udev files for this: the
|
||||||
|
# image merges (systemd-sysext.service) AFTER systemd-modules-load and early udev have already
|
||||||
|
# run, so at a plain reboot vhci-hcd is never loaded and its rule never applied. Mirror BOTH into
|
||||||
|
# real /etc (read at the normal early-boot time, and shadowing the /usr copies by filename) so the
|
||||||
|
# module loads early and udev's coldplug trigger grants the group access. Refreshed every merge so
|
||||||
|
# a rule/module change in a new image propagates (neither is user-editable config). Then load +
|
||||||
|
# (re)apply now, no reboot, for this session.
|
||||||
|
install -Dm0644 /usr/lib/modules-load.d/punktfunk.conf /etc/modules-load.d/punktfunk.conf 2>/dev/null || :
|
||||||
|
install -Dm0644 /usr/lib/udev/rules.d/60-punktfunk.rules /etc/udev/rules.d/60-punktfunk.rules 2>/dev/null || :
|
||||||
|
udevadm control --reload 2>/dev/null || :
|
||||||
|
modprobe vhci-hcd 2>/dev/null || :
|
||||||
|
# Re-fire the vhci rule against the (possibly already-present) controller so attach/detach pick up
|
||||||
|
# the input-group ownership even when the module's original add event predated the reloaded rule.
|
||||||
|
udevadm trigger --subsystem-match=platform --sysname-match='vhci_hcd.*' 2>/dev/null || :
|
||||||
# The /etc payload a sysext can't carry. The gamescope-session drop-in is %config(noreplace):
|
# The /etc payload a sysext can't carry. The gamescope-session drop-in is %config(noreplace):
|
||||||
# only seed it, never clobber a local edit. The tray autostart entry is not user config.
|
# only seed it, never clobber a local edit. The tray autostart entry is not user config.
|
||||||
if [ -f "$ETC_SRC/gamescope-session-plus/sessions.d/steam" ] \
|
if [ -f "$ETC_SRC/gamescope-session-plus/sessions.d/steam" ] \
|
||||||
|
|||||||
Reference in New Issue
Block a user