summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-05-23 19:51:07 +0200
committerHans de Goede <hdegoede@redhat.com>2013-05-24 16:30:38 +0200
commit6b41074352bec3e8fe132fc74768da8e930a2ab5 (patch)
treef7aacea9e3024a4b7024f3c4080018dcd179831c
parentda5b335e0c01650818d8e85973728e288c1f409d (diff)
downloadlibusb-6b41074352bec3e8fe132fc74768da8e930a2ab5.tar.gz
all: Allow backend to provide a better get_config_descriptor_by_value
Our core get_config_descriptor_by_value is not exactly pretty nor efficient, allow the backends to provide something better. Note that the callback signature differs from get_config_descriptor in that backend owned memory gets returned. This saves a needless malloc + memcpy + free. If this turns out to be a problem for some backends we can always change things to work like get_config_descriptor. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--libusb/descriptor.c14
-rw-r--r--libusb/libusbi.h16
-rw-r--r--libusb/os/linux_usbfs.c13
-rw-r--r--libusb/os/openbsd_usb.c1
-rw-r--r--libusb/os/wince_usb.c1
-rw-r--r--libusb/os/windows_usb.c1
-rw-r--r--libusb/version_nano.h2
7 files changed, 39 insertions, 9 deletions
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index 5fb96ea..44d93ee 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -678,8 +678,18 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
{
- int idx;
- int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
+ int r, idx, host_endian;
+ unsigned char *buf = NULL;
+
+ if (usbi_backend->get_config_descriptor_by_value) {
+ r = usbi_backend->get_config_descriptor_by_value(dev,
+ bConfigurationValue, &buf, &host_endian);
+ if (r < 0)
+ return r;
+ return raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
+ }
+
+ r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
if (r < 0)
return r;
else if (idx == -1)
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index bf240e8..090ac5b 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -665,6 +665,22 @@ struct usbi_os_backend {
uint8_t config_index, unsigned char *buffer, size_t len,
int *host_endian);
+ /* Like get_config_descriptor but then by bConfigurationValue instead
+ * of by index.
+ *
+ * Optional, if not present the core will call get_config_descriptor
+ * for all configs until it finds the desired bConfigurationValue.
+ *
+ * Returns a pointer to the raw-descriptor in *buffer, this memory
+ * is valid as long as device is valid.
+ *
+ * Returns the length of the returned raw-descriptor on success,
+ * or a LIBUSB_ERROR code on failure.
+ */
+ int (*get_config_descriptor_by_value)(struct libusb_device *device,
+ uint8_t bConfigurationValue, unsigned char **buffer,
+ int *host_endian);
+
/* Get the bConfigurationValue for the active configuration for a device.
* Optional. This should only be implemented if you can retrieve it from
* cache (don't generate I/O).
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 280e312..57ab80c 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -701,8 +701,8 @@ static int seek_to_next_config(struct libusb_context *ctx,
}
}
-static int get_config_descriptor_by_value(struct libusb_device *dev,
- unsigned char **buffer, uint8_t value)
+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);
@@ -711,6 +711,8 @@ static int get_config_descriptor_by_value(struct libusb_device *dev,
struct libusb_config_descriptor *config;
*buffer = NULL;
+ /* Unlike the device desc. config descs. are always in raw format */
+ *host_endian = 0;
/* Skip device header */
descriptors += DEVICE_DESC_LENGTH;
@@ -737,9 +739,6 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
int r, config;
unsigned char *config_desc;
- /* Unlike the device desc. config descs. are always in raw format */
- *host_endian = 0;
-
if (sysfs_can_relate_devices) {
r = sysfs_get_active_config(dev, &config);
if (r < 0)
@@ -752,7 +751,8 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
if (config == -1)
return LIBUSB_ERROR_NOT_FOUND;
- r = get_config_descriptor_by_value(dev, &config_desc, config);
+ r = op_get_config_descriptor_by_value(dev, config, &config_desc,
+ host_endian);
if (r < 0)
return r;
@@ -2458,6 +2458,7 @@ const struct usbi_os_backend linux_usbfs_backend = {
.get_device_descriptor = op_get_device_descriptor,
.get_active_config_descriptor = op_get_active_config_descriptor,
.get_config_descriptor = op_get_config_descriptor,
+ .get_config_descriptor_by_value = op_get_config_descriptor_by_value,
.open = op_open,
.close = op_close,
diff --git a/libusb/os/openbsd_usb.c b/libusb/os/openbsd_usb.c
index 06aaff4..e1c91f4 100644
--- a/libusb/os/openbsd_usb.c
+++ b/libusb/os/openbsd_usb.c
@@ -99,6 +99,7 @@ const struct usbi_os_backend openbsd_backend = {
obsd_get_device_descriptor,
obsd_get_active_config_descriptor,
obsd_get_config_descriptor,
+ NULL, /* get_config_descriptor_by_value() */
obsd_get_configuration,
obsd_set_configuration,
diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c
index 2e6eedd..f1f64ac 100644
--- a/libusb/os/wince_usb.c
+++ b/libusb/os/wince_usb.c
@@ -984,6 +984,7 @@ const struct usbi_os_backend wince_backend = {
wince_get_device_descriptor,
wince_get_active_config_descriptor,
wince_get_config_descriptor,
+ NULL, /* get_config_descriptor_by_value() */
wince_get_configuration,
wince_set_configuration,
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 061a0f8..3eb5585 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -2275,6 +2275,7 @@ const struct usbi_os_backend windows_backend = {
windows_get_device_descriptor,
windows_get_active_config_descriptor,
windows_get_config_descriptor,
+ NULL, /* get_config_descriptor_by_value() */
windows_get_configuration,
windows_set_configuration,
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 0d49847..c29c8ff 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10713
+#define LIBUSB_NANO 10714