Score:3

Ubuntu 22.04.1: How to automatically reset USB connections upon wake?

in flag

I have a Lenovo ThinkPad E15 that came with Windows 10 installed. I added Ubuntu 22.04.1 as an option (dual-boot).

Whenever the laptop sleeps (goes into a "suspend" state) and then later I wake it up, the Logitech wireless mouse scroll wheel doesn't work. ("Logitech MK270 Wireless Keyboard and Mouse Combo", but the only thing that doesn't work is the scroll wheel.)

I already asked about this problem, and I gave a bounty for an answer that helped me make progress but didn't fully solve it.

Currently the result of cat /etc/systemd/system/reset-usb-upon-wake@.service is:

[Unit]
Description="Reset a USB device after system resume"
After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target

[Service]
Type=simple
ExecStart=/usr/bin/usbreset %i
User=root
Group=root

[Install]
WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target

When I wake the computer, the mouse scroll wheel doesn't work.

I run sudo systemctl status reset-usb-upon-wake@046d:c534.service and see:

○ reset-usb-upon-wake@046d:c534.service - "Reset a USB device after system resume"
     Loaded: loaded (/etc/systemd/system/reset-usb-upon-wake@.service; disabled; vendor preset: enabled)
     Active: inactive (dead)

Then I run sudo systemctl start reset-usb-upon-wake@046d:c534.service, and the result is:

  • It prints a bunch of empty newlines to the terminal infinitely until I cancel out of the command. ‍♀️
  • After exiting that command, my scroll wheel works again.
  • sudo systemctl status reset-usb-upon-wake@046d:c534.service still shows "inactive (dead)".

I also tried sudo systemctl enable reset-usb-upon-wake@046d:c534.service, but the status still shows as dead after running that too.

How can I completely fix this problem so that I never have to think about my scroll wheel and it always works, even after waking from sleep?

P.S. I also tried sudo vim /etc/udev/rules.d/99-usbreset.rules and saving these lines to that new file:

# Reset Logitech wireless mouse on resume from sleep
SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c534", RUN+="/usr/bin/usbreset %p"

P.P.S. In response to an answer:

lsusb && lsmod | grep usbhid
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 008: ID 27c6:55a4 Shenzhen Goodix Technology Co.,Ltd. Goodix FingerPrint Device
Bus 003 Device 006: ID 30c9:0014 Luxvisions Innotech Limited Integrated Camera
Bus 003 Device 039: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 003 Device 038: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 003 Device 040: ID 0d8c:0014 C-Media Electronics, Inc. Audio Adapter (Unitek Y-247A)
Bus 003 Device 037: ID 0bda:5411 Realtek Semiconductor Corp. RTS5411 Hub
Bus 003 Device 003: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 003 Device 004: ID 0451:82ff Texas Instruments, Inc. 
Bus 003 Device 002: ID 0451:8442 Texas Instruments, Inc. 
Bus 003 Device 009: ID 8087:0026 Intel Corp. AX201 Bluetooth
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
usbhid                 65536  1 hid_logitech_dj
hid                   151552  7 i2c_hid,hid_cmedia,usbhid,hid_multitouch,hid_generic,hid_logitech_dj,hid_logitech_hidpp

UPDATE 2:

lsmod | grep hid_logitech_dj && lsmod | grep hid_logitech_hidpp
hid_logitech_dj        28672  0
usbhid                 65536  1 hid_logitech_dj
hid                   151552  7 i2c_hid,hid_cmedia,usbhid,hid_multitouch,hid_generic,hid_logitech_dj,hid_logitech_hidpp
hid_logitech_hidpp     49152  0
hid                   151552  7 i2c_hid,hid_cmedia,usbhid,hid_multitouch,hid_generic,hid_logitech_dj,hid_logitech_hidpp
Raffa avatar
jp flag
First of all I would use `Type=simple` to keep the process active and not `Type=oneshot` ... Second, I would enable the service with `sudo systemctl enable reset-usb-upon-wake@046d:c534.service` so it runs automatically when system boots ... Reload configuration after changes with `sudo systemctl daemon-reload` then restart your service or do both by simply rebooting your system.
Ryan avatar
in flag
@Raffa Thank you! Just before you commented, I found the answer (now posted below) that seems to be working for me. But if I have trouble with it later, I'll try `Type=simple`, like you said. And yes, I think `sudo` was important. Thanks so much for your help!
Ryan avatar
in flag
My answer must not be complete because this morning my scroll wheel again wasn't working. So now I'm trying my same answer but with `Type=simple`. If that works over an extended number of days, I'll let you know, and I can delete my answer, and you can write one, and I'll accept it. @Raffa
Ryan avatar
in flag
@Raffa Even with your adjustment, my answer didn't work, so I deleted it.
Score:3
jp flag

How to detect reset-able USB devices?

Just run usbreset and it should tell you what it can do and how ... e.g. like so:

$ usbreset 
Usage: # <=== This is how to do it (reset devices)
  usbreset PPPP:VVVV - reset by product and vendor id
  usbreset BBB/DDD   - reset by bus and device number
  usbreset "Product" - reset by product name

Devices: # <=== These are the devices that it sees and can reset
  Number 001/002  ID 8087:0a3a  
  Number 001/005  ID 05ac:14a7  iPhone
  Number 001/003  ID 0bda:55ea  EasyCamera

So, how to auto execute upon system wake up from sleep?

A simple and yet very reliable way is to create a script in /lib/systemd/system-sleep/ that reads the positional parameter $1 and runs commands accordingly.

Executable files in that directory will be run before and after system sleep/suspend, hibernate, or hybrid-sleep with two positional parameters passed to them ... $1 will hold either pre or post and $2 will hold the action i.e. sleep, hibernate ... etc.

The procedure will be like so:

  • Create the script file and open it for editing ... e.g. like so:

    sudo nano /lib/systemd/system-sleep/fix-my-mouse-wheel
    
  • Use this template in the file ... i.e. copy/paste it in the file then modify it to add your command(s) in the right section then save the file afterwords:

    #!/bin/sh
    
    case "${1}" in
      pre)
        # Command(s)/script(s) "each on a newline" to be executed before system goes to sleep/hibernate
          ;;
      post)
        sleep 5 # You most likely will need this sleep call. Leave it alone.
        # Command(s)/script(s) "each on a newline" to be executed after system wakes up from sleep/hibernate
        # e.g. usbreset 05ac:14a7
          ;;
    esac
    
  • Make it executable like so:

    sudo chmod +x /lib/systemd/system-sleep/fix-my-mouse-wheel
    
  • Done.

Ryan avatar
in flag
Thanks for your answer. Isn't this what I've already tried? I'm not sure what you're saying I should do differently. The pre and post section split sounds new, but you didn't mention that that is specifically what I was missing. Thanks.
Raffa avatar
jp flag
@Ryan This is a different approach without the need for a dedicated service i.e. you just need what's described in the answer to be able to auto reset after sleep ... I have added a commented example of a `usbreset` command to the script above. Put your command exactly in the line below it without a leading `#` ... I guess you know how to do this ... Also I wanted to point out that `usbreset` is better used as well for listing devices as `lsusb` will report extra devices that `usbreset` can't handle and will report `No such device found` if you try to reset them.
Ryan avatar
in flag
Oh ok. I'm very optimistic about this! On my first test, it seems to have worked so far. Fingers crossed that it continues to work in the next few days. I'll let you know! Thanks!
Ryan avatar
in flag
I've probably identified another factor at play. I have a Monoprice USB switch that my external keyboard and mouse (with the scroll wheel) are plugged into. It allows me to use my keyboard/mouse setup with both my Windows desktop and my Ubuntu laptop. When switching to my Ubuntu laptop just now, the mouse worked but scroll wheel didn't. So at first I thought " I guess this solution didn't work either". But then I forced the laptop to sleep and wake up, and the scroll wheel worked. So I wonder if sometimes my Ubuntu laptop isn't sleeping when I'd think it would.
Ryan avatar
in flag
E.g. when I leave it unused for hours / days, & my external monitor & the USB switch are switched over for use with the Windows desktop. So maybe this script *can be* a viable solution if I can edit it to also activate when I press the USB switch button. I will try to pay attention to whether the laptop hasn't been sleeping when I expected. And I'll resolve that separately. But either way, I do want my USB mouse scroll wheel to *always just work* without me thinking about it (even in the cases where I switch back & forth between Windows desktop & Ubuntu laptop without either sleeping). Thanks!
Raffa avatar
jp flag
@Ryan That script is **only** going to work if triggered by system waking up from sleep and nothing else ... Please run this while your USB hub is switched to Ubuntu `grep -q '046d:c534' <(lsusb) && echo "Connected" || echo "Disconnected"` then switch the hub to Windows and run it again and report if the status is detected as *Connected* then *Disconnected* respectively ... We might be able to write a separate script for the USB hub switch action if its detected by the above command ... Assuming '046d:c534' is the mouse ID
Ryan avatar
in flag
No matter what I did, it always said Connected (even when I unplugged the switch entirely), which was really confusing. Then I found a *2nd* Logitech USB nub was plugged into the laptop. It must be to a similar wireless mouse (I have no idea where it is). After unplugging that nub, now Connected & Disconnected display as we'd expected based on the switch button. Maybe the presence of this nub was causing a problem (such as via a race condition). It might explain the erratic nature of why my mouse wheel would sometimes work upon waking and sometimes not. I'll see in the coming days. Thanks!
Raffa avatar
jp flag
@Ryan That is good news anyway … Now that we can detect the switch button action, we are able to write a script that will automatically reset your mouse after you press the button to switch to Ubuntu in case you need it … And your mouse will be reset in either situations after sleep or after switch button press … Waiting for your update and we’ll take it from there.
Ryan avatar
in flag
Note to self: I had to remove this script because (maybe due to a recent change in Ubuntu?) it was interfering with me trying to enter my password whenever waking / unlocking the computer. That new problem then annoyed me even more than what the script was trying to solve (and had never completely solved).
Score:1
py flag

I had this same problem for a while(in recent ubuntu installs), and no scripts that I saw suggested anywhere as a solution worked for me.

In the end modprobe did the trick, but here is the catch:

If you lsmod | grep usbhid

You might see that usbhid is "used by"(second column) something else. In my case, I draw often, and so I see a 'wacom' listed there. This means that after a suspend I have to do(the order matters):

sudo rmmod wacom && sudo rmmod usbhid && sudo modprobe usbhid && sudo modprobe wacom

If I rmmod usbhid before 'wacom' it errors out and the process does nothing because of the dependency issue. If it's a clean startup i can just do the rmmod/modprobe combo on usbhid and it works.

Now, my device is a Msoft keyboard/mouse combo and it uses the usbhid only, the logitech device might be different, I saw in the other post that you claimed it uses hid_logitech_dj also, but you also said that modprobing it doesnt work. The question is where did you get that name from, did you find it with lsmod as depicted above? I don't see why modprobing wouldn't work if you figure out what you actually have to unload/reload, in your specific system.

Instead of chaining commands, try doing one command at a time and see if any of them return errors.

Your case might be a specific edge case so who knows. It's a shame that Canonical hasn't looked into this, it's like some old suspension bug that took years to be fixed.

I hope this helps you, even if you hit another dead end, don't give up. As depicted above, in principle, this problem is not unsolvable.

Edit:

This issue seems connected with new Linux Kernel 5 features that implemented fancy mouse support.

In the case of some Logitech and other mouses it's possible that simply cycling the modules doesn't work because of the mouse wheel high precision/sensitivity. As per the Solaar post, users would have to reset the mouse wheel to get it to function, otherwise it would be active but seems inactive or slow.

Useful Links:

1.Another post with similar solutions.

2.Launchpad Post with similar problem

3.Logitech firmware bug report

4.Solaar issue (Solaar is a Linux device manager for Logitech devices)

5.Linux kernel bug report

Ryan avatar
in flag
Thank you so much for your thoughts! I just added the output of `lsusb && lsmod | grep usbhid` to my answer above. Are you saying that the next time my scroll wheel doens't work I should try `sudo modprobe -r hid_logitech_dj` and then `sudo modprobe hid_logitech_dj`? And if that fixes it, then try using those commands in my wake service? Thanks.
Oratorium avatar
py flag
Based on your added output, I think you can try `sudo rmmod hid_logitech_dj && sudo rmmod usbhid && sudo modprobe usbhid && sudo modprobe hid_logitech_dj` Right off the bat. But try these commands one at a time, in that order and see what happens.
Oratorium avatar
py flag
Another thing is your hid has a lot of users(7). My has 2: usbhid,hid_generic. So there is no telling if anything else has to be recycled. It would be interesting if you did `lsmod | grep hid_logitech_dj` and `lsmod | grep hid_logitech_hidpp`, just for starters, so we can understand what's going on. That is, in case the above doesn't work right off the bat.
Ryan avatar
in flag
Thanks for your suggestions. Running those 4 commands separately in that order did not throw errors but also did not make my scroll wheel work. I added Update 2 to my answer to show you the other commands you asked about. I'm curious for your thoughts. I will try to add a bounty to this question now. It's my biggest pain point on Ubuntu.
Oratorium avatar
py flag
It's very strange hid_logitech_hidpp isn't tied to anything. You could try doing `rmmod hid_logitech_hidpp` first and `modprobe hid_logitech_hidpp` last, but I'd be surprised if it worked. The thing about your lsusb is that you seem to have a lot of devices in there. Are you using any other USB attached devices beyond the mouse? Also, what's the exact model of the mouse you are using? I'll wait for the response and will see if I can find any extra info on it.
Oratorium avatar
py flag
I have two more things for you to try: First: try going into mouse options and *disabling two finger scrolling* AND the *edge scrolling* on the mouse/touchpad options, I remember reading this worked on some devices. It might just do the trick! Second: if none of the above work, you can try installing lomoco: `sudo apt-get install lomoco` It's an app for logitech allegedly, as i don't have such devices i can't test it and know nothing of it, but it seems to have extra config options for certain devices.(according to the pkg description)
Oratorium avatar
py flag
Added a few posts that are worth looking into. Specially Solaar, according to the post it has/had a feature with a toggle that would help with this problem for logitech devices, *and* they might be working on a permafix. If you decide to install it, there seems to be a PPA, and if you had installed lomoco I would remove that before installing Solaar just in case.
Score:0
gh flag
[Unit]                                                                                                                                                       
Description="Reset a USB device after system resume"                                                                                                         
After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target                                                                      
                                                                                                                                                             
[Service]                                                                                                                                                    
Type=simple                                                                                                                                                  
ExecStart=/usr/bin/usbreset 046d:c534                                                                                                                  
User=root                                                                                                                                                    
Group=input                                                                                                                                                  
[Install]                                                                                                                                                    
WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target                                 

I think udev will not work in this case.

sudo systemctl enable reset-usb-upon-wake@046d:c534.service

Then let systemd know something changed.

sudo systemctl daemon-reload
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.