diff options
author | Chris Dickens <christopher.a.dickens@gmail.com> | 2016-01-06 09:57:15 -0800 |
---|---|---|
committer | Chris Dickens <christopher.a.dickens@gmail.com> | 2016-01-23 22:57:36 -0800 |
commit | ba73390b74cd6af292017b88e3a95fb5b8223c85 (patch) | |
tree | 32411da44063271fd2460ab33fd8f4dc7eb4fd2a | |
parent | d7cf58bafb9c77514db3381e115dae5129ffba2d (diff) | |
download | libusb-ba73390b74cd6af292017b88e3a95fb5b8223c85.tar.gz |
linux: Correctly return device configuration when using usbfs
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>
-rw-r--r-- | libusb/os/linux_usbfs.c | 42 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
2 files changed, 20 insertions, 24 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index a63852f..217a747 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -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; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 226d5b9..ecc5375 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11026 +#define LIBUSB_NANO 11027 |