X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=hardware%2Fcommon%2Fusb.c;h=6e678fdb401d1d681000fc3a6e273c7374656957;hb=a7c01629f6e96a79912977ed7262841cedf4ddfa;hp=9a5323e2a2cfb1a3730e26b59daeb2a28009f54c;hpb=1eb0a0df666e8ed117c9b3d3c65291367cbb961f;p=libsigrok.git diff --git a/hardware/common/usb.c b/hardware/common/usb.c index 9a5323e2..6e678fdb 100644 --- a/hardware/common/usb.c +++ b/hardware/common/usb.c @@ -1,5 +1,5 @@ /* - * This file is part of the sigrok project. + * This file is part of the libsigrok project. * * Copyright (C) 2012 Uwe Hermann * Copyright (C) 2012 Bert Vermeulen @@ -33,14 +33,7 @@ #define SUBCLASS_USBTMC 0x03 #define USBTMC_USB488 0x01 -/* Message logging helpers with driver-specific prefix string. */ -#define DRIVER_LOG_DOMAIN "usb: " -#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args) -#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args) -#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args) -#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args) -#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args) -#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) +#define LOG_PREFIX "usb" /** * Find USB devices according to a connection string. @@ -243,3 +236,95 @@ SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb) return ret; } + +#ifdef _WIN32 +SR_PRIV gpointer usb_thread(gpointer data) +{ + struct sr_context *ctx = data; + + while (ctx->usb_thread_running) { + g_mutex_lock(&ctx->usb_mutex); + libusb_wait_for_event(ctx->libusb_ctx, NULL); + SetEvent(ctx->usb_event); + g_mutex_unlock(&ctx->usb_mutex); + g_thread_yield(); + } + + return NULL; +} + +SR_PRIV int usb_callback(int fd, int revents, void *cb_data) +{ + struct sr_context *ctx = cb_data; + int ret; + + g_mutex_lock(&ctx->usb_mutex); + ret = ctx->usb_cb(fd, revents, ctx->usb_cb_data); + + if (ctx->usb_thread_running) { + ResetEvent(ctx->usb_event); + g_mutex_unlock(&ctx->usb_mutex); + } + + return ret; +} +#endif + +SR_PRIV int usb_source_add(struct sr_context *ctx, int timeout, + sr_receive_data_callback_t cb, void *cb_data) +{ + if (ctx->usb_source_present) { + sr_err("A USB event source is already present."); + return SR_ERR; + } + +#ifdef _WIN32 + ctx->usb_event = CreateEvent(NULL, TRUE, FALSE, NULL); + g_mutex_init(&ctx->usb_mutex); + ctx->usb_thread_running = TRUE; + ctx->usb_thread = g_thread_new("usb", usb_thread, ctx); + ctx->usb_pollfd.fd = ctx->usb_event; + ctx->usb_pollfd.events = G_IO_IN; + ctx->usb_cb = cb; + ctx->usb_cb_data = cb_data; + sr_session_source_add_pollfd(&ctx->usb_pollfd, timeout, usb_callback, ctx); +#else + const struct libusb_pollfd **lupfd; + unsigned int i; + + lupfd = libusb_get_pollfds(ctx->libusb_ctx); + for (i = 0; lupfd[i]; i++) + sr_source_add(lupfd[i]->fd, lupfd[i]->events, timeout, cb, cb_data); + free(lupfd); +#endif + ctx->usb_source_present = TRUE; + + return SR_OK; +} + +SR_PRIV int usb_source_remove(struct sr_context *ctx) +{ + if (!ctx->usb_source_present) + return SR_OK; + +#ifdef _WIN32 + ctx->usb_thread_running = FALSE; + g_mutex_unlock(&ctx->usb_mutex); + libusb_unlock_events(ctx->libusb_ctx); + g_thread_join(ctx->usb_thread); + g_mutex_clear(&ctx->usb_mutex); + sr_session_source_remove_pollfd(&ctx->usb_pollfd); + CloseHandle(ctx->usb_event); +#else + const struct libusb_pollfd **lupfd; + unsigned int i; + + lupfd = libusb_get_pollfds(ctx->libusb_ctx); + for (i = 0; lupfd[i]; i++) + sr_source_remove(lupfd[i]->fd); + free(lupfd); +#endif + ctx->usb_source_present = FALSE; + + return SR_OK; +}