Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T248 doesn't send inputs to Wine on Steam Deck #90

Open
konchunas opened this issue Apr 3, 2024 · 22 comments
Open

T248 doesn't send inputs to Wine on Steam Deck #90

konchunas opened this issue Apr 3, 2024 · 22 comments

Comments

@konchunas
Copy link
Contributor

Hi,
Thanks for your amazing reverse engineering work on this project.

I'm on Steam Deck and I have managed to install this driver as DKMS module just fine. Oversteer started showing every action performed and wheel reacts back to feedback successfully.

But somehow it doesn't allow me to play games in Wine. Any game I launch just doesn't react to wheel inputs. If I launch wine control joy.cpl I can see my wheel as "Thrustmaster Thrustmaster Racing Wheel FFB". But in this window no input is registered, nor axes, not buttons. The same happens in all games. If I use Steam "Disable Steam Input" I can see the wheel in gamepads lists, but it doesn't react to inputs. Tried AC, ETS2, Beam.ng, Automobilista.

I have tried both protontricks of many possible versions and system-wide installed wine to no avail. Just to be sure I have given RW access to all users using udev rules to b696. The wheel is updated to Firmware version 2.0 and set to PC mode. So far it works only in native apps: in Oversteer and in Linux version of Beam.ng.

What's is really interesting is that after I launch wine control joy.cpl or run a game oversteer stops seeing the wheel and says error "No device available". And I have to re-plug the wheel to make it seen again. This is why I think this issue might be driver related. But nothing is written to dmesg when it happens, I'm not sure what logs to look into.

Could you assist me in nailing down this issue?

@Kimplul
Copy link
Owner

Kimplul commented Apr 3, 2024

Did you already read #61? Sounds fairly similar.

@konchunas
Copy link
Contributor Author

I have already checked that issue and tried all the steps, but there is a difference. Even when launching control panel with system-wide installed wine I don't get any inputs or feedback.
The window looks and stays like this regardless of inputs:
Screenshot_20240404_110322

And again, after using and closing this panel the wheel stops being detected by Oversteer, which is quite suspicious. Is it getting hijacked and not released? Are there ways to check if the device is controlled and by which apps?

Here is the wine log just in case. Could those wineusb alternate settings lines mean something?
wine-joy.log

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

I have already checked that issue and tried all the steps, but there is a difference. Even when launching control panel with system-wide installed wine I don't get any inputs or feedback.

Fair enough, though that maybe the same issue was just manifesting with slightly different symptoms but that doesn't seem to be the case.

Is it getting hijacked and not released?

Certainly sounds like it.

Are there ways to check if the device is controlled and by which apps?

One way could maybe be to run something like

sudo lsof | grep /dev/input/eventX

where eventX can be found by

stat /dev/input/by-id/usb-Thrustmaster_Thrustmaster_T300RS_Racing_wheel-event-joystick

The /dev/input/by-id/whatever is just a symlink to the actual eventX device file.
I kind of suspect that you'll only see Xorg, as the input should flow through the windowing system to the currently selected program, but if Xorg is being starved of input I suppose it's possible some other program tried to bypass it (to reduce latency?) and is getting stuck somewhere. Probably worth checking anyhow.

Here is the wine log just in case. Could those wineusb alternate settings lines mean something?

I'm sceptical. I'll check my own logs but they seem familiar, pretty sure I also get them. I'll do that later today.

Just FYI, you can enable more messages in the wine logs: https://wiki.winehq.org/Wine_Developer%27s_Guide/Debug_Logging
Of particular interest would probably be ones related to input, maybe something like WINEDEBUG=+joyclp,+xinput,+input. +all would maybe be too verbose, but you can try that as well if you want.
There's instructions for finding debug channels over at https://wiki.winehq.org/Debug_Channels, you'll have to grep through the source code which is a bit unfortunate.

@konchunas
Copy link
Contributor Author

Thanks for detailed response.

I have figured out my eventX number. It is detected as busy only when Oversteer is opened.
With wine control joy.cpl running it not detected at all using your method.

Even worse. If I do cat /dev/input/event9 some gibberish is printed onto terminal when I move the wheel. But as soon as I launch wine control panel it goes into cat: /dev/input/event9: No such device. And both event and js devices disappear from the filesystem.

Is it silent driver crash? I'm open to putting additional logs into T248 source and recompile to catch it.

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

Is it silent driver crash?

If it were a crash, I would expect dmesg to complain about it loudly, though I guess it can't be ruled out. If you run sudo lsmod, does it still show the driver as being loaded? Should show up as hid_tmff_new (module naming is a bit weird). Assuming the driver itself is fine, it should still show up.

A couple other logs that could contain info are sudo journalctl -f and /var/log/Xorg.0.log. You can get more verbose logging with sudo udevadm control --log-priority=info, and Xorg has a verbosity command line switch that you could toggle. I'm not entirely sure how that would be done on a steam deck, though. evdev is part of Xorg and is responsible for /dev/input/, so hopefully there would be at least something in Xorg.0.log about if evdev thinks the wheel is being disconnected or something.

I'm open to putting additional logs into T248 source and recompile to catch it.

Adding some print statements is doable, you would need to remove the check at

if (max_count && tmff2->allow_scheduling)
and add a print statement to the same function and add schedule_delayed_work(&tmff2->work, 0); to the end of tmff2_wheel_init(). This should effectively make the driver run in an infinite loop with a small delay between iterations as soon as it load, while still allowing it to be used without completely bricking your system. Your dmesg log would be pretty much filled with garbage.

Just adding print statements to tmff2_open() or tmff2_play() might not be enough, as there's the possibility of the driver being cut off from the rest of the system for whatever reason but still functioning, resulting in zero dmesg printouts. Not entirely sure how that would be possible, but it's something to consider.

I would consider adding printing as a backup to if lsmod etc. indicate that the driver is crashing.

@konchunas
Copy link
Contributor Author

I have found Xorg.0.log, but it doesn't show anything suspicious. The same for journalctl, just regular connect-disconnect messages.

Only notable parts are:

[   506.392] (II) config/udev: Adding input device Thrustmaster Thrustmaster Racing Wheel FFB (/dev/input/js1)
[   506.392] (II) No input driver specified, ignoring this device.
[   506.392] (II) This device may have been added with another device file.
[   506.458] (II) config/udev: Adding input device Thrustmaster Thrustmaster Racing Wheel FFB (/dev/input/event19)
[   506.458] (II) No input driver specified, ignoring this device.
[   506.458] (II) This device may have been added with another device file.

But same warnings happen to my other devices which work fine.

lsmod shows hid_tmff_new, but it is Used counter is 0. Is it correct?

I'm also suspicious of very generic name of my device. Shouldn't it be something about T248? I have just tried removing dkms module alltogether and it still shows the same name, albeit no force feedback setting in Oversteer.

Regarding module modifications I'm unable to put it into endless loop. I have added hid_warn at the end of tmff2_work_handler and removed the condition you mentioned.
What is unclear is how to put schedule_delayed_work(&tmff2->work, 0); to the end of tmff2_wheel_init().
Whichever way I tried I have no additional output to dmesg. Should it be inside err: label, but before return res;?

On a side note, isn't this line unreachable?
https://github.com/Kimplul/hid-tmff2/blob/275b64dc3fa3f1956e8f81e33f0f951a5deafdc5/src/hid-tmff2.c#L597C2-L597C18

There is return 0 before it, and I don't see any way to jump here. Is it supposed to be inside err: label? (I don't have any experience in writing drivers)

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

lsmod shows hid_tmff_new, but it is Used counter is 0. Is it correct?

Shows 0 for me as well, so should be fine. Not entirely sure why 0, as my wheel is definitely using the driver.

Shouldn't it be something about T248?

In an ideal world, sure, but the device name is taken directly from the device and Thrustmaster for whatever reason uses the generic name for this model. So it's not an obvious indicator of anything being messed up, unfortunately.

Should it be inside err: label, but before return res;?

No, the err label is for when things go wrong. if there are no dmesg errors then nothing is going wrong during the initialization, so add right before return 0;. Remember to sudo modprobe -r hid-tmff-new before installing the modified version, as you might still have the old version in the kernel.

On a side note, isn't this line unreachable?

Hah, good catch. I used to have a small ladder of error codes at one point, I did a small-ish refactoring when I added the T248 to the driver and got rid of most of the ladder, must've overdone it a bit.

goto err;
should actually jump to it, I'm missing an err2 label. In fact, I'm also not freeing tmff2->states, should fix that too. Thanks for pointing that out.

I'm currently experimenting with running the Steam Deck's version of SteamOS on a virtual machine, let's see if that shows anything interesting.

@konchunas
Copy link
Contributor Author

Thanks, I have put schedule_delayed_work(&tmff2->work, 0); before aforementioned return 0 in wheel_init.
I have also hid_info before last line of tmff2_work_handler and removed the condition you mentioned.

Here is what I got in dmesg after reconnecting the wheel.

[ 4575.692838] usb 1-1.4: USB disconnect, device number 12
[ 4577.971561] usb 1-1.4: new full-speed USB device number 13 using xhci_hcd
[ 4578.107885] usb 1-1.4: New USB device found, idVendor=044f, idProduct=b696, bcdDevice= 1.00
[ 4578.107897] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 4578.107901] usb 1-1.4: Product: Thrustmaster Racing Wheel FFB
[ 4578.107904] usb 1-1.4: Manufacturer: Thrustmaster
[ 4578.193568] input: Thrustmaster Thrustmaster Racing Wheel FFB as /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0012/input/input48
[ 4578.193774] tmff2 0003:044F:B696.0012: input,hidraw7: USB HID v1.11 Joystick [Thrustmaster Thrustmaster Racing Wheel FFB] on usb-0000:04:00.3-1.4/input0
[ 4578.219296] tmff2 0003:044F:B696.0012: force feedback for T248 bleah
[ 4578.227096] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.247118] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.261648] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.278350] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.294833] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.311513] tmff2 0003:044F:B696.0012: msg from the driver
[ 4578.324944] tmff2 0003:044F:B696.0012: msg from the driver

Message repeated only 7 times. Wasn't it supposed to be endless loop?

We schedule immediate work in init and then reschedule it on every tick in itself. Is that desired effect?

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

Oh, right, there's also

cancel_delayed_work_sync(&tmff2->work);

I assume that whenever someone closes the device we don't need to run the work loop anymore. You'll have to remove that line as well. Sorry, forgot about it.

The only other case where the work loop is stopped is when the driver is unloaded, in

static void tmff2_remove(struct hid_device *hdev)

@konchunas
Copy link
Contributor Author

Alright, I have commented out all cancels I could find and got into endless loop.
As soon as I opened wine joystick control panel my Steam Deck went dark, froze and restarted :)
That's something, i guess...

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

Progress! Did you look at dmesg while it froze and/or does sudo journalctl --boot=-1 show anything?

@konchunas
Copy link
Contributor Author

So I ended up uncommenting cancel_delayed_work in tmff2_remove so it stops freezing and restarting.

And if I put hid_info(hdev, "device removed"); in that function I get the following behaviour in dmesg.

  • Stream of endless msg from the driver
  • As soon as I open wine i get device removed and stream stops.

As if it was gracefully removed. Is it proper behaviour? Is it kernel callback?

Still nothing in logs as to why it happens.

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

As if it was gracefully removed. Is it proper behaviour? Is it kernel callback?

tmff2_remove() should only be called when the module is explicitly asked to be unloaded, as far as I'm aware. An explicit unload can be triggered by udev, usually when the user removes a device. Unsure why your system decides to unload the driver all of a sudden. Maybe try running sudo udevadmin monitor --kernel --udev and see if any events are being triggered when wine starts?

@konchunas
Copy link
Contributor Author

This output at the exact moment I launch wine control joy.cpl

UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

KERNEL[2626.739120] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41/event16 (input)
UDEV  [2626.746846] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41/event16 (input)
KERNEL[2626.766674] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41/js1 (input)
UDEV  [2626.770179] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41/js1 (input)
KERNEL[2626.803315] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41 (input)
KERNEL[2626.803360] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/hidraw/hidraw5 (hidraw)
KERNEL[2626.803382] unbind   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010 (hid)
KERNEL[2626.803405] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010 (hid)
KERNEL[2626.803426] unbind   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0 (usb)
UDEV  [2626.805782] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/hidraw/hidraw5 (hidraw)
UDEV  [2626.806794] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010/input/input41 (input)
UDEV  [2626.808357] unbind   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010 (hid)
UDEV  [2626.809395] remove   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0/0003:044F:B696.0010 (hid)
UDEV  [2626.810989] unbind   /devices/pci0000:00/0000:00:08.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4:1.0 (usb)

I'm going to try to figure out what exactly triggers this.

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

I got SteamOS to run on a virtual machine and I can replicate this, which is at least something.

@konchunas
Copy link
Contributor Author

Thank you for your help and quick response!
Let's hope we could figure something out.

I'm currently trying to find a way for udevadm to show exact rules which trigger the event. But I'm not sure if it even has this functionality or if it of udevadm's doing.

@konchunas
Copy link
Contributor Author

Does it happen to T300RS as well on a virtual machine?

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

There are ways to make kernel debugging messages appear in dmesg by the way: https://www.kernel.org/doc/html/v5.12/admin-guide/dynamic-debug-howto.html

Playing around with these, I get this sort of interesting message when running wine control joy.cpl:

[...]
[ 3659.263220] usbhid 1-3:1.0: disconnect by usbfs
[...]

This message seems to be generated here: https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/devio.c#L2353
Apparently as part of some ioctl() that explicitly requests a disconnect. Unsure where on earth that ioctl() is from, though. Evdev? Udev? No clue.

Does it happen to T300RS as well on a virtual machine?

Yep.

@konchunas
Copy link
Contributor Author

If I stop the UDev rule by sudo udevadm control --stop and then launch wine It still shows the remove event coming from KERNEL.

What I also noticed it is possible to reproduce this behaviour by using any wine command e.g. wine notepad

@konchunas
Copy link
Contributor Author

Okay, so I have decided to go the other way and I have installed Wine 7.0 from Flatpak. (Pacman version is 8.10)
It isn't available in command line as wine, so I had to navigate into ~/.wine/drive_c/windows/system32/control.exe in GUI file explorer and launch it using context menu.

And the wheel sends inputs there. Which is a win.

At least we ruled out that it is a driver issue. That ioctl call might be newer wine addition for all we know.

@Kimplul
Copy link
Owner

Kimplul commented Apr 4, 2024

Good thinking with testing different Wine versions. Next step might be to open up an issue over in https://github.com/ValveSoftware/SteamOS/issues. I don't know if the pacman version of wine also contains some Valve patches, but I know that a newer wine version (9 vs 8) on my desktop doesn't show this behaviour. Could of course still be environmental or something, not sure, maybe some combination of different packages not working together. Seeing that the wheels have worked on the Steam Deck before this, and I haven't at least yet received reports that they would be broken on any other distro I think Valve might be the most appropriate entity to turn to in this case.

@konchunas
Copy link
Contributor Author

Thanks a lot for assisting me with this issue. It was quite the journey and your skills are amazing.
Appreciate your help even though it wasn't in your code directly. At least a little bug was caught along the way. :)

I'm going to create an issue in SteamOS repo next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants