From owner-p4-projects@FreeBSD.ORG Fri May 29 15:12:43 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id AEAC61065673; Fri, 29 May 2009 15:12:43 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 55A7C1065670 for ; Fri, 29 May 2009 15:12:43 +0000 (UTC) (envelope-from syl@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 4353C8FC17 for ; Fri, 29 May 2009 15:12:43 +0000 (UTC) (envelope-from syl@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4TFChLm056453 for ; Fri, 29 May 2009 15:12:43 GMT (envelope-from syl@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4TFChUx056451 for perforce@freebsd.org; Fri, 29 May 2009 15:12:43 GMT (envelope-from syl@FreeBSD.org) Date: Fri, 29 May 2009 15:12:43 GMT Message-Id: <200905291512.n4TFChUx056451@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to syl@FreeBSD.org using -f From: Sylvestre Gallon To: Perforce Change Reviews Cc: Subject: PERFORCE change 163025 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 May 2009 15:12:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=163025 Change 163025 by syl@syl_rincewind on 2009/05/29 15:12:12 Split libusb10.c (more than 1400 lines) into 2 files. libusb10_io.c contains now io operations. Affected files ... .. //depot/projects/soc2009/syl_usb/src/lib/libusb/Makefile#3 edit .. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#17 edit .. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.h#1 add .. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_io.c#1 add Differences ... ==== //depot/projects/soc2009/syl_usb/src/lib/libusb/Makefile#3 (text+ko) ==== @@ -26,6 +26,7 @@ # libusb 1.0 compat SRCS+= libusb10.c SRCS+= libusb10_desc.c +SRCS+= libusb10_io.c INCS+= libusb.h MAN+= libusb10.3 ==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#17 (text+ko) ==== @@ -36,6 +36,7 @@ #include "libusb20_desc.h" #include "libusb20_int.h" #include "libusb.h" +#include "libusb10.h" /* * XXX TODO @@ -43,78 +44,11 @@ * - implement last io funcs. */ -/* - * The two following macros were taken from the original LibUSB v1.0 - * for sake of compatibility: - */ -#define USB_LIST_INIT(entry) \ - (entry)->prev = (entry)->next = entry; -#define USB_LIST_EMPTY(entry) \ - ((entry)->next = (entry)) - -#define LIST_ADD(entry, head) \ - (entry)->next = (head)->next; \ - (entry)->prev = (head); \ - (head)->next->prev = (entry); \ - (head)->next = (entry); -#define LIST_ADD_TAIL(entry, head) \ - (entry)->next = (head); \ - (entry)->prev = (head)->prev; \ - (head)->prev->next = (entry); \ - (head)->prev = (entry); -#define LIST_DEL(entry) \ - (entry)->next->prev = (entry)->prev; \ - (entry)->prev->next = (entry)->next; - -#define LIST_ENT(ptr, type, member) \ - ((type *)((char *)(ptr) - (unsigned long) (&((type*)0L)->member))) -#define LIST_FOREACH_ENTRY(pos, head, member) \ - for (pos = LIST_ENT((head)->next, typeof(*pos), member) ; \ - &pos->member != head ; \ - pos = LIST_ENT(pos->member.next, typeof(*pos), member)) -#define LIST_FOREACH_ENTRY_SAFE(pos, n, head, member) \ - for (pos = LIST_ENT((head)->next, typeof(*pos), member), \ - n = LIST_ENT(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = LIST_ENT(n->member.next, typeof(*n), member)) - -/* fetch libusb20_transfer from libusb20_device */ -#define GET_XFER(xfer, endpoint, pdev)\ - xfer = libusb20_tr_get_pointer(pdev, \ - (2 *endpoint)|(endpoint/0x80)); \ - if (xfer == NULL) \ - return (LIBUSB_ERROR_OTHER); - - -static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out); -static int handle_timeouts(struct libusb_context *ctx); -static int handle_events(struct libusb_context *ctx, struct timeval *tv); +static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; struct libusb_context *usbi_default_context = NULL; -static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; - -/* if ctx is NULL use default context*/ - -#define GET_CONTEXT(ctx) \ - if (ctx == NULL) ctx = usbi_default_context; - -#define MAX(a,b) (((a)>(b))?(a):(b)) -#define USB_TIMED_OUT (1<<0) /* Library initialisation / deinitialisation */ -struct usb_pollfd { - struct libusb_pollfd pollfd; - struct list_head list; -}; - -struct usb_transfer { - int num_iso_packets; - struct list_head list; - struct timeval timeout; - int transferred; - uint8_t flags; -}; - void libusb_set_debug(libusb_context * ctx, int level) { @@ -892,571 +826,3 @@ return (0); } -/* Polling and timing */ - -int -libusb_try_lock_events(libusb_context * ctx) -{ - int ret; - - GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->pollfd_modify_lock); - ret = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); - - if (ret != 0) - return (1); - - ret = pthread_mutex_trylock(&ctx->events_lock); - - if (ret != 0) - return (1); - - ctx->event_handler_active = 1; - return (0); -} - -void -libusb_lock_events(libusb_context * ctx) -{ - GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->events_lock); - ctx->event_handler_active = 1; -} - -void -libusb_unlock_events(libusb_context * ctx) -{ - GET_CONTEXT(ctx); - ctx->event_handler_active = 0; - pthread_mutex_unlock(&ctx->events_lock); - - pthread_mutex_lock(&ctx->event_waiters_lock); - pthread_cond_broadcast(&ctx->event_waiters_cond); - pthread_mutex_unlock(&ctx->event_waiters_lock); -} - -int -libusb_event_handling_ok(libusb_context * ctx) -{ - int ret; - - GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->pollfd_modify_lock); - ret = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); - - if (ret) - return (0); - return (1); -} - -int -libusb_event_handler_active(libusb_context * ctx) -{ - int ret; - - GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->pollfd_modify_lock); - ret = ctx->pollfd_modify; - pthread_mutex_unlock(&ctx->pollfd_modify_lock); - - if (ret) - return (1); - return (ctx->event_handler_active); -} - -void -libusb_lock_event_waiters(libusb_context * ctx) -{ - GET_CONTEXT(ctx); - pthread_mutex_lock(&ctx->event_waiters_lock); - return; -} - -void -libusb_unlock_event_waiters(libusb_context * ctx) -{ - GET_CONTEXT(ctx); - pthread_mutex_unlock(&ctx->event_waiters_lock); - return; -} - -int -libusb_wait_for_event(libusb_context * ctx, struct timeval *tv) -{ - int ret; - struct timespec ts; - - GET_CONTEXT(ctx); - if (tv == NULL) { - pthread_cond_wait(&ctx->event_waiters_cond, - &ctx->event_waiters_lock); - return (0); - } - - ret = clock_gettime(CLOCK_REALTIME, &ts); - if (ret < 0) - return (LIBUSB_ERROR_OTHER); - - ts.tv_sec = tv->tv_sec; - ts.tv_nsec = tv->tv_usec * 1000; - if (ts.tv_nsec > 1000000000) { - ts.tv_nsec -= 1000000000; - ts.tv_sec++; - } - - ret = pthread_cond_timedwait(&ctx->event_waiters_cond, - &ctx->event_waiters_lock, &ts); - - if (ret == ETIMEDOUT) - return (1); - return (0); -} - -static int -get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out) -{ - struct timeval timeout; - int ret; - - ret = libusb_get_next_timeout(ctx, &timeout); - - if (ret) { - if (timerisset(&timeout) == 0) - return 1; - if (timercmp(&timeout, tv, <) != 0) - *out = timeout; - else - *out = *tv; - } else { - *out = *tv; - } - - return (0); -} - -static int -handle_timeouts(struct libusb_context *ctx) -{ - struct timespec sys_ts; - struct timeval sys_tv; - struct timeval *cur_tv; - struct usb_transfer *xfer; - struct libusb_transfer *uxfer; - int ret; - - GET_CONTEXT(ctx); - ret = 0; - - pthread_mutex_lock(&ctx->flying_transfers_lock); - if (USB_LIST_EMPTY(&ctx->flying_transfers)); - goto out; - - ret = clock_gettime(CLOCK_MONOTONIC, &sys_ts); - TIMESPEC_TO_TIMEVAL(&sys_tv, &sys_ts); - - LIST_FOREACH_ENTRY(xfer, &ctx->flying_transfers, list) { - cur_tv = &xfer->timeout; - - if (timerisset(cur_tv) == 0) - goto out; - - if (xfer->flags & USB_TIMED_OUT) - continue; - - if ((cur_tv->tv_sec > sys_tv.tv_sec) || (cur_tv->tv_sec == sys_tv.tv_sec && - cur_tv->tv_usec > sys_tv.tv_usec)) - goto out; - - xfer->flags |= USB_TIMED_OUT; - uxfer = (libusb_transfer *) (((uint8_t *)xfer) + - sizeof(struct usb_transfer)); - ret = libusb_cancel_transfer(uxfer); - } -out: - pthread_mutex_unlock(&ctx->flying_transfers_lock); - return (ret); -} - -static int -handle_events(struct libusb_context *ctx, struct timeval *tv) -{ - struct usb_pollfd *ipollfd; - struct libusb_pollfd *tmppollfd; - struct pollfd *fds; - int tmpfd; - int ret; - int timeout; - nfds_t nfds; - int i; - - nfds = 0; - i = -1; - - pthread_mutex_lock(&ctx->pollfds_lock); - LIST_FOREACH_ENTRY(ipollfd, &ctx->pollfds, list) - nfds++; - - fds = malloc(sizeof(*fds) * nfds); - if (fds == NULL) - return (LIBUSB_ERROR_NO_MEM); - - LIST_FOREACH_ENTRY(ipollfd, &ctx->pollfds, list) { - tmppollfd = &ipollfd->pollfd; - tmpfd = tmppollfd->fd; - i++; - fds[i].fd = tmpfd; - fds[i].events = tmppollfd->events; - fds[i].revents = 0; - } - - pthread_mutex_unlock(&ctx->pollfds_lock); - - timeout = (tv->tv_sec * 1000) + (tv->tv_usec / 1000); - if (tv->tv_usec % 1000) - timeout++; - - ret = poll(fds, nfds, timeout); - if (ret == 0) { - free(fds); - return(handle_timeouts(ctx)); - } else if (ret == -1 && errno == EINTR) { - free(fds); - return LIBUSB_ERROR_INTERRUPTED; - } else if (ret < 0) { - free(fds); - return (LIBUSB_ERROR_IO); - } - - if (fds[0].revents) { - if (ret == 1){ - ret = 0; - goto handled; - } else { - fds[0].revents = 0; - ret--; - } - } - - ret = /*unknown*/0; -handled: - free(fds); - return ret; -} - -int -libusb_handle_events_timeout(libusb_context * ctx, struct timeval *tv) -{ - struct timeval timeout; - struct timeval poll_timeout; - int ret; - - GET_CONTEXT(ctx); - ret = libusb_get_next_timeout(ctx, &timeout); - if (ret != 0) { - if (timerisset(&timeout) == 0) - return (handle_timeouts(ctx)); - if (timercmp(&timeout, tv, <)) - poll_timeout = timeout; - else - poll_timeout = *tv; - } else { - poll_timeout = *tv; - } -retry: - if (libusb_try_lock_events(ctx) == 0) { - ret = handle_events(ctx, &poll_timeout); - libusb_unlock_events(ctx); - return ret; - } - - libusb_lock_event_waiters(ctx); - if (libusb_event_handler_active(ctx) == 0) { - libusb_unlock_event_waiters(ctx); - goto retry; - } - - ret = libusb_wait_for_event(ctx, &poll_timeout); - libusb_unlock_event_waiters(ctx); - - if (ret < 0) - return ret; - else if (ret == 1) - return (handle_timeouts(ctx)); - return (0); -} - -int -libusb_handle_events(libusb_context * ctx) -{ - struct timeval tv; - - tv.tv_sec = 2; - tv.tv_usec = 0; - return (libusb_handle_events_timeout(ctx, &tv)); -} - -int -libusb_handle_events_locked(libusb_context * ctx, struct timeval *tv) -{ - int ret; - struct timeval timeout; - struct timeval poll_tv; - - GET_CONTEXT(ctx); - ret = libusb_get_next_timeout(ctx, &timeout); - if (ret) { - if (timerisset(&timeout) == 0) - return handle_timeouts(ctx); - if (timercmp(&timeout, tv, <) != 0) - poll_tv = timeout; - else - poll_tv = *tv; - } else { - poll_tv = *tv; - } - return (handle_events(ctx, &poll_tv)); -} - -int -libusb_get_next_timeout(libusb_context * ctx, struct timeval *tv) -{ - struct usb_transfer *xfer; - struct timeval *next_tv; - struct timeval cur_tv; - struct timespec cur_ts; - int found; - int ret; - - GET_CONTEXT(ctx); - found = 0; - pthread_mutex_lock(&ctx->flying_transfers_lock); - if (USB_LIST_EMPTY(&ctx->flying_transfers)) - return (0); - - LIST_FOREACH_ENTRY(xfer, &ctx->flying_transfers, list) { - if (!(xfer->flags & LIBUSB_TRANSFER_TIMED_OUT)) { - found = 1; - break ; - } - } - pthread_mutex_unlock(&ctx->flying_transfers_lock); - - if (found == 0) { - return 0; - } - - next_tv = &xfer->timeout; - if (timerisset(next_tv) == 0) - return (0); - - ret = clock_gettime(CLOCK_MONOTONIC, &cur_ts); - if (ret < 0) - return (LIBUSB_ERROR_OTHER); - TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); - - if (timercmp(&cur_tv, next_tv, >=)) - timerclear(tv); - else - timersub(next_tv, &cur_tv, tv); - - return (1); -} - -void -libusb_set_pollfd_notifiers(libusb_context * ctx, - libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, - void *user_data) -{ - GET_CONTEXT(ctx); - ctx->fd_added_cb = added_cb; - ctx->fd_removed_cb = removed_cb; - ctx->fd_cb_user_data = user_data; -} - -struct libusb_pollfd ** -libusb_get_pollfds(libusb_context * ctx) -{ - struct usb_pollfd *pollfd; - libusb_pollfd **ret; - int i; - - GET_CONTEXT(ctx); - i = 0; - pthread_mutex_lock(&ctx->pollfds_lock); - LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) - i++; - - ret = calloc(i + 1 , sizeof(struct libusb_pollfd *)); - if (ret == NULL) { - pthread_mutex_unlock(&ctx->pollfds_lock); - return (NULL); - } - - i = 0; - LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) - ret[i++] = (struct libusb_pollfd *) pollfd; - ret[i] = NULL; - - return (ret); -} - -/* Synchronous device I/O */ - -static void ctrl_tr_cb(struct libusb_transfer *transfer) -{ - int *complet = transfer->user_data; - - *complet = 1; -} - -int -libusb_control_transfer(libusb_device_handle * devh, - uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, - unsigned char *data, uint16_t wLength, unsigned int timeout) -{ - struct libusb_transfer *xfer; - struct libusb_control_setup *ctr; - unsigned char *buff; - int complet; - int ret; - - if (devh == NULL || data == NULL) - return (LIBUSB_ERROR_NO_MEM); - - xfer = libusb_alloc_transfer(0); - if (xfer == NULL) - return (LIBUSB_ERROR_NO_MEM); - - buff = malloc(sizeof(libusb_control_setup) + wLength); - if (buff == NULL) { - libusb_free_transfer(xfer); - return (LIBUSB_ERROR_NO_MEM); - } - - ctr = (libusb_control_setup *)buff; - ctr->bmRequestType = bmRequestType; - ctr->bRequest = bRequest; - ctr->wValue = wValue; - ctr->wIndex = wIndex; - ctr->wLength = wLength; - if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) - memcpy(buff + sizeof(libusb_control_setup), data, wLength); - - xfer->dev_handle = devh; - xfer->endpoint = 0; - xfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; - xfer->timeout = timeout; - xfer->buffer = buff; - xfer->length = sizeof(libusb_control_setup) + wLength; - xfer->user_data = &complet; - xfer->callback = ctrl_tr_cb; - xfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER; - complet = 0; - - if ((ret = libusb_submit_transfer(xfer)) < 0) { - libusb_free_transfer(xfer); - return (ret); - } - - while (!complet) - if ((ret = libusb_handle_events(devh->dev->ctx)) < 0) { - libusb_cancel_transfer(xfer); - libusb_free_transfer(xfer); - while (!complet) - if (libusb_handle_events(devh->dev->ctx)) - break; - return (ret); - } - - if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) - memcpy(data, buff + sizeof(libusb_control_setup), wLength); - - switch (xfer->status) { - case LIBUSB_TRANSFER_COMPLETED: - ret = xfer->actual_length; - break; - case LIBUSB_TRANSFER_TIMED_OUT: - case LIBUSB_TRANSFER_STALL: - case LIBUSB_TRANSFER_NO_DEVICE: - ret = xfer->status; - break; - default: - ret = LIBUSB_ERROR_OTHER; - } - libusb_free_transfer(xfer); - return (ret); -} - -int -libusb_bulk_transfer(struct libusb_device_handle *devh, - unsigned char endpoint, unsigned char *data, int length, - int *transferred, unsigned int timeout) -{ - struct libusb_transfer *xfer; - int complet; - int ret; - - if (devh == NULL || data == NULL) - return (LIBUSB_ERROR_NO_MEM); - - xfer = libusb_alloc_transfer(0); - if (xfer == NULL) - return (LIBUSB_ERROR_NO_MEM); - - xfer->dev_handle = devh; - xfer->endpoint = endpoint; - xfer->type = LIBUSB_TRANSFER_TYPE_BULK; - xfer->timeout = timeout; - xfer->buffer = data; - xfer->length = length; - xfer->user_data = &complet; - xfer->callback = ctrl_tr_cb; - complet = 0; - - if ((ret = libusb_submit_transfer(xfer)) < 0) { - libusb_free_transfer(xfer); - return (ret); - } - - while (!complet) - if ((ret = libusb_handle_events(devh->dev->ctx)) < 0) { - libusb_cancel_transfer(xfer); - libusb_free_transfer(xfer); - while (!complet) - if (libusb_handle_events(devh->dev->ctx)) - break; - return (ret); - } - - *transferred = xfer->actual_length; - switch (xfer->status) { - case LIBUSB_TRANSFER_COMPLETED: - ret = xfer->actual_length; - break; - case LIBUSB_TRANSFER_TIMED_OUT: - case LIBUSB_TRANSFER_OVERFLOW: - case LIBUSB_TRANSFER_STALL: - case LIBUSB_TRANSFER_NO_DEVICE: - ret = xfer->status; - break; - default: - ret = LIBUSB_ERROR_OTHER; - } - - libusb_free_transfer(xfer); - return (0); -} - -/* - * Need to fix xfer->type - */ -int -libusb_interrupt_transfer(struct libusb_device_handle *devh, - unsigned char endpoint, unsigned char *data, int length, int *transferred, - unsigned int timeout) -{ - return (libusb_bulk_transfer(devh, endpoint, data, length, - transferred, timeout)); -}