systemofapwne/leetmouse

Only one mouse axis (like horizontal) or none works.

systemofapwne opened this issue ยท 45 comments

This is a reminder for myself

This bug can be replicated with at least the following mice:

  • Steelseries Rival 110: Only horizontal axis works. Moving the mouse vertically registers as scrolling instead
  • Steelseries Rival 600/650: No mouseinput is registered at all

My suspicion no 1: These mice actually consist of several USB devices and the mouse output gets mixed up?

# Unplug and replug mouse while having dmesg running
klaus@aurora ~ $ sudo dmesg -w
[ 1303.089569] usb 5-1.1: new full-speed USB device number 14 using xhci_hcd
[ 1303.373715] usb 5-1.1: New USB device found, idVendor=1038, idProduct=1724, bcdDevice= 2.34
[ 1303.373729] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1303.373736] usb 5-1.1: Product: SteelSeries Rival 600
[ 1303.373741] usb 5-1.1: Manufacturer: SteelSeries
[ 1303.404496] hid-generic 0003:1038:1724.0017: hiddev1,hidraw4: USB HID v1.11 Device [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input0
[ 1303.405749] input: SteelSeries SteelSeries Rival 600 as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.1/0003:1038:1724.0018/input/input48
[ 1303.406046] hid-generic 0003:1038:1724.0018: input,hidraw5: USB HID v1.11 Mouse [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input1
[ 1303.407801] input: SteelSeries SteelSeries Rival 600 Keyboard as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.2/0003:1038:1724.0019/input/input49
[ 1303.463250] input: SteelSeries SteelSeries Rival 600 Consumer Control as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.2/0003:1038:1724.0019/input/input50
[ 1303.463444] hid-generic 0003:1038:1724.0019: input,hidraw6: USB HID v1.11 Keyboard [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input2

When I bind the mouse to "leetmouse" instead of usbhid, we only do this for one (input1) of the three inputs (input0, input1, input2), since the other do not work with this modded mousedriver.

My suspicion no 2: Writing back modified mouse values do not get processed properly.
This is at least supported by the Steelseries Rival 110 behaviour, which works only with horizontal movement but not vertical (which rather then makes the mouse scroll like when scrolling with the wheel).

Update on this.
After playing around a bit, it looks like interrupts caused by mouse movements successfully reach usb_mouse_irq. However the usb request block (urb) has a faulty status code of EOVERFLOW here on my Steelseries Rival 600.
This prevents it from further relaying processed data back to the kernel, which is supposed to happen here.

It could be, that issue with the Rival 110 (only one axis working) is related to that: Not yet an overflow, yet, data is getting already corrupted prior processing.
I now have to find out, what the main reason is. I will quickly add a second, older, mouser and check, if that one works as expected.

Ok, the reason for the overflow was indeed caused by my device sending too much packets. I simply increased the maximum allowed packets from 8 to 16 in here and here (while for the later one, I don't know, if this is related. Anyhow, reserving more space should not be bad).

Now my Steelseries Rival 600 at least is not overflowing anymore. However, the data coming from it seems to havemixed up entries in data which then ends up again in vertical movement -> scrolling.
But at least I can now debug the driver, hooray!

Good news. It looks like I found the cuplprit. It seems like the struct, which has the raw data in it from the USB device (type: signed char) , is not properly aligned.
I played around and figured, that an offset of +1 for REL_Y and REL_WHEEL will properly map the mouse movement and scroll wheel.

	input_report_rel(dev, REL_X,     data[1]);
	input_report_rel(dev, REL_Y,     data[3]);          //Used to be data[2]
    
	input_report_rel(dev, REL_WHEEL, data[5]);   //Used to be data[3]

The question now is, why this happens and especially if this is true for every single mice and for every kernel version. It could be, that this is just kernel specific (to be tested). Since I'm on bleeding edge with Arch and Manjaro (Right now 5.11.2-1), this could be totally different for other famous systems with more "stable"/"LTS" kernels like Debian.

I tried my two mice at home:

  1. Cooler Master MM710 (Mouse sensor: PixArt PMW3389): the horizontal axis is translated to the vertical axis. The vertical one seems to be related to the scrolling mouse.
  2. Swiftpoint Tracer (Mouse sensor: PixArt PMW3360): No mouse input registerd at all.

I'm also on Arch with the 5.11.6-1 kernel.

I added a branch for testing purposes. Can you give https://github.com/systemofapwne/mousedriver/tree/mousebug_testing_hack a try? I'm pretty confident, that your Swiftpoint Tracer now registers input and that you also should have working acceleration on both axis.

However: I do not suggest to consider this to be a fix! It is a workaround of a problem which I do not fully understand yet and may or may not work on your or every other system and kernel version.

Further more, acceleration is "broken" when it is too high. But that now just looks like an overflow of an uint -> int (suddenly, acceleration becomes negative with a lot of mouse movement).

After sniffing the raw USB data sent from my mouse to the host, I see that transmitted data is simply a multi-byte value for relative X and Y movement.
According to a quick reading of the USB HID 1.11 standard, the transmitted data for a mouse is supposed to look like this:

|   Byte | Bits   | Description                 |
|      0 | 0      | Button1                     |
|        | 1      | Button2                     |
|        | 2      | Button3                     |
|        | 4 to 7 | Device-specific             |
|      1 | 0 to 7 | X displacement              |
|      2 | 0 to 7 | Y displacement              |
| 3 to n | 0 to 7 | Device speciffic (optional) |

However my mouse reports data like this

|   Byte | Description    |
|      0 | Buttons        |
| 1 to 2 | X displacement |
| 3 to 4 | Y displacement |
|      5 | Scrollwheel    |
|      5 | Always zero    |
|      7 | Buttons        |
|      8 | Always zero    |

X and Y displacement are represented as a multi-byte number.
The bug happenes, because leetmouse.c assumes the USB HID convention so

  • data[0] --> Buttons
  • data[1] --> X
  • data[2] --> Y
  • data[3] --> Scrollwheel

The fix is in principle easy. However in order to make it work for every single mouse, I question myself, how to identify if the mouse is sending multibyte relative positions or single-byte positions. I will now try to understand how the usbhid linux driver works, which is not related to usbmouse.d/leetmouse.c (it seems like, usbhid is the logical successors to the old usbmouse.c driver)

I did try the mousebug_testing_hack branch.

  • MM710: No mouseinput is registered at all
  • Swiftpoint Tracer: Only horizontal axis works. Moving the mouse vertically registers as scrolling instead

Can you confirm, that you are on the "mousebug_testing_hack" branch and that no local changes of leetmouse.c are present (git status). And if you are, maybe try a make clean && make and a rmmod leetmouse && insmod leetmouse.ko. It looks like, that the results you have are still based on an older version.

Btw: The branch testing contains my current "testing" code, which I want to push to master once I have found a solution to these bugs. If you still see no input at all from one of your mice, compile the kernel module based from the "testing" branch and observe dmesg -w. This should then spam an error + suggestion for a fix for a common type of issue I have seen, causing an EOVERFLOW.

I confirm that I tried to use the mousebug_testing_hack branch.
I used the following commands:
git clone -b mousebug_testing_hack https://github.com/systemofapwne/mousedriver.git
cd mousedriver
make clean && make
sudo rmmod leetmouse
sudo insmod leetmouse.ko
After that I did the binding.
I did not see any error spaming in the dmesg -w. I did save everything that happend in the terminal in a txt that you can find below. I hope this helps.
mousedriver_log.txt

I confirm that I tried to use the mousebug_testing_hack branch.
I used the following commands:
git clone -b mousebug_testing_hack https://github.com/systemofapwne/mousedriver.git
cd mousedriver
make clean && make
sudo rmmod leetmouse
sudo insmod leetmouse.ko
After that I did the binding.
I did not see any error spaming in the dmesg -w. I did save everything that happend in the terminal in a txt that you can find below. I hope this helps.
mousedriver_log.txt

Try
git clone -b testing https://github.com/systemofapwne/mousedriver.git
and repeat the steps. Only this version will "spam" the error.

I will keep a cleaner look on your logfile later this day. It looks ok when quickly looking over it.

I tried it and get the same results.
Here are the logs for the second test:
mousedriver_log_testing.txt

I tried it and get the same results.
Here are the logs for the second test:
mousedriver_log_testing.txt

Thank you. Can please send me the output of the following two commands (do not need to be bound by leetmouse):

With Cooler Master attached
lsusb -v -d 2516:012f
With Swiftpoint Tracer attached
lsusb -v -d 214e:0014

I have the feeling, that the issue might be, these mice are multi-interface devices and that you might need to bind another interface of them to leetmouse.

E.g.

echo -n "1-2.4:1.1" > /sys/bus/usb/drivers/leetmouse/unbind
echo -n "1-2.4:1.1" > /sys/bus/usb/drivers/usbhid/bind

instead of

echo -n "1-2.4:1.0" > /sys/bus/usb/drivers/leetmouse/unbind
echo -n "1-2.4:1.0" > /sys/bus/usb/drivers/usbhid/bind

Sidenote: The way of binding mice to leetmouse is subjet to change to ease up useability in the future (basically a udev rule).

I did run both command and the output is in the file below.
mousedriver_lsusb_log.txt

I did try to bind other interfaces. 1-2.4:1.0, 1-2.4:1.1, 1-2.4:1.2, 1-2.4:1.3. Except for the 1.0 all of them returned the following error: echo: write error: no such device.

Thanks again for looking into this!

Thank you for the feedback. Unfortunately I was unable to work on the issue the past few days due to problems with my pc: I suffered from data-corruption on my SSD.

While trying to pin down my SSD issues, I was able to trigger it when the leetmouse kernel module was loaded.
I therefore give the formal warning: DO NOT USE THIS DRIVER UNTIL I FOUND THE REASON FOR MY SSD ISSUES
That issue will be tracked here: #3

Thanks for the warning. Good luck with your issues.

The data corruption bug now seems to be fixed (at least on two of my systems) in the master branch and the testing branch.
Time for me to work on your issues again the next few days :)

I just merged my latest testing code to master. This now offers some udev magic to absolutely make sure, the right device is bound to leetmouse.

Please note that the package can now be installed to your system via makepkg & pacman (see the Readme.org)

You can try testing it. Keep a look at dmesg -w and journalctl -xf | grep leetmouse when replugging the mouse.

If you can not get working input with any mice, you might want to delete the udev rule for debugging (lives in /usr/lib/udev/rules.d/99-leetmouse.rules) and refresh udev udevadm control --reload-rules

I am however sure for certain, that the bug is not yet fixed. I have several mice at home for testing and my ~15 years old Logitech G5 mouse seems to use a "narrow" width (1 byte) for transmitting mouse events for X and Y while my Steelseries Rival 600 uses wide (2 byte).

I just gave it a try.
Really nice to be able to install it through pacman.
Once installed, I saw no difference until I unplugged replugged the mouse.
There, similar issue as before.

  • With the Cooler master it was only possible to move the mouse upward, but not downward. It was also very difficult to understand which mouse movement lead to the cursor going up because the movement was extremely slow.
  • With the Swiftpoint lateral movements translated to vertical cursor movement and vertical to scrolling.

What can I send you to help?

Good to hear, that the new installation method of the driver works for you!
Unfortunately, there is not much that you can do, to help me further.

But I am now very confident to know, what the root cause of the mixup of axis etc is: The driver expects the mouse to be in "Boot protocol" mode (e.g. for using your mouse in BIOS), which dictates exactly, how the data has to be sent from the device to the system.
However, the mouse is doing a context switch when it first is getting probed by hid-generic. And this happens before the udev rule can grab the device and bind it to leetmouse.

There are basically two routes I can walk

  • Reset the mouse to "boot protocol" mode (which might cripple some functionalities)
  • Figuring out the actual data structure, which is sent from the device after switching the context.

I prefere the later option. The data structure description is sent to the driver (upon request) as an USB descriptor. I already dumped the descriptor for two mice (see testing branch in the debug folder).
I will work on this the next days.

I just noticed one thing, you could do @Thomot512: Can you please dump the USB descriptor (please only the RAW code) of your mice?
You will find and instruction on this here.
This will help me on writing an overall crude HID Descriptor parser. I just have 3 mice at home I can test it against. As more devices I can test it against, as better it will be.

Here are the USB descrioptor of both my mice:
coolermaster_mm710.txt
swiftpoint_tracer.txt

Here are the USB descrioptor of both my mice:
coolermaster_mm710.txt
swiftpoint_tracer.txt

These dumps are gold! They heavily influenced on how I wrote the parser for the HID descriptor!
I also learned the hard way, that I definitely NEED to rewrite this driver to the hid-core/hid-generic base of the linux HID drivers.
However, I implemented a hack to the leetmouse driver to act "sort of like a HID driver, yet not being one".

Can you please give the testing branch a try again? I am especially interested in your Swiftpoint Tracer: The reported data from your mouse to the host system has a strange format, so I implemented a bit-shifting mechanism to match it's pattern (should work for every mouse reporting a "strange format"). For the swiftpoint tracer mouse, I expect the scrollwheel to be affected of this: Either it works, as espected or it completely acts irradically.

I just tested the testing branch.
With the Cooler Master MM710 it gave good results, axis were working as intended, buttons and mouse wheel as well.
With the Swiftpoint Tracer on the other hand, the pointer was moving erratically. A pure horizontal movement of a few millimeter would make the pointer teleport (move so fast that I cannot pick the movement on a 120Hz monitor) in an other direction. I thinks it has mostly to do with sensitivity. As if it would have selected the highest possible DPI and any micro movement make the mouse react by a lot. Not sure though the mouse was moving to fast.
The mouse wheel was behaving somewhat normally except up and down where reversed. I was not able to test the buttons, because I could not control the pointer enough to point at something clickable.

I'm happy to see the progress :)
Can you do me a favour and try to narrow down the issue on the swiftpoint mouse?

  • Is this still happening with 400 DPI? And what is the current DPI setting on the mouse?
  • Can you try to modify the PRE_SCALE_X and PRE_SCALE_Y values in driver/config.h? They are currently adjusted for a 400 DPI mouse to have "decent sensitivity". If your mouse is, lets say, at 3*400 = 1200 DPI, scale down these values by a factor of 3, hence 0.33f each.

If you confirm, that the DPI is in fact low on that mouse when having these problems, then I have to further invest some time on it. I would then ask you to dump the raw data-stream of the mouse, when moving it. I will then prepare a modified driver for you, which can do this.

I tried to change the Swiftpoint mouse DPI to 400, which made no difference. On the Cooler Master it did change it's speed as expected.
When changing the pre scale x and y (or the post scale same with both) I did not notice any differences with any of the two mouses. When changing the sensitivity in KDE System Config, I was able to considerably slow down the cursor to a point that I can better describe the issue with the swiftpoint:

  • When moving the mouse in any direction the cursor moves in the supposed direction but extremely fast and sometimes it stops and then teleport.
  • When moving the mouse to the left on the horizontal axis the cursor moves to the left and down. The movement is also very fast and choppy.

Edit: Until now when changing the config I reinstalled the whole driver. Is there an other method?

using mm710 mouse, moving the mouse up, right or down doesnt move the cursor at all. only moving the mouse left causes the cursor to move up. the cursor movement going up feels ok though even though its going up not left.

using mm710 mouse, moving the mouse up, right or down doesnt move the cursor at all. only moving the mouse left causes the cursor to move up. the cursor movement going up feels ok though even though its going up not left.

Make sure to test this with the testing branch and not with master. The master branch does not parse the report descriptor of your mouse and currently is "hard coded" for the way my main mouse outputs data to the host.

Anyhow, I am working on this. It looks even my crude "report descriptor parser" is not performing well. E.g. when your mouse tags the data with a Report ID (which is the reason why @Thomot512 SwiftPoint tracer does not work), the whole thing gets more and more complicated. I am REALLY thinking about moving away from the driver base (which already works) and implement a sub-driver for the HID Core driver of linux. This was anyway planned, but looked like too much work to be done quickly. However I now have spent countless hours on parsing different mice. This gets very frustrating :D

all working good on the testing branch with this mouse thanks, though the first time i installed the testing driver my cursor would only move up and it would do a left click whenever i moved the mouse up, but working fine on a reinstall. i also have many mice, i will perform testing on them too. gl thanks

all working good on the testing branch with this mouse thanks, though the first time i installed the testing driver my cursor would only move up and it would do a left click whenever i moved the mouse up, but working fine on a reinstall. i also have many mice, i will perform testing on them too. gl thanks

Good to hear. Please attach data like described in debug/Readme.org for any problematic mouse.

i have tested on my second gaming mouse and only works in vertical movement and no buttons work.
here is outputs of that mouse from the readme

the sensitivity also didnt change on the mm710 when changing values in the config.h file.

i have tested on my second gaming mouse and only works in vertical movement and no buttons work.
here is outputs of that mouse from the readme

the sensitivity also didnt change on the mm710 when changing values in the config.h file.

Thank you very much. The report descriptor looks normal. However I see, why it fails: My parser (in testing) has a bug, which I already have fixed locally (code not yet pushed). Stay tuned.

Also: What mouse is that? I would like to take take its information into my /debug/devices folder.

oh sry i forgot to name the file, should be, Trust_GXT 101 GAV

I just have pushed the latest "testing" version with the enhanced HID Descriptor parser. This should add more compatibility to other mice. However, I have one mouse at home, which still has strange X and Y movement (too fast). This mouse also has a "Report ID" tag like the Swiftpoint Tracer of @Thomot512.

Please try to test the latest version and report back.

on the latest testing version the gxt still can only move vertically but now all the buttons work on it. mm710 still working fine

After drawing a lot of blocks on paper with bits and bytes, I finally was able to get my problematic mouse (CSL optical mouse) working. (It really was a mess XD)

@Thomot512 Can you please test the latest commits in "testing" with your swiftpoint tracer?
@0Dragonmoon Can you please do the same with your Trust_GXT?

I just deinstalled everything, deleted the mousedriver folder, recloned the testing branch with:
git clone -b testing https://github.com/systemofapwne/mousedriver.git
and reinstalled the driver.
I saw no difference with the previous iteration.

No change here on the GXT either.

This is very sad to hear. I need further input from your side (raw mouse packets to be precise).
I just pushed a new update to testing, which can be used to extract the raw USB packets.

Can you please install the latest driver and then perform the following

  • dmesg -w | grep Raw > raw.txt
  • As root: echo "1" > /sys/module/leetmouse/parameters/debug
  • Now, do not touch any other mouse!
  • Do the following with the affected mouse in that order: 1) Move your mouse in a circle. 2) Click a few buttons 3) Sroll up or down
  • As root: echo "0" > /sys/module/leetmouse/parameters/debug

Then attach the file "raw.txt" please.

@0Dragonmoon I think I found the error for your mouse. The GXT should work now. If not, send the raw data, as asked in the previous comment.

However the Swift Point Tracer might still be messed up. For that, I need the raw packts.

just tested, the GXT works now :D

I just tested it and it appear to be working with both my mice.
The Swiftpoint has a lot of buttons that can be mapped to macros, and even this is working fine!
I still need to test if pre-scale and post-scale are now working. I'll edit with the results.

Edit: I'm still unable to see any effect of pre-scale or post-scale. I tried to multiply them by 10 to see and I don't feel any difference.

Ok, at least this is a fantastic news, that the rewritten HID descriptor parser and the usb-packet extractor seem to work now.
I will mark this bug as solved soon and will further concentrate on features

The pre-scale and post-scale should have an influence. If not, then the mouse is either not bound to leetmouse or you might edit the wrong file (should be driver/config.h, derived from config.sample.h).

However I plan to implement an easier interface via /sys/module/leetmouse for pushing the config parameters. The config.h way will become at some point deprecated.

Disregard my previous comment @Thomot512. I found a bug in the install script. Now, your custom config should get installed.

However, as stated earlier, the config.h method might get dropped in favour of the sysfs interface. But this will not happen before I have implemented a daemon and a user-space application for tweaking the acceleration parameters in an easy way.

Indeed it seems to be working now. Thanks.

I think, this bug has been fixed.
If someone finds a problematic mouse again, feel free to re-open this topic. I will then work on fixing the HID report descriptor parser and the stream extractor.