From 0f463fe671455670efcf4a93e526b2a9082b0afe Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sat, 3 May 2008 16:24:11 +0100 Subject: [PATCH] Add libusb_set_configuration() --- libusb/core.c | 25 +++++++++++++++++++++++++ libusb/libusb.h | 8 ++++++-- libusb/libusbi.h | 2 ++ libusb/os/linux_usbfs.c | 17 +++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/libusb/core.c b/libusb/core.c index d13f434..3924eb2 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -541,6 +541,31 @@ API_EXPORTED libusb_device *libusb_get_device(libusb_device_handle *dev_handle) } /** \ingroup dev + * Set the active configuration for a device. The operating system may have + * already set an active configuration on the device, but for portability + * reasons you should use this function to select the configuration you want + * before claiming any interfaces. + * + * If you wish to change to another configuration at some later time, you + * must release all claimed interfaces using libusb_release_interface() before + * setting a new active configuration. + * + * \param dev a device handle + * \param configuration the bConfigurationValue of the configuration you + * wish to activate + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist + * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed + * \returns another LIBUSB_ERROR code on other failure + */ +API_EXPORTED int libusb_set_configuration(libusb_device_handle *dev, + int configuration) +{ + usbi_dbg("configuration %d", configuration); + return usbi_backend->set_configuration(dev, configuration); +} + +/** \ingroup dev * Claim an interface on a given device handle. You must claim the interface * you wish to use before you can perform I/O on any of its endpoints. * diff --git a/libusb/libusb.h b/libusb/libusb.h index 44202c9..e1dcf3a 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -522,8 +522,9 @@ enum libusb_error { LIBUSB_ERROR_INVALID_PARAM = -2, LIBUSB_ERROR_ACCESS = -3, LIBUSB_ERROR_NOT_FOUND = -4, - LIBUSB_ERROR_NO_MEM = -5, - LIBUSB_ERROR_OTHER = -6, + LIBUSB_ERROR_BUSY = -5, + LIBUSB_ERROR_NO_MEM = -6, + LIBUSB_ERROR_OTHER = -7, }; /** \ingroup asyncio @@ -648,12 +649,15 @@ uint8_t libusb_get_device_address(libusb_device *dev); libusb_device_handle *libusb_open(libusb_device *dev); void libusb_close(libusb_device_handle *dev_handle); libusb_device *libusb_get_device(libusb_device_handle *dev_handle); + +int libusb_set_configuration(libusb_device_handle *dev, int configuration); int libusb_claim_interface(libusb_device_handle *dev, int iface); int libusb_release_interface(libusb_device_handle *dev, int iface); libusb_device_handle *libusb_open_device_with_vid_pid(uint16_t vendor_id, uint16_t product_id); + int libusb_set_interface_altsetting(libusb_device_handle *dev, int iface, int altsetting); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 69e565a..611f62b 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -273,6 +273,8 @@ struct usbi_os_backend { int (*open)(struct libusb_device_handle *handle); void (*close)(struct libusb_device_handle *handle); + int (*set_configuration)(struct libusb_device_handle *handle, int config); + int (*claim_interface)(struct libusb_device_handle *handle, int iface); int (*release_interface)(struct libusb_device_handle *handle, int iface); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index a2b792c..5849864 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -421,6 +421,22 @@ static void op_close(struct libusb_device_handle *dev_handle) close(fd); } +static int op_set_configuration(struct libusb_device_handle *handle, int config) +{ + int fd = __device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_SETCONFIG, &config); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + + usbi_err("failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + static int op_claim_interface(struct libusb_device_handle *handle, int iface) { int fd = __device_handle_priv(handle)->fd; @@ -1096,6 +1112,7 @@ const struct usbi_os_backend linux_usbfs_backend = { .get_device_list = op_get_device_list, .open = op_open, .close = op_close, + .set_configuration = op_set_configuration, .claim_interface = op_claim_interface, .release_interface = op_release_interface, -- 2.7.4