1

Sometimes I need to unplug and connect a USB flash memory device to fix a problem.

Is there a way to do it in software?

1

Save the following as usbreset.c :

/* usbreset -- send a USB port reset to a USB device */

#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");

    close(fd);
    return 0;
}

The run the following commands in terminal:

Compile the program:

$ cc usbreset.c -o usbreset

Get the Bus and Device ID of the USB device you want to reset:

$ lsusb  
Bus 002 Device 003: ID 0fe9:9010 DVICO 

Make our compiled program executable:

$ chmod +x usbreset

Execute the program with sudo privilege; make necessary substitution for <Bus> and <Device> ids as found by running the lsusb command:

$ sudo ./usbreset /dev/bus/usb/002/003  

Source: https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line

  • Thank you for making it non-programmer friendly! How does it differ from a/sys/bus/ based solution? Is it better? – unfa Sep 20 '18 at 11:16
  • Also: I have trouble finding what bus/port I need to feed to it based on a /dev/sdX device node name. – unfa Sep 20 '18 at 13:06
0

I've made a script for that. Just feed it the name of the device node in /dev/ and it'll do what you want. Save the below code to a script and use it like sudo ./reset-drive.sh sdb. It's made to only work for USB mass storage class devices, so it'll not affect anything else (hard drives, USB mice, keyboards) - that makes it safer. You can tell it to reset your hard drive - it won't work.

#!/bin/bash
drive="$1" # expects input like "sda" "sdc" etc.

cd /sys/bus/usb/drivers/usb-storage

for i in *; do
  if [[ $(udevadm info -q path -n "/dev/$drive" | grep -c "$i") == "1" ]]; then
    echo $i > unbind
    echo $i > bind
  fi
done

How does this work?

Go to the directory containing port information aboout devices in USB Mass Storage class:

cd /sys/bus/usb/drivers/usb-storage

Now evaluate all devices listed there to find one that matches the given device node.

for i in *; do
  if [[ $(udevadm info -q path -n "/dev/$drive" | grep -c "$i") == "1" ]]; 
then

Once it's found, feed the corresponding USB port path name to the unbind and bind files that are used to issue port commands:

echo $i > unbind
echo $i > bind

PS: This solution was based on the following article: http://billauer.co.il/blog/2013/02/usb-reset-ehci-uhci-linux/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.