linux: Correctly return device configuration when using usbfs
authorChris Dickens <christopher.a.dickens@gmail.com>
Wed, 6 Jan 2016 17:57:15 +0000 (09:57 -0800)
committerChris Dickens <christopher.a.dickens@gmail.com>
Sun, 24 Jan 2016 06:57:36 +0000 (22:57 -0800)
libusb_get_configuration() has been broken when using a Linux kernel
that requires the use of usbfs to obtain the current configuration
value. This commit resolves this issue and also modifies the
usbfs_get_active_config() function to update the cached active
configuration value itself instead of requiring the callers to do it.

Closes #137

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/os/linux_usbfs.c
libusb/version_nano.h

index a63852f..217a747 100644 (file)
@@ -843,6 +843,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
 /* send a control message to retrieve active configuration */
 static int usbfs_get_active_config(struct libusb_device *dev, int fd)
 {
+       struct linux_device_priv *priv = _device_priv(dev);
        unsigned char active_config = 0;
        int r;
 
@@ -864,10 +865,23 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
                /* we hit this error path frequently with buggy devices :( */
                usbi_warn(DEVICE_CTX(dev),
                        "get_configuration failed ret=%d errno=%d", r, errno);
-               return LIBUSB_ERROR_IO;
+               priv->active_config = -1;
+       } else {
+               if (active_config > 0) {
+                       priv->active_config = active_config;
+               } else {
+                       /* some buggy devices have a configuration 0, but we're
+                        * reaching into the corner of a corner case here, so let's
+                        * not support buggy devices in these circumstances.
+                        * stick to the specs: a configuration value of 0 means
+                        * unconfigured. */
+                       usbi_warn(DEVICE_CTX(dev),
+                               "active cfg 0? assuming unconfigured device");
+                       priv->active_config = -1;
+               }
        }
 
-       return active_config;
+       return LIBUSB_SUCCESS;
 }
 
 static int initialize_device(struct libusb_device *dev, uint8_t busnum,
@@ -966,28 +980,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
        }
 
        r = usbfs_get_active_config(dev, fd);
-       if (r > 0) {
-               priv->active_config = r;
-               r = LIBUSB_SUCCESS;
-       } else if (r == 0) {
-               /* some buggy devices have a configuration 0, but we're
-                * reaching into the corner of a corner case here, so let's
-                * not support buggy devices in these circumstances.
-                * stick to the specs: a configuration value of 0 means
-                * unconfigured. */
-               usbi_dbg("active cfg 0? assuming unconfigured device");
-               priv->active_config = -1;
-               r = LIBUSB_SUCCESS;
-       } else if (r == LIBUSB_ERROR_IO) {
-               /* buggy devices sometimes fail to report their active config.
-                * assume unconfigured and continue the probing */
-               usbi_warn(ctx, "couldn't query active configuration, assuming"
-                              " unconfigured");
-               priv->active_config = -1;
-               r = LIBUSB_SUCCESS;
-       } /* else r < 0, just return the error code */
-
        close(fd);
+
        return r;
 }
 
@@ -1345,6 +1339,8 @@ static int op_get_configuration(struct libusb_device_handle *handle,
        } else {
                r = usbfs_get_active_config(handle->dev,
                                            _device_handle_priv(handle)->fd);
+               if (r == LIBUSB_SUCCESS)
+                       *config = _device_priv(handle->dev)->active_config;
        }
        if (r < 0)
                return r;
index 226d5b9..ecc5375 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11026
+#define LIBUSB_NANO 11027