PERFORCE change 163025 for review
Sylvestre Gallon
syl at FreeBSD.org
Fri May 29 15:12:45 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163025
Change 163025 by syl at 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));
-}
More information about the p4-projects
mailing list