Resetting the USB Bus under linux

Posted by Benjamin Close on September 15, 2008 under UniSA | 15 Comments to Read

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);
        }
      }
}



Donations keep this site alive

  • avatar

    Peter said,

    Echt toll…und was soll #include ohne Angabe der include Datei???

  • avatar

    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>

  • avatar

    Benjamin Close said,

    Oops, I believe the two includes are correct – article updated, thanks!

  • avatar

    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 [...]

  • avatar

    Charlotte said,

    Thanks for sharing this. It really works! Thanks again, keep it up!

  • avatar

    RaspBooth – erste Klasse fertig | carsten-franz.eu said,

    [...] anspreche. Da sich meine Kamera totgestellt hatte, nachdem ich ein Foto gemacht habe, setze ich resetusb [...]

  • avatar

    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 [...]

  • avatar

    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.

  • avatar

    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

  • avatar

    Ade Malsasa Akbar said,

    Thank you from Indonesia. I will try and come back soon to report :)

  • avatar

    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.

  • avatar

    Benjamin Close said,

    Try linking in the usb libraries: -lusb or was it -lusbcore .. I can’t remember any more :(

  • avatar

    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.

  • avatar

    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.

  • avatar

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

Add A Comment

*