[BUG] HID: logitech-hidpp: G502 LIGHTSPEED loses hi-res scroll state after S3 resume

4 messages, 2 authors, 16d ago · open the first message on its own page

[BUG] HID: logitech-hidpp: G502 LIGHTSPEED loses hi-res scroll state after S3 resume

From: Quinn Schive <hidden>
Date: 2026-09-09 15:58:32

Hello,

Before the technical details: I am not a programmer or kernel developer.

I originally noticed an intermittent scrolling problem with my Logitech 
G502 LIGHTSPEED after waking my computer from sleep. I used ChatGPT to 
help me investigate the issue, guide me through collecting diagnostics, 
and interpret the kernel/input data. It also directed me to the relevant 
Linux MAINTAINERS entries and suggested reporting the findings to the 
HID/HID++ and USB maintainers and mailing lists.

The commands and measurements below were performed on my actual system. 
I have tried to separate directly observed results from my 
interpretation of what may be happening. Please forgive any terminology 
mistakes on my part.

System / hardware:

* Distribution: Arch Linux
* Desktop environment: KDE Plasma
* Display protocol: Wayland
* Kernel: 7.2.3-arch1-3
* libinput: 1.31.3
* systemd: 261.2-1
* Suspend mode: deep (S3)
* Motherboard: ASUS ProArt X870E-CREATOR WIFI
* Motherboard revision: Rev 1.xx
* BIOS vendor: American Megatrends Inc.
* BIOS version: 2402
* BIOS release date: 2026-07-13
* CPU: AMD Ryzen 9 9950X3D2
* GPU: XFX SPEEDSTER MERC 310 Radeon RX 7900 XTX Black Edition
* RAM: 96 GB (2 x 48 GB) TEAMGROUP T-Create Expert DDR5-6400 CL32
* PSU: Seasonic PRIME TX-1600 Noctua Edition
* Case: ASUS ProArt PA602
* CPU cooling: Noctua 420 mm AIO

Relevant USB / mouse hardware:

* Mouse: Logitech G502 LIGHTSPEED Wireless Gaming Mouse
* HID++ device ID: 046d:407f
* LIGHTSPEED receiver: Logitech 046d:c539
* Receiver firmware/configuration string: RQR39.06_B0040
* Mouse HID++ version reported by kernel: HID++ 4.2
* USB controller hosting the receiver: AMD 800 Series Chipset USB 3.x 
XHCI Controller
* PCI ID: 1022:43fd
* Revision: 01
* Subsystem: ASMedia 1b21:1142
* Kernel driver: xhci-pci-prom21
* PCI address: 0000:0f:00.0

A second matching PROM21 XHCI controller is present at:

* PCI address: 0000:11:00.0
* PCI ID: 1022:43fd
* Revision: 01
* Kernel driver: xhci-pci-prom21

Loaded Logitech HID++ module:

filename:
/lib/modules/7.2.3-arch1-3/kernel/drivers/hid/hid-logitech-hidpp.ko.zst

srcversion:
7CC87403B0A8F2C3D6BE42C

vermagic:
7.2.3-arch1-3 SMP preempt mod_unload

The existing G502 quirk is present in this kernel:

LDJ_DEVICE(0x407f),
.driver_data = HIDPP_QUIRK_RESET_HI_RES_SCROLL

The issue:

After some S3 resumes, mouse wheel scrolling becomes approximately 8 
times slower.

Turning the G502 off and back on immediately restores normal scrolling.

I captured the failure before power-cycling the mouse.

During the resume that triggered the problem, both PROM21 xHCI 
controllers reported:

xhci-pci-prom21 0000:11:00.0: xHC error in resume, USBSTS 0x401, Reinit
usb usb10: root hub lost power or was reset
usb usb11: root hub lost power or was reset

xhci-pci-prom21 0000:0f:00.0: xHC error in resume, USBSTS 0x401, Reinit
usb usb8: root hub lost power or was reset
usb usb9: root hub lost power or was reset

The Logitech receiver is on usb 8-5 and was subsequently reset:

usb 8-5: reset full-speed USB device number 3 using xhci-pci-prom21

Afterwards, the receiver remained logically present:

/sys/bus/usb/devices/8-5/power/persist = 1
/sys/bus/usb/devices/8-5/power/control = on
/sys/bus/usb/devices/8-5/power/runtime_status = active
/sys/bus/usb/devices/8-5/authorized = 1
/sys/bus/usb/devices/8-5/bConfigurationValue = 1

The G502 power_supply state while connected and affected was:

POWER_SUPPLY_STATUS=Unknown
POWER_SUPPLY_ONLINE=0
POWER_SUPPLY_VOLTAGE_NOW=4148000
POWER_SUPPLY_CAPACITY=98
POWER_SUPPLY_MODEL_NAME=G502 LIGHTSPEED Wireless Gaming Mouse
POWER_SUPPLY_MANUFACTURER=Logitech

I then measured the raw evdev events while scrolling exactly one 
physical wheel detent at a time.

In the broken state, all 10 trials were identical:

1 physical detent:
REL_WHEEL_HI_RES = -15
REL_WHEEL = <none>

I also attached a kprobe to hidpp_scroll_counter_handle_scroll().

For one physical detent in the broken state:

raw=-1 multiplier=8

Given the HID++ calculation:

hi_res_value = hi_res_value * 120 / counter->wheel_multiplier

this produces:

-1 * 120 / 8 = -15

which exactly matches the evdev output and appears to explain the 
approximately 8x slow scrolling.

I then traced hi_res_scroll_enable() while intentionally power-cycling 
the G502.

Before power-cycle:

g502scroll: raw=-1 multiplier=8

During reconnection, hi_res_scroll_enable() was called multiple times:

g502enable: hi_res_scroll_enable.isra.0
g502enable: hi_res_scroll_enable.isra.0
g502enable: hi_res_scroll_enable.isra.0

Immediately afterwards scrolling returned to normal.

I repeated the single-detent evdev test in the healthy state.

In the working state, one physical detent produces a burst of -15 
high-resolution events totaling approximately -120 and consistently 
produces:

REL_WHEEL=-1

Examples:

HI_RES=[-15,-15,-15,-15,-15,-15,-15,-15]
sum=-120
REL_WHEEL=[-1]

Some trials varied slightly around the physical detent boundary, for 
example -105, -135, or -165 total high-resolution units, but 
REL_WHEEL=-1 was consistently generated in the healthy state.

By comparison, the broken state was consistently:

HI_RES=[-15]
sum=-15
REL_WHEEL=[]

The cached kernel wheel multiplier remained 8 in both the broken and 
healthy states.

My interpretation, with the caveat that I am not familiar with the HID++ 
driver internals, is:

1. Before suspend, the G502 is configured for high-resolution scrolling 
and hid-logitech-hidpp stores wheel_multiplier=8.

2. During S3 resume, the PROM21 xHCI controller fails normal resume and 
is reinitialized.

3. The LIGHTSPEED receiver gets a USB reset while USB persistence keeps 
the logical receiver/HID device present.

4. The G502 appears to lose its high-resolution wheel reporting 
configuration. In the affected state, one physical detent generates only 
one raw increment.

5. hid-logitech-hidpp retains wheel_multiplier=8 and apparently does not 
re-run the necessary high-resolution configuration on this recovery path.

6. The driver consequently converts the single raw increment to:

    1 * 120 / 8 = 15

    high-resolution units, so userspace receives approximately one 
eighth of the expected wheel movement.

7. Power-cycling the G502 causes hi_res_scroll_enable() to execute again.

8. After that, a physical detent once again produces multiple raw 
increments whose high-resolution output totals approximately 120, and 
normal scrolling immediately returns.

This appears related to:

ed80cc4667ac997b84546e6d35f0a0ae525d239c
HID: logitech-hidpp: Add HIDPP_QUIRK_RESET_HI_RES_SCROLL

but the existing quirk does not appear to cover this particular S3 / 
receiver USB-reset recovery path.

I have the complete kernel journal, PCI configuration output, USB 
topology, evdev captures, and ftrace/kprobe output available if they 
would be useful.

I am also happy to run additional diagnostics or test a proposed patch. 
I may need fairly explicit instructions for kernel development/testing 
steps, as I am not a programmer.

Thank you,

Quinn S.

Re: [BUG] HID: logitech-hidpp: G502 LIGHTSPEED loses hi-res scroll state after S3 resume

From: Michal Pecio <hidden>
Date: 2026-09-09 20:27:32

On Wed, 9 Sep 2026 09:58:28 -0600, Quinn Schive wrote: 
After some S3 resumes, mouse wheel scrolling becomes approximately 8 
times slower.

Turning the G502 off and back on immediately restores normal
scrolling.

I captured the failure before power-cycling the mouse.

During the resume that triggered the problem, both PROM21 xHCI 
controllers reported:

xhci-pci-prom21 0000:11:00.0: xHC error in resume, USBSTS 0x401, Reinit
usb usb10: root hub lost power or was reset
usb usb11: root hub lost power or was reset
Hi,

You could try if this problem is fixed by the following patch:
https://lore.kernel.org/linux-usb/178832755831.50581.1058201741431375556@gmail.com/

That being said,
My interpretation, with the caveat that I am not familiar with the
HID++ driver internals, is:

1. Before suspend, the G502 is configured for high-resolution
scrolling and hid-logitech-hidpp stores wheel_multiplier=8.

2. During S3 resume, the PROM21 xHCI controller fails normal resume
and is reinitialized.

3. The LIGHTSPEED receiver gets a USB reset while USB persistence
keeps the logical receiver/HID device present.

4. The G502 appears to lose its high-resolution wheel reporting 
configuration. In the affected state, one physical detent generates
only one raw increment.

5. hid-logitech-hidpp retains wheel_multiplier=8 and apparently does
not re-run the necessary high-resolution configuration on this
recovery path.
this still looks like missing functionality in the driver.
Needs to handle reset_resume() perhaps?

Regards,
Michal

Re: [BUG] HID: logitech-hidpp: G502 LIGHTSPEED loses hi-res scroll state after S3 resume

From: Quinn Schive <hidden>
Date: 2026-09-10 00:13:33

Hi Michal,

I tested the patch you suggested, and so far it appears to have fixed 
the problem on my system.

For reference, I have two AMD PROM21 xHCI controllers:

0f:00.0 AMD 800 Series Chipset USB 3.x XHCI Controller [1022:43fd]
11:00.0 AMD 800 Series Chipset USB 3.x XHCI Controller [1022:43fd]

Before applying the patch, the problem was occurring often enough that 
it was very easy to reproduce. I was able to reproduce the resume 
failure on the unmodified Arch Linux 7.2.4 kernel:

xhci-pci-prom21 0000:11:00.0: xHC error in resume, USBSTS 0x401, Reinit
usb usb10: root hub lost power or was reset
usb usb11: root hub lost power or was reset

The same type of failure also occurred on the other PROM21 controller.

I then built the same Arch Linux 7.2.4 kernel with the v5 "usb: 
pci-quirks: always assert xHCI OS ownership" patch applied.

I have now completed 10+ consecutive S3 deep suspend/resume cycles with 
the patched kernel. This included several short manual suspend cycles, 
normal automatic suspend cycles, and one suspend lasting about 40 minutes.

So far, across all 10+ cycles, I have not seen any of the following:

xHC error in resume
USBSTS 0x401
PROM21 controller reinitialization
root hub lost power or was reset
reset of the Logitech LIGHTSPEED receiver

Subjectively, the G502 wheel has also remained completely normal after 
every resume. Before applying the patch, the slow scrolling problem was 
happening very frequently and was easy to reproduce, so the difference 
has been quite noticeable.

These are just my findings on this particular system, but at this point 
the patch appears to be working very well here.

If there are any additional tests, logs, or specific suspend/resume 
scenarios you would like me to try, please let me know and I would be 
happy to test them.

Thanks for pointing me to the patch.

Regards,
Quinn S.

On 2026-09-09 14:27, Michal Pecio wrote:
On Wed, 9 Sep 2026 09:58:28 -0600, Quinn Schive wrote:
quoted
After some S3 resumes, mouse wheel scrolling becomes approximately 8
times slower.

Turning the G502 off and back on immediately restores normal
scrolling.

I captured the failure before power-cycling the mouse.

During the resume that triggered the problem, both PROM21 xHCI
controllers reported:

xhci-pci-prom21 0000:11:00.0: xHC error in resume, USBSTS 0x401, Reinit
usb usb10: root hub lost power or was reset
usb usb11: root hub lost power or was reset
Hi,

You could try if this problem is fixed by the following patch:
https://lore.kernel.org/linux-usb/178832755831.50581.1058201741431375556@gmail.com/

That being said,
quoted
My interpretation, with the caveat that I am not familiar with the
HID++ driver internals, is:

1. Before suspend, the G502 is configured for high-resolution
scrolling and hid-logitech-hidpp stores wheel_multiplier=8.

2. During S3 resume, the PROM21 xHCI controller fails normal resume
and is reinitialized.

3. The LIGHTSPEED receiver gets a USB reset while USB persistence
keeps the logical receiver/HID device present.

4. The G502 appears to lose its high-resolution wheel reporting
configuration. In the affected state, one physical detent generates
only one raw increment.

5. hid-logitech-hidpp retains wheel_multiplier=8 and apparently does
not re-run the necessary high-resolution configuration on this
recovery path.
this still looks like missing functionality in the driver.
Needs to handle reset_resume() perhaps?

Regards,
Michal

Re: [BUG] HID: logitech-hidpp: G502 LIGHTSPEED loses hi-res scroll state after S3 resume

From: Michal Pecio <hidden>
Date: 2026-09-10 08:38:51

On Wed, 9 Sep 2026 18:13:17 -0600, Quinn Schive wrote:
I tested the patch you suggested, and so far it appears to have fixed 
the problem on my system.
Thanks for testing, looks like that issue may be somewhat widespread.
BTW, you may respond to the patch (in its original thread) with:

  Tested-by: Your Name <email@address>

and a brief note that it's confirmed to work for you as well.

As for the Logitech driver, I'd guess it needs something like this.
Of course, the xHCI patch must be removed to reproduce this again.
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 1504de32b1c8..0107ffc9efb3 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -4711,6 +4711,21 @@ static bool hidpp_application_equals(struct hid_device *hdev,
 	return report && report->application == application;
 }
 
+static int hidpp_reset_resume(struct hid_device *hdev)
+{
+	struct hidpp_device *hidpp = hid_get_drvdata(hdev);
+	int ret = 1234;
+
+	/* reset disables hi-res scroll, restore if it was used */
+	if (hidpp && hidpp->vertical_wheel_counter.wheel_multiplier > 1)
+		ret = hi_res_scroll_enable(hidpp);
+
+	dev_info(&hdev->dev, "hidpp_reset_resume mult %d ret %d\n",
+			hidpp ? hidpp->vertical_wheel_counter.wheel_multiplier : 4321,
+			ret);
+	return 0;
+}
+
 static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	struct hidpp_device *hidpp;
@@ -5059,6 +5074,7 @@ static struct hid_driver hidpp_driver = {
 	.input_configured = hidpp_input_configured,
 	.input_mapping = hidpp_input_mapping,
 	.input_mapped = hidpp_input_mapped,
+	.reset_resume = pm_ptr(hidpp_reset_resume),
 };
 
 module_hid_driver(hidpp_driver);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help