implement libusb_reset_device()
authorDaniel Drake <dsd@gentoo.org>
Sun, 4 May 2008 13:10:19 +0000 (14:10 +0100)
committerDaniel Drake <dsd@gentoo.org>
Sun, 4 May 2008 13:10:19 +0000 (14:10 +0100)
libusb/core.c
libusb/libusb.h
libusb/libusbi.h
libusb/os/linux_usbfs.c

index f5e0238..2dce681 100644 (file)
@@ -694,6 +694,28 @@ API_EXPORTED int libusb_clear_halt(libusb_device_handle *dev,
        return usbi_backend->clear_halt(dev, endpoint);
 }
 
+/** \ingroup dev
+ * Perform a USB port reset to reinitialize a device. The system will attempt
+ * to restore the previous configuration and alternate settings after the
+ * reset has completed.
+ *
+ * If the reset fails, the descriptors change, or the previous state cannot be
+ * restored, the device will appear to be disconnected and reconnected. This
+ * means that the device handle is no longer valid (you should close it) and
+ * rediscover the device. A return code of LIBUSB_ERROR_NOT_FOUND indicates
+ * when this is the case.
+ *
+ * \param dev a handle of the device to reset
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if re-enumeration is required
+ * \returns another LIBUSB_ERROR code on other failure
+ */
+API_EXPORTED int libusb_reset_device(libusb_device_handle *dev)
+{
+       usbi_dbg("");
+       return usbi_backend->reset_device(dev);
+}
+
 /** \ingroup lib
  * Initialize libusb. This function must be called before calling any other
  * libusb function.
index b376fdc..06a1a64 100644 (file)
@@ -660,6 +660,7 @@ libusb_device_handle *libusb_open_device_with_vid_pid(uint16_t vendor_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);
+int libusb_reset_device(libusb_device_handle *dev);
 
 /* async I/O */
 
index c912632..bf4aa19 100644 (file)
@@ -282,6 +282,7 @@ struct usbi_os_backend {
                int iface, int altsetting);
        int (*clear_halt)(struct libusb_device_handle *handle,
                unsigned char endpoint);
+       int (*reset_device)(struct libusb_device_handle *handle);
 
        void (*destroy_device)(struct libusb_device *dev);
 
index 0066910..e67d7b6 100644 (file)
@@ -501,6 +501,21 @@ static int op_clear_halt(struct libusb_device_handle *handle,
        return 0;
 }
 
+static int op_reset_device(struct libusb_device_handle *handle)
+{
+       int fd = __device_handle_priv(handle)->fd;
+       int r = ioctl(fd, IOCTL_USBFS_RESET, NULL);
+       if (r) {
+               if (errno == ENODEV)
+                       return LIBUSB_ERROR_NOT_FOUND;
+
+               usbi_err("reset 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;
@@ -1141,6 +1156,7 @@ const struct usbi_os_backend linux_usbfs_backend = {
 
        .set_interface_altsetting = op_set_interface,
        .clear_halt = op_clear_halt,
+       .reset_device = op_reset_device,
 
        .destroy_device = op_destroy_device,