Is it possible to reset the connection of a USB device, without physically disconnecting/connecting from the PC?
Specifically, my device is a digital camera. I'm using gphoto2
, but lately I get "device read errors", so I'd like to try to do a software-reset of the connection.
From what I can tell, there are no kernel modules being loaded for the camera. The only one that looks related is usbhid
.
Save the following as
usbreset.c
The run the following commands in terminal:
Compile the program:
Get the Bus and Device ID of the USB device you want to reset:
Make our compiled program executable:
Execute the program with sudo privilege; make necessary substitution for
<Bus>
and<Device>
ids as found by running thelsusb
command: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)
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 likelsusb
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:This will reset all of USB1/2/3 attached ports[1]:
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
anduhci_hcd
are for USB1.1 ports,ehci_hcd
is for USB2 ports andxhci_hcd
is for USB3 ports. (see https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))I've created a Python script that simplifies the whole process based on answers here.
Save the script below as reset_usb.py or clone this repo.
Usage:
Script:
I needed to automate this in a python script, so I adapted LiLo's extremely helpful answer to the following:
In my case it was the cp210x driver (which I could tell from
lsmod | grep usbserial
), so you could save the above snippet as reset_usb.py and then do this:This might also be helpful if you don't already have a c compiler setup on your system, but you do have python.
Since the APT package usbutils provides the usbreset binary you can just reset the USB device by:
I'm using kind of sledgehammer by reloading the modules. This is my usb_reset.sh script:
And this is my systemd service file /usr/lib/systemd/system/usbreset.service which runs usb_reset.sh after my diplay manager has started:
Quickest way to reset will be to reset the USB controller itself. Doing so will enforce udev to unregister the device on disconnection, and register is back once you enable it.
This should work for most PC environment. However, if you are using some custom hardware you can simply iterate through the device names. With this method you don't need to find out the device name by lsusb. You can incorporate in a automated script as well.
As the special case of the question is a communication problem of gphoto2 with a camera on USB, there is an option in gphoto2 to reset its USB connection:
Maybe this option didn't exist in 2010 when the question was asked.
I made a python script which will reset a particular USB device based on the device number. You can find out the device number from command lsusb.
for example:
In this string 004 is the device number