summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2009-06-10 21:42:05 +0100
committerDaniel Drake <dsd@gentoo.org>2009-06-10 21:42:05 +0100
commit060e006e663fd59c281be29b71eb197e02b210e8 (patch)
tree3ad1a064f483b1f643ea218abba6251d7717d3a9
parentc4a905022f684da9a4a853eb9232a81a53df2652 (diff)
downloadlibusb-060e006e663fd59c281be29b71eb197e02b210e8.tar.gz
Linux: fix config descriptor parsing on big-endian systems
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.
-rw-r--r--libusb/descriptor.c1
-rw-r--r--libusb/os/linux_usbfs.c9
2 files changed, 8 insertions, 2 deletions
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index adc6220..acd7668 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -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)
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 7727ba6..08de28c 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -62,6 +62,13 @@
* 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;
}