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!

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.

Frankly speaking, I don’t understand exactly how and why this works, and I can’t even tell if this is the smoothest way to solve the issue. It doesn’t look like there are any adverse side effects, but I can’t know. On my machine, this looked just like the USB devices going off and on the bus (in /var/log/messages).

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.

#!/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 (maybe because there’s no EHCI device currently attached) and it seems like it appears as xhci on some systems. The new script catches all cases.

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

Add a Comment

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