Add libusb_set_configuration()
authorDaniel Drake <dsd@gentoo.org>
Sat, 3 May 2008 15:24:11 +0000 (16:24 +0100)
committerDaniel Drake <dsd@gentoo.org>
Sat, 3 May 2008 15:28:51 +0000 (16:28 +0100)
libusb/core.c
libusb/libusb.h
libusb/libusbi.h
libusb/os/linux_usbfs.c

index d13f434..3924eb2 100644 (file)
@@ -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.
  *
index 44202c9..e1dcf3a 100644 (file)
@@ -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);
 
index 69e565a..611f62b 100644 (file)
@@ -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);
 
index a2b792c..5849864 100644 (file)
@@ -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,