From a81f1304cdfa48a36e8aa1160be5bee73ba66b8c Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 29 Jun 2026 14:13:22 +0000 Subject: [PATCH] =?UTF-8?q?docs(steam):=20gadget=20PoC=20=E2=80=94=20inter?= =?UTF-8?q?face=202=20PROVEN=20(Steam=20opens=20+=20XInput-reserves=20it)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the Deck (which ships dummy_hcd + raw_gadget + configfs f_hid), a pure-shell configfs gadget stood up a real 3-interface USB Deck (kbd=0/mouse=1/controller=2, 28de:1205) on a dummy_hcd loopback UDC. hid-steam bound all 3 interfaces, and crucially Steam PROMOTED the interface-2 controller: "Local Device Found ... Interface: 2 ... Steam controller device opened for index 14 ... Steam Controller reserving XInput slot 1" — exactly where the interface -1 UHID Deck was filtered. It then failed only at feature-report exchange (f_hid can't serve HID GET_REPORT: "steam_send_report: error -32", "couldn't get controller details ... zombie controller"), and no gamepad evdev formed for the same reason. So interface 2 is necessary AND sufficient for Steam to open+XInput-reserve the Deck; the remaining piece is serving feature/output reports, which raw_gadget can (full control, like UHID). Next: a raw_gadget 3-interface Deck emulator. Doc §11. Not pushed. Co-Authored-By: Claude Opus 4.8 (1M context) --- design/steam-controller-deck-support.md | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/design/steam-controller-deck-support.md b/design/steam-controller-deck-support.md index cea6a0a..378c825 100644 --- a/design/steam-controller-deck-support.md +++ b/design/steam-controller-deck-support.md @@ -732,3 +732,29 @@ configfs) or a kernel USB bus driver — a much larger, less portable lift, and 1. A **live SDL/non-Steam game** on a Linux host actually consuming the virtual Deck's grips/trackpads (the path that *does* work) — needs a real Deck/SC client + a Steam-Input-disabled consumer. 2. The **Moonlight paddle regression** from the M3 xpad-map change (stock paddle client → host). + +### Gadget PoC — interface 2 is PROVEN on the Deck (2026-06-29) + +SteamOS ships every primitive (`CONFIG_USB_DUMMY_HCD=m`, `CONFIG_USB_RAW_GADGET=m`, +`CONFIG_USB_CONFIGFS_F_HID=y`), so the gadget path is testable on the Deck itself with no +module-building. A pure-shell **configfs gadget** (`deck_gadget_up.sh`) stood up a real 3-interface +USB Deck on a `dummy_hcd` loopback UDC — keyboard = interface 0, mouse = 1, **controller = interface +2** (`STEAMDECK_RDESC`), `28DE:1205`. Result: + +- It enumerates as a real USB device (`lsusb: 28de:1205 Valve Software Steam Deck Controller`) and + `hid-steam` binds **all three** interfaces — the controller on `bInterfaceNumber=02`. +- **Steam promoted it:** `Local Device Found … Interface: 2 … !! Steam controller device opened for + index 14 … Steam Controller reserving XInput slot 1`. *This is the proof: a device on interface 2 + IS opened + XInput-reserved by Steam, where the interface-`-1` UHID device was filtered out.* +- It then failed at the next step — `f_hid` can't serve HID **feature reports** (`hid-steam: + steam_send_report: error -32 (ae 16 01)` → serial `XXXXXXXXXX`; Steam: `couldn't get controller + details … GetControllerInfo failed … Disconnecting zombie controller`). No gamepad evdev was + created either, for the same reason (hid-steam can't complete Deck init without the feature/output + channel). + +**Conclusion: the wall is fully characterised and climbable.** Interface 2 is necessary *and* +sufficient for Steam to open + XInput-reserve the Deck; the only remaining piece is serving the +HID feature/output reports, which `f_hid` can't but **`raw_gadget` can** (userspace handles every +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.