Updated netlink code to parse events that do not contain BUSNUM and
authorJustin Bischoff <justin.bischoff@ciinow.com>
Wed, 26 Mar 2014 19:00:20 +0000 (12:00 -0700)
committerNathan Hjelm <hjelmn@me.com>
Tue, 8 Apr 2014 04:36:50 +0000 (22:36 -0600)
  DEVNUM but do have a DEVICE parameter.

 These netlink events are now parsed:
 >>>>>>>>>>>>>>>>>
 add@/devices/platform/brcm-ohci-0.0/usb3/3-2/3-2:1.0
 ACTION=add
 DEVPATH=/devices/platform/brcm-ohci-0.0/usb3/3-2/3-2:1.0
 SUBSYSTEM=usb
 SEQNUM=290
 PHYSDEVBUS=usb
 DEVICE=/proc/bus/usb/003/003
 PRODUCT=45e/28e/114
 TYPE=255/255/255
 INTERFACE=255/93/1
 <<<<<<<<<<<<<<<<<

 Also added a retry when opening the device file to work around a race condition with the kernel

libusb/os/linux_netlink.c
libusb/os/linux_usbfs.c
libusb/version_nano.h

index f1c1be1..306f0b4 100644 (file)
@@ -224,8 +224,32 @@ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const ch
 
        tmp = netlink_message_parse(buffer, len, "BUSNUM");
        if (NULL == tmp) {
-               /* no bus number (likely a usb interface). ignore*/
-               return -1;
+               /* no bus number. try "DEVICE" */
+               tmp = netlink_message_parse(buffer, len, "DEVICE");
+               if (NULL == tmp) {
+                       /* not usb. ignore */
+                       return -1;
+               }
+               
+               /* Parse a device path such as /dev/bus/usb/003/004 */
+               char *pLastSlash = (char*)strrchr(tmp,'/');
+               if(NULL == pLastSlash) {
+                       return -1;
+               }
+
+               *devaddr = strtoul(pLastSlash + 1, NULL, 10);
+               if (errno) {
+                       errno = 0;
+                       return -1;
+               }
+               
+               *busnum = strtoul(pLastSlash - 3, NULL, 10);
+               if (errno) {
+                       errno = 0;
+                       return -1;
+               }
+               
+               return 0;
        }
 
        *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
index 50c9161..5ad6129 100644 (file)
@@ -184,6 +184,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
        struct libusb_context *ctx = DEVICE_CTX(dev);
        char path[PATH_MAX];
        int fd;
+       int delay = 10000;
 
        if (usbdev_names)
                snprintf(path, PATH_MAX, "%s/usbdev%d.%d",
@@ -196,6 +197,18 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
        if (fd != -1)
                return fd; /* Success */
 
+       if (errno == ENOENT) {
+               if (!silent) 
+                       usbi_err(ctx, "File doesn't exist, wait %d ms and try again\n", delay/1000);
+   
+               /* Wait 10ms for USB device path creation.*/
+               usleep(delay);
+
+               fd = open(path, mode);
+               if (fd != -1)
+                       return fd; /* Success */
+       }
+       
        if (!silent) {
                usbi_err(ctx, "libusb couldn't open USB device %s: %s",
                         path, strerror(errno));
index 0a01033..ce329f2 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10877
+#define LIBUSB_NANO 10878