Reset Usb Device Under Linux

· 486 words · 3 minute read

I use an USB-TV dongle to capture 433MHz signals sent out by various devices such as weather stations to display the data in a Prometheus/Grafana stack.

The dongle stops working from time to time (sometimes it’s overheating, sometimes it just stops working) and needs a power cycle. As it is cumbersome to power cycle it manually by unplugging and replugging it I was looking into a way to do the power cycle through Linux’s USB interface.

To show the connected USB devices query /sys/bus/usb/devices:

# ll /sys/bus/usb/devices
total 0
lrwxrwxrwx 1 root root 0 Nov  3  2016 1-0:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-0:1.0
lrwxrwxrwx 1 root root 0 Nov  3  2016 1-1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1:1.0
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1.1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.1
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1:1.0
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1.1:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.1/1-1.1.1:1.0
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1.3 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3
lrwxrwxrwx 1 root root 0 Feb  7 13:17 1-1.1.3:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3:1.0
lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2
lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2:1.0
lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2:1.1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2:1.1
lrwxrwxrwx 1 root root 0 Feb  7 13:17 usb1 -> ../../../devices/platform/soc/3f980000.usb/usb1

In the listing it is possible to see which device was attached last (in my case (re)plugged/powercycled):

lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2
lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2:1.0 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2:1.0
lrwxrwxrwx 1 root root 0 Apr  6 09:05 1-1.1.3.2:1.1 -> ../../../devices/platform/soc/3f980000.usb/usb1/1-1/1-1.1/1-1.1.3/1-1.1.3.2/1-1.1.3.2:1.1

The device path explained in short:

The generic form is

X-Y.Z:A.B

Each field identify the connection point of your device. The first two field are mandatory:

  • X is the USB bus of your motherboard where is connected the USB system.
  • Y is the port in use on the bus system

So the USB device identified with the string 3-3 is the device connected on the port 3 of the bus 3.

If you connect an USB hub, you are extending the connection capability of a single USB port. The Linux kernel identify this situation by appending the Z field.

  • Z is the port is use on an hub

A more detailed explanation can be found here:

This means that my device is connected to a hub on the first USB bus of my motherboard.

To perform the power cycle it is possible to echo the device path to unbind and bind the device. First I tried to powercycle the device itself, which did not work for me:

# echo "1-1.1.3.2" > /sys/bus/usb/drivers/usb/unbind
# echo "1-1.1.3.2" > /sys/bus/usb/drivers/usb/bind

What worked was to powercycle the whole USB hub:

# echo "1-1" > /sys/bus/usb/drivers/usb/unbind
# echo "1-1" > /sys/bus/usb/drivers/usb/bind

More information can be found here: