feat(steam): raw_gadget virtual Deck — full Steam Input recognition (proven on Deck)

The interface-2 wall is climbed. packaging/linux/steam-deck-gadget/deck_raw_gadget.c
is a raw_gadget userspace emulator of a real 3-interface USB Steam Deck (28DE:1205,
mouse=0/keyboard=1/controller=2) on a dummy_hcd loopback UDC, with descriptors
captured verbatim from a physical Deck and full HID feature-report handling.

Live on a real Deck (SteamOS 3.8.11): hid-steam reads our serial (PFDECK000),
creates the Steam Deck + Motion Sensors evdevs, and Steam Input PROMOTES it —
controller.txt "Interface: 2 ... device opened ... reserving XInput slot 1" +
"input: Microsoft X-Box 360 pad 1". Stable (1 connect, 0 disconnects, no zombie);
the kernel Steam Deck evdev is then grabbed by Steam Input which exposes its own
X-Box pad, exactly like a real Deck. First time a virtual Deck is fully Steam-Input
promoted (UHID can't — it has no USB interface number, so Steam filters it).

Also includes the configfs f_hid variant (configfs_gadget_up/down.sh) — the minimal
reproducer that proved interface 2 makes Steam open+XInput-reserve the device, but
f_hid can't serve feature reports so Steam dropped it as a zombie.

Gotchas documented in the README: 7-byte vs 9-byte endpoint descriptor, no-data OUT
controls acked via zero-length EP0_READ (not WRITE, else error -110), streamer must
not start before SET_CONFIGURATION is acked. SteamOS-host only (needs dummy_hcd +
raw_gadget). Recognition proven; feeding real client reports + a host backend is next.
Not pushed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-29 14:38:26 +00:00
parent a81f1304cd
commit 8870e85233
5 changed files with 452 additions and 0 deletions
+30
View File
@@ -758,3 +758,33 @@ HID feature/output reports, which `f_hid` can't but **`raw_gadget` can** (usersp
control transfer, exactly like the UHID path). Next: a `raw_gadget` userspace emulator of the
3-interface Deck (controller on interface 2) that answers the serial/attribute/settings feature
reports + streams the 64-byte state report — then re-test hid-steam gamepad evdev + Steam promotion.
### Gadget path SUCCESS — raw_gadget Deck gets full Steam Input recognition (2026-06-29)
The `f_hid` zombie was a feature-report problem, and `raw_gadget` (userspace handles every control
transfer) solves it. `packaging/linux/steam-deck-gadget/deck_raw_gadget.c` presents the real
3-interface Deck (descriptors captured verbatim from a physical Deck, controller on interface 2) and
answers the HID feature reports hid-steam/Steam need. Live on the Deck:
```
hid-steam ... Steam Controller 'PFDECK000' connected (serial READ — not XXXXXXXXXX)
input: Steam Deck / Steam Deck Motion Sensors (kernel gamepad + IMU evdevs)
controller.txt: Interface: 2 ... device opened for index 14 ... reserving XInput slot 1
input: Microsoft X-Box 360 pad 1 (Steam Input's XInput output — PROMOTED)
```
Stable (1 connect, 0 disconnects, no zombie). The kernel `"Steam Deck"` evdev is then grabbed by
Steam Input, which exposes its own X-Box 360 pad — a real Deck's exact behaviour. **This is the first
time a virtual Steam Deck has been fully promoted by Steam Input** (UHID can't; the interface-2 wall
is climbed). The hard part — recognition — is done.
Implementation gotchas (see the packaging README): `struct usb_endpoint_descriptor` is 9 bytes but
the wire descriptor needs 7; no-data OUT controls are acked with a zero-length `EP0_READ` not
`EP0_WRITE` (else `error -110`); the input streamer must not start until after SET_CONFIGURATION is
acked. Scope: SteamOS-host only (needs `dummy_hcd` + `raw_gadget`, which SteamOS ships; a generic
Linux host would have to build them).
**Remaining:** feed real client state through the interface-2 endpoint (the `steam_proto` serializer
already produces correct Deck reports — wire it to the gadget's stream), and wrap this as a host
gamepad backend (a `raw_gadget` alternative to the UHID `SteamDeckPad`). Then the streamed Deck/SC
client reaches the host's games as a true Deck through Steam Input.