linux_usbfs: Fallback to usbfs if device has no sysfs_dir
authorVianney le Clément de Saint-Marcq <code@quartic.eu>
Tue, 13 Dec 2016 12:57:25 +0000 (13:57 +0100)
committerNathan Hjelm <hjelmn@me.com>
Wed, 9 Jan 2019 01:20:07 +0000 (18:20 -0700)
Handle devices that are initialized with NULL as sysfs_dir.  For such
devices, the usbfs functions should be used instead of their sysfs
counterparts.

Signed-off-by: Vianney le Clément de Saint-Marcq <code@quartic.eu>
Signed-off-by: Nathan Hjelm <hjelmn@me.com>
libusb/os/linux_usbfs.c
libusb/version_nano.h

index 768e7d5..7bda951 100644 (file)
@@ -636,7 +636,7 @@ static int op_get_device_descriptor(struct libusb_device *dev,
 {
        struct linux_device_priv *priv = _device_priv(dev);
 
-       *host_endian = sysfs_has_descriptors ? 0 : 1;
+       *host_endian = (priv->sysfs_dir && sysfs_has_descriptors) ? 0 : 1;
        memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH);
 
        return 0;
@@ -756,9 +756,11 @@ static int seek_to_next_descriptor(struct libusb_context *ctx,
 }
 
 /* Return offset to next config */
-static int seek_to_next_config(struct libusb_context *ctx,
+static int seek_to_next_config(struct libusb_device *dev,
        unsigned char *buffer, int size)
 {
+       struct libusb_context *ctx = DEVICE_CTX(dev);
+       struct linux_device_priv *priv = _device_priv(dev);
        struct libusb_config_descriptor config;
 
        if (size == 0)
@@ -785,7 +787,7 @@ static int seek_to_next_config(struct libusb_context *ctx,
         * config descriptor with verified bLength fields, with descriptors
         * with an invalid bLength removed.
         */
-       if (sysfs_has_descriptors) {
+       if (priv->sysfs_dir && sysfs_has_descriptors) {
                int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG,
                                                   buffer, size);
                if (next == LIBUSB_ERROR_NOT_FOUND)
@@ -814,7 +816,6 @@ static int seek_to_next_config(struct libusb_context *ctx,
 static int op_get_config_descriptor_by_value(struct libusb_device *dev,
        uint8_t value, unsigned char **buffer, int *host_endian)
 {
-       struct libusb_context *ctx = DEVICE_CTX(dev);
        struct linux_device_priv *priv = _device_priv(dev);
        unsigned char *descriptors = priv->descriptors;
        int size = priv->descriptors_len;
@@ -830,7 +831,7 @@ static int op_get_config_descriptor_by_value(struct libusb_device *dev,
 
        /* Seek till the config is found, or till "EOF" */
        while (1) {
-               int next = seek_to_next_config(ctx, descriptors, size);
+               int next = seek_to_next_config(dev, descriptors, size);
                if (next < 0)
                        return next;
                config = (struct libusb_config_descriptor *)descriptors;
@@ -846,16 +847,16 @@ static int op_get_config_descriptor_by_value(struct libusb_device *dev,
 static int op_get_active_config_descriptor(struct libusb_device *dev,
        unsigned char *buffer, size_t len, int *host_endian)
 {
+       struct linux_device_priv *priv = _device_priv(dev);
        int r, config;
        unsigned char *config_desc;
 
-       if (sysfs_can_relate_devices) {
+       if (priv->sysfs_dir && sysfs_can_relate_devices) {
                r = sysfs_get_active_config(dev, &config);
                if (r < 0)
                        return r;
        } else {
                /* Use cached bConfigurationValue */
-               struct linux_device_priv *priv = _device_priv(dev);
                config = priv->active_config;
        }
        if (config == -1)
@@ -887,7 +888,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
 
        /* Seek till the config is found, or till "EOF" */
        for (i = 0; ; i++) {
-               r = seek_to_next_config(DEVICE_CTX(dev), descriptors, size);
+               r = seek_to_next_config(dev, descriptors, size);
                if (r < 0)
                        return r;
                if (i == config_index)
@@ -979,7 +980,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
        }
 
        /* cache descriptors in memory */
-       if (sysfs_has_descriptors)
+       if (sysfs_dir && sysfs_has_descriptors)
                fd = _open_sysfs_attr(dev, "descriptors");
        else
                fd = _get_usbfs_fd(dev, O_RDONLY, 0);
@@ -995,7 +996,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
                        return LIBUSB_ERROR_NO_MEM;
                }
                /* usbfs has holes in the file */
-               if (!sysfs_has_descriptors) {
+               if (!(sysfs_dir && sysfs_has_descriptors)) {
                        memset(priv->descriptors + priv->descriptors_len,
                               0, descriptors_size - priv->descriptors_len);
                }
@@ -1018,7 +1019,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
                return LIBUSB_ERROR_IO;
        }
 
-       if (sysfs_can_relate_devices)
+       if (sysfs_dir && sysfs_can_relate_devices)
                return LIBUSB_SUCCESS;
 
        /* cache active config */
@@ -1404,15 +1405,16 @@ static void op_close(struct libusb_device_handle *dev_handle)
 static int op_get_configuration(struct libusb_device_handle *handle,
        int *config)
 {
+       struct linux_device_priv *priv = _device_priv(handle->dev);
        int r;
 
-       if (sysfs_can_relate_devices) {
+       if (priv->sysfs_dir && sysfs_can_relate_devices) {
                r = sysfs_get_active_config(handle->dev, config);
        } else {
                r = usbfs_get_active_config(handle->dev,
                                            _device_handle_priv(handle)->fd);
                if (r == LIBUSB_SUCCESS)
-                       *config = _device_priv(handle->dev)->active_config;
+                       *config = priv->active_config;
        }
        if (r < 0)
                return r;
index 90aad01..5a0e235 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11332
+#define LIBUSB_NANO 11333