All of lore.kernel.org
 help / color / mirror / Atom feed
* [BUG] usbcore: EPROTO on first-stage Config Descriptor read (ShanWan clone, 2563:028e)
@ 2026-07-20  5:50 Anon
  2026-07-20 13:46 ` Alan Stern
  0 siblings, 1 reply; 6+ messages in thread
From: Anon @ 2026-07-20  5:50 UTC (permalink / raw)
  To: linux-usb

Rapoo V600SE / ShanWan-family chipset -- X-input persona (2563:028E)
fails USB enumeration one stage earlier than the known Switch Pro
fallback bug

Hardware
--------
Product: Rapoo V600SE Dual-Mode Vibration Gamepad (marketed with
Hall-effect sticks/triggers, X/D/A mode switching)
Underlying chipset family: ShenZhen ShanWan Technology Co., Ltd.
(confirmed via multiple vendor IDs observed from the same physical
unit: 0x2563, 0x20BC)
System: CachyOS (Arch-based), systemd-boot bootloader, kernel 7.1.3-2-cachyos
USB controller: xHCI (xhci_hcd)

Summary
-------
This controller presents at least four distinct USB identities from
the same physical hardware, depending on mode-button state and
connection type. Three of these are already individually documented in
various places (ArchWiki, xpad issue tracker, hid-shanwan project) as
instances of a known ShanWan firmware bug: a malformed response to the
two-stage USB Configuration Descriptor read causing -71 EPROTO
(sometimes -32 EPIPE), leading to enumeration failure and a silent
firmware-side fallback to a lower-capability "Android" persona.

What doesn't appear to be documented anywhere I could find: the
specific persona corresponding to this device's X-input mode
(2563:028E) fails at an earlier stage of enumeration than the
already-documented Switch Pro fallback (057E:2009), and the known
workarounds for the latter (usbcore.old_scheme_first=1, various
usbcore.quirks= flag combinations) do not fix the former. I'm posting
the full investigation in case this is useful to whoever maintains
hid-shanwan, xpad, or the ArchWiki Gamepad page, or in case someone
recognizes this specific failure signature and knows a fix I haven't
found.

The four personas observed
---------------------------
1. VID:PID 05AC:033E (spoofs Apple's vendor ID)
   Windows behavior: Not normally seen (Windows reaches the modes below)
   Linux behavior: Default fallback, wired. Enumerates cleanly. Full
analog sticks+triggers. No EV_FF.
   Driver claiming it: hid-generic

2. VID:PID 20BC:5001 (ShanWan)
   Windows behavior: Not normally seen
   Linux behavior: Default fallback, wireless (2.4GHz dongle).
Functionally identical to above.
   Driver claiming it: hid-generic

3. VID:PID 057E:2009 (spoofs Nintendo's real Switch Pro Controller ID)
   Windows behavior: Not normally seen
   Linux behavior: Reachable only with usbcore.old_scheme_first=1.
Rumble works. No analog trigger channel (protocol-accurate to real
Switch Pro hardware, which has digital-only triggers).
   Driver claiming it: hid-nintendo (in-kernel)

4. VID:PID 2563:028E (ShanWan vendor ID, reusing Microsoft's real Xbox
360 Controller product ID)
   Windows behavior: This is X-input mode on Windows. Full analog
triggers + working rumble.
   Linux behavior: Never successfully completes enumeration under any
combination of workarounds tested.
   Driver claiming it: N/A -- never gets far enough

Root cause (confirmed at byte level via raw usbmon)
-----------------------------------------------------
This matches the general failure mode already described on the
ArchWiki Gamepad page (https://wiki.archlinux.org/title/Gamepad) for
ShanWan-family devices: during enumeration, the host requests the
Configuration Descriptor in two stages -- a 9-byte header first (to
learn wTotalLength), then the full descriptor. Some ShanWan firmware
responds to the first request by sending the full descriptor anyway,
which is a USB spec violation, and strict host controllers reject it
with EPROTO/EPIPE. Windows tolerates this; Linux (by default) does
not, and the device firmware silently re-enumerates into a
lower-capability fallback persona after the failure.

What's new here: I captured both the 057E:2009 failure and the
2563:028E failure at the raw usbmon level (via
/sys/kernel/debug/usb/usbmon/1u, not Wireshark's usb.idVendor-filtered
view -- that filter only matches devices that finish registering, and
is blind to failures during enumeration itself, which cost me a fair
amount of time before I realized it). The two personas fail at
different stages:

057E:2009 (Switch Pro) -- fails on the second-stage (41-byte) descriptor read

C Ci:1:039:0 0 9  = 09022900 01010080 fa                    (9-byte
header -- SUCCEEDS)
S Ci:1:039:0 s 80 06 0200 0000 0029 41 <                     (request
full 41-byte descriptor)
C Ci:1:039:0 -71 0                                            (FAILS)
[ ...repeats -71 two more times, then device is abandoned, new device
number starts fresh and succeeds cleanly... ]

This is the case usbcore.old_scheme_first=1 fixes -- it doesn't
correct the malformed response, but changes the enumeration approach
enough that a subsequent full attempt succeeds.

2563:028E (X-input) -- fails on the first-stage (9-byte) descriptor read itself

C Ci:1:044:0 0 18 = 12010002 00000040 63258e02 30010002 0301  (Device
descriptor -- SUCCEEDS, decodes to idVendor=2563, idProduct=028e)
S Ci:1:044:0 s 80 06 0600 0000 000a 10 <                       (Device
Qualifier probe)
C Ci:1:044:0 -32 0                                             (stalls
x3 -- normal/expected, not the bug)
S Ci:1:044:0 s 80 06 0200 0000 0009 9 <
(Configuration descriptor, 9-byte header stage)
C Ci:1:044:0 -71 0                                             (FAILS
immediately, on the very first stage)

Workarounds tested against 2563:028E, all unsuccessful
---------------------------------------------------------
1. usbcore.old_scheme_first=1 (both as a live sysfs toggle via
/sys/module/usbcore/parameters/old_scheme_first, and previously
persisted via systemd-boot entry) -- no effect, still falls back every
time, confirmed via lsusb immediately after physical mode-button
press.
2. usbcore.quirks=2563:028e:ik (USB_QUIRK_DEVICE_QUALIFIER +
USB_QUIRK_NO_LPM) -- no effect.
3. usbcore.quirks=2563:028e:gn (USB_QUIRK_DELAY_INIT +
USB_QUIRK_DELAY_CTRL_MSG) -- no effect.

Given the failure happens on the first config descriptor request
rather than the second, I suspect none of the currently-defined
usbcore.quirks letters target this exact failure mode, since (as far
as I can tell from Documentation/admin-guide/kernel-parameters.txt)
none of them specifically address "device sends a malformed/oversized
response to a request smaller than what it wants to send" -- the
actual documented ShanWan bug -- at either stage. It's possible a more
aggressive retry-on-EPROTO patch, or a quirk that makes usbcore skip
straight to requesting the full descriptor length (bypassing the
two-stage negotiation entirely) for a specific VID:PID, would be
needed.

Additional relevant background found during this investigation
-------------------------------------------------------------------
- hid-shanwan project (https://github.com/hbiyik/hid-shanwan)
documents a related but distinct "Rich Mode vs Poor Mode" fallback
behavior for a different ShanWan wireless gamepad (2563:0575), where
an unrecognized HID/USB request (rather than the descriptor-stage bug
above) causes a similar fallback to a reduced-capability persona
(20BC:0055) with force feedback disabled. Same vendor family, same
general "fails gracefully into a worse mode" firmware philosophy,
different specific trigger.
- xpad issue #336 (https://github.com/paroj/xpad/issues/336) documents
a user with what appears to be the same physical chipset seeing both
2563:0575 and 20BC:5001 during mode transitions, captured via a
similar raw-usbmon grep technique to the one I used.
- The mainline kernel does have a hid-shanwan.c driver (added via
patches referenced on LKML, CONFIG_HID_SHANWAN / CONFIG_SHANWAN_FF),
but per its own documentation it only restores force feedback for
devices that reach "rich mode" successfully -- it cannot help a device
that's stuck in fallback due to a failed enumeration, which is the
situation here.

What I'm hoping for
--------------------
- Has anyone seen this specific earlier-stage (first 9-byte header)
EPROTO failure on a ShanWan-family device, as opposed to the more
commonly documented second-stage failure? Is there a known fix?
- Would a patch that increases retry attempts specifically around
EPROTO on the Configuration Descriptor's first stage (perhaps gated to
known-bad VID:PID ranges, similar to how hid-shanwan and hid-sony's
existing ShanWan quirks are scoped) be a reasonable ask, or is this
considered out of scope for mainline given it's cloned/unofficial
hardware?
- I'm not a kernel developer, but I'm willing to test patches, provide
more capture data, or run a device on a spare machine if that's useful
to anyone actively working on hid-shanwan or xpad.

Happy to attach full usbmon capture files and Wireshark exports on
request -- trimmed the above to the relevant excerpts for readability.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-05  6:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20  5:50 [BUG] usbcore: EPROTO on first-stage Config Descriptor read (ShanWan clone, 2563:028e) Anon
2026-07-20 13:46 ` Alan Stern
2026-07-21  0:50   ` Anon
2026-07-21  1:57     ` Alan Stern
2026-07-21  2:35       ` Anon
2026-08-05  6:14   ` Michal Pecio

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.