Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Synchronous I/O functions for libusb |
| 3 | * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org> |
| 4 | * |
| 5 | * This library is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU Lesser General Public |
| 7 | * License as published by the Free Software Foundation; either |
| 8 | * version 2.1 of the License, or (at your option) any later version. |
| 9 | * |
| 10 | * This library is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * Lesser General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU Lesser General Public |
| 16 | * License along with this library; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | */ |
| 19 | |
| 20 | #include <config.h> |
| 21 | #include <errno.h> |
| 22 | #include <stdint.h> |
| 23 | #include <stdlib.h> |
| 24 | #include <string.h> |
| 25 | |
| 26 | #include "libusbi.h" |
| 27 | |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 28 | /** |
| 29 | * @defgroup syncio Synchronous device I/O |
| 30 | * |
| 31 | * This page documents libusb's synchronous (blocking) API for USB device I/O. |
| 32 | * This interface is easy to use but has some limitations. More advanced users |
| 33 | * may wish to consider using the \ref asyncio "asynchronous I/O API" instead. |
| 34 | */ |
| 35 | |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 36 | static void ctrl_transfer_cb(struct libusb_transfer *transfer) |
| 37 | { |
| 38 | int *completed = transfer->user_data; |
| 39 | *completed = 1; |
| 40 | usbi_dbg("actual_length=%d", transfer->actual_length); |
| 41 | /* caller interprets result and frees transfer */ |
| 42 | } |
| 43 | |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 44 | /** \ingroup syncio |
Daniel Drake | ba5d9a4 | 2008-05-11 15:36:24 +0100 | [diff] [blame] | 45 | * Perform a USB control transfer. |
| 46 | * |
| 47 | * The direction of the transfer is inferred from the bmRequestType field of |
| 48 | * the setup packet. |
| 49 | * |
| 50 | * The wValue, wIndex and wLength fields values should be given in host-endian |
| 51 | * byte order. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 52 | * |
| 53 | * \param dev_handle a handle for the device to communicate with |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 54 | * \param bmRequestType the request type field for the setup packet |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 55 | * \param bRequest the request field for the setup packet |
| 56 | * \param wValue the value field for the setup packet |
| 57 | * \param wIndex the index field for the setup packet |
| 58 | * \param data a suitably-sized data buffer for either input or output |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 59 | * (depending on direction bits within bmRequestType) |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 60 | * \param wLength the length field for the setup packet. The data buffer should |
| 61 | * be at least this size. |
| 62 | * \param timeout timeout (in millseconds) that this function should wait |
| 63 | * before giving up due to no response being received. For no timeout, use |
| 64 | * value 0. |
Daniel Drake | 885c2a5 | 2008-05-05 21:34:31 +0100 | [diff] [blame] | 65 | * \returns on success, the number of bytes actually transferred |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 66 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 67 | * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the |
| 68 | * device |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 69 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 70 | * \returns another LIBUSB_ERROR code on other failures |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 71 | */ |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 72 | API_EXPORTED int libusb_control_transfer(libusb_device_handle *dev_handle, |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 73 | uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 74 | unsigned char *data, uint16_t wLength, unsigned int timeout) |
| 75 | { |
Daniel Drake | 211f80c | 2008-03-25 16:24:30 +0000 | [diff] [blame] | 76 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 77 | unsigned char *buffer; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 78 | int completed = 0; |
| 79 | int r; |
| 80 | |
| 81 | if (!transfer) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 82 | return LIBUSB_ERROR_NO_MEM; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 83 | |
Daniel Drake | aae05f6 | 2008-03-10 11:32:15 +0000 | [diff] [blame] | 84 | buffer = malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 85 | if (!buffer) { |
| 86 | libusb_free_transfer(transfer); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 87 | return LIBUSB_ERROR_NO_MEM; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 88 | } |
| 89 | |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 90 | libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 91 | wLength); |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 92 | if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 93 | memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); |
| 94 | |
Daniel Drake | aae05f6 | 2008-03-10 11:32:15 +0000 | [diff] [blame] | 95 | libusb_fill_control_transfer(transfer, dev_handle, buffer, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 96 | ctrl_transfer_cb, &completed, timeout); |
Daniel Drake | bef33bb | 2008-05-19 15:43:27 +0100 | [diff] [blame] | 97 | transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 98 | r = libusb_submit_transfer(transfer); |
| 99 | if (r < 0) { |
| 100 | libusb_free_transfer(transfer); |
| 101 | return r; |
| 102 | } |
| 103 | |
| 104 | while (!completed) { |
Daniel Drake | 8d80985 | 2008-03-30 22:19:00 +0100 | [diff] [blame] | 105 | r = libusb_handle_events(); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 106 | if (r < 0) { |
Daniel Drake | 7ac0a40 | 2008-04-27 23:27:04 +0100 | [diff] [blame] | 107 | libusb_cancel_transfer(transfer); |
| 108 | while (!completed) |
| 109 | if (libusb_handle_events() < 0) |
| 110 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 111 | libusb_free_transfer(transfer); |
| 112 | return r; |
| 113 | } |
| 114 | } |
| 115 | |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 116 | if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 117 | memcpy(data, libusb_control_transfer_get_data(transfer), |
| 118 | transfer->actual_length); |
| 119 | |
| 120 | switch (transfer->status) { |
| 121 | case LIBUSB_TRANSFER_COMPLETED: |
| 122 | r = transfer->actual_length; |
| 123 | break; |
| 124 | case LIBUSB_TRANSFER_TIMED_OUT: |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 125 | r = LIBUSB_ERROR_TIMEOUT; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 126 | break; |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 127 | case LIBUSB_TRANSFER_STALL: |
| 128 | r = LIBUSB_ERROR_PIPE; |
| 129 | break; |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 130 | case LIBUSB_TRANSFER_NO_DEVICE: |
| 131 | r = LIBUSB_ERROR_NO_DEVICE; |
| 132 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 133 | default: |
| 134 | usbi_warn("unrecognised status code %d", transfer->status); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 135 | r = LIBUSB_ERROR_OTHER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | libusb_free_transfer(transfer); |
| 139 | return r; |
| 140 | } |
| 141 | |
| 142 | static void bulk_transfer_cb(struct libusb_transfer *transfer) |
| 143 | { |
| 144 | int *completed = transfer->user_data; |
| 145 | *completed = 1; |
| 146 | usbi_dbg("actual_length=%d", transfer->actual_length); |
| 147 | /* caller interprets results and frees transfer */ |
| 148 | } |
| 149 | |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 150 | static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 151 | unsigned char endpoint, unsigned char *buffer, int length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 152 | int *transferred, unsigned int timeout, unsigned char type) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 153 | { |
Daniel Drake | 211f80c | 2008-03-25 16:24:30 +0000 | [diff] [blame] | 154 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 155 | int completed = 0; |
| 156 | int r; |
| 157 | |
| 158 | if (!transfer) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 159 | return LIBUSB_ERROR_NO_MEM; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 160 | |
| 161 | libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, |
| 162 | bulk_transfer_cb, &completed, timeout); |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 163 | transfer->type = type; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 164 | |
| 165 | r = libusb_submit_transfer(transfer); |
| 166 | if (r < 0) { |
| 167 | libusb_free_transfer(transfer); |
| 168 | return r; |
| 169 | } |
| 170 | |
| 171 | while (!completed) { |
Daniel Drake | 8d80985 | 2008-03-30 22:19:00 +0100 | [diff] [blame] | 172 | r = libusb_handle_events(); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 173 | if (r < 0) { |
Daniel Drake | 7ac0a40 | 2008-04-27 23:27:04 +0100 | [diff] [blame] | 174 | libusb_cancel_transfer(transfer); |
| 175 | while (!completed) |
| 176 | if (libusb_handle_events() < 0) |
| 177 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 178 | libusb_free_transfer(transfer); |
| 179 | return r; |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | *transferred = transfer->actual_length; |
| 184 | switch (transfer->status) { |
| 185 | case LIBUSB_TRANSFER_COMPLETED: |
| 186 | r = 0; |
| 187 | break; |
| 188 | case LIBUSB_TRANSFER_TIMED_OUT: |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 189 | r = LIBUSB_ERROR_TIMEOUT; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 190 | break; |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 191 | case LIBUSB_TRANSFER_STALL: |
| 192 | r = LIBUSB_ERROR_PIPE; |
| 193 | break; |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame^] | 194 | case LIBUSB_TRANSFER_OVERFLOW: |
| 195 | r = LIBUSB_ERROR_OVERFLOW; |
| 196 | break; |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 197 | case LIBUSB_TRANSFER_NO_DEVICE: |
| 198 | r = LIBUSB_ERROR_NO_DEVICE; |
| 199 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 200 | default: |
| 201 | usbi_warn("unrecognised status code %d", transfer->status); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 202 | r = LIBUSB_ERROR_OTHER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 203 | } |
| 204 | |
| 205 | libusb_free_transfer(transfer); |
| 206 | return r; |
| 207 | } |
| 208 | |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 209 | /** \ingroup syncio |
| 210 | * Perform a USB bulk transfer. The direction of the transfer is inferred from |
| 211 | * the direction bits of the endpoint address. |
| 212 | * |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 213 | * For bulk reads, the <tt>length</tt> field indicates the maximum length of |
| 214 | * data you are expecting to receive. If less data arrives than expected, |
| 215 | * this function will return that data, so be sure to check the |
| 216 | * <tt>transferred</tt> output parameter. |
| 217 | * |
| 218 | * You should also check the <tt>transferred</tt> parameter for bulk writes. |
| 219 | * Not all of the data may have been written. |
| 220 | * |
| 221 | * Also check <tt>transferred</tt> when dealing with a timeout error code. |
| 222 | * libusb may have to split your transfer into a number of chunks to satisfy |
| 223 | * underlying O/S requirements, meaning that the timeout may expire after |
| 224 | * the first few chunks have completed. libusb is careful not to lose any data |
| 225 | * that may have been transferred; do not assume that timeout conditions |
| 226 | * indicate a complete lack of I/O. |
| 227 | * |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 228 | * \param dev_handle a handle for the device to communicate with |
| 229 | * \param endpoint the address of a valid endpoint to communicate with |
| 230 | * \param data a suitably-sized data buffer for either input or output |
| 231 | * (depending on endpoint) |
| 232 | * \param length for bulk writes, the number of bytes from data to be sent. for |
| 233 | * bulk reads, the maximum number of bytes to receive into the data buffer. |
| 234 | * \param transferred output location for the number of bytes actually |
| 235 | * transferred. |
| 236 | * \param timeout timeout (in millseconds) that this function should wait |
| 237 | * before giving up due to no response being received. For no timeout, use |
| 238 | * value 0. |
| 239 | * |
| 240 | * \returns 0 on success (and populates <tt>transferred</tt>) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 241 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 242 | * <tt>transferred</tt>) |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 243 | * \returns LIBUSB_ERROR_PIPE if the endpoint halted |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame^] | 244 | * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see |
| 245 | * \ref packetoverflow |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 246 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 247 | * \returns another LIBUSB_ERROR code on other failures |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 248 | */ |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 249 | API_EXPORTED int libusb_bulk_transfer(struct libusb_device_handle *dev_handle, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 250 | unsigned char endpoint, unsigned char *data, int length, int *transferred, |
| 251 | unsigned int timeout) |
| 252 | { |
| 253 | return do_sync_bulk_transfer(dev_handle, endpoint, data, length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 254 | transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 255 | } |
| 256 | |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 257 | /** \ingroup syncio |
| 258 | * Perform a USB interrupt transfer. The direction of the transfer is inferred |
| 259 | * from the direction bits of the endpoint address. |
| 260 | * |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 261 | * For interrupt reads, the <tt>length</tt> field indicates the maximum length |
| 262 | * of data you are expecting to receive. If less data arrives than expected, |
| 263 | * this function will return that data, so be sure to check the |
| 264 | * <tt>transferred</tt> output parameter. |
| 265 | * |
| 266 | * You should also check the <tt>transferred</tt> parameter for interrupt |
| 267 | * writes. Not all of the data may have been written. |
| 268 | * |
| 269 | * Also check <tt>transferred</tt> when dealing with a timeout error code. |
| 270 | * libusb may have to split your transfer into a number of chunks to satisfy |
| 271 | * underlying O/S requirements, meaning that the timeout may expire after |
| 272 | * the first few chunks have completed. libusb is careful not to lose any data |
| 273 | * that may have been transferred; do not assume that timeout conditions |
| 274 | * indicate a complete lack of I/O. |
| 275 | * |
| 276 | * The default endpoint bInterval value is used as the polling interval. |
| 277 | * |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 278 | * \param dev_handle a handle for the device to communicate with |
| 279 | * \param endpoint the address of a valid endpoint to communicate with |
| 280 | * \param data a suitably-sized data buffer for either input or output |
| 281 | * (depending on endpoint) |
| 282 | * \param length for bulk writes, the number of bytes from data to be sent. for |
| 283 | * bulk reads, the maximum number of bytes to receive into the data buffer. |
| 284 | * \param transferred output location for the number of bytes actually |
| 285 | * transferred. |
| 286 | * \param timeout timeout (in millseconds) that this function should wait |
| 287 | * before giving up due to no response being received. For no timeout, use |
| 288 | * value 0. |
| 289 | * |
| 290 | * \returns 0 on success (and populates <tt>transferred</tt>) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 291 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 292 | * \returns LIBUSB_ERROR_PIPE if the endpoint halted |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame^] | 293 | * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see |
| 294 | * \ref packetoverflow |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 295 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 296 | * \returns another LIBUSB_ERROR code on other error |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 297 | */ |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 298 | API_EXPORTED int libusb_interrupt_transfer( |
| 299 | struct libusb_device_handle *dev_handle, unsigned char endpoint, |
| 300 | unsigned char *data, int length, int *transferred, unsigned int timeout) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 301 | { |
| 302 | return do_sync_bulk_transfer(dev_handle, endpoint, data, length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 303 | transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 304 | } |
| 305 | |