3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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
27 #include <sys/queue.h>
37 #include "libusb20_desc.h"
38 #include "libusb20_int.h"
43 get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out)
45 struct timeval timeout;
48 ret = libusb_get_next_timeout(ctx, &timeout);
51 if (timerisset(&timeout) == 0)
53 if (timercmp(&timeout, tv, <) != 0)
65 handle_timeouts(struct libusb_context *ctx)
67 struct timespec sys_ts;
68 struct timeval sys_tv;
69 struct timeval *cur_tv;
70 struct usb_transfer *xfer;
71 struct libusb_transfer *uxfer;
77 pthread_mutex_lock(&ctx->flying_transfers_lock);
78 if (USB_LIST_EMPTY(&ctx->flying_transfers))
81 ret = clock_gettime(CLOCK_MONOTONIC, &sys_ts);
82 TIMESPEC_TO_TIMEVAL(&sys_tv, &sys_ts);
84 LIST_FOREACH_ENTRY(xfer, &ctx->flying_transfers, list) {
85 cur_tv = &xfer->timeout;
87 if (timerisset(cur_tv) == 0)
90 if (xfer->flags & USB_TIMED_OUT)
93 if ((cur_tv->tv_sec > sys_tv.tv_sec) || (cur_tv->tv_sec == sys_tv.tv_sec &&
94 cur_tv->tv_usec > sys_tv.tv_usec))
97 xfer->flags |= USB_TIMED_OUT;
98 uxfer = (libusb_transfer *) ((uint8_t *)xfer +
99 sizeof(struct usb_transfer));
100 ret = libusb_cancel_transfer(uxfer);
103 pthread_mutex_unlock(&ctx->flying_transfers_lock);
108 handle_events(struct libusb_context *ctx, struct timeval *tv)
110 struct libusb_pollfd *tmppollfd;
111 struct libusb_device_handle *devh;
112 struct usb_pollfd *ipollfd;
113 struct usb_transfer *cur;
114 struct usb_transfer *cancel;
115 struct libusb_transfer *xfer;
126 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "handle_events enter");
131 pthread_mutex_lock(&ctx->pollfds_lock);
132 LIST_FOREACH_ENTRY(ipollfd, &ctx->pollfds, list)
135 fds = malloc(sizeof(*fds) * nfds);
137 return (LIBUSB_ERROR_NO_MEM);
139 LIST_FOREACH_ENTRY(ipollfd, &ctx->pollfds, list) {
140 tmppollfd = &ipollfd->pollfd;
141 tmpfd = tmppollfd->fd;
144 fds[i].events = tmppollfd->events;
148 pthread_mutex_unlock(&ctx->pollfds_lock);
150 timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
151 if (tv->tv_usec % 1000)
154 ret = poll(fds, nfds, timeout);
157 return (handle_timeouts(ctx));
158 } else if (ret == -1 && errno == EINTR) {
160 return (LIBUSB_ERROR_INTERRUPTED);
161 } else if (ret < 0) {
163 return (LIBUSB_ERROR_IO);
166 if (fds[0].revents) {
176 pthread_mutex_lock(&ctx->open_devs_lock);
177 for (i = 0 ; i < nfds && ret > 0 ; i++) {
184 LIST_FOREACH_ENTRY(devh, &ctx->open_devs, list) {
185 if (libusb20_dev_get_fd(devh->os_priv) == tfds->fd)
189 if (tfds->revents & POLLERR) {
190 usb_remove_pollfd(ctx, libusb20_dev_get_fd(devh->os_priv));
191 usb_handle_disconnect(devh);
196 pthread_mutex_lock(&libusb20_lock);
197 dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_PROCESS");
198 ret = libusb20_dev_process(devh->os_priv);
199 pthread_mutex_unlock(&libusb20_lock);
202 if (ret == 0 || ret == LIBUSB20_ERROR_NO_DEVICE)
210 pthread_mutex_unlock(&ctx->open_devs_lock);
214 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "handle_events leave");
218 /* Polling and timing */
221 libusb_try_lock_events(libusb_context * ctx)
226 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_try_lock_events enter");
228 pthread_mutex_lock(&ctx->pollfd_modify_lock);
229 ret = ctx->pollfd_modify;
230 pthread_mutex_unlock(&ctx->pollfd_modify_lock);
235 ret = pthread_mutex_trylock(&ctx->events_lock);
240 ctx->event_handler_active = 1;
242 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_try_lock_events leave");
247 libusb_lock_events(libusb_context * ctx)
250 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_events enter");
252 pthread_mutex_lock(&ctx->events_lock);
253 ctx->event_handler_active = 1;
255 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_events leave");
259 libusb_unlock_events(libusb_context * ctx)
262 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_events enter");
264 ctx->event_handler_active = 0;
265 pthread_mutex_unlock(&ctx->events_lock);
267 pthread_mutex_lock(&ctx->event_waiters_lock);
268 pthread_cond_broadcast(&ctx->event_waiters_cond);
269 pthread_mutex_unlock(&ctx->event_waiters_lock);
271 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_events leave");
275 libusb_event_handling_ok(libusb_context * ctx)
280 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handling_ok enter");
282 pthread_mutex_lock(&ctx->pollfd_modify_lock);
283 ret = ctx->pollfd_modify;
284 pthread_mutex_unlock(&ctx->pollfd_modify_lock);
289 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handling_ok leave");
294 libusb_event_handler_active(libusb_context * ctx)
299 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handler_active enter");
301 pthread_mutex_lock(&ctx->pollfd_modify_lock);
302 ret = ctx->pollfd_modify;
303 pthread_mutex_unlock(&ctx->pollfd_modify_lock);
308 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_event_handler_active leave");
309 return (ctx->event_handler_active);
313 libusb_lock_event_waiters(libusb_context * ctx)
316 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_event_waiters enter");
318 pthread_mutex_lock(&ctx->event_waiters_lock);
320 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_lock_event_waiters leave");
324 libusb_unlock_event_waiters(libusb_context * ctx)
327 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_event_waiters enter");
329 pthread_mutex_unlock(&ctx->event_waiters_lock);
331 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unlock_event_waiters leave");
335 libusb_wait_for_event(libusb_context * ctx, struct timeval *tv)
341 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter");
344 pthread_cond_wait(&ctx->event_waiters_cond,
345 &ctx->event_waiters_lock);
349 ret = clock_gettime(CLOCK_REALTIME, &ts);
351 return (LIBUSB_ERROR_OTHER);
353 ts.tv_sec = tv->tv_sec;
354 ts.tv_nsec = tv->tv_usec * 1000;
355 if (ts.tv_nsec > 1000000000) {
356 ts.tv_nsec -= 1000000000;
360 ret = pthread_cond_timedwait(&ctx->event_waiters_cond,
361 &ctx->event_waiters_lock, &ts);
363 if (ret == ETIMEDOUT)
366 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event leave");
371 libusb_handle_events_timeout(libusb_context * ctx, struct timeval *tv)
373 struct timeval timeout;
374 struct timeval poll_timeout;
378 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout enter");
380 ret = get_next_timeout(ctx, tv, &poll_timeout);
382 return handle_timeouts(ctx);
385 if (libusb_try_lock_events(ctx) == 0) {
386 ret = handle_events(ctx, &poll_timeout);
387 libusb_unlock_events(ctx);
391 libusb_lock_event_waiters(ctx);
392 if (libusb_event_handler_active(ctx) == 0) {
393 libusb_unlock_event_waiters(ctx);
397 ret = libusb_wait_for_event(ctx, &poll_timeout);
398 libusb_unlock_event_waiters(ctx);
403 return (handle_timeouts(ctx));
405 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout leave");
410 libusb_handle_events(libusb_context * ctx)
416 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events enter");
420 ret = libusb_handle_events_timeout(ctx, &tv);
422 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events leave");
427 libusb_handle_events_locked(libusb_context * ctx, struct timeval *tv)
430 struct timeval poll_tv;
433 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_locked enter");
435 ret = get_next_timeout(ctx, tv, &poll_tv);
437 return handle_timeouts(ctx);
440 ret = handle_events(ctx, &poll_tv);
442 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_locked leave");
447 libusb_get_next_timeout(libusb_context * ctx, struct timeval *tv)
449 struct usb_transfer *xfer;
450 struct timeval *next_tv;
451 struct timeval cur_tv;
452 struct timespec cur_ts;
457 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_next_timeout enter");
460 pthread_mutex_lock(&ctx->flying_transfers_lock);
461 if (USB_LIST_EMPTY(&ctx->flying_transfers)) {
462 pthread_mutex_unlock(&ctx->flying_transfers_lock);
466 LIST_FOREACH_ENTRY(xfer, &ctx->flying_transfers, list) {
467 if (!(xfer->flags & USB_TIMED_OUT)) {
472 pthread_mutex_unlock(&ctx->flying_transfers_lock);
478 next_tv = &xfer->timeout;
479 if (timerisset(next_tv) == 0)
482 ret = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
484 return (LIBUSB_ERROR_OTHER);
485 TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
487 if (timercmp(&cur_tv, next_tv, >=) != 0)
490 timersub(next_tv, &cur_tv, tv);
492 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_next_timeout leave");
497 libusb_set_pollfd_notifiers(libusb_context * ctx,
498 libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
502 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_pollfd_notifiers enter");
504 ctx->fd_added_cb = added_cb;
505 ctx->fd_removed_cb = removed_cb;
506 ctx->fd_cb_user_data = user_data;
508 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_pollfd_notifiers leave");
511 struct libusb_pollfd **
512 libusb_get_pollfds(libusb_context * ctx)
514 struct usb_pollfd *pollfd;
519 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_pollfds enter");
522 pthread_mutex_lock(&ctx->pollfds_lock);
523 LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list)
526 ret = calloc(i + 1 , sizeof(struct libusb_pollfd *));
528 pthread_mutex_unlock(&ctx->pollfds_lock);
533 LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list)
534 ret[i++] = (struct libusb_pollfd *) pollfd;
537 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_pollfds leave");
542 /* Synchronous device I/O */
544 static void ctrl_tr_cb(struct libusb_transfer *transfer)
551 dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "CALLBACK ENTER");
553 complet = transfer->user_data;
558 libusb_control_transfer(libusb_device_handle * devh,
559 uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
560 unsigned char *data, uint16_t wLength, unsigned int timeout)
562 struct libusb_transfer *xfer;
563 struct libusb_control_setup *ctr;
569 ctx = devh->dev->ctx;
571 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_control_transfer enter");
573 if (devh == NULL || data == NULL)
574 return (LIBUSB_ERROR_NO_MEM);
576 xfer = libusb_alloc_transfer(0);
578 return (LIBUSB_ERROR_NO_MEM);
580 buff = malloc(sizeof(libusb_control_setup) + wLength);
582 libusb_free_transfer(xfer);
583 return (LIBUSB_ERROR_NO_MEM);
586 ctr = (libusb_control_setup *)buff;
587 ctr->bmRequestType = bmRequestType;
588 ctr->bRequest = bRequest;
589 ctr->wValue = wValue;
590 ctr->wIndex = wIndex;
591 ctr->wLength = wLength;
592 if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
593 memcpy(buff + sizeof(libusb_control_setup), data, wLength);
595 xfer->dev_handle = devh;
597 xfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
598 xfer->timeout = timeout;
600 xfer->length = sizeof(libusb_control_setup) + wLength;
601 xfer->user_data = &complet;
602 xfer->callback = ctrl_tr_cb;
603 xfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER;
606 if ((ret = libusb_submit_transfer(xfer)) < 0) {
607 libusb_free_transfer(xfer);
612 if ((ret = libusb_handle_events(ctx)) < 0) {
613 libusb_cancel_transfer(xfer);
615 if (libusb_handle_events(ctx) < 0) {
618 libusb_free_transfer(xfer);
623 if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
624 memcpy(data, buff + sizeof(libusb_control_setup), wLength);
626 switch (xfer->status) {
627 case LIBUSB_TRANSFER_COMPLETED:
628 ret = xfer->actual_length;
630 case LIBUSB_TRANSFER_TIMED_OUT:
631 case LIBUSB_TRANSFER_STALL:
632 case LIBUSB_TRANSFER_NO_DEVICE:
636 ret = LIBUSB_ERROR_OTHER;
638 libusb_free_transfer(xfer);
640 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_control_transfer leave");
645 do_transfer(struct libusb_device_handle *devh,
646 unsigned char endpoint, unsigned char *data, int length,
647 int *transferred, unsigned int timeout, int type)
649 struct libusb_transfer *xfer;
654 if (devh == NULL || data == NULL)
655 return (LIBUSB_ERROR_NO_MEM);
657 xfer = libusb_alloc_transfer(0);
659 return (LIBUSB_ERROR_NO_MEM);
661 ctx = devh->dev->ctx;
663 xfer->dev_handle = devh;
664 xfer->endpoint = endpoint;
666 xfer->timeout = timeout;
668 xfer->length = length;
669 xfer->user_data = &complet;
670 xfer->callback = ctrl_tr_cb;
673 if ((ret = libusb_submit_transfer(xfer)) < 0) {
674 libusb_free_transfer(xfer);
678 while (complet == 0) {
679 if ((ret = libusb_handle_events(ctx)) < 0) {
680 libusb_cancel_transfer(xfer);
681 libusb_free_transfer(xfer);
682 while (complet == 0) {
683 if (libusb_handle_events(ctx) < 0)
690 *transferred = xfer->actual_length;
691 switch (xfer->status) {
692 case LIBUSB_TRANSFER_COMPLETED:
693 ret = xfer->actual_length;
695 case LIBUSB_TRANSFER_TIMED_OUT:
696 case LIBUSB_TRANSFER_OVERFLOW:
697 case LIBUSB_TRANSFER_STALL:
698 case LIBUSB_TRANSFER_NO_DEVICE:
702 ret = LIBUSB_ERROR_OTHER;
705 libusb_free_transfer(xfer);
710 libusb_bulk_transfer(struct libusb_device_handle *devh,
711 unsigned char endpoint, unsigned char *data, int length,
712 int *transferred, unsigned int timeout)
719 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
721 ret = do_transfer(devh, endpoint, data, length, transferred,
722 timeout, LIBUSB_TRANSFER_TYPE_BULK);
724 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave");
729 * Need to fix xfer->type
732 libusb_interrupt_transfer(struct libusb_device_handle *devh,
733 unsigned char endpoint, unsigned char *data, int length,
734 int *transferred, unsigned int timeout)
741 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
743 ret = do_transfer(devh, endpoint, data, length, transferred,
744 timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
746 dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave");