Avoiding reboot: Resetting USB on a Linux machine

This post was written by eli on February 1, 2013
Posted Under: Linux,USB

Every now and then, some USB device misbehaves badly enough to knock out the entire interface, to the extent that the system doesn’t detect any new USB devices. Or work so well with the existing ones, for that matter. The solution for me until now was to reboot the computer. But hey, I don’t like rebooting Linux!

April 2023 update: Except for the solution suggested below, there are two additional methods for solving a problem like this. These two methods are more targeted towards the offending device, so I would suggest trying them out first (plus, there are zh/ja/ko translations).

So this script (I call it usbreset) performs a reset to the USB drivers as necessary to bring them back to life. As a side effect, an equivalent to unplugging and replugging all USB devices takes place. If possible, unmount any connected USB storage device (e.g. disk on key) before doing this. Also, if you’re in the middle of printing through a USB device, or some other operation, this will not be graceful.

An interesting thing I noted, was that if there’s a really problematic device on the bus (for example, a device that fails to enumerate), this script doesn’t return. It probably gets stuck on one of the writes to “bind” (hasn’t checked that all the way through).

Use at your own risk. You are root, you should know what you’re doing (or gamble like myself). Script follows.

If it doesn’t work for you, check the comments below. The names of the /sys files vary slightly among different distributions.

A word about how this script works, so it goes like this: The USB controllers are PCI / PCIe / fake PCI devices. So the script goes to the /sys directory that is related to the PCI devices’ driver, and unbinds them from the device, and then bind them back. So it’s like saying, nah, this device doesn’t belong to the driver, and then say, well, it is. And in the latter stage, the driver initializes the device, which does the job. On a good day.

Those file names like 0000:00:14.0 that appear in /sys/bus/pci/drivers/xhci_hcd/ are the PCI bus addresses of the USB controllers that are handled by the xhci_hcd driver. These will vanish from the directory after writing to “unbind” and return after writing to “bind”. The names can be found in /sys/bus/pci/devices/. Use “lspci” to tell which device is which.

#!/bin/bash

if [[ $EUID != 0 ]] ; then
  echo This must be run as root!
  exit 1
fi

for xhci in /sys/bus/pci/drivers/?hci_hcd ; do

  if ! cd $xhci ; then
    echo Weird error. Failed to change directory to $xhci
    exit 1
  fi

  echo Resetting devices from $xhci...

  for i in ????:??:??.? ; do
    echo -n "$i" > unbind
    echo -n "$i" > bind
  done
done

The script above is in fact a newer version of the script, which I updated to in June 2014, after upgrading my kernel to 3.12. The older one, to which some of the comments relate, is this one:

#!/bin/bash

SYSEHCI=/sys/bus/pci/drivers/ehci_hcd
SYSUHCI=/sys/bus/pci/drivers/uhci_hcd

if [[ $EUID != 0 ]] ; then
 echo This must be run as root!
 exit 1
fi

if ! cd $SYSUHCI ; then
 echo Weird error. Failed to change directory to $SYSUHCI
 exit 1
fi

for i in ????:??:??.? ; do
 echo -n "$i" > unbind
 echo -n "$i" > bind
done

if ! cd $SYSEHCI ; then
 echo Weird error. Failed to change directory to $SYSEHCI
 exit 1
fi

for i in ????:??:??.? ; do
 echo -n "$i" > unbind
 echo -n "$i" > bind
done

The problem with the old script is that the EHCI subdirectory doesn’t appear on my system, because xHCI is a catch-all for all USB versions, hence when a USB port is 3.0 capable, it’s driven by the xhci_hcd driver only. The new script catches all possibilities. Hopefully.

Reader Comments

Hi I tried your script yesterday, and it worked perfectly. Then I updated to Ubuntu 13.04, and now I get the ehci_hcd error, do you have any idea why?

#1 
Written By Jesper on April 30th, 2013 @ 05:29

No idea. I’ll be glad if you found out and posted another comment saying how you solved this…

#2 
Written By eli on April 30th, 2013 @ 11:29

Thanks for the info Eli, the problem that Jesper might be having is that the bus names might be slightly different. I put an updated script at https://enc.com.au/2014/02/14/resetting-usb-devices/ with a link back here because its largely your script with that change and some minor cleanups.

#3 
Written By Craig on February 14th, 2014 @ 12:43

sudo ./reset_usb
./reset_usb: line 17: echo: write error: No such device
./reset_usb: line 18: echo: write error: No such device
./reset_usb: line 21: cd: /sys/bus/pci/drivers/ehci_hcd: No such file or directory
Weird error. Failed to change directory to /sys/bus/pci/drivers/ehci_hcd

For what it’s worth. VMware loves to kill my USB for some reason.

#4 
Written By rwicks on June 25th, 2014 @ 01:38

Hmmm… Why did you use the old version?

But yes, VMware has a thing about stealing USB devices under my nose, but I didn’t know that it eliminated them too. :)

#5 
Written By eli on June 25th, 2014 @ 07:23

+1

#6 
Written By Axel on July 3rd, 2014 @ 13:48

Thanks for sharing, mate! You helped me out there. (y)

#7 
Written By alboe on August 21st, 2014 @ 11:14

Eli,

I have a wonky USB port on my Linux laptop, and it sometimes just locks up and the mouse stops working.

I tried your script above and it works like a charm. No more rebooting to fix the USB port! Thanks so much!

Cheers,

Steve

#8 
Written By Steve on September 18th, 2014 @ 01:25

Works great, one of my USB drives likes to go offline during file copies on occasion, this allowed me to get it back online so I could continue where I left off.

Thanks a ton!

#9 
Written By Adam on October 6th, 2014 @ 20:46

Great script thanks.

I have a USB UPS that goes mental randomly.
Ran the script on debian wheezy without issues.

Now I can make it part of my nut-server ups script to auto reset the usb bus once it looses communication.

#10 
Written By Kevin on November 3rd, 2014 @ 19:17

added to my Linux 14.04, it works really fine; many thanks!!!

#11 
Written By michele_s on November 10th, 2014 @ 19:13

Awesome, thank you! Saved me lots of time.

Problem: The script will choke on an empty ?hci_hcd directory, because bash for loop will use the literal string “????:??:??.?” instead of null.

Solution: in the first line of the script use:

shopt -s nullglob

Thanks again!

#12 
Written By Michael on December 18th, 2014 @ 18:23

I am getting errors on Ubuntu Server 14.04.

And the other dudes comment that had made his own fixes also didn’t work for my system. And the dudes comment of the other dudes comment had posted some github and also that didn’t work…

tzz@upuffle:~$ sudo ./resetusbs.sh
Resetting devices from /sys/bus/pci/drivers/uhci_hcd…
./resetusbs.sh: line 18: echo: write error: No such device
./resetusbs.sh: line 19: echo: write error: No such device
Resetting devices from /sys/bus/pci/drivers/xhci_hcd…

#13 
Written By Tyee Cambron on February 28th, 2015 @ 18:47

Haha ok I forgot what script I am using. I should have made multiple files for the different scripts… For your June 2014 script, I get:

tzz@upuffle:~$ sudo ./resetusbs.sh
Reseting: xhci_hcd
Not present: ehci_hcd
Reseting: uhci_hcd
sh: printf: I/O error
sh: printf: I/O error

#14 
Written By Tyee Cambron on February 28th, 2015 @ 19:07

My mouse often becomes erratic after a hibernate, and this script fixes the issue! Kubuntu 14.10

Thanks!

#15 
Written By Bart on March 12th, 2015 @ 09:39

I probably have this issue once a day. Thanks for posting your script, worked perfectly for me.

#16 
Written By DJ on March 19th, 2015 @ 16:01

worked perfect!! =D

#17 
Written By Dtripp on March 23rd, 2015 @ 22:40

Tried several other bash solutions, and 2 C scripts – neither worked on Ubuntu 14.04 running 3.13.0-48-generic.

This one did. Thanks!

#18 
Written By Victor on April 3rd, 2015 @ 10:54

Nice work!

#19 
Written By Thomas on April 18th, 2015 @ 00:15

Thank you so much, I have spent many hours looking for something like this, and now I finally found this working solution!

#20 
Written By Ingemar on June 11th, 2015 @ 08:51

I have been rebooting my system for last one or two months. But not anymore!
Thanks. :D

#21 
Written By Satthy Sivabalasingam on July 28th, 2015 @ 06:56

Another fully satisfied customer (so to speak). No more reboots for this reason thanks to you.

#22 
Written By Henrique Maia on August 17th, 2015 @ 18:09

Works on Fedora 22 & Lenovo T450s. Thanks!

#23 
Written By Zoltan Kis on August 19th, 2015 @ 09:46

I do not believe. Impressive, I had already tried everything. He stopped there.
=> usb 2-1.5: new low-speed USB device number 4 using ehci-pci
I would generally scaling device namber 5,6,7 … 16. then froze the xwindows.
I changed the script to ehci-pci and it seems that work … Thank you! you saved my day.

#24 
Written By Ricardo on September 27th, 2015 @ 10:51

Thanks, this fixed my problem of hanging usb3 controller.

I just updated it to avoid printing errors in cases where the ?hci folder is not having any busses.

#!/bin/bash

if [[ $EUID != 0 ]] ; then
echo This must be run as root!
exit 1
fi

for xhci in /sys/bus/pci/drivers/?hci_hcd ; do

if ! cd $xhci ; then
echo Weird error. Failed to change directory to $xhci
exit 1
fi

echo Resetting devices from $xhci…

for i in ????:??:??.? ; do

if [ $i == "????:??:??.?" ]; then
echo “ignoring”
continue
fi
echo “Device $xhci:$i”
echo -n “$i” > unbind
echo -n “$i” > bind
done
done

#25 
Written By Egil on November 13th, 2015 @ 10:14

this script gives an error in fedora 23:
Resetting devices from /sys/bus/pci/drivers/uhci_hcd…
Resetting devices from /sys/bus/pci/drivers/xhci_hcd…
./unplug: line 18: echo: write error: No such device
./unplug: line 19: echo: write error: No such device

#26 
Written By tony on November 22nd, 2015 @ 21:23

Works like a charm, thank you !

#27 
Written By manuel on December 8th, 2015 @ 10:37

It does reset the device.
Most likely this will fix when my USB-sound system does not work.
(Until now when it doesn’t, I unplug and replug the device).

Thanks!

#28 
Written By Stefan on December 14th, 2015 @ 19:52

you forgot “cd ..” before last “done” in forst script!

#29 
Written By mark on December 21st, 2015 @ 20:16

That would have been quite peculiar, given all the comments saying it worked for them, wouldn’t it?

So no, the loop runs on absolute paths (/sys/bus/…), so it doesn’t matter what the current directory is at the end of the loop.

#30 
Written By eli on December 21st, 2015 @ 23:10

Works perfectly for me, on Linux Mint 17.1, kernel 3.13
On lenovo Laptop… thanks for the post

#31 
Written By Ammar Shareef on December 26th, 2015 @ 10:02

I had to change ?hci_hcd to ?hci-pci on my system to get it to find the devices, but once I did that it works great on my desktop system.

#32 
Written By Keith Hearn on February 2nd, 2016 @ 04:50

Strangely enough, I don’t have *-hcd folders there. I do have a bunch of -pci folders (ehci-pci, uhci-pci and ohci-pci), which seem to contain the information you use later in the script.

This is Slackware 14.1, always a bit different from other distros, but I thought you might be interested.

#33 
Written By John on February 2nd, 2016 @ 07:39

Minor error in my previous message. Your script expects *_hcd folders, Slackware uses *-pci names. Note the underscore/normal dash.

After changing the script to ?hci-pci, the script worked fine.

Thanks!

#34 
Written By John on February 2nd, 2016 @ 07:43

worked perfect!! =D

add Reset ohci.

#35 
Written By tistructor on March 10th, 2016 @ 01:15

Thanks! I’m on a Lenovo laptop that I’m dual-booting. Every time it went to sleep in Linux, on wake my mouse would fail. I thought for a while, it was the unifying receiver for Logitech(M570 trackball), but realized it was actually not loading at the USB level, even with unplug/plug. I rebooted constantly, but it apparently isn’t a clean/full reboot, so often times it’d just fail even after a reboot. Much thanks!

#36 
Written By Paul on March 12th, 2016 @ 06:30

Thank you!! :)

This helped me greatly.

#37 
Written By Ray Reilly on March 15th, 2016 @ 14:49

Hey all, works for me on Linux Mint 17. Only had to change “?hci_hcd” to “?hci-pci” :)

#38 
Written By Henk on May 24th, 2016 @ 10:36

I had to modify your script slightly, and it worked like a charm for me. However, in June 2016, it stopped working. The script would just hang, and then I’d have to reboot. lsusb also just hangs once the mouse stops responding, so I can’t use that to check for problems.

I’m using Ubuntu 14.04 LTS with uname -r returning 3.13.0-88-generic

#39 
Written By Marya on July 19th, 2016 @ 17:35

Thank you! Great job! Worked perfectly on CentOS 7.

#40 
Written By TGNANDT on May 1st, 2017 @ 22:02

Worked perfectly, thanks.

However I would replace the line warning to run as root with:

exec sudo bash “$0″

#41 
Written By Troy Rollo on June 6th, 2017 @ 08:23

I can’t use this meethod as one of my USB devices is the memory stick the OS itself is running on (as a live CD).

Is there a means of resetting ONLY other USB devices?

#42 
Written By Shucks on September 14th, 2017 @ 02:27

Worked perfect! Thought the USB backup drive had died, replaced it, but still that “hub_port_status failed” in /var/log/messages. Ran the usb_reset script on CentOS 6.5, then the drive appeared again – and both the old and new drive worked.

#43 
Written By ErikLtz on September 14th, 2017 @ 23:34

USB speaker and microphone wasn’t available anymore in the sound manager. Ran the script and everything worked again. Great! One small issue: The script seemed to hang, so I did CTRL C, provided the password and USB was fixed.

#44 
Written By Einar Jørgensen on November 19th, 2017 @ 22:28

On VirtualBox I had USB 2.0 controller selected, so my driver directory was /sys/bus/pci/drivers/ehci-pci/.
To find correct directory use

lspci

to find id of USB controller, then search for the ID.
For example (the Id was 0c in my case):

cd /sys/bus
find . -name “*00:0c.0″

to see where your device is located. Modified script works as expected. Thanks!

#45 
Written By Marko on November 21st, 2017 @ 15:25

Almost 2018 and still working. Thank you!

#46 
Written By Hikki on December 29th, 2017 @ 23:18

> for xhci in /sys/bus/pci/drivers/?hci_hcd ; do

I had change “?hci_hcd” to “?hci-pci” to make it run.

#47 
Written By Ikem on March 21st, 2018 @ 23:48

Worked perfectly! Thought the USB backup drive had died, replaced it, but still that “hub_port_status failed” in /var/log/messages. Ran the usb_reset script on CentOS 6.5, then the drive appeared again – and both the old and new drive worked.

#48 
Written By stefnie kayelle on April 19th, 2018 @ 08:29

IF anyone is using MINT Cinnamon, This is how i had to configure the script including a pause inbetween unbind and bind…

#!/bin/bash
shopt -s nullglob
if [[ $EUID != 0 ]] ; then
echo This must be run as root!
exit 1
fi

for ehci in /sys/bus/pci/drivers/?hci-pci ; do

if ! cd $ehci ; then
echo Weird error. Failed to change directory to $ehci
exit 1
fi

echo Resetting devices from $ehci…

for i in ????:??:??.? ; do
echo -n “$i” > unbind
echo -n “$i” > bind
read -t5
done
done

Thanks to the auther for this very useful script!!!!

#49 
Written By Mark Braught on June 3rd, 2018 @ 19:00

Just another happy user! Many thanks!

#50 
Written By martin on August 27th, 2018 @ 22:04

cool!
it’s working perfectly for me on FC26!

#51 
Written By Jack on October 6th, 2018 @ 19:33

Most of the time, by unplugging and them again plugging is helpful. Because USB reset can simulate the unplug and replug operation.

#52 
Written By Error Code 0xc000000f on November 14th, 2018 @ 10:04

Thanks! I learned quite a bit from the script but eventually ended up using a Python script because I didn’t want to operate at such a low level (that’s not a judgment but a technical term :))

So here’s a high level approach…

First get some details about the particular USB device you want to reset.

>lsusb
or
>usb-devices

What we need are the vendor ID and product ID
the output of lsusb will have this info in this format:
ID 1234:5678
usb-devices spells it out more clearly:
Vendor=1234 ProdID=5678 Rev=01.00

Now install the Python package that provides USB support (pyusb)
sudo pip3 install pyusb

Create a python script with the following in it and you’re good to go:

#!/usr/bin/python3

from usb.core import find as finddev
dev = finddev(idVendor=0x1234, idProduct=0x5678)
dev.reset()

That’s it!

#53 
Written By SM on February 15th, 2019 @ 09:30

Man, it worked for me too (on a Debian Cinnamon Mint derivative, kernel 4.19.20), thank you!

Eli, is there a way to subscribe to your blog?

thank you again for publishing,
-vb

#54 
Written By Vadim on March 20th, 2019 @ 17:18

Hi,

Unfortunately, there is no subscription. It’s a pile of random posts anyhow.

Eli

#55 
Written By eli on March 20th, 2019 @ 17:25

Works on ubuntu 16.04. Thanks! This save me from countless reboot when switching between two computers with a USB switch and the logitech keyboard/mouse combo.

#56 
Written By Tintin on March 27th, 2019 @ 10:27

Great, thank you! Works perfectly with Manjaro KDE.

#57 
Written By Marcus on April 2nd, 2019 @ 07:33

Hi, i’ve been finding ways to reset USB without rebooting/physical reconnect and managed to stumble upon yours. It works wonder on uBuntu 16.04!!!

However, when i tried on a Nano Jetson, which is a arm64 architecture, the directory /sys/bus/pci/drivers/?hci_hcd do not work as the USB file was not in it BUT i do found out the directory of the USB itself.

By changing:
‘/sys/bus/pci/drivers/?hci_hcd’ to ‘/sys/bus/usb/drivers/usb’
and
‘for i in ????:??:??.? ; do’ to ‘for i in usb? ; do’
it works on both amd64 and arm64 now.

#58 
Written By steven on December 2nd, 2019 @ 09:17

Many thanks for your script! It saved me immense grief when all of my USB devices went dark on my Ubuntu 16.04 system with lots of unsaved work. Unplugging and replugging everything hadn’t had any effect, and the system put up a dialog advising me I had files open and how did I want to restart that I couldn’t dispatch because the mouse didn’t work! I ssh’d in from a laptop, and your script brought my desktop back to life – WHEW!!

Again, many thanks!!

Happy New Year – 2020, “the year of perfect vision”

#59 
Written By Fred Koschara on January 25th, 2020 @ 04:25

Many thanks, all ports are working again. It fixes my most frequent reason to reboot!

#60 
Written By Florian Hillen on July 15th, 2020 @ 08:04

Working on Linux MX19 dual boot with Windows 10 and I can finally just do a reboot without the need to power off to get USB-Ethernet-adapter to work.

THANK YOU!

#61 
Written By Peter on October 2nd, 2020 @ 16:06

Amazing! Thanks!

#62 
Written By Amir on October 9th, 2020 @ 18:42

None of these work on raspberry pi, I have both directories on Raspberry Pi, also tried python script, but I guess it detects four times the same vid,pid combination and that is why it fails to reset anything, at least for stlink v2 programmers. I use 4 of them, vid 0x0483,pid 0x3748, the same on each of them. I can distinguisg them by commandline stm8flash -S serial number option. The only solution I think there is to power cycle each one separetly . Power cycling on usb hub doesn’t work neither. Newest firmware loaded in to stlinks.

#63 
Written By Adam on January 19th, 2021 @ 11:47

The reason it doesn’t work on Raspberry Pi is that this script relies on that the USB host controllers are PCI (or PCIe) devices, and hence their drivers can be bound and unbound to these devices in /sys/bus/pci/drivers/.

I suggest looking for the relevant /sys/bus/ location on your device. The path should be quite similar.

#64 
Written By eli on January 19th, 2021 @ 13:19

Many thanks for the usbreset script! I have been looking for a solution for a once and then hanging built-in usb-hub for a very long time now and have finally found it here.

#65 
Written By Jens on March 24th, 2021 @ 13:34

I’ve been having USB issues for months, and this one script works to fix them all! Amazing, thankyou so much!

#66 
Written By Paddy on May 2nd, 2021 @ 09:22

Thanks for usbreset; works as expected on Ubuntu Mate 21.04. My networking / wifi connection drops occasionally (but not w/ other home computers) and the standard service start/restart instructions to network manager do not revive the connection. Would the same logic in usbreset work to bring back my wireless adapter? Here is a line from lspci:
03:00.0 Network controller: Qualcomm Atheros QCA9565 / AR9565 Wireless Network Adapter (rev 01)
and here is the contents of the driver ath9k:
0000:03:00.0 bind module new_id remove_id uevent unbind
Thanks in advance…

#67 
Written By Jim Haefner on January 14th, 2022 @ 04:16

Well, why don’t you give it a try and tell us all?

#68 
Written By eli on January 14th, 2022 @ 09:14

Works on MX21.1. Thanks.

#69 
Written By Alexander on May 20th, 2022 @ 03:12

Saved my ass. Thanks. (Fedora 37)

#70 
Written By Geoffrey Leach on January 12th, 2023 @ 16:50

All good thanks !
I also don’t like to reboot a linux… It is so much not the spirit…

#71 
Written By Johann on August 22nd, 2023 @ 22:49

Add a Comment

required, use real name
required, will not be published
optional, your blog address