Skip to content

G923 Xbox/PC (046d:c26d → c26e): udev rule 73 locks up the machine, and probe fails with g920_get_config -1 #52

Description

@adnanmur

I have a G923 Racing Wheel for Xbox One and PC and tried v0.23.0 on SteamOS.
Reporting two separate problems, the first of which is fairly serious.

Hardware: Logitech G923 for Xbox One and PC (046d:c26d046d:c26e)
Host: Lenovo Legion Go, SteamOS 3.8 (holo), kernel 6.16.12-valve24.5-neptune-616
Driver: logitech-trueforce-dkms 0.23.0 (module builds and loads cleanly)


1. Rule 73 hard-locks the machine on plug-in

73-logitech-g923-xbox-modeswitch.rules calls usb_modeswitch inline in a
RUN+=. RUN+= executes synchronously inside the udev worker, holding the
device lock for the duration of the USB control transfer.

On this machine that wedged USB hotplug hard enough to take the desktop down,
and the box would not finish booting while the wheel was attached — it only
came back after unplugging it. No kernel oops was recorded (/sys/fs/pstore
empty), which is what a lock-up rather than a crash looks like. On a Legion Go
the built-in controllers are internal USB devices, so a wedged USB stack reads
as a total system freeze.

There are two contributing factors:

(a) Inline execution. upstream usb_modeswitch ships usb_modeswitch@.service
and dispatches through it precisely so the switch never runs inside a udev
worker. Rule 73 does not.

(b) Driver contention. In c26d the wheel speaks Xbox GIP, so xbox-gip
binds it first
:

7-1.3:1.0 -> xbox-gip
input22 (virtual)  ABS=30000 (ABS_HAT0X|ABS_HAT0Y only), ff capability 0

so usb_modeswitch is fighting a driver that already holds the interface. The
rule's own comment anticipates this for xone; it applies to xbox-gip too.

What works reliably: release the holder, then switch.

# unbind whatever holds the interfaces, then
usb_modeswitch -v 046d -p c26d -M 0f00010142 -C 0x03 -m 01 -r 81

Done that way, from a systemd unit dispatched by ENV{SYSTEMD_WANTS} instead of
RUN+=, the switch completes in ~1.7s with no freeze, across many replugs and
reboots.

Suggested fix: dispatch rule 73 via ENV{SYSTEMD_WANTS} (or
systemd-run --no-block) rather than RUN+=, and unbind any bound driver on
the c26d interfaces before switching.


2. Probe fails on c26e: g920_get_config returns -1

Once in c26e, hid-logitech-dd fails to probe:

logitech-dd 0003:046D:C26E.0004: G920 FFB init: starting (quirks=0x8, reports=0x06)
logitech-dd 0003:046D:C26E.0004: g920_get_config failed: errno -1 (FFB will not register)
logitech-dd 0003:046D:C26E.0004: probe with driver logitech-dd failed with error -1

g920_get_config() fails at its first call, hidpp_root_get_feature(HIDPP_PAGE_G920_FORCE_FEEDBACK).

Notably the in-tree hid-logitech-hidpp reads that same feature page without
trouble
on the same wheel:

logitech-hidpp-device 0003:046D:C26E.0004: HID++ 4.2 device connected.
logitech-hidpp-device 0003:046D:C26E.0004: Force feedback support loaded (firmware release 2).

and gives a fully working wheel: ABS=30027 (steering + 3 pedal axes + D-pad),
FF=31fff0000, 63 simultaneous effects, range=900. So the feature exists and
the wheel answers — something in this driver's init path is the difference.

Attempting to force the issue by blacklisting hid_logitech_hidpp so
hid-logitech-dd binds at plug-in crash-looped the machine (two consecutive
boots died at 1m32s and 2m34s while probing the wheel), so I have not pushed
further.

Happy to run diagnostics, apply patches, or capture HID++ traffic — the wheel is
here and I can test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions