Resetting the USB Bus under linux
Today Snappy, the little photo box we have taking photos of the new Bruce Lab, broke again. Hence I quickly came up with a way of resetting the USB device under linux based on libusb. Sadly whilst I can confirm this does reset the device gphoto2 still doesn’t like our little Canon Ixus 400 and we still get timeouts after about 12 hours of taking photos – 1 photo every 2 minutes. Below is the hack of a program I used.
To compile use: gcc -o outputname resetusb.c -lusb
#include <stdio.h> #include <usb.h> int main(void) { struct usb_bus *busses; usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); struct usb_bus *bus; int c, i, a; /* ... */ for (bus = busses; bus; bus = bus->next) { struct usb_device *dev; int val; usb_dev_handle *junk; for (dev = bus->devices; dev; dev = dev->next) { char buf[1024]; junk = usb_open ( dev ); usb_get_string_simple(junk,2,buf,1023); if ( junk == NULL ){ printf("Can't open %p (%s)\n", dev, buf ); } else { val = usb_reset(junk); printf( "reset %p %d (%s)\n", dev, val, buf ); } usb_close(junk); } } }
Peter said,
Echt toll…und was soll #include ohne Angabe der include Datei???
Ray said,
The libraries referenced in the #include statements don’t show up on the web page (presumably because the lt / gt characters cause it to be interpreted as an HTML tag).
Just guessing, but I think they need to be:
#include <stdio.h>
#include <usb.h>
Benjamin Close said,
Oops, I believe the two includes are correct – article updated, thanks!
can't access USB disk now and then said,
[…] USB stack. I've used the following in the past when doing some USB work on a development platform: http://www.clearchain.com/blog/posts…us-under-linux It works fairly well, but doesn't recover from all conditions of course. The main issue might be […]
Charlotte said,
Thanks for sharing this. It really works! Thanks again, keep it up!
RaspBooth – erste Klasse fertig | carsten-franz.eu said,
[…] anspreche. Da sich meine Kamera totgestellt hatte, nachdem ich ein Foto gemacht habe, setze ich resetusb […]
resetusb auf dem Raspberry Pi compilieren | carsten-franz.eu said,
[…] Möglichkeit gesucht die USB-Ports zurückzusetzen. Über Google bin ich dann auf einen Post von Benjamin Close gestoßen der eine Umsetzung in C beschrieben […]
David Pendell said,
This doesn’t appear to support USB 3.0. You wouldn’t happen to know how to add that would you?
d.p.
Benjamin Close said,
Hmm, haven’t needed this in a while. For USB 3.0 you could try:
http://davidjb.com/blog/2012/06/restartreset-usb-in-ubuntu-12-04-without-rebooting
Ade Malsasa Akbar said,
Thank you from Indonesia. I will try and come back soon to report 🙂
Ade Malsasa Akbar said,
I am back. I use gcc and Geany duet, compile your code and meet this:
gcc -Wall -o “resetusb” “resetusb.c” (in directory: /home/master)
resetusb.c: In function ‘main’:
resetusb.c:12:17: warning: unused variable ‘a’ [-Wunused-variable]
resetusb.c:12:14: warning: unused variable ‘i’ [-Wunused-variable]
resetusb.c:12:11: warning: unused variable ‘c’ [-Wunused-variable]
resetusb.c:31:1: warning: control reaches end of non-void function [-Wreturn-type]
/tmp/ccI2EJkr.o: In function `main’:
resetusb.c:(.text+0x1c): undefined reference to `usb_init’
resetusb.c:(.text+0x21): undefined reference to `usb_find_busses’
resetusb.c:(.text+0x26): undefined reference to `usb_find_devices’
resetusb.c:(.text+0x2b): undefined reference to `usb_get_busses’
resetusb.c:(.text+0x5b): undefined reference to `usb_open’
resetusb.c:(.text+0x83): undefined reference to `usb_get_string_simple’
resetusb.c:(.text+0xb5): undefined reference to `usb_reset’
resetusb.c:(.text+0xea): undefined reference to `usb_close’
collect2: ld returned 1 exit status
Compilation failed.
I already have libusb-dev. I use Ubuntu 12.04 as my system. How to fix this? Thank you.
Benjamin Close said,
Try linking in the usb libraries: -lusb or was it -lusbcore .. I can’t remember any more 🙁
Ade Malsasa Akbar said,
Hello, Benjamin. I inform you today that I have done. It works, works like charm on my Ubuntu 12.04 32 bit. I have missed your instruction:
gcc -o outputname resetusb.c -lusb
at first time I see this page. Thank you. I have copied this program into /usr/bin and I can call it via sudo resetusb. And it works! Thank you from Indonesia.
Joseph Graham said,
This really fixes my mobile broadband card which breaks every few hours! But is there a way to reset only that specific device rather than every USB device?
I tried http://tiebing.blogspot.co.uk/2011/07/simulate-unplug-usb-device-on-linux-usb.html and it resets only one device but it doesn’t actually fix my broadband card.
Benjamin Close said,
The source code simply enumerates every usb device and resets it. If you only want one device, you could do something like:
....
if ( junk == NULL ){
printf("Can't open %p (%s)\n", dev, buf );
} else if (strcmp(buf,"WHAT EVER THE DEVICE NAME IS")==0){
val = usb_reset(junk);
printf( "reset %p %d (%s)\n", dev, val, buf );
}
....
To find out what to put in the WHAT EVER THE DEVICE NAME IS just print it out:
printf("Device name is: %s\n", buf);
mariusz said,
It works! Thanks a lot 🙂
RaspBooth – erste Klasse fertig | carsten-franz.eu said,
[…] anspreche. Da sich meine Kamera totgestellt hatte, nachdem ich ein Foto gemacht habe, setze ich resetusb […]
Add A Comment