Add functionality to clear endpoint halt conditions
authorDaniel Drake <dsd@gentoo.org>
Sun, 4 May 2008 12:46:41 +0000 (13:46 +0100)
committerDaniel Drake <dsd@gentoo.org>
Sun, 4 May 2008 12:46:41 +0000 (13:46 +0100)
libusb/core.c
libusb/libusb.h
libusb/libusbi.h
libusb/os/linux_usbfs.c

index 59df43e..f5e0238 100644 (file)
@@ -674,6 +674,26 @@ API_EXPORTED int libusb_set_interface_alt_setting(libusb_device_handle *dev,
                alternate_setting);
 }
 
+/** \ingroup dev
+ * Clear the halt/stall condition for an endpoint. Endpoints with halt status
+ * are unable to receive or transmit data until the halt condition is stalled.
+ *
+ * You should cancel all pending transfers before attempting to clear the halt
+ * condition.
+ *
+ * \param dev a device handle
+ * \param endpoint the endpoint to clear halt status
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+API_EXPORTED int libusb_clear_halt(libusb_device_handle *dev,
+       unsigned char endpoint)
+{
+       usbi_dbg("endpoint %x", endpoint);
+       return usbi_backend->clear_halt(dev, endpoint);
+}
+
 /** \ingroup lib
  * Initialize libusb. This function must be called before calling any other
  * libusb function.
index b69dd7f..b376fdc 100644 (file)
@@ -657,9 +657,9 @@ 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_alt_setting(libusb_device_handle *dev,
        int interface_number, int alternate_setting);
+int libusb_clear_halt(libusb_device_handle *dev, unsigned char endpoint);
 
 /* async I/O */
 
index 611f62b..c912632 100644 (file)
@@ -280,6 +280,8 @@ struct usbi_os_backend {
 
        int (*set_interface_altsetting)(struct libusb_device_handle *handle,
                int iface, int altsetting);
+       int (*clear_halt)(struct libusb_device_handle *handle,
+               unsigned char endpoint);
 
        void (*destroy_device)(struct libusb_device *dev);
 
index d1c1100..0066910 100644 (file)
@@ -485,6 +485,22 @@ static int op_set_interface(struct libusb_device_handle *handle, int iface,
        return 0;
 }
 
+static int op_clear_halt(struct libusb_device_handle *handle,
+       unsigned char endpoint)
+{
+       int fd = __device_handle_priv(handle)->fd;
+       int r = ioctl(fd, IOCTL_USBFS_CLEAR_HALT, &endpoint);
+       if (r) {
+               if (errno == ENOENT)
+                       return LIBUSB_ERROR_NOT_FOUND;
+
+               usbi_err("clear_halt failed error %d errno %d", r, errno);
+               return LIBUSB_ERROR_OTHER;
+       }
+
+       return 0;
+}
+
 static void op_destroy_device(struct libusb_device *dev)
 {
        unsigned char *nodepath = __device_priv(dev)->nodepath;
@@ -1124,6 +1140,7 @@ const struct usbi_os_backend linux_usbfs_backend = {
        .release_interface = op_release_interface,
 
        .set_interface_altsetting = op_set_interface,
+       .clear_halt = op_clear_halt,
 
        .destroy_device = op_destroy_device,