简体   繁体   中英

C - how can i reset the USB Bus under linux?

Daily--about 5 to 10 times--my USB camera disappears from the system. It's been happening from day 1 because the manufacturer driver is not compatible with Linux. lsusb and dmesg show it correctly at first, but after a longer period of time sometimes it disappears. The best solution to fix it is to reset the USB interface for that camera to get it back. I did it a few times manually using the C source code and it worked, but when I am doing it in a Bash loop it seems it's failing over and over. Any idea?

How can I make both programs work, so that I get my /dev/video0 or 1 or 2 always available?

Step 1: Resetting the USB bus under Linux using this code:

/* few times it's resetting but when I use it in a Bash loop it's not doing it */
#include <stdio.h>
#include <usb.h>

int main(int argc, char *argv[]) {
  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);

      switch(argc) {
       case 1:
        if ( junk == NULL ) {
          printf("Can't open %p (%s)\n", dev, buf );
        } else if (strcmp(buf,"HD Pro Webcam C920")==0) {
          val = usb_reset(junk);
          printf( "reset %p %d (%s)\n", dev, val, buf );
        }
        break;

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

Step 2: Running as scanner - to make sure video0 or 1 or 2 is available, if not available resetting the USB bus

#!/bin/bash
j=true
while $j
do
  for i in 0 1 2
  do
    tmp="/dev/video$i"
    if [ -e $tmp ]
    then
      echo "/dev/video$i"
      j=false
    else
      echo "NO - camera found - restarting the USB $i"
      echo ROOT_PASSWORD_TO_EXECUTE | sudo -S /var/tmp/c-restartusb/restartusb
    fi
  done
done
echo "Camera - logic ended, expecting the camera is available now"

Step 3: Still it's not available?

NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1
NO - camera found - restart the USB 2
NO - camera found - restart the USB 0
NO - camera found - restart the USB 1

Don't sure your reset usb code right...

Can you find the usb device ?

If you can, try below:

BTW, This code is from here . should be work if you can find the usb node:

/* 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;
}

If you can't, you maybe want to rescan to find the usb device like this:

echo 1 > /sys/dev/block/8:16/device/rescan

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM