How do you reset a USB device from the command line?
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 thelsusb
command:$ sudo ./usbreset /dev/bus/usb/002/003
Source of above program: http://marc.info/?l=linux-usb&m=121459435621262&w=2
I haven't found myself in your specific circumstances before, so I'm not sure if it'll do enough, but the simplest way I've found to reset a USB device is this command: (No external apps necessary)
sudo sh -c "echo 0 > /sys/bus/usb/devices/1-4.6/authorized"
sudo sh -c "echo 1 > /sys/bus/usb/devices/1-4.6/authorized"
That's the actual one I use to reset my Kinect since libfreenect seems to have no API for putting it back to sleep. It's on my Gentoo box, but the kernel should be new enough to use the same path structure for sysfs.
Yours obviously wouldn't be 1-4.6
but you can either pull that device path from your kernel log (dmesg
) or you can use something like lsusb
to get the vendor and product IDs and then use a quick command like this to list how the paths relate to different vendor/product ID pairs:
for X in /sys/bus/usb/devices/*; do
echo "$X"
cat "$X/idVendor" 2>/dev/null
cat "$X/idProduct" 2>/dev/null
echo
done
This will reset all of USB1/2/3 attached ports[1]:
for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
[ -e "$i" ] || continue
echo "${i##*/}" > "${i%/*}/unbind"
echo "${i##*/}" > "${i%/*}/bind"
done
I believe this will solve your problem. If you do not want to reset all of the USB endpoints, you can use appropriate device ID from /sys/bus/pci/drivers/ehci_hcd
Notes:
[1]: the *hci_hcd
kernel drivers typically control the USB ports. ohci_hcd
and uhci_hcd
are for USB1.1 ports, ehci_hcd
is for USB2 ports and xhci_hcd
is for USB3 ports. (see https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))