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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user