Linux: fix config descriptor parsing on big-endian systems
authorDaniel Drake <dsd@gentoo.org>
Wed, 10 Jun 2009 20:42:05 +0000 (21:42 +0100)
committerDaniel Drake <dsd@gentoo.org>
Wed, 10 Jun 2009 20:42:05 +0000 (21:42 +0100)
Multi-byte fields in the configuration descriptors that come back from
usbfs are always in bus endian format.

Thanks to Joe Jezak for help investigating and fixing this.

libusb/descriptor.c
libusb/os/linux_usbfs.c

index adc6220..acd7668 100644 (file)
@@ -559,6 +559,7 @@ API_EXPORTED int libusb_get_config_descriptor(libusb_device *dev,
                goto err;
        }
 
+       host_endian = 0;
        r = usbi_backend->get_config_descriptor(dev, config_index, buf,
                _config->wTotalLength, &host_endian);
        if (r < 0)
index 7727ba6..08de28c 100644 (file)
  * included as of Linux 2.6.26.
  */
 
+/* endianness for multi-byte fields:
+ *
+ * Descriptors exposed by usbfs have the multi-byte fields in the device
+ * descriptor as host endian. Multi-byte fields in the other descriptors are
+ * bus-endian. The kernel documentation says otherwise, but it is wrong.
+ */
+
 static const char *usbfs_path = NULL;
 
 /* do we have a busnum to relate devices? this also implies that we can read
@@ -439,7 +446,6 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
        if (sysfs_has_descriptors) {
                return sysfs_get_active_config_descriptor(dev, buffer, len);
        } else {
-               *host_endian = 1;
                return usbfs_get_active_config_descriptor(dev, buffer, len);
        }
 }
@@ -504,7 +510,6 @@ static int op_get_config_descriptor(struct libusb_device *dev,
 
        r = get_config_descriptor(DEVICE_CTX(dev), fd, config_index, buffer, len);
        close(fd);
-       *host_endian = 1;
        return r;
 }