Sunday, October 9, 2016

How to reset usb device from console (for example, usb wi-fi device)

I use external USB wi-fi for my desktop with Ubuntu. Occasionally after waking up this device does not work. I do not know the cause root of the issue, but there are several solution to relieve: pull out and then put in the device into usb port, or do the same thing programmatically as described below. Create a file usbreset.c (I placed it to ~/src/usbreset):
/* usbreset -- send a USB port reset to a USB device
 * Source:

/* How to find device name:
 *  lsusb
 * Find your device in the output, see the "Bus" and "Device numbers"
 * Device name is
 *  /dev/bus/usb/<bus>/<device number>
 * For example,
 *  /dev/bus/usb/001/001

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/usbdevice_fs.h>

int main(int argc, char **argv)
    const char *filename;
    int fd;
    int rc;

    if (argc != 2) {
        fprintf(stderr, "Usage: usbreset device-filename\n");
        return 1;
    filename = argv[1];

    fd = open(filename, O_WRONLY);
    if (fd < 0) {
        perror("Error opening output file");
        return 1;

    printf("Resetting USB device %s\n", filename);
    rc = ioctl(fd, USBDEVFS_RESET, 0);
    if (rc < 0) {
        perror("Error in ioctl");
        return 1;
    printf("Reset successful\n");

    return 0;
Source of this code

Compile the code:

cc usbreset.c -o usbreset
Make the file executable
chmod +x usbreset
Then, you can repeat the steps from this answer every time you need to restart the device. But you need to run manually lsusb, generate path to the device, and input superuser password every time. You can automatize this. We need to change owner to root and set setuid bit on the executable:
sudo chown root:root ~/src/usbreset/usbreset
sudo chmod 4755 usbreset
We can see
$ ls -l usbreset
-rwsr-xr-x 1 root root 8906 Sep 16  2015 usbreset
My PATH contains ~/bin directory, so in ~/bin I create symlink to the executable
ln -s ~/src/usbreset/usbreset usbreset-bin
$ ll usbreset-bin 
lrwxrwxrwx 1 alex alex 32 Oct  9 12:46 usbreset-bin -> /home/alex/src/usbreset/usbreset*
Create a file usbreset in ~/bin

import subprocess

devices = subprocess.check_output(['lsusb']).splitlines()
wifi_devices = filter(lambda x: '802.11n' in x, devices)
assert len(wifi_devices) == 1
wifi_device = wifi_devices[0]
items = wifi_device.split(":")[0].split(" ")
assert len(items) == 4
assert items[0] == "Bus"
bus = items[1]
assert items[2] == "Device"
device = items[3]

device_path = "/dev/bus/usb/{bus}/{device}".format(bus = bus, device = device)"/home/alex/bin/usbreset-bin", device_path))
You need to change "/home/alex" path to your home directory. Then, you can just run
in console for usb wi-fi resetting.

No comments:

Post a Comment