libusb10_io.c (c500e4dd03b53b2f9d020fee096d971e231f3c77) | libusb10_io.c (390065b18e0ee636279b106ff06f0a1463589ab1) |
---|---|
1/* $FreeBSD$ */ 2/*- 3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 | 1/* $FreeBSD$ */ 2/*- 3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 |
27#include <sys/queue.h> | |
28#include <stdlib.h> 29#include <unistd.h> 30#include <stdio.h> 31#include <poll.h> 32#include <pthread.h> 33#include <time.h> 34#include <errno.h> | 27#include <stdlib.h> 28#include <unistd.h> 29#include <stdio.h> 30#include <poll.h> 31#include <pthread.h> 32#include <time.h> 33#include <errno.h> |
34#include <sys/queue.h> |
|
35 36#include "libusb20.h" 37#include "libusb20_desc.h" 38#include "libusb20_int.h" 39#include "libusb.h" 40#include "libusb10.h" 41 | 35 36#include "libusb20.h" 37#include "libusb20_desc.h" 38#include "libusb20_int.h" 39#include "libusb.h" 40#include "libusb10.h" 41 |
42UNEXPORTED int 43usb_add_pollfd(libusb_context *ctx, int fd, short events) | 42UNEXPORTED void 43libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd, 44 struct libusb20_device *pdev, int fd, short events) |
44{ | 45{ |
45 struct usb_pollfd *pollfd; 46 | |
47 if (ctx == NULL) | 46 if (ctx == NULL) |
48 return (LIBUSB_ERROR_INVALID_PARAM); 49 50 pollfd = malloc(sizeof(*pollfd)); 51 if (pollfd == NULL) 52 return (LIBUSB_ERROR_NO_MEM); | 47 return; /* invalid */ |
53 | 48 |
49 if (pollfd->entry.tqe_prev != NULL) 50 return; /* already queued */ 51 52 if (fd < 0) 53 return; /* invalid */ 54 55 pollfd->pdev = pdev; |
|
54 pollfd->pollfd.fd = fd; 55 pollfd->pollfd.events = events; 56 | 56 pollfd->pollfd.fd = fd; 57 pollfd->pollfd.events = events; 58 |
57 pthread_mutex_lock(&ctx->pollfds_lock); 58 TAILQ_INSERT_TAIL(&ctx->pollfds, pollfd, list); 59 pthread_mutex_unlock(&ctx->pollfds_lock); | 59 CTX_LOCK(ctx); 60 TAILQ_INSERT_TAIL(&ctx->pollfds, pollfd, entry); 61 CTX_UNLOCK(ctx); |
60 61 if (ctx->fd_added_cb) 62 ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); | 62 63 if (ctx->fd_added_cb) 64 ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); |
63 return (0); | |
64} 65 66UNEXPORTED void | 65} 66 67UNEXPORTED void |
67usb_remove_pollfd(libusb_context *ctx, int fd) | 68libusb10_remove_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd) |
68{ | 69{ |
69 struct usb_pollfd *pollfd; 70 int found; | 70 if (ctx == NULL) 71 return; /* invalid */ |
71 | 72 |
72 found = 0; 73 pthread_mutex_lock(&ctx->pollfds_lock); | 73 if (pollfd->entry.tqe_prev == NULL) 74 return; /* already dequeued */ |
74 | 75 |
75 TAILQ_FOREACH(pollfd, &ctx->pollfds, list) { 76 if (pollfd->pollfd.fd == fd) { 77 found = 1; 78 break ; 79 } 80 } | 76 CTX_LOCK(ctx); 77 TAILQ_REMOVE(&ctx->pollfds, pollfd, entry); 78 pollfd->entry.tqe_prev = NULL; 79 CTX_UNLOCK(ctx); |
81 | 80 |
82 if (found == 0) { 83 pthread_mutex_unlock(&ctx->pollfds_lock); 84 return ; 85 } 86 87 TAILQ_REMOVE(&ctx->pollfds, pollfd, list); 88 pthread_mutex_unlock(&ctx->pollfds_lock); 89 free(pollfd); 90 | |
91 if (ctx->fd_removed_cb) | 81 if (ctx->fd_removed_cb) |
92 ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); | 82 ctx->fd_removed_cb(pollfd->pollfd.fd, ctx->fd_cb_user_data); |
93} 94 | 83} 84 |
95UNEXPORTED void 96usb_handle_transfer_completion(struct usb_transfer *uxfer, 97 enum libusb_transfer_status status) 98{ 99 libusb_transfer *xfer; 100 libusb_context *ctx; 101 int len; | 85/* This function must be called locked */ |
102 | 86 |
103 xfer = (struct libusb_transfer *) ((uint8_t *)uxfer + 104 sizeof(struct usb_transfer)); 105 ctx = xfer->dev_handle->dev->ctx; 106 107 pthread_mutex_lock(&ctx->flying_transfers_lock); 108 TAILQ_REMOVE(&ctx->flying_transfers, uxfer, list); 109 pthread_mutex_unlock(&ctx->flying_transfers_lock); 110 111 if (status == LIBUSB_TRANSFER_COMPLETED && xfer->flags & 112 LIBUSB_TRANSFER_SHORT_NOT_OK) { 113 len = xfer->length; 114 if (xfer->type == LIBUSB_TRANSFER_TYPE_CONTROL) 115 len -= sizeof(libusb_control_setup); 116 if (len != uxfer->transferred) { 117 status = LIBUSB_TRANSFER_ERROR; 118 } 119 } 120 121 xfer->status = status; 122 xfer->actual_length = uxfer->transferred; 123 124 if (xfer->callback) 125 xfer->callback(xfer); 126 if (xfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER) 127 libusb_free_transfer(xfer); 128 129 pthread_mutex_lock(&ctx->event_waiters_lock); 130 pthread_cond_broadcast(&ctx->event_waiters_cond); 131 pthread_mutex_unlock(&ctx->event_waiters_lock); 132} 133 134UNEXPORTED void 135usb_handle_disconnect(struct libusb_device_handle *devh) | 87static int 88libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv) |
136{ | 89{ |
137 struct libusb_context *ctx; 138 struct libusb_transfer *xfer; 139 struct usb_transfer *cur; 140 struct usb_transfer *to_cancel; 141 142 ctx = devh->dev->ctx; 143 144 while (1) { 145 pthread_mutex_lock(&ctx->flying_transfers_lock); 146 to_cancel = NULL; 147 TAILQ_FOREACH(cur, &ctx->flying_transfers, list) { 148 xfer = (struct libusb_transfer *) ((uint8_t *)cur + 149 sizeof(struct usb_transfer)); 150 if (xfer->dev_handle == devh) { 151 to_cancel = cur; 152 break ; 153 } 154 } 155 pthread_mutex_unlock(&ctx->flying_transfers_lock); 156 157 if (to_cancel == NULL) 158 break ; 159 160 usb_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE); 161 } 162 return ; 163} 164 165UNEXPORTED int 166get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out) 167{ 168 struct timeval timeout; 169 170 if (libusb_get_next_timeout(ctx, &timeout)) { 171 if (timerisset(&timeout) == 0) 172 return 1; 173 if (timercmp(&timeout, tv, <) != 0) 174 *out = timeout; 175 else 176 *out = *tv; 177 } else { 178 *out = *tv; 179 } 180 181 return (0); 182} 183 184UNEXPORTED int 185handle_timeouts(struct libusb_context *ctx) 186{ 187 struct timespec sys_ts; 188 struct timeval sys_tv; 189 struct timeval *cur_tv; 190 struct usb_transfer *xfer; 191 struct libusb_transfer *uxfer; 192 int ret; 193 194 GET_CONTEXT(ctx); 195 ret = 0; 196 197 pthread_mutex_lock(&ctx->flying_transfers_lock); 198 if (TAILQ_EMPTY(&ctx->flying_transfers)) 199 goto out; 200 201 ret = clock_gettime(CLOCK_MONOTONIC, &sys_ts); 202 TIMESPEC_TO_TIMEVAL(&sys_tv, &sys_ts); 203 204 TAILQ_FOREACH(xfer, &ctx->flying_transfers, list) { 205 cur_tv = &xfer->timeout; 206 207 if (timerisset(cur_tv) == 0) 208 goto out; 209 210 if (xfer->flags & USB_TIMED_OUT) 211 continue; 212 213 if ((cur_tv->tv_sec > sys_tv.tv_sec) || (cur_tv->tv_sec == sys_tv.tv_sec && 214 cur_tv->tv_usec > sys_tv.tv_usec)) 215 goto out; 216 217 xfer->flags |= USB_TIMED_OUT; 218 uxfer = (libusb_transfer *) ((uint8_t *)xfer + 219 sizeof(struct usb_transfer)); 220 ret = libusb_cancel_transfer(uxfer); 221 } 222out: 223 pthread_mutex_unlock(&ctx->flying_transfers_lock); 224 return (ret); 225} 226 227UNEXPORTED int 228handle_events(struct libusb_context *ctx, struct timeval *tv) 229{ 230 struct libusb_pollfd *tmppollfd; 231 struct libusb_device_handle *devh; 232 struct usb_pollfd *ipollfd; | 90 struct libusb_device *dev; 91 struct libusb20_device **ppdev; 92 struct libusb_super_pollfd *pfd; |
233 struct pollfd *fds; | 93 struct pollfd *fds; |
234 struct pollfd *tfds; | 94 struct libusb_super_transfer *sxfer; 95 struct libusb_transfer *uxfer; |
235 nfds_t nfds; | 96 nfds_t nfds; |
236 int tmpfd; 237 int ret; | |
238 int timeout; 239 int i; | 97 int timeout; 98 int i; |
240 241 GET_CONTEXT(ctx); 242 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "handle_events enter"); | 99 int err; |
243 | 100 |
101 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub enter"); 102 |
|
244 nfds = 0; | 103 nfds = 0; |
245 i = -1; | 104 i = 0; 105 TAILQ_FOREACH(pfd, &ctx->pollfds, entry) 106 nfds++; |
246 | 107 |
247 pthread_mutex_lock(&ctx->pollfds_lock); 248 TAILQ_FOREACH(ipollfd, &ctx->pollfds, list) 249 nfds++; 250 | |
251 fds = alloca(sizeof(*fds) * nfds); 252 if (fds == NULL) 253 return (LIBUSB_ERROR_NO_MEM); 254 | 108 fds = alloca(sizeof(*fds) * nfds); 109 if (fds == NULL) 110 return (LIBUSB_ERROR_NO_MEM); 111 |
255 TAILQ_FOREACH(ipollfd, &ctx->pollfds, list) { 256 tmppollfd = &ipollfd->pollfd; 257 tmpfd = tmppollfd->fd; 258 i++; 259 fds[i].fd = tmpfd; 260 fds[i].events = tmppollfd->events; | 112 ppdev = alloca(sizeof(*ppdev) * nfds); 113 if (ppdev == NULL) 114 return (LIBUSB_ERROR_NO_MEM); 115 116 TAILQ_FOREACH(pfd, &ctx->pollfds, entry) { 117 fds[i].fd = pfd->pollfd.fd; 118 fds[i].events = pfd->pollfd.events; |
261 fds[i].revents = 0; | 119 fds[i].revents = 0; |
120 ppdev[i] = pfd->pdev; 121 if (pfd->pdev != NULL) 122 libusb_get_device(pfd->pdev)->refcnt++; 123 i++; |
|
262 } 263 | 124 } 125 |
264 pthread_mutex_unlock(&ctx->pollfds_lock); | 126 if (tv == NULL) 127 timeout = -1; 128 else 129 timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000); |
265 | 130 |
266 timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000); 267 if (tv->tv_usec % 1000) 268 timeout++; | 131 CTX_UNLOCK(ctx); 132 err = poll(fds, nfds, timeout); 133 CTX_LOCK(ctx); |
269 | 134 |
270 ret = poll(fds, nfds, timeout); 271 if (ret == 0) 272 return (handle_timeouts(ctx)); 273 else if (ret == -1 && errno == EINTR) 274 return (LIBUSB_ERROR_INTERRUPTED); 275 else if (ret < 0) 276 return (LIBUSB_ERROR_IO); | 135 if ((err == -1) && (errno == EINTR)) 136 err = LIBUSB_ERROR_INTERRUPTED; 137 else if (err < 0) 138 err = LIBUSB_ERROR_IO; |
277 | 139 |
278 if (fds[0].revents) { 279 if (ret == 1){ 280 ret = 0; 281 goto handled; 282 } else { 283 fds[0].revents = 0; 284 ret--; | 140 if (err < 1) { 141 for (i = 0; i != nfds; i++) { 142 if (ppdev[i] != NULL) { 143 CTX_UNLOCK(ctx); 144 libusb_unref_device(libusb_get_device(ppdev[i])); 145 CTX_LOCK(ctx); 146 } |
285 } | 147 } |
148 goto do_done; |
|
286 } | 149 } |
150 for (i = 0; i != nfds; i++) { 151 if (fds[i].revents == 0) 152 continue; 153 if (ppdev[i] != NULL) { 154 dev = libusb_get_device(ppdev[i]); |
|
287 | 155 |
288 pthread_mutex_lock(&ctx->open_devs_lock); 289 for (i = 0, devh = NULL ; i < nfds && ret > 0 ; i++) { | 156 err = libusb20_dev_process(ppdev[i]); 157 if (err) { 158 /* cancel all transfers - device is gone */ 159 libusb10_cancel_all_transfer(dev); 160 /* 161 * make sure we don't go into an infinite 162 * loop 163 */ 164 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 165 } 166 CTX_UNLOCK(ctx); 167 libusb_unref_device(dev); 168 CTX_LOCK(ctx); |
290 | 169 |
291 tfds = &fds[i]; 292 if (!tfds->revents) 293 continue; | 170 } else { 171 uint8_t dummy; |
294 | 172 |
295 ret--; 296 TAILQ_FOREACH(devh, &ctx->open_devs, list) { 297 if (libusb20_dev_get_fd(devh->os_priv) == tfds->fd) 298 break ; | 173 while (1) { 174 if (read(fds[i].fd, &dummy, 1) != 1) 175 break; 176 } |
299 } | 177 } |
178 } |
|
300 | 179 |
301 if (tfds->revents & POLLERR) { 302 usb_remove_pollfd(ctx, libusb20_dev_get_fd(devh->os_priv)); 303 if (devh != NULL) 304 usb_handle_disconnect(devh); 305 continue ; 306 } | 180 err = 0; |
307 | 181 |
182do_done: |
|
308 | 183 |
309 pthread_mutex_lock(&libusb20_lock); 310 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_PROCESS"); 311 if (devh != NULL) 312 ret = libusb20_dev_process(devh->os_priv); 313 pthread_mutex_unlock(&libusb20_lock); | 184 /* Do all done callbacks */ |
314 | 185 |
186 while ((sxfer = TAILQ_FIRST(&ctx->tr_done))) { 187 TAILQ_REMOVE(&ctx->tr_done, sxfer, entry); 188 sxfer->entry.tqe_prev = NULL; |
|
315 | 189 |
316 if (ret == 0 || ret == LIBUSB20_ERROR_NO_DEVICE) 317 continue; 318 else if (ret < 0) 319 goto out; | 190 ctx->tr_done_ref++; 191 192 CTX_UNLOCK(ctx); 193 194 uxfer = (struct libusb_transfer *)( 195 ((uint8_t *)sxfer) + sizeof(*sxfer)); 196 197 if (uxfer->callback != NULL) 198 (uxfer->callback) (uxfer); 199 200 if (uxfer->flags & LIBUSB_TRANSFER_FREE_BUFFER) 201 free(uxfer->buffer); 202 203 if (uxfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER) 204 libusb_free_transfer(uxfer); 205 206 CTX_LOCK(ctx); 207 208 ctx->tr_done_ref--; 209 ctx->tr_done_gen++; |
320 } 321 | 210 } 211 |
322 ret = 0; 323out: 324 pthread_mutex_unlock(&ctx->open_devs_lock); | 212 /* Wakeup other waiters */ 213 pthread_cond_broadcast(&ctx->ctx_cond); |
325 | 214 |
326handled: 327 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "handle_events leave"); 328 return ret; | 215 return (err); |
329} 330 331/* Polling and timing */ 332 333int | 216} 217 218/* Polling and timing */ 219 220int |
334libusb_try_lock_events(libusb_context * ctx) | 221libusb_try_lock_events(libusb_context *ctx) |
335{ | 222{ |
336 int ret; | 223 int err; |
337 | 224 |
338 GET_CONTEXT(ctx); 339 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_try_lock_events enter"); 340 341 pthread_mutex_lock(&ctx->pollfd_modify_lock); 342 ret = ctx->pollfd_modify; 343 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 344 345 if (ret != 0) | 225 ctx = GET_CONTEXT(ctx); 226 if (ctx == NULL) |
346 return (1); 347 | 227 return (1); 228 |
348 ret = pthread_mutex_trylock(&ctx->events_lock); 349 350 if (ret != 0) | 229 err = CTX_TRYLOCK(ctx); 230 if (err) |
351 return (1); | 231 return (1); |
352 353 ctx->event_handler_active = 1; | |
354 | 232 |
355 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_try_lock_events leave"); 356 return (0); | 233 err = (ctx->ctx_handler != NO_THREAD); 234 if (err) 235 CTX_UNLOCK(ctx); 236 else 237 ctx->ctx_handler = pthread_self(); 238 239 return (err); |
357} 358 359void | 240} 241 242void |
360libusb_lock_events(libusb_context * ctx) | 243libusb_lock_events(libusb_context *ctx) |
361{ | 244{ |
362 GET_CONTEXT(ctx); 363 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_events enter"); 364 365 pthread_mutex_lock(&ctx->events_lock); 366 ctx->event_handler_active = 1; 367 368 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_events leave"); | 245 ctx = GET_CONTEXT(ctx); 246 CTX_LOCK(ctx); 247 if (ctx->ctx_handler == NO_THREAD) 248 ctx->ctx_handler = pthread_self(); |
369} 370 371void | 249} 250 251void |
372libusb_unlock_events(libusb_context * ctx) | 252libusb_unlock_events(libusb_context *ctx) |
373{ | 253{ |
374 GET_CONTEXT(ctx); 375 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_events enter"); 376 377 ctx->event_handler_active = 0; 378 pthread_mutex_unlock(&ctx->events_lock); 379 380 pthread_mutex_lock(&ctx->event_waiters_lock); 381 pthread_cond_broadcast(&ctx->event_waiters_cond); 382 pthread_mutex_unlock(&ctx->event_waiters_lock); 383 384 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_events leave"); | 254 ctx = GET_CONTEXT(ctx); 255 if (ctx->ctx_handler == pthread_self()) { 256 ctx->ctx_handler = NO_THREAD; 257 pthread_cond_broadcast(&ctx->ctx_cond); 258 } 259 CTX_UNLOCK(ctx); |
385} 386 387int | 260} 261 262int |
388libusb_event_handling_ok(libusb_context * ctx) | 263libusb_event_handling_ok(libusb_context *ctx) |
389{ | 264{ |
390 int ret; 391 392 GET_CONTEXT(ctx); 393 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handling_ok enter"); 394 395 pthread_mutex_lock(&ctx->pollfd_modify_lock); 396 ret = ctx->pollfd_modify; 397 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 398 399 if (ret != 0) 400 return (0); 401 402 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handling_ok leave"); 403 return (1); | 265 ctx = GET_CONTEXT(ctx); 266 return (ctx->ctx_handler == pthread_self()); |
404} 405 406int | 267} 268 269int |
407libusb_event_handler_active(libusb_context * ctx) | 270libusb_event_handler_active(libusb_context *ctx) |
408{ | 271{ |
409 int ret; 410 411 GET_CONTEXT(ctx); 412 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handler_active enter"); 413 414 pthread_mutex_lock(&ctx->pollfd_modify_lock); 415 ret = ctx->pollfd_modify; 416 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 417 418 if (ret != 0) 419 return (1); 420 421 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handler_active leave"); 422 return (ctx->event_handler_active); | 272 ctx = GET_CONTEXT(ctx); 273 return (ctx->ctx_handler != NO_THREAD); |
423} 424 425void | 274} 275 276void |
426libusb_lock_event_waiters(libusb_context * ctx) | 277libusb_lock_event_waiters(libusb_context *ctx) |
427{ | 278{ |
428 GET_CONTEXT(ctx); 429 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_event_waiters enter"); 430 431 pthread_mutex_lock(&ctx->event_waiters_lock); 432 433 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_event_waiters leave"); | 279 ctx = GET_CONTEXT(ctx); 280 CTX_LOCK(ctx); |
434} 435 436void | 281} 282 283void |
437libusb_unlock_event_waiters(libusb_context * ctx) | 284libusb_unlock_event_waiters(libusb_context *ctx) |
438{ | 285{ |
439 GET_CONTEXT(ctx); 440 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_event_waiters enter"); 441 442 pthread_mutex_unlock(&ctx->event_waiters_lock); 443 444 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_event_waiters leave"); | 286 ctx = GET_CONTEXT(ctx); 287 CTX_UNLOCK(ctx); |
445} 446 447int | 288} 289 290int |
448libusb_wait_for_event(libusb_context * ctx, struct timeval *tv) | 291libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) |
449{ | 292{ |
450 int ret; | |
451 struct timespec ts; | 293 struct timespec ts; |
294 int err; |
|
452 | 295 |
453 GET_CONTEXT(ctx); | 296 ctx = GET_CONTEXT(ctx); |
454 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter"); 455 456 if (tv == NULL) { | 297 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter"); 298 299 if (tv == NULL) { |
457 pthread_cond_wait(&ctx->event_waiters_cond, 458 &ctx->event_waiters_lock); | 300 pthread_cond_wait(&ctx->ctx_cond, 301 &ctx->ctx_lock); |
459 return (0); 460 } | 302 return (0); 303 } |
461 462 ret = clock_gettime(CLOCK_REALTIME, &ts); 463 if (ret < 0) | 304 err = clock_gettime(CLOCK_REALTIME, &ts); 305 if (err < 0) |
464 return (LIBUSB_ERROR_OTHER); 465 466 ts.tv_sec = tv->tv_sec; 467 ts.tv_nsec = tv->tv_usec * 1000; | 306 return (LIBUSB_ERROR_OTHER); 307 308 ts.tv_sec = tv->tv_sec; 309 ts.tv_nsec = tv->tv_usec * 1000; |
468 if (ts.tv_nsec > 1000000000) { | 310 if (ts.tv_nsec >= 1000000000) { |
469 ts.tv_nsec -= 1000000000; 470 ts.tv_sec++; 471 } | 311 ts.tv_nsec -= 1000000000; 312 ts.tv_sec++; 313 } |
314 err = pthread_cond_timedwait(&ctx->ctx_cond, 315 &ctx->ctx_lock, &ts); |
|
472 | 316 |
473 ret = pthread_cond_timedwait(&ctx->event_waiters_cond, 474 &ctx->event_waiters_lock, &ts); 475 476 if (ret == ETIMEDOUT) | 317 if (err == ETIMEDOUT) |
477 return (1); 478 | 318 return (1); 319 |
479 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event leave"); | |
480 return (0); 481} 482 483int | 320 return (0); 321} 322 323int |
484libusb_handle_events_timeout(libusb_context * ctx, struct timeval *tv) | 324libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv) |
485{ | 325{ |
486 struct timeval poll_timeout; 487 int ret; 488 489 GET_CONTEXT(ctx); | 326 int err; 327 328 ctx = GET_CONTEXT(ctx); 329 |
490 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout enter"); 491 | 330 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout enter"); 331 |
492 ret = get_next_timeout(ctx, tv, &poll_timeout); 493 if (ret != 0) { 494 return handle_timeouts(ctx); 495 } 496retry: 497 if (libusb_try_lock_events(ctx) == 0) { 498 ret = handle_events(ctx, &poll_timeout); 499 libusb_unlock_events(ctx); 500 return ret; 501 } | 332 libusb_lock_events(ctx); |
502 | 333 |
503 libusb_lock_event_waiters(ctx); 504 if (libusb_event_handler_active(ctx) == 0) { 505 libusb_unlock_event_waiters(ctx); 506 goto retry; 507 } 508 509 ret = libusb_wait_for_event(ctx, &poll_timeout); 510 libusb_unlock_event_waiters(ctx); | 334 err = libusb_handle_events_locked(ctx, tv); |
511 | 335 |
512 if (ret < 0) 513 return ret; 514 else if (ret == 1) 515 return (handle_timeouts(ctx)); | 336 libusb_unlock_events(ctx); |
516 517 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout leave"); | 337 338 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout leave"); |
518 return (0); | 339 340 return (err); |
519} 520 521int | 341} 342 343int |
522libusb_handle_events(libusb_context * ctx) | 344libusb_handle_events(libusb_context *ctx) |
523{ | 345{ |
524 struct timeval tv; 525 int ret; 526 527 GET_CONTEXT(ctx); 528 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events enter"); 529 530 tv.tv_sec = 2; 531 tv.tv_usec = 0; 532 ret = libusb_handle_events_timeout(ctx, &tv); 533 534 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events leave"); 535 return (ret); | 346 return (libusb_handle_events_timeout(ctx, NULL)); |
536} 537 538int | 347} 348 349int |
539libusb_handle_events_locked(libusb_context * ctx, struct timeval *tv) | 350libusb_handle_events_locked(libusb_context *ctx, struct timeval *tv) |
540{ | 351{ |
541 int ret; 542 struct timeval poll_tv; | 352 int err; |
543 | 353 |
544 GET_CONTEXT(ctx); 545 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_locked enter"); | 354 ctx = GET_CONTEXT(ctx); |
546 | 355 |
547 ret = get_next_timeout(ctx, tv, &poll_tv); 548 if (ret != 0) { 549 return handle_timeouts(ctx); | 356 if (libusb_event_handling_ok(ctx)) { 357 err = libusb10_handle_events_sub(ctx, tv); 358 } else { 359 libusb_wait_for_event(ctx, tv); 360 err = 0; |
550 } | 361 } |
551 552 ret = handle_events(ctx, &poll_tv); 553 554 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_locked leave"); 555 return (ret); | 362 return (err); |
556} 557 558int | 363} 364 365int |
559libusb_get_next_timeout(libusb_context * ctx, struct timeval *tv) | 366libusb_get_next_timeout(libusb_context *ctx, struct timeval *tv) |
560{ | 367{ |
561 struct usb_transfer *xfer; 562 struct timeval *next_tv; 563 struct timeval cur_tv; 564 struct timespec cur_ts; 565 int found; 566 int ret; 567 568 GET_CONTEXT(ctx); 569 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_next_timeout enter"); 570 571 found = 0; 572 pthread_mutex_lock(&ctx->flying_transfers_lock); 573 if (TAILQ_EMPTY(&ctx->flying_transfers)) { 574 pthread_mutex_unlock(&ctx->flying_transfers_lock); 575 return (0); 576 } 577 578 TAILQ_FOREACH(xfer, &ctx->flying_transfers, list) { 579 if (!(xfer->flags & USB_TIMED_OUT)) { 580 found = 1; 581 break ; 582 } 583 } 584 pthread_mutex_unlock(&ctx->flying_transfers_lock); 585 586 if (found == 0) { 587 return 0; 588 } 589 590 next_tv = &xfer->timeout; 591 if (timerisset(next_tv) == 0) 592 return (0); 593 594 ret = clock_gettime(CLOCK_MONOTONIC, &cur_ts); 595 if (ret < 0) 596 return (LIBUSB_ERROR_OTHER); 597 TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); 598 599 if (timercmp(&cur_tv, next_tv, >=) != 0) 600 timerclear(tv); 601 else 602 timersub(next_tv, &cur_tv, tv); 603 604 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_next_timeout leave"); 605 return (1); | 368 /* all timeouts are currently being done by the kernel */ 369 timerclear(tv); 370 return (0); |
606} 607 608void | 371} 372 373void |
609libusb_set_pollfd_notifiers(libusb_context * ctx, | 374libusb_set_pollfd_notifiers(libusb_context *ctx, |
610 libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, 611 void *user_data) 612{ | 375 libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, 376 void *user_data) 377{ |
613 GET_CONTEXT(ctx); 614 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_pollfd_notifiers enter"); | 378 ctx = GET_CONTEXT(ctx); |
615 616 ctx->fd_added_cb = added_cb; 617 ctx->fd_removed_cb = removed_cb; 618 ctx->fd_cb_user_data = user_data; | 379 380 ctx->fd_added_cb = added_cb; 381 ctx->fd_removed_cb = removed_cb; 382 ctx->fd_cb_user_data = user_data; |
619 620 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_pollfd_notifiers leave"); | |
621} 622 623struct libusb_pollfd ** | 383} 384 385struct libusb_pollfd ** |
624libusb_get_pollfds(libusb_context * ctx) | 386libusb_get_pollfds(libusb_context *ctx) |
625{ | 387{ |
626 struct usb_pollfd *pollfd; | 388 struct libusb_super_pollfd *pollfd; |
627 libusb_pollfd **ret; 628 int i; 629 | 389 libusb_pollfd **ret; 390 int i; 391 |
630 GET_CONTEXT(ctx); 631 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_pollfds enter"); | 392 ctx = GET_CONTEXT(ctx); |
632 | 393 |
394 CTX_LOCK(ctx); 395 |
|
633 i = 0; | 396 i = 0; |
634 pthread_mutex_lock(&ctx->pollfds_lock); 635 TAILQ_FOREACH(pollfd, &ctx->pollfds, list) 636 i++; | 397 TAILQ_FOREACH(pollfd, &ctx->pollfds, entry) 398 i++; |
637 | 399 |
638 ret = calloc(i + 1 , sizeof(struct libusb_pollfd *)); 639 if (ret == NULL) { 640 pthread_mutex_unlock(&ctx->pollfds_lock); 641 return (ret); 642 } | 400 ret = calloc(i + 1, sizeof(struct libusb_pollfd *)); 401 if (ret == NULL) 402 goto done; |
643 644 i = 0; | 403 404 i = 0; |
645 TAILQ_FOREACH(pollfd, &ctx->pollfds, list) 646 ret[i++] = (struct libusb_pollfd *) pollfd; | 405 TAILQ_FOREACH(pollfd, &ctx->pollfds, entry) 406 ret[i++] = &pollfd->pollfd; |
647 ret[i] = NULL; 648 | 407 ret[i] = NULL; 408 |
649 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_pollfds leave"); | 409done: 410 CTX_UNLOCK(ctx); |
650 return (ret); 651} 652 653 654/* Synchronous device I/O */ 655 | 411 return (ret); 412} 413 414 415/* Synchronous device I/O */ 416 |
656static void ctrl_tr_cb(struct libusb_transfer *transfer) 657{ 658 libusb_context *ctx; 659 int *complet; 660 661 ctx = NULL; 662 GET_CONTEXT(ctx); 663 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "CALLBACK ENTER"); 664 665 complet = transfer->user_data; 666 *complet = 1; 667} 668 | |
669int | 417int |
670libusb_control_transfer(libusb_device_handle * devh, | 418libusb_control_transfer(libusb_device_handle *devh, |
671 uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, | 419 uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, |
672 unsigned char *data, uint16_t wLength, unsigned int timeout) | 420 uint8_t *data, uint16_t wLength, unsigned int timeout) |
673{ | 421{ |
674 struct libusb_transfer *xfer; 675 struct libusb_control_setup *ctr; 676 libusb_context *ctx; 677 unsigned char *buff; 678 int complet; 679 int ret; | 422 struct LIBUSB20_CONTROL_SETUP_DECODED req; 423 int err; 424 uint16_t actlen; |
680 | 425 |
681 ctx = devh->dev->ctx; 682 GET_CONTEXT(ctx); 683 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_control_transfer enter"); | 426 if (devh == NULL) 427 return (LIBUSB_ERROR_INVALID_PARAM); |
684 | 428 |
685 if (devh == NULL || data == NULL) 686 return (LIBUSB_ERROR_NO_MEM); | 429 if ((wLength != 0) && (data == NULL)) 430 return (LIBUSB_ERROR_INVALID_PARAM); |
687 | 431 |
688 xfer = libusb_alloc_transfer(0); 689 if (xfer == NULL) 690 return (LIBUSB_ERROR_NO_MEM); | 432 LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); |
691 | 433 |
692 buff = malloc(sizeof(libusb_control_setup) + wLength); 693 if (buff == NULL) { 694 libusb_free_transfer(xfer); 695 return (LIBUSB_ERROR_NO_MEM); 696 } | 434 req.bmRequestType = bmRequestType; 435 req.bRequest = bRequest; 436 req.wValue = wValue; 437 req.wIndex = wIndex; 438 req.wLength = wLength; |
697 | 439 |
698 ctr = (libusb_control_setup *)buff; 699 ctr->bmRequestType = bmRequestType; 700 ctr->bRequest = bRequest; 701 ctr->wValue = wValue; 702 ctr->wIndex = wIndex; 703 ctr->wLength = wLength; 704 if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) 705 memcpy(buff + sizeof(libusb_control_setup), data, wLength); | 440 err = libusb20_dev_request_sync(devh, &req, data, 441 &actlen, timeout, 0); |
706 | 442 |
707 xfer->dev_handle = devh; 708 xfer->endpoint = 0; 709 xfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; 710 xfer->timeout = timeout; 711 xfer->buffer = buff; 712 xfer->length = sizeof(libusb_control_setup) + wLength; 713 xfer->user_data = &complet; 714 xfer->callback = ctrl_tr_cb; 715 xfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER; 716 complet = 0; | 443 if (err == LIBUSB20_ERROR_PIPE) 444 return (LIBUSB_ERROR_PIPE); 445 else if (err == LIBUSB20_ERROR_TIMEOUT) 446 return (LIBUSB_ERROR_TIMEOUT); 447 else if (err) 448 return (LIBUSB_ERROR_NO_DEVICE); |
717 | 449 |
718 if ((ret = libusb_submit_transfer(xfer)) < 0) { 719 libusb_free_transfer(xfer); 720 return (ret); 721 } | 450 return (actlen); 451} |
722 | 452 |
723 while (complet == 0) 724 if ((ret = libusb_handle_events(ctx)) < 0) { 725 libusb_cancel_transfer(xfer); 726 while (complet == 0) 727 if (libusb_handle_events(ctx) < 0) { 728 break; 729 } 730 libusb_free_transfer(xfer); 731 return (ret); 732 } | 453static void 454libusb10_do_transfer_cb(struct libusb_transfer *transfer) 455{ 456 libusb_context *ctx; 457 int *pdone; |
733 | 458 |
459 ctx = GET_CONTEXT(NULL); |
|
734 | 460 |
735 if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) 736 memcpy(data, buff + sizeof(libusb_control_setup), wLength); | 461 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done"); |
737 | 462 |
738 switch (xfer->status) { 739 case LIBUSB_TRANSFER_COMPLETED: 740 ret = xfer->actual_length; 741 break; 742 case LIBUSB_TRANSFER_TIMED_OUT: 743 case LIBUSB_TRANSFER_STALL: 744 case LIBUSB_TRANSFER_NO_DEVICE: 745 ret = xfer->status; 746 break; 747 default: 748 ret = LIBUSB_ERROR_OTHER; 749 } 750 libusb_free_transfer(xfer); 751 752 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_control_transfer leave"); 753 return (ret); | 463 pdone = transfer->user_data; 464 *pdone = 1; |
754} 755 | 465} 466 |
467/* 468 * TODO: Replace the following function. Allocating and freeing on a 469 * per-transfer basis is slow. --HPS 470 */ |
|
756static int | 471static int |
757do_transfer(struct libusb_device_handle *devh, 758 unsigned char endpoint, unsigned char *data, int length, | 472libusb10_do_transfer(libusb_device_handle *devh, 473 uint8_t endpoint, uint8_t *data, int length, |
759 int *transferred, unsigned int timeout, int type) 760{ | 474 int *transferred, unsigned int timeout, int type) 475{ |
761 struct libusb_transfer *xfer; | |
762 libusb_context *ctx; | 476 libusb_context *ctx; |
763 int complet; | 477 struct libusb_transfer *xfer; 478 volatile int complet; |
764 int ret; 765 | 479 int ret; 480 |
766 if (devh == NULL || data == NULL) 767 return (LIBUSB_ERROR_NO_MEM); | 481 if (devh == NULL) 482 return (LIBUSB_ERROR_INVALID_PARAM); |
768 | 483 |
484 if ((length != 0) && (data == NULL)) 485 return (LIBUSB_ERROR_INVALID_PARAM); 486 |
|
769 xfer = libusb_alloc_transfer(0); 770 if (xfer == NULL) 771 return (LIBUSB_ERROR_NO_MEM); 772 | 487 xfer = libusb_alloc_transfer(0); 488 if (xfer == NULL) 489 return (LIBUSB_ERROR_NO_MEM); 490 |
773 ctx = devh->dev->ctx; 774 GET_CONTEXT(ctx); | 491 ctx = libusb_get_device(devh)->ctx; |
775 776 xfer->dev_handle = devh; 777 xfer->endpoint = endpoint; 778 xfer->type = type; 779 xfer->timeout = timeout; 780 xfer->buffer = data; 781 xfer->length = length; | 492 493 xfer->dev_handle = devh; 494 xfer->endpoint = endpoint; 495 xfer->type = type; 496 xfer->timeout = timeout; 497 xfer->buffer = data; 498 xfer->length = length; |
782 xfer->user_data = &complet; 783 xfer->callback = ctrl_tr_cb; | 499 xfer->user_data = (void *)&complet; 500 xfer->callback = libusb10_do_transfer_cb; |
784 complet = 0; 785 | 501 complet = 0; 502 |
786 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "SUBMIT_TRANSFER"); | |
787 if ((ret = libusb_submit_transfer(xfer)) < 0) { 788 libusb_free_transfer(xfer); | 503 if ((ret = libusb_submit_transfer(xfer)) < 0) { 504 libusb_free_transfer(xfer); |
789 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "SUBMIT_TRANSFER FAILED %i", ret); | |
790 return (ret); 791 } | 505 return (ret); 506 } |
792 | |
793 while (complet == 0) { 794 if ((ret = libusb_handle_events(ctx)) < 0) { 795 libusb_cancel_transfer(xfer); | 507 while (complet == 0) { 508 if ((ret = libusb_handle_events(ctx)) < 0) { 509 libusb_cancel_transfer(xfer); |
796 libusb_free_transfer(xfer); 797 while (complet == 0) { 798 if (libusb_handle_events(ctx) < 0) 799 break ; 800 } 801 return (ret); | 510 usleep(1000); /* nice it */ |
802 } 803 } 804 805 *transferred = xfer->actual_length; | 511 } 512 } 513 514 *transferred = xfer->actual_length; |
806 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "xfer->status %i", xfer->status); | 515 |
807 switch (xfer->status) { 808 case LIBUSB_TRANSFER_COMPLETED: | 516 switch (xfer->status) { 517 case LIBUSB_TRANSFER_COMPLETED: |
809 ret = xfer->actual_length; | 518 ret = 0; |
810 break; 811 case LIBUSB_TRANSFER_TIMED_OUT: | 519 break; 520 case LIBUSB_TRANSFER_TIMED_OUT: |
521 ret = LIBUSB_ERROR_TIMEOUT; 522 break; |
|
812 case LIBUSB_TRANSFER_OVERFLOW: | 523 case LIBUSB_TRANSFER_OVERFLOW: |
524 ret = LIBUSB_ERROR_OVERFLOW; 525 break; |
|
813 case LIBUSB_TRANSFER_STALL: | 526 case LIBUSB_TRANSFER_STALL: |
527 ret = LIBUSB_ERROR_PIPE; 528 break; |
|
814 case LIBUSB_TRANSFER_NO_DEVICE: | 529 case LIBUSB_TRANSFER_NO_DEVICE: |
815 ret = xfer->status; | 530 ret = LIBUSB_ERROR_NO_DEVICE; |
816 break; 817 default: 818 ret = LIBUSB_ERROR_OTHER; | 531 break; 532 default: 533 ret = LIBUSB_ERROR_OTHER; |
534 break; |
|
819 } 820 821 libusb_free_transfer(xfer); 822 return (ret); 823} 824 825int | 535 } 536 537 libusb_free_transfer(xfer); 538 return (ret); 539} 540 541int |
826libusb_bulk_transfer(struct libusb_device_handle *devh, 827 unsigned char endpoint, unsigned char *data, int length, | 542libusb_bulk_transfer(libusb_device_handle *devh, 543 uint8_t endpoint, uint8_t *data, int length, |
828 int *transferred, unsigned int timeout) 829{ 830 libusb_context *ctx; 831 int ret; | 544 int *transferred, unsigned int timeout) 545{ 546 libusb_context *ctx; 547 int ret; |
832 833 ctx = NULL; 834 GET_CONTEXT(ctx); | 548 549 ctx = GET_CONTEXT(NULL); |
835 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter"); 836 | 550 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter"); 551 |
837 ret = do_transfer(devh, endpoint, data, length, transferred, | 552 ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, |
838 timeout, LIBUSB_TRANSFER_TYPE_BULK); 839 840 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave"); 841 return (ret); 842} 843 | 553 timeout, LIBUSB_TRANSFER_TYPE_BULK); 554 555 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave"); 556 return (ret); 557} 558 |
844/* 845 * Need to fix xfer->type 846 */ | |
847int | 559int |
848libusb_interrupt_transfer(struct libusb_device_handle *devh, 849 unsigned char endpoint, unsigned char *data, int length, | 560libusb_interrupt_transfer(libusb_device_handle *devh, 561 uint8_t endpoint, uint8_t *data, int length, |
850 int *transferred, unsigned int timeout) 851{ 852 libusb_context *ctx; 853 int ret; 854 | 562 int *transferred, unsigned int timeout) 563{ 564 libusb_context *ctx; 565 int ret; 566 |
855 ctx = NULL; 856 GET_CONTEXT(ctx); | 567 ctx = GET_CONTEXT(NULL); |
857 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter"); 858 | 568 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter"); 569 |
859 ret = do_transfer(devh, endpoint, data, length, transferred, | 570 ret = libusb10_do_transfer(devh, endpoint, data, length, transferred, |
860 timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); 861 862 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave"); 863 return (ret); 864} | 571 timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); 572 573 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave"); 574 return (ret); 575} |