diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-05-04 13:46:41 +0100 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-05-04 13:46:41 +0100 |
commit | c01f744ce07bbeccbe353e956479f0cc5a811a6f (patch) | |
tree | ac277becb6c434756403419d89b4fbf5efd63d50 | |
parent | 5878daa85e3364bb3885190425d4f9deaa2d8c36 (diff) | |
download | libusb-c01f744ce07bbeccbe353e956479f0cc5a811a6f.tar.gz |
Add functionality to clear endpoint halt conditions
-rw-r--r-- | libusb/core.c | 20 | ||||
-rw-r--r-- | libusb/libusb.h | 2 | ||||
-rw-r--r-- | libusb/libusbi.h | 2 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.c | 17 |
4 files changed, 40 insertions, 1 deletions
diff --git a/libusb/core.c b/libusb/core.c index 59df43e..f5e0238 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -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. diff --git a/libusb/libusb.h b/libusb/libusb.h index b69dd7f..b376fdc 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -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 */ diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 611f62b..c912632 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -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); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index d1c1100..0066910 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -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, |