After a long uptime specific (cheap) devices or components connected to the USB ports lock up or malfunction. Unplugging and plugging them usually fixes issues, but physical access to the system (especially a remote server) is neither always possible or desirable.
In cases like this, Linux (unlike Windows) can trigger a USB subsystem restart by deactivating and reactivating the USB controller(s).
The hardware ID(s) of the controllers differ from manufacturer to manufacturer and from hardware to hardware. So the first thing to do is find out the correct hardware ID(s).
Running
cd /sys/bus/pci/drivers/ehci_hcd
ls
returns a list of one or more controller IDs, in the form of 0000:00:xx.y.
Edit: For USB 3.0 controllers, use instead
cd /sys/bus/pci/drivers/xhci_hcd
ls
On my system which has two AMD USB controllers, the following IDs are found:
0000:00:12.2 0000:00:13.2 bind module new_id remove_id uevent unbind
Now that the ID or IDs are known, you need to run a set of commands that trigger the disabling and re-enabling of that device. You can run this command for a specific controller (if you know which one) or for all controllers if you don’t have anything critical connected to the USB. The command is:
echo -n "0000:00:xx.y" > unbind
Remember to enable them back:
echo -n "0000:00:xx.y" > bind
where instead of xx.y you fill in the correct set of numbers to use the IDs discovered above.
This procedure is the same for all RHEL-like distributions (Red Hat Enterprise, CentOS, Fedora).
I can confirm that this works for a Raspberry Pi 4 running Manjaro ARM64 as well. Thanks!
Thanks too !
Golden – thanks! Saved me rebooting and losing my precious uptime 🙂