Opened 3 years ago
Last modified 2 years ago
#17699 new bug
HID parser computes incorrect size for reports
Reported by: | scph1001 | Owned by: | nobody |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | Drivers/Input/HID/USB | Version: | R1/Development |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Platform: | All |
Description
Expected behavior: My Razer Viper 8k mouse works, as it does on Windows and Linux. Actual behavior: The mouse doesn't work at all. No inputs are registered.
This is present in both beta R3 and the latest git commit. It happens on both bare metal and with USB passthrough on Linux (exposing the USB device natively to the VM). Other mice and devices work fine.
I've compiled the latest git version with #define TRACE_USB
for more detailed info in the syslog. These lines seem to be of interest:
KERN: usb xhci 0: Event Interrupt 3 KERN: usb xhci 0: event[17] = 32 (0x00000000072ec5a0 0x03000000 0x01038001) 2 KERN: usb xhci 0: HandleTransferComplete: ed 0, code 3, transferred 0 1 KERN: usb xhci 0: got an interrupt for a non-Event Data TRB! 5132 KERN: usb xhci 0: transfer error on slot 1 endpoint 3: Babble detected 1 KERN: usb xhci 0: HandleTransferComplete td 0xffffffff8213e248 trb 10 found 2 KERN: usb xhci 0: unlink descriptor for pipe 3 KERN: usb xhci 0: HandleTransferComplete td 0xffffffff8213e248 done 4 KERN: usb xhci 0: event[18] = 0 (0x0000000000000000 0x00000000 0x00000000) 5 KERN: usb xhci 0: finishing transfers 6 KERN: usb xhci 0: finishing transfer td 0xffffffff8213e248 7 KERN: usb xhci 0: transfer not successful, actualLength=90 8 KERN: usb_hid: error waiting for report: Device FIFO overrun
This mouse always tries to run at 8kHz polling rate. This absolutely cannot be configured on the mouse-side. I've tried.
If adding support for high polling rates (ideal) isn't planned, is it possible there's a way for the OS/driver to negotiate with the device to run at 1000hz or lower? For example, on Linux you apparently can do options usbhid mousepoll=4
to force 250hz polling rate on a device. It would be nice be able to use this mouse with Haiku somehow since it's my primary mouse, even if at a low polling rate.
Attachments (8)
Change History (41)
by , 3 years ago
Attachment: | syslog.txt added |
---|
comment:1 by , 3 years ago
KERN: usb xhci 0: transfer error on slot 1 endpoint 3: Babble detected
It's pretty interesting this also occurs with USB passthrough.
Despite being the maintainer of the XHCI driver, I am not especially familiar with USB-HID and its interactions with the stack. This could possibly be a bug in our HID code, and not in XHCI. Then again it's possible that such "high rate" polling requires some other options configured in XHCI that we do not have; I don't actually know, and I'm not quite sure where to begin.
follow-up: 5 comment:2 by , 3 years ago
There is nothing about this on the HID side.
The way it works is HID uses interrupt endpoints. The endpoints have an "interval" (like isochronous endpoints). This interval defines how often the endpoint should be polled for new data.
Most device will have 8 there (resulting in the 125Hz = 1/8 of 1000Hz), "gamer" devices will have 1 (resulting in 1000Hz).
The unit is frames, so > 1000Hz is only possible for high speed (USB2) devices:
"The units are expressed in frames, thus this equates to either 1ms for low/full speed devices and 125us for high speed devices." (from https://www.beyondlogic.org/usbnutshell/usb5.shtml)
As far as I know it is entirely up to the *HCI layer to take care of this.
Also, it should not matter if we use a higher or lower rate than what's specified. The USB spec allows for the host to pick a different rate. The device can only say what it prefers. So:
This mouse always tries to run at 8kHz polling rate. This absolutely cannot be configured on the mouse-side. I've tried.
This doesn't make sense to me. The mouse can request what it wants in its endpoint descriptor, but it will always be the computer who decides when it wants to read from the endpoint.
What can happen is that the device refuses to work if it was not polled at the "correct" rate. This is not allowed by the spec, but some devices don't care about that.
So, things to check at XHCI level:
- Is the endpoint interval taken into account at all for interrupt endpoints?
- Is the conversion of the endpoint interval to time/frequency taking into acocunt wether the device is high speed?
- Is the device actually high speed? I had only encountered low speed devices for HID so far, but I can see why "gamer" hardware would be high speed.
comment:3 by , 3 years ago
Is the endpoint interval taken into account at all for interrupt endpoints? Is the conversion of the endpoint interval to time/frequency taking into acocunt wether the device is high speed?
Yes and yes: https://github.com/haiku/haiku/blob/master/src/add-ons/kernel/busses/usb/xhci.cpp#L2017
I guess someone else can read the referenced portion of the spec to see if the calculation isn't quite correct. However I seem to recall that in addition to reading the relevant spec sections, I mostly patterned this code very closely off OpenBSD, so that should be an additional way it's known to be correct.
comment:4 by , 3 years ago
Platform: | x86-64 → All |
---|---|
Version: | R1/beta3 → R1/Development |
comment:5 by , 3 years ago
This mouse always tries to run at 8kHz polling rate. This absolutely cannot be configured on the mouse-side. I've tried.
This doesn't make sense to me. The mouse can request what it wants in its endpoint descriptor, but it will always be the computer who decides when it wants to read from the endpoint.
What can happen is that the device refuses to work if it was not polled at the "correct" rate. This is not allowed by the spec, but some devices don't care about that.
What I meant is the mouse can be configured with Razer software to rate-limit its positional updates to e.g. 500hz intervals, but it still wants to send mouse-click messages with minimal delay regardless, so it always requests to run at 8000hz regardless of what you set the polling rate option to on the mouse's onboard settings. It updates mouse click state every 125us even if you set positional updates to only update every 2ms.
In any case, based on what you say it should be possible for Haiku to tell this mouse "you need to run at 1000hz, not 8000hz" or something. I don't think it'll stop working. Is there a way to actually do this yet? Would be nice to have a way to use this mouse with Haiku in the meantime.
comment:6 by , 3 years ago
I don't think we have a way to specify that yet anywhere, no. Seems like a kind of advanced option, it probably belongs in a USB-HID settings file or something, if we even need it at all.
I assume the listusb, etc. were taken in QEMU? I notice you seem to have only EHCI/UHCI controllers there; the behavior may be different if the mouse is attached in USB 2.0 mode. You should instead create an "xhci" device in QEMU and attach the USB passthrough to that instead; it may affect behavior.
If you want to try and debug this, the place to start is to add tracing at the part of XHCI that I linked above to determine how the interval is being computed, and precisely what value we wind up with. I may be able to determine what we can try next based on that.
I guess we should also enhance listusb a bit, I see a lot of descriptors that are only dumped in "raw" form...
comment:7 by , 3 years ago
It looks like the usb device combines three input interfaces, handled by the same driver usb_hid. As it's not the standard situation, this might be not so well supported.
comment:8 by , 3 years ago
Indeed it could well be a USB-HID problem and not an XHCI one at all. Possibly if USB-HID failed to queue "in" transfers appropriately, it might cause this error?
comment:9 by , 3 years ago
I don't see why that would be a problem. There are no realtime constraints on HID transfers. The OS can poll the endpoint as rarely as it wants, and as often as it wants until the limit specified by the endpoint bInterval.
If the OS doesn't schedule a transfer, nothing should happen. The mouse will just wait until it's its turn to send some data on the bus. On a busy USB1 bus with lots of devices, this can take quite a bit longer than the mouse asked for, and that's not a problem.
So I don't see how anything the HID layer does could result in this specific error.
The multiple interfaces however should be looked in more carefully. Why is the mouse not a single interface? We can decode the descriptors for each of the interfaces and see how they are different. If all 3 report the same thing, probably we are expected to pick only one interface, and not all 3 at the same time. This may confuse the mouse if we behave differently from other OS.
I guess we should also enhance listusb a bit, I see a lot of descriptors that are only dumped in "raw" form...
Code has to be written for each descriptor type. These however will not tell you a lot:
- 00 01: this is HID version 1.0
- 00: no specified language code
- 01: one single HID descriptor for this interface
- 22: this is an HID report descriptor
- The last two bytes indicate the descriptor length
Then further details about the report descriptors which can be extraced following this information are in the .bin files already attached to this ticket.
comment:10 by , 3 years ago
Mouse and keyboard are on the same USB device. They don't report the same thing. See https://linux-hardware.org/?probe=563a58b492&log=input_devices for devices under "/devices/pci0000:00/0000:00:07.1/0000:0b:00.3/usb5/5-2" The first is the mouse. The second bis fourth are composite for the keyboard. The last looks like for the leds.
comment:11 by , 3 years ago
I see a 90 byte length feature report (Vendor defined), perhaps it is used to set polling rate, dpi and fancy rgb colors. You can check OpenRazer for that and do the trick via libusb. Perhaps razer stuff needs a custom hid driver the same way we do with wacom.
By the way, I have a Razer deathadder not working also but did not have time to check why (but is not HID related).
follow-up: 13 comment:12 by , 3 years ago
scph1001, could you eventually try with OpenBSD or FreeBSD? These have no special razer support, and should work out of the box as this device exposes at least two standard interfaces.
follow-up: 14 comment:13 by , 3 years ago
Replying to korli:
scph1001, could you eventually try with OpenBSD or FreeBSD? These have no special razer support, and should work out of the box as this device exposes at least two standard interfaces.
I couldn't get OpenBSD to properly install and boot, but I can confirm the mouse works perfectly on FreeBSD with USB passthrough.
comment:14 by , 3 years ago
Replying to scph1001:
I couldn't get OpenBSD to properly install and boot, but I can confirm the mouse works perfectly on FreeBSD with USB passthrough.
OK. No quirks for this device AFAICT https://github.com/freebsd/freebsd-src/blob/main/sys/dev/hid/hidquirk.c#L83
comment:15 by , 3 years ago
I guess the next thing to do is to print out the computed intervals in XHCI and see if there is anything incorrect.
follow-up: 18 comment:16 by , 2 years ago
5132 KERN: usb xhci 0: transfer error on slot 1 endpoint 3: Babble detected
So, in another test with the USB RNDIS driver, we found that this happens if we schedule a transfer with a too small buffer. In USB-HID, the transfer size is computed from the HID report.
This gives two possibilities:
- We don't parse the descriptors correctly, and compute an incorrect size
- The device sends more bytes than it says it will
Some things you can try to check this in src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp:
- At line 184, add a TRACE_ALWAYS("Computed report size: %d\n", fParser.MaxReportSize()); and check what's the result
- Do something like fTransferBufferSize *= 2; this will provide a much larger buffer to the device, does it start working then?
comment:17 by , 2 years ago
If I compute things right, the trace should reveal:
0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x02, // Usage (Mouse) 0xA1, 0x01, // Collection (Application) 0x09, 0x01, // Usage (Pointer) 0xA1, 0x00, // Collection (Physical) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (0x01) 0x29, 0x05, // Usage Maximum (0x05) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x05, // Report Count (5) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x01, // Report Size (1) 0x95, 0x03, // Report Count (3) 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 0x09, 0x40, // Usage (0x40) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x38, // Usage (Wheel) 0x15, 0x81, // Logical Minimum (-127) 0x25, 0x7F, // Logical Maximum (127) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x16, 0x00, 0x80, // Logical Minimum (-32768) 0x26, 0xFF, 0x7F, // Logical Maximum (32767) 0x75, 0x10, // Report Size (16) 0x95, 0x02, // Report Count (2) 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 0x09, 0x02, // Usage (0x02) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x08, // Report Size (8) 0x95, 0x5A, // Report Count (90) 0xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection // 94 bytes
This report should have a size of 98 bytes,
0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0xE0, // Usage Minimum (0xE0) 0x29, 0xE7, // Usage Maximum (0xE7) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x19, 0x00, // Usage Minimum (0x00) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x0E, // Report Count (14) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x0C, // Usage Page (Consumer) 0x09, 0x01, // Usage (Consumer Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x02, // Report ID (2) 0x19, 0x00, // Usage Minimum (Unassigned) 0x2A, 0x3C, 0x02, // Usage Maximum (AC Format) 0x15, 0x00, // Logical Minimum (0) 0x26, 0x3C, 0x02, // Logical Maximum (572) 0x95, 0x01, // Report Count (1) 0x75, 0x10, // Report Size (16) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x08, // Report Size (8) 0x95, 0x0D, // Report Count (13) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x80, // Usage (Sys Control) 0xA1, 0x01, // Collection (Application) 0x85, 0x03, // Report ID (3) 0x19, 0x81, // Usage Minimum (Sys Power Down) 0x29, 0x83, // Usage Maximum (Sys Wake Up) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x03, // Report Count (3) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x05, // Report Count (5) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x08, // Report Size (8) 0x95, 0x0E, // Report Count (14) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x00, // Usage (Undefined) 0xA1, 0x01, // Collection (Application) 0x85, 0x04, // Report ID (4) 0x09, 0x03, // Usage (0x03) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x35, 0x00, // Physical Minimum (0) 0x46, 0xFF, 0x00, // Physical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x0F, // Report Count (15) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x00, // Usage (Undefined) 0xA1, 0x01, // Collection (Application) 0x85, 0x05, // Report ID (5) 0x09, 0x03, // Usage (0x03) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x35, 0x00, // Physical Minimum (0) 0x46, 0xFF, 0x00, // Physical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x0F, // Report Count (15) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection // 159 bytes
This report should have a size of 75 bytes,
0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x05, 0x07, // Usage Page (Kbrd/Keypad) 0x19, 0xE0, // Usage Minimum (0xE0) 0x29, 0xE7, // Usage Maximum (0xE7) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x19, 0x00, // Usage Minimum (0x00) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x06, // Report Count (6) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x05, 0x08, // Usage Page (LEDs) 0x19, 0x01, // Usage Minimum (Num Lock) 0x29, 0x03, // Usage Maximum (Scroll Lock) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x03, // Report Count (3) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x95, 0x05, // Report Count (5) 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection // 61 bytes
This report should have a size of 8 bytes.
comment:18 by , 2 years ago
Replying to pulkomandy:
5132 KERN: usb xhci 0: transfer error on slot 1 endpoint 3: Babble detected
So, in another test with the USB RNDIS driver, we found that this happens if we schedule a transfer with a too small buffer. In USB-HID, the transfer size is computed from the HID report.
This gives two possibilities:
- We don't parse the descriptors correctly, and compute an incorrect size
- The device sends more bytes than it says it will
Some things you can try to check this in src/add-ons/kernel/drivers/input/usb_hid/HIDDevice.cpp:
- At line 184, add a TRACE_ALWAYS("Computed report size: %d\n", fParser.MaxReportSize()); and check what's the result
- Do something like fTransferBufferSize *= 2; this will provide a much larger buffer to the device, does it start working then?
fTransferBufferSize *=2
didn't work, but I tried fTransferBufferSize *= 8
and it actually did work! However the mouse is very sluggish and laggy/choppy, to an unusable degree.
Here is the serial output (syslog) from the session, including the computed report sizes: https://pastebin.com/CUjqwQLV
follow-up: 26 comment:19 by , 2 years ago
Component: | Drivers/USB/XHCI → Drivers/Input/USB-HID |
---|---|
Owner: | changed from | to
Summary: | XHCI driver can't handle high polling rate devices (>1000hz) → HID parser computes incorrect size for reports |
usb_hid: Computed report size: 90
This report should have a size of 98 bytes,
usb_hid: Computed report size: 16
This report should have a size of 75 bytes,
usb_hid: Computed report size: 8
usb_hid: Computed report size: 8
Indeed the USB HID parser really doesn't agree with me, except for the last one.
I would say that's a bug in the HID parser then. And probably nothing to do with the polling rate.
comment:20 by , 2 years ago
I have a gaming mouse (Razer Deathadder 2013) not working too. Syslog prints this several times:
KERN: usb error uhci 1: td (0x0ae4da40) error: status: 0x39580000; token: 0x00288269; KERN: usb_hid: error waiting for report: Device FIFO overrun
And then starts printing this:
KERN: td (0x0ae55700) error: status: 0x20040000; token: 0x00e08269; KERN: usb error uhci 1: usb_hid: error waiting for report: Device check-sum error
Perhaps this is an unrelated bug, but last time I tried to track this error didn't seem a HID bug to me.
comment:21 by , 2 years ago
Now that we know it's a HID problem, I searched about razer HID problems. The information in these posts may be helpful.
Support for Razer Viper 8KHz: https://github.com/openrazer/openrazer/issues/1426
Before every command send it also sends a 81 command, which at least as i found it in the code has something to do with the firmware? Im not sure if thats wanted or not, but it definetly doesnt happen in the original Razer Software, so its something i noted and wanted to share.
Included is a bunch of Wireshark captures of the Viper 8K: https://github.com/openrazer/openrazer/files/6145149/Captures.zip
Two more: Razer Anansi : Invalid USB repsonse spamming: https://github.com/openrazer/openrazer/issues/347
kernel: razerkbd: Invalid Report Length. Start Marker: 00 id: 00 Num Params: 00 Reserved: 00 Command: 00 Params: 0000000000000000000000 0000000000
BlackWidow Elite: Invalid USB response.: https://github.com/openrazer/openrazer/issues/1191
[ 9.180700] kernel: razer driver: Invalid USB response. USB Report length: 26 [ 9.180704] kernel: razerkbd: Invalid Report Length. Start Marker: 00 id: 00 Num Params: 00 Reserved: 00 Command: 00 Params: 00000000000000000000000000000000 . [ 9.823816] kernel: iommu ivhd0: AMD-Vi: Event logged [INVALID_DEVICE_REQUEST device=00:00.0 pasid=0x00000 address=0xfffffffdf8000000 flags=0x0a00]
follow-up: 23 comment:22 by , 2 years ago
The information in these posts may be helpful.
Maybe so, but the immediate problem has nothing to do with these and looks to be already identified by PulkoMandy: our HID parser determines incorrect report sizes, and then correspondingly queues transfers that are too small. Fixing this should hopefully resolve the problem.
comment:23 by , 2 years ago
Replying to waddlesplash:
The information in these posts may be helpful.
Maybe so, but the immediate problem has nothing to do with these and looks to be already identified by PulkoMandy: our HID parser determines incorrect report sizes, and then correspondingly queues transfers that are too small. Fixing this should hopefully resolve the problem.
Does the report size need to be an exact value, or does it just need to be big enough? After some testing, the mouse doesn't start working until the buffer size is multiplied by 4, then gets progressively slower the more it's multiplied after that.
It also doesn't detect any clicks unless I'm moving the mouse while holding down the button. So there may be more issues...?
comment:24 by , 2 years ago
I would guess that, by making the transfers larger than the report size, that you can wind up with more than 1 report in a transfer, and thus the mouse will get "slower" because the HID driver only expects 1 report in a transfer; it sizes transfers that way after all. That would likely also explain why clicks are not detected unless you are moving the mouse, because the first "click" report has a high probability of getting "lost" in your oversized buffers.
comment:25 by , 2 years ago
I would guess that, by making the transfers larger than the report size, that you can wind up with more than 1 report in a transfer, and thus the mouse will get "slower" because the HID driver only expects 1 report in a transfer
I doubt that, but I can't say what will happen when we submit a transfer with the wrong size, certainly the device will be confused by it, whatever it does.
USB is normally packet-based, so each transfer should be separate, it is not a stream of bytes like reading from a file or a TCP socket.
Anyways, there isn't really a need to speculate or reverse engineer exactly how the mouse behaves. Rather we should look at our HID code and understand why it's not computing the report sizes properly in this case.
comment:26 by , 2 years ago
Replying to pulkomandy:
usb_hid: Computed report size: 90
This report should have a size of 98 bytes,
usb_hid: Computed report size: 16
This report should have a size of 75 bytes,
usb_hid: Computed report size: 8
usb_hid: Computed report size: 8
Indeed the USB HID parser really doesn't agree with me, except for the last one.
I would say that's a bug in the HID parser then. And probably nothing to do with the polling rate.
I hardcoded the values you listed here into the code to test (e.g. checking if == 90 and setting to 98), and found that for the first computed value, the mouse only works if the value is a multiple of 8. Neither 90 nor 98 work. Are you sure that's correct?
The other two values have no effect whatsoever on the mouse, even if I set them to 0.
follow-up: 28 comment:27 by , 2 years ago
Are you sure that's correct?
No, I could have failed something in my calculation. Which size did you find is working? 96 then? Or does it need to be larger than that?
comment:28 by , 2 years ago
Replying to pulkomandy:
Are you sure that's correct?
No, I could have failed something in my calculation. Which size did you find is working? 96 then? Or does it need to be larger than that?
96 does work, but so do lower values as long as they're a multiple of 8 (16 and lower is very laggy). So the problem might not even an undersized buffer. 32 and 24 seem to be the smoothest value based on my testing, more than 96. However, even at 32 the clicking issue still remains and the mouse is moving at about half the speed it should be.
Switching directions with the mouse is also delayed by one count (if I move right, stop, then move one pixel left, it moves right one more pixel before moving left). So it seems like it's processing an old packet whenever a new one comes in.
comment:29 by , 2 years ago
Guys, i think i see the problem!
In maxReportSize calculating only "Input" reports should be taken into account.
"Feature" reports can't appear on interrupt channel, they send/receive only on control channel.
I'm sure this affects most "USB\HID"-related tickets about keyboards and mouse work incorrectly
by , 2 years ago
Attachment: | hid_report_size_calc_fix.patch added |
---|
one of the solutions to the problem
comment:30 by , 2 years ago
Looks good! Would you please submit this patch to Gerrit (https://review.haiku-os.org), along with your other patch to the HID driver?
comment:31 by , 2 years ago
(Details on how to submit patches to Gerrit can be found at https://dev.haiku-os.org/wiki/CodingGuidelines/SubmittingPatches#Submittingyourcommits)
syslog