summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2008-05-10 20:56:44 +0100
committerDaniel Drake <dsd@gentoo.org>2008-05-10 20:56:44 +0100
commit8ebb4ccdfaf5f095a1c38787d909d280ea64405c (patch)
tree8f4dda07a59ff06423abe7300d79fb55303cde98
parentc3844f7aeb2176636ce6e6ef697659fdb0b30048 (diff)
downloadlibusb-8ebb4ccdfaf5f095a1c38787d909d280ea64405c.tar.gz
Linux: fix caching of active configuration for non-sysfs
-rw-r--r--TODO1
-rw-r--r--libusb/descriptor.c48
-rw-r--r--libusb/libusbi.h2
-rw-r--r--libusb/os/linux_usbfs.c12
4 files changed, 41 insertions, 22 deletions
diff --git a/TODO b/TODO
index 2b53246..f1e4345 100644
--- a/TODO
+++ b/TODO
@@ -5,7 +5,6 @@ review functionality missing over 0.1
endianness of control setup, issues when resubmitting transfers
serialization of handle_events
internal docs for OS porters
-configuration handling
check which messages are sent during open, claim interface, close, release
unconfigured devices
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index 8814ced..f545c7f 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -557,6 +557,32 @@ err:
return NULL;
}
+/* iterate through all configurations, returning the index of the configuration
+ * matching a specific bConfigurationValue in the idx output parameter, or -1
+ * if the config was not found.
+ * returns 0 or a LIBUSB_ERROR code
+ */
+int usbi_get_config_index_by_value(struct libusb_device *dev,
+ uint8_t bConfigurationValue, int *idx)
+{
+ int i;
+
+ usbi_dbg("value %d", bConfigurationValue);
+ for (i = 0; i < dev->num_configurations; i++) {
+ unsigned char tmp[6];
+ int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp));
+ if (r < 0)
+ return r;
+ if (tmp[5] == bConfigurationValue) {
+ *idx = i;
+ return 0;
+ }
+ }
+
+ *idx = -1;
+ return 0;
+}
+
/** \ingroup desc
* Get a USB configuration descriptor with a specific bConfigurationValue.
* This is a non-blocking function which does not involve any requests being
@@ -575,26 +601,12 @@ API_EXPORTED
struct libusb_config_descriptor *libusb_get_config_descriptor_by_value(
libusb_device *dev, uint8_t bConfigurationValue)
{
- int i;
- int r;
- int found = -1;
-
- usbi_dbg("value %d", bConfigurationValue);
- for (i = 0; i < dev->num_configurations; i++) {
- unsigned char tmp[6];
- r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp));
- if (r < 0)
- return NULL;
- if (tmp[5] == bConfigurationValue) {
- found = 1;
- break;
- }
- }
-
- if (!found)
+ int idx;
+ int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
+ if (r < 0 || idx == -1)
return NULL;
else
- return libusb_get_config_descriptor(dev, i);
+ return libusb_get_config_descriptor(dev, idx);
}
/** \ingroup desc
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index c807903..a59a5e6 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -229,6 +229,8 @@ void usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
void usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
int usbi_parse_descriptor(unsigned char *source, char *descriptor, void *dest);
+int usbi_get_config_index_by_value(struct libusb_device *dev,
+ uint8_t bConfigurationValue, int *idx);
/* polling */
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 957900a..4c0fb41 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -383,10 +383,16 @@ static int cache_active_config(struct libusb_device *dev, int fd,
struct libusb_config_descriptor config;
unsigned char tmp[8];
unsigned char *buf;
+ int idx;
int r;
- /* FIXME */
- r = get_config_descriptor(fd, active_config, tmp, sizeof(tmp));
+ r = usbi_get_config_index_by_value(dev, active_config, &idx);
+ if (r < 0)
+ return r;
+ if (idx == -1)
+ return LIBUSB_ERROR_NOT_FOUND;
+
+ r = get_config_descriptor(fd, idx, tmp, sizeof(tmp));
if (r < 0) {
usbi_err("first read error %d", r);
return r;
@@ -397,7 +403,7 @@ static int cache_active_config(struct libusb_device *dev, int fd,
if (!buf)
return LIBUSB_ERROR_NO_MEM;
- r = get_config_descriptor(fd, active_config, buf, config.wTotalLength);
+ r = get_config_descriptor(fd, idx, buf, config.wTotalLength);
if (r < 0) {
free(buf);
return r;