diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-25 01:29:57 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-25 01:29:57 +0000 |
commit | 57da20696c104d02637d09b948da3ddf1d71ce2f (patch) | |
tree | 26c27435fe9d4f7751419ad8c0dbddad7d657dc5 | |
parent | 347956a8b0462b76c7b1cf31f1358b3dc9f9849a (diff) | |
download | chromium_src-57da20696c104d02637d09b948da3ddf1d71ce2f.zip chromium_src-57da20696c104d02637d09b948da3ddf1d71ce2f.tar.gz chromium_src-57da20696c104d02637d09b948da3ddf1d71ce2f.tar.bz2 |
Revert 225105 "Roll libusbx to 1.0.17"
Linux ChromiumOS Full: check_licenses failed
'third_party/libusb/src/libusb/version_nano.h' has non-whitelisted license
'UNKNOWN'
FAILED
http://build.chromium.org/p/chromium.chromiumos/builders/Linux%20ChromiumOS%20Full/builds/25811
> Roll libusbx to 1.0.17
>
> R=meacer@chromium.org
>
> Review URL: https://codereview.chromium.org/24227008
TBR=ikarienator@chromium.org
Review URL: https://codereview.chromium.org/24452005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225120 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 321 insertions, 585 deletions
diff --git a/third_party/libusb/src/libusb/core.c b/third_party/libusb/src/libusb/core.c index e816284..e29e8df 100644 --- a/third_party/libusb/src/libusb/core.c +++ b/third_party/libusb/src/libusb/core.c @@ -33,9 +33,6 @@ #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif -#ifdef HAVE_SYSLOG_H -#include <syslog.h> -#endif #ifdef __ANDROID__ #include <android/log.h> @@ -50,8 +47,6 @@ const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend; const struct usbi_os_backend * const usbi_backend = &darwin_backend; #elif defined(OS_OPENBSD) const struct usbi_os_backend * const usbi_backend = &openbsd_backend; -#elif defined(OS_NETBSD) -const struct usbi_os_backend * const usbi_backend = &netbsd_backend; #elif defined(OS_WINDOWS) const struct usbi_os_backend * const usbi_backend = &windows_backend; #elif defined(OS_WINCE) @@ -61,7 +56,7 @@ const struct usbi_os_backend * const usbi_backend = &wince_backend; #endif struct libusb_context *usbi_default_context = NULL; -static const struct libusb_version libusb_version_internal = +const struct libusb_version libusb_version_internal = { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO, LIBUSB_RC, "http://libusbx.org" }; static int default_context_refcnt = 0; @@ -569,10 +564,6 @@ void usbi_disconnect_device(struct libusb_device *dev) dev->attached = 0; usbi_mutex_unlock(&dev->lock); - usbi_mutex_lock(&ctx->usb_devs_lock); - list_del(&dev->list); - usbi_mutex_unlock(&ctx->usb_devs_lock); - /* Signal that an event has occurred for this device if we support hotplug AND * the hotplug pipe is ready. This prevents an event from getting raised during * initial enumeration. libusb_handle_events will take care of dereferencing the @@ -583,6 +574,10 @@ void usbi_disconnect_device(struct libusb_device *dev) usbi_err(DEVICE_CTX(dev), "error writing hotplug message"); } } + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_del(&dev->list); + usbi_mutex_unlock(&ctx->usb_devs_lock); } /* Perform some final sanity checks on a newly discovered device. If this @@ -1878,6 +1873,10 @@ err_free_ctx: if (ctx == usbi_default_context) usbi_default_context = NULL; + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + usbi_mutex_static_lock(&active_contexts_lock); list_del (&ctx->list); usbi_mutex_static_unlock(&active_contexts_lock); @@ -1889,10 +1888,6 @@ err_free_ctx: } usbi_mutex_unlock(&ctx->usb_devs_lock); - usbi_mutex_destroy(&ctx->open_devs_lock); - usbi_mutex_destroy(&ctx->usb_devs_lock); - usbi_mutex_destroy(&ctx->hotplug_cbs_lock); - free(ctx); err_unlock: usbi_mutex_static_unlock(&default_context_lock); @@ -2031,42 +2026,10 @@ int usbi_gettimeofday(struct timeval *tp, void *tzp) } #endif -static void usbi_log_str(struct libusb_context *ctx, - enum libusb_log_level level, const char * str) +static void usbi_log_str(struct libusb_context *ctx, const char * str) { -#if defined(USE_SYSTEM_LOGGING_FACILITY) -#if defined(OS_WINDOWS) || defined(OS_WINCE) - /* Windows CE only supports the Unicode version of OutputDebugString. */ - WCHAR wbuf[USBI_MAX_LOG_LEN]; - MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)); - OutputDebugStringW(wbuf); -#elif defined(__ANDROID__) - int priority = ANDROID_LOG_UNKNOWN; - switch (level) { - case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break; - case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break; - case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break; - case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break; - } - __android_log_write(priority, "libusb", str); -#elif defined(HAVE_SYSLOG_FUNC) - int syslog_level = LOG_INFO; - switch (level) { - case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break; - case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break; - case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break; - case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break; - } - syslog(syslog_level, "%s", str); -#else /* All of gcc, Clang, XCode seem to use #warning */ -#warning System logging is not supported on this platform. Logging to stderr will be used instead. - fputs(str, stderr); -#endif -#else - fputs(str, stderr); -#endif /* USE_SYSTEM_LOGGING_FACILITY */ UNUSED(ctx); - UNUSED(level); + fputs(str, stderr); } void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, @@ -2096,11 +2059,33 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, return; #endif +#ifdef __ANDROID__ + int prio; + switch (level) { + case LOG_LEVEL_INFO: + prio = ANDROID_LOG_INFO; + break; + case LOG_LEVEL_WARNING: + prio = ANDROID_LOG_WARN; + break; + case LOG_LEVEL_ERROR: + prio = ANDROID_LOG_ERROR; + break; + case LOG_LEVEL_DEBUG: + prio = ANDROID_LOG_DEBUG; + break; + default: + prio = ANDROID_LOG_UNKNOWN; + break; + } + + __android_log_vprint(prio, "LibUsb", format, args); +#else usbi_gettimeofday(&now, NULL); if ((global_debug) && (!has_debug_header_been_displayed)) { has_debug_header_been_displayed = 1; - usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>\n"); - usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------\n"); + usbi_log_str(ctx, "[timestamp] [threadID] facility level [function call] <message>\n"); + usbi_log_str(ctx, "--------------------------------------------------------------------------------\n"); } if (now.tv_usec < timestamp_origin.tv_usec) { now.tv_sec--; @@ -2123,7 +2108,7 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, prefix = "debug"; break; case LIBUSB_LOG_LEVEL_NONE: - return; + break; default: prefix = "unknown"; break; @@ -2158,7 +2143,8 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, } strcpy(buf + header_len + text_len, USBI_LOG_LINE_END); - usbi_log_str(ctx, level, buf); + usbi_log_str(ctx, buf); +#endif } void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, diff --git a/third_party/libusb/src/libusb/descriptor.c b/third_party/libusb/src/libusb/descriptor.c index e1c4915..ba6d1467 100644 --- a/third_party/libusb/src/libusb/descriptor.c +++ b/third_party/libusb/src/libusb/descriptor.c @@ -660,7 +660,7 @@ int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, /* iterate through all configurations, returning the index of the configuration * matching a specific bConfigurationValue in the idx output parameter, or -1 * if the config was not found. - * returns 0 on success or a LIBUSB_ERROR code + * returns 0 or a LIBUSB_ERROR code */ int usbi_get_config_index_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, int *idx) @@ -673,10 +673,8 @@ int usbi_get_config_index_by_value(struct libusb_device *dev, int host_endian; int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp), &host_endian); - if (r < 0) { - *idx = -1; + if (r < 0) return r; - } if (tmp[5] == bConfigurationValue) { *idx = i; return 0; diff --git a/third_party/libusb/src/libusb/hotplug.c b/third_party/libusb/src/libusb/hotplug.c index 081bc79..6b04342 100644 --- a/third_party/libusb/src/libusb/hotplug.c +++ b/third_party/libusb/src/libusb/hotplug.c @@ -59,11 +59,7 @@ * * A callback function must return an int (0 or 1) indicating whether the callback is * expecting additional events. Returning 0 will rearm the callback and 1 will cause - * the callback to be deregistered. Note that when callbacks are called from - * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE - * flag, the callback return value is ignored, iow you cannot cause a callback - * to be deregistered by returning 1 when it is called from - * libusb_hotplug_register_callback(). + * the callback to be deregistered. * * Callbacks for a particular context are automatically deregistered by libusb_exit(). * @@ -171,7 +167,8 @@ static int usbi_hotplug_match_cb (struct libusb_context *ctx, return 0; } - return hotplug_cb->cb (ctx, dev, event, hotplug_cb->user_data); + return hotplug_cb->cb (ctx == usbi_default_context ? NULL : ctx, + dev, event, hotplug_cb->user_data); } void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, @@ -195,7 +192,18 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, usbi_mutex_unlock(&ctx->hotplug_cbs_lock); - /* the backend is expected to call the callback for each active transfer */ + /* loop through and disconnect all open handles for this device */ + if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { + struct libusb_device_handle *handle; + + usbi_mutex_lock(&ctx->open_devs_lock); + list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { + if (dev == handle->dev) { + usbi_handle_disconnect (handle); + } + } + usbi_mutex_unlock(&ctx->open_devs_lock); + } } int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, @@ -245,29 +253,19 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, list_add(&new_callback->list, &ctx->hotplug_cbs); - usbi_mutex_unlock(&ctx->hotplug_cbs_lock); - - if (flags & LIBUSB_HOTPLUG_ENUMERATE) { - int i, len; - struct libusb_device **devs; - - len = (int) libusb_get_device_list(ctx, &devs); - if (len < 0) { - libusb_hotplug_deregister_callback(ctx, - new_callback->handle); - return len; - } + struct libusb_device *dev; - for (i = 0; i < len; i++) { - usbi_hotplug_match_cb(ctx, devs[i], - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, - new_callback); + usbi_mutex_lock(&ctx->usb_devs_lock); + + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) { + (void) usbi_hotplug_match_cb (ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, new_callback); } - libusb_free_device_list(devs, 1); + usbi_mutex_unlock(&ctx->usb_devs_lock); } + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); if (handle) { *handle = new_callback->handle; diff --git a/third_party/libusb/src/libusb/io.c b/third_party/libusb/src/libusb/io.c index 4f22963..4368b99 100644 --- a/third_party/libusb/src/libusb/io.c +++ b/third_party/libusb/src/libusb/io.c @@ -787,7 +787,7 @@ void cb(struct libusb_transfer *transfer) void myfunc() { struct libusb_transfer *transfer; - unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned (2))); + unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE]; int completed = 0; transfer = libusb_alloc_transfer(0); @@ -1459,8 +1459,6 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) } usbi_mutex_unlock(&ctx->flying_transfers_lock); - /* keep a reference to this device */ - libusb_ref_device(transfer->dev_handle->dev); out: updated_fds = (itransfer->flags & USBI_TRANSFER_UPDATED_FDS); usbi_mutex_unlock(&itransfer->lock); @@ -1524,7 +1522,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct libusb_context *ctx = TRANSFER_CTX(transfer); - struct libusb_device_handle *handle = transfer->dev_handle; uint8_t flags; int r = 0; @@ -1565,7 +1562,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, usbi_mutex_lock(&ctx->event_waiters_lock); usbi_cond_broadcast(&ctx->event_waiters_cond); usbi_mutex_unlock(&ctx->event_waiters_lock); - libusb_unref_device(handle->dev); return 0; } @@ -2000,8 +1996,8 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv) /* read the message from the hotplug thread */ ret = usbi_read(ctx->hotplug_pipe[0], &message, sizeof (message)); - if (ret != sizeof(message)) { - usbi_err(ctx, "hotplug pipe read error %d != %u", + if (ret < sizeof(message)) { + usbi_err(ctx, "hotplug pipe read error %d < %d", ret, sizeof(message)); r = LIBUSB_ERROR_OTHER; goto handled; diff --git a/third_party/libusb/src/libusb/libusb.h b/third_party/libusb/src/libusb/libusb.h index d144b3e..15bd0d5 100644 --- a/third_party/libusb/src/libusb/libusb.h +++ b/third_party/libusb/src/libusb/libusb.h @@ -156,7 +156,7 @@ typedef unsigned __int32 uint32_t; extern "C" { #endif -/** \fn libusb_cpu_to_le16 +/** \def libusb_cpu_to_le16 * \ingroup misc * Convert a 16-bit value from host-endian to little-endian format. On * little endian systems, this function does nothing. On big endian systems, @@ -1434,7 +1434,7 @@ static inline unsigned char *libusb_control_transfer_get_data( static inline struct libusb_control_setup *libusb_control_transfer_get_setup( struct libusb_transfer *transfer) { - return (struct libusb_control_setup *)(void *) transfer->buffer; + return (struct libusb_control_setup *) transfer->buffer; } /** \ingroup asyncio @@ -1443,7 +1443,6 @@ static inline struct libusb_control_setup *libusb_control_transfer_get_setup( * be given in host-endian byte order. * * \param buffer buffer to output the setup packet into - * This pointer must be aligned to at least 2 bytes boundary. * \param bmRequestType see the * \ref libusb_control_setup::bmRequestType "bmRequestType" field of * \ref libusb_control_setup @@ -1464,7 +1463,7 @@ static inline void libusb_fill_control_setup(unsigned char *buffer, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { - struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + struct libusb_control_setup *setup = (struct libusb_control_setup *) buffer; setup->bmRequestType = bmRequestType; setup->bRequest = bRequest; setup->wValue = libusb_cpu_to_le16(wValue); @@ -1500,7 +1499,6 @@ void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); * \param dev_handle handle of the device that will handle the transfer * \param buffer data buffer. If provided, this function will interpret the * first 8 bytes as a setup packet and infer the transfer length from that. - * This pointer must be aligned to at least 2 bytes boundary. * \param callback callback function to be invoked on transfer completion * \param user_data user data to pass to callback function * \param timeout timeout for the transfer in milliseconds @@ -1510,7 +1508,7 @@ static inline void libusb_fill_control_transfer( unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) { - struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + struct libusb_control_setup *setup = (struct libusb_control_setup *) buffer; transfer->dev_handle = dev_handle; transfer->endpoint = 0; transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; @@ -1885,7 +1883,7 @@ typedef enum { * * Since version 1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102 * - * \param ctx context of this notification + * \param libusb_context context of this notification * \param device libusb_device this event occurred on * \param event event that occurred * \param user_data user data provided when this callback was registered @@ -1905,18 +1903,6 @@ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, * armed until either it is deregistered with libusb_hotplug_deregister_callback() * or the supplied callback returns 1 to indicate it is finished processing events. * - * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be - * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices - * already plugged into the machine. Note that libusbx modifies its internal - * device list from a separate thread, while calling hotplug callbacks from - * libusb_handle_events(), so it is possible for a device to already be present - * on, or removed from, its internal device list, while the hotplug callbacks - * still need to be dispatched. This means that when using \ref - * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival - * of the same device, once from libusb_hotplug_register_callback() and once - * from libusb_handle_events(); and/or your callback may be called for the - * removal of a device for which an arrived call was never made. - * * Since version 1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102 * * \param[in] ctx context to register this callback with diff --git a/third_party/libusb/src/libusb/libusbi.h b/third_party/libusb/src/libusb/libusbi.h index bc608b92..02efae30 100644 --- a/third_party/libusb/src/libusb/libusbi.h +++ b/third_party/libusb/src/libusb/libusbi.h @@ -23,8 +23,6 @@ #include "config.h" -#include <stdlib.h> - #include <stddef.h> #include <stdint.h> #include <time.h> @@ -435,7 +433,7 @@ void usbi_connect_device (struct libusb_device *dev); void usbi_disconnect_device (struct libusb_device *dev); /* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ -#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) +#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) #include <unistd.h> #include "os/poll_posix.h" #elif defined(OS_WINDOWS) || defined(OS_WINCE) @@ -997,7 +995,6 @@ extern const struct usbi_os_backend * const usbi_backend; extern const struct usbi_os_backend linux_usbfs_backend; extern const struct usbi_os_backend darwin_backend; extern const struct usbi_os_backend openbsd_backend; -extern const struct usbi_os_backend netbsd_backend; extern const struct usbi_os_backend windows_backend; extern const struct usbi_os_backend wince_backend; diff --git a/third_party/libusb/src/libusb/os/darwin_usb.c b/third_party/libusb/src/libusb/os/darwin_usb.c index 58467c3..3f315e8 100644 --- a/third_party/libusb/src/libusb/os/darwin_usb.c +++ b/third_party/libusb/src/libusb/os/darwin_usb.c @@ -210,7 +210,6 @@ static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 loca return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator); } -/* Returns 1 on success, 0 on failure. */ static int get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) { CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0); int ret = 0; @@ -288,7 +287,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { usbi_dbg ("notifying context %p of device disconnect", ctx); - dev = usbi_get_device_by_session_id(ctx, (unsigned long) session); + dev = usbi_get_device_by_session_id(ctx, session); if (dev) { /* signal the core that this device has been disconnected. the core will tear down this device when the reference count reaches 0 */ @@ -702,7 +701,7 @@ static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct da else usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device", idVendor, idProduct, darwin_error_str (ret), ret); - return darwin_to_libusb (ret); + return -1; } /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */ @@ -710,7 +709,7 @@ static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct da /* not a valid device */ usbi_warn (ctx, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device", idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct)); - return LIBUSB_ERROR_NO_DEVICE; + return -1; } usbi_dbg ("cached device descriptor:"); @@ -730,19 +729,21 @@ static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct da dev->can_enumerate = 1; - return LIBUSB_SUCCESS; + return 0; } static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out) { struct darwin_cached_device *new_device; - UInt64 sessionID = 0, parent_sessionID = 0; + UInt64 sessionID, parent_sessionID; int ret = LIBUSB_SUCCESS; usb_device_t **device; io_service_t parent; kern_return_t result; UInt8 port = 0; + *cached_out = NULL; + /* get some info from the io registry */ (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID); (void) get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, &port); @@ -758,8 +759,6 @@ static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t ser usbi_mutex_lock(&darwin_cached_devices_lock); do { - *cached_out = NULL; - list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) { usbi_dbg("matching sessionID 0x%x against cached device with sessionID 0x%x", sessionID, new_device->session); if (new_device->session == sessionID) { @@ -774,18 +773,20 @@ static int darwin_get_cached_device(struct libusb_context *ctx, io_service_t ser usbi_dbg("caching new device with sessionID 0x%x\n", sessionID); - device = darwin_device_from_service (service); - if (!device) { - ret = LIBUSB_ERROR_NO_DEVICE; - break; - } - new_device = calloc (1, sizeof (*new_device)); if (!new_device) { ret = LIBUSB_ERROR_NO_MEM; break; } + device = darwin_device_from_service (service); + if (!device) { + ret = LIBUSB_ERROR_NO_DEVICE; + free (new_device); + new_device = NULL; + break; + } + /* add this device to the cached device list */ list_add(&new_device->list, &darwin_cached_devices); @@ -832,7 +833,7 @@ static int process_new_device (struct libusb_context *ctx, io_service_t service) do { ret = darwin_get_cached_device (ctx, service, &cached_device); - if (ret < 0 || !cached_device->can_enumerate) { + if (ret < 0 || (cached_device && !cached_device->can_enumerate)) { return ret; } @@ -845,7 +846,7 @@ static int process_new_device (struct libusb_context *ctx, io_service_t service) usbi_dbg ("allocating new device in context %p for with session 0x%08x", ctx, cached_device->session); - dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session); + dev = usbi_alloc_device(ctx, cached_device->session); if (!dev) { return LIBUSB_ERROR_NO_MEM; } @@ -856,7 +857,7 @@ static int process_new_device (struct libusb_context *ctx, io_service_t service) darwin_ref_cached_device (priv->dev); if (cached_device->parent_session > 0) { - dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session); + dev->parent_dev = usbi_get_device_by_session_id (ctx, cached_device->parent_session); } else { dev->parent_dev = NULL; } diff --git a/third_party/libusb/src/libusb/os/linux_netlink.c b/third_party/libusb/src/libusb/os/linux_netlink.c index f1c1be1..3a68f69 100644 --- a/third_party/libusb/src/libusb/os/linux_netlink.c +++ b/third_party/libusb/src/libusb/os/linux_netlink.c @@ -21,10 +21,6 @@ */ #include "config.h" -#include "libusb.h" -#include "libusbi.h" -#include "linux_usbfs.h" - #include <ctype.h> #include <dirent.h> #include <errno.h> @@ -34,113 +30,46 @@ #include <stdlib.h> #include <string.h> #include <sys/types.h> - -#ifdef HAVE_ASM_TYPES_H -#include <asm/types.h> -#endif - -#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> -#endif - #include <arpa/inet.h> -#ifdef HAVE_LINUX_NETLINK_H -#include <linux/netlink.h> -#endif +#include "libusb.h" +#include "libusbi.h" +#include "linux_usbfs.h" -#ifdef HAVE_LINUX_FILTER_H +#include <linux/netlink.h> #include <linux/filter.h> -#endif #define KERNEL 1 static int linux_netlink_socket = -1; -static int netlink_control_pipe[2] = { -1, -1 }; static pthread_t libusb_linux_event_thread; static void *linux_netlink_event_thread_main(void *arg); struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL }; -static int set_fd_cloexec_nb (int fd) -{ - int flags; - -#if defined(FD_CLOEXEC) - flags = fcntl (linux_netlink_socket, F_GETFD); - if (0 > flags) { - return -1; - } - - if (!(flags & FD_CLOEXEC)) { - fcntl (linux_netlink_socket, F_SETFD, flags | FD_CLOEXEC); - } -#endif - - flags = fcntl (linux_netlink_socket, F_GETFL); - if (0 > flags) { - return -1; - } - - if (!(flags & O_NONBLOCK)) { - fcntl (linux_netlink_socket, F_SETFL, flags | O_NONBLOCK); - } - - return 0; -} - int linux_netlink_start_event_monitor(void) { - int socktype = SOCK_RAW; int ret; snl.nl_groups = KERNEL; -#if defined(SOCK_CLOEXEC) - socktype |= SOCK_CLOEXEC; -#endif -#if defined(SOCK_NONBLOCK) - socktype |= SOCK_NONBLOCK; -#endif - - linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); - if (-1 == linux_netlink_socket && EINVAL == errno) { - linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); - } - + linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); if (-1 == linux_netlink_socket) { return LIBUSB_ERROR_OTHER; } - ret = set_fd_cloexec_nb (linux_netlink_socket); - if (0 != ret) { - close (linux_netlink_socket); - linux_netlink_socket = -1; - return LIBUSB_ERROR_OTHER; - } - ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl)); if (0 != ret) { - close(linux_netlink_socket); return LIBUSB_ERROR_OTHER; } /* TODO -- add authentication */ /* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */ - ret = usbi_pipe(netlink_control_pipe); - if (ret) { - usbi_err(NULL, "could not create netlink control pipe"); - close(linux_netlink_socket); - return LIBUSB_ERROR_OTHER; - } - ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL); if (0 != ret) { - close(netlink_control_pipe[0]); - close(netlink_control_pipe[1]); - close(linux_netlink_socket); return LIBUSB_ERROR_OTHER; } @@ -150,29 +79,21 @@ int linux_netlink_start_event_monitor(void) int linux_netlink_stop_event_monitor(void) { int r; - char dummy = 1; if (-1 == linux_netlink_socket) { /* already closed. nothing to do */ return LIBUSB_SUCCESS; } - /* Write some dummy data to the control pipe and - * wait for the thread to exit */ - r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy)); - if (r <= 0) { - usbi_warn(NULL, "netlink control pipe signal failed"); + r = close(linux_netlink_socket); + if (0 > r) { + usbi_err(NULL, "error closing netlink socket. %s", strerror(errno)); + return LIBUSB_ERROR_OTHER; } - pthread_join(libusb_linux_event_thread, NULL); - close(linux_netlink_socket); - linux_netlink_socket = -1; + pthread_cancel(libusb_linux_event_thread); - /* close and reset control pipe */ - close(netlink_control_pipe[0]); - close(netlink_control_pipe[1]); - netlink_control_pipe[0] = -1; - netlink_control_pipe[1] = -1; + linux_netlink_socket = -1; return LIBUSB_SUCCESS; } @@ -293,7 +214,7 @@ static int linux_netlink_read_message(void) /* signal device is available (or not) to all contexts */ if (detached) - linux_device_disconnected(busnum, devaddr, sys_name); + linux_hotplug_disconnected(busnum, devaddr, sys_name); else linux_hotplug_enumerate(busnum, devaddr, sys_name); @@ -302,32 +223,20 @@ static int linux_netlink_read_message(void) static void *linux_netlink_event_thread_main(void *arg) { - char dummy; - int r; - struct pollfd fds[] = { - { .fd = netlink_control_pipe[0], - .events = POLLIN }, - { .fd = linux_netlink_socket, - .events = POLLIN }, - }; + struct pollfd fds = {.fd = linux_netlink_socket, + .events = POLLIN}; /* silence compiler warning */ (void) arg; - while (poll(fds, 2, -1) >= 0) { - if (fds[0].revents & POLLIN) { - /* activity on control pipe, read the byte and exit */ - r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy)); - if (r <= 0) { - usbi_warn(NULL, "netlink control pipe read failed"); - } + while (1 == poll(&fds, 1, -1)) { + if (POLLIN != fds.revents) { break; } - if (fds[1].revents & POLLIN) { - usbi_mutex_static_lock(&linux_hotplug_lock); - linux_netlink_read_message(); - usbi_mutex_static_unlock(&linux_hotplug_lock); - } + + usbi_mutex_static_lock(&linux_hotplug_lock); + linux_netlink_read_message(); + usbi_mutex_static_unlock(&linux_hotplug_lock); } return NULL; diff --git a/third_party/libusb/src/libusb/os/linux_udev.c b/third_party/libusb/src/libusb/os/linux_udev.c index 99ac943..5a2aadf 100644 --- a/third_party/libusb/src/libusb/os/linux_udev.c +++ b/third_party/libusb/src/libusb/os/linux_udev.c @@ -46,7 +46,6 @@ /* udev context */ static struct udev *udev_ctx = NULL; static int udev_monitor_fd = -1; -static int udev_control_pipe[2] = {-1, -1}; static struct udev_monitor *udev_monitor = NULL; static pthread_t linux_event_thread; @@ -96,23 +95,14 @@ int linux_udev_start_event_monitor(void) goto err_free_monitor; } - r = usbi_pipe(udev_control_pipe); - if (r) { - usbi_err(NULL, "could not create udev control pipe"); - goto err_free_monitor; - } - r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL); if (r) { usbi_err(NULL, "creating hotplug event thread (%d)", r); - goto err_close_pipe; + goto err_free_monitor; } return LIBUSB_SUCCESS; -err_close_pipe: - close(udev_control_pipe[0]); - close(udev_control_pipe[1]); err_free_monitor: udev_monitor_unref(udev_monitor); udev_monitor = NULL; @@ -125,19 +115,14 @@ err_free_ctx: int linux_udev_stop_event_monitor(void) { - char dummy = 1; - int r; - assert(udev_ctx != NULL); assert(udev_monitor != NULL); assert(udev_monitor_fd != -1); - /* Write some dummy data to the control pipe and - * wait for the thread to exit */ - r = usbi_write(udev_control_pipe[1], &dummy, sizeof(dummy)); - if (r <= 0) { - usbi_warn(NULL, "udev control pipe signal failed"); - } + /* Cancel the event thread. This is the only way to guarantee the + thread exits since closing the monitor fd won't necessarily cause + poll to return. */ + pthread_cancel(linux_event_thread); pthread_join(linux_event_thread, NULL); /* Release the udev monitor */ @@ -149,45 +134,27 @@ int linux_udev_stop_event_monitor(void) udev_unref(udev_ctx); udev_ctx = NULL; - /* close and reset control pipe */ - close(udev_control_pipe[0]); - close(udev_control_pipe[1]); - udev_control_pipe[0] = -1; - udev_control_pipe[1] = -1; - return LIBUSB_SUCCESS; } static void *linux_udev_event_thread_main(void *arg) { - char dummy; - int r; struct udev_device* udev_dev; - struct pollfd fds[] = { - {.fd = udev_control_pipe[0], - .events = POLLIN}, - {.fd = udev_monitor_fd, - .events = POLLIN}, - }; + struct pollfd fds = {.fd = udev_monitor_fd, + .events = POLLIN}; usbi_dbg("udev event thread entering."); - while (poll(fds, 2, -1) >= 0) { - if (fds[0].revents & POLLIN) { - /* activity on control pipe, read the byte and exit */ - r = usbi_read(udev_control_pipe[0], &dummy, sizeof(dummy)); - if (r <= 0) { - usbi_warn(NULL, "udev control pipe read failed"); - } + while (1 == poll(&fds, 1, -1)) { + if (NULL == udev_monitor || POLLIN != fds.revents) { break; } - if (fds[1].revents & POLLIN) { - usbi_mutex_static_lock(&linux_hotplug_lock); - udev_dev = udev_monitor_receive_device(udev_monitor); - if (udev_dev) - udev_hotplug_event(udev_dev); - usbi_mutex_static_unlock(&linux_hotplug_lock); - } + + usbi_mutex_static_lock(&linux_hotplug_lock); + udev_dev = udev_monitor_receive_device(udev_monitor); + if (udev_dev) + udev_hotplug_event(udev_dev); + usbi_mutex_static_unlock(&linux_hotplug_lock); } usbi_dbg("udev event thread exiting"); @@ -240,7 +207,7 @@ static void udev_hotplug_event(struct udev_device* udev_dev) if (strncmp(udev_action, "add", 3) == 0) { linux_hotplug_enumerate(busnum, devaddr, sys_name); } else if (detached) { - linux_device_disconnected(busnum, devaddr, sys_name); + linux_hotplug_disconnected(busnum, devaddr, sys_name); } else { usbi_err(NULL, "ignoring udev action %s", udev_action); } diff --git a/third_party/libusb/src/libusb/os/linux_usbfs.c b/third_party/libusb/src/libusb/os/linux_usbfs.c index 142fa2b..09288af 100644 --- a/third_party/libusb/src/libusb/os/linux_usbfs.c +++ b/third_party/libusb/src/libusb/os/linux_usbfs.c @@ -1,4 +1,3 @@ -/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ /* * Linux usbfs backend for libusbx * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org> @@ -121,9 +120,7 @@ static int sysfs_has_descriptors = -1; /* how many times have we initted (and not exited) ? */ static volatile int init_count = 0; -/* Serialize hotplug start/stop */ -usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; -/* Serialize scan-devices, event-thread, and poll */ +/* Serialize hotplug start/stop, scan-devices, event-thread, and poll */ usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; static int linux_start_event_monitor(void); @@ -422,7 +419,7 @@ static int op_init(struct libusb_context *ctx) if (sysfs_has_descriptors) usbi_dbg("sysfs has complete descriptors"); - usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + usbi_mutex_static_lock(&linux_hotplug_lock); r = LIBUSB_SUCCESS; if (init_count == 0) { /* start up hotplug event handler */ @@ -436,20 +433,20 @@ static int op_init(struct libusb_context *ctx) linux_stop_event_monitor(); } else usbi_err(ctx, "error starting hotplug event monitor"); - usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); + usbi_mutex_static_unlock(&linux_hotplug_lock); return r; } static void op_exit(void) { - usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + usbi_mutex_static_lock(&linux_hotplug_lock); assert(init_count != 0); if (!--init_count) { /* tear down event handler */ (void)linux_stop_event_monitor(); } - usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); + usbi_mutex_static_unlock(&linux_hotplug_lock); } static int linux_start_event_monitor(void) @@ -472,19 +469,11 @@ static int linux_stop_event_monitor(void) static int linux_scan_devices(struct libusb_context *ctx) { - int ret; - - usbi_mutex_static_lock(&linux_hotplug_lock); - #if defined(USE_UDEV) - ret = linux_udev_scan_devices(ctx); + return linux_udev_scan_devices(ctx); #else - ret = linux_default_scan_devices(ctx); + return linux_default_scan_devices(ctx); #endif - - usbi_mutex_static_unlock(&linux_hotplug_lock); - - return ret; } static void op_hotplug_poll(void) @@ -607,8 +596,6 @@ int linux_get_device_address (struct libusb_context *ctx, int detached, uint8_t *busnum, uint8_t *devaddr,const char *dev_node, const char *sys_name) { - int sysfs_attr; - usbi_dbg("getting address for device: %s detached: %d", sys_name, detached); /* can't use sysfs to read the bus and device number if the * device has been detached */ @@ -629,22 +616,17 @@ int linux_get_device_address (struct libusb_context *ctx, int detached, usbi_dbg("scan %s", sys_name); - sysfs_attr = __read_sysfs_attr(ctx, sys_name, "busnum"); - if (0 > sysfs_attr) - return sysfs_attr; - if (sysfs_attr > 255) - return LIBUSB_ERROR_INVALID_PARAM; - *busnum = (uint8_t) sysfs_attr; - - sysfs_attr = __read_sysfs_attr(ctx, sys_name, "devnum"); - if (0 > sysfs_attr) - return sysfs_attr; - if (sysfs_attr > 255) - return LIBUSB_ERROR_INVALID_PARAM; + *busnum = __read_sysfs_attr(ctx, sys_name, "busnum"); + if (0 > *busnum) + return *busnum; - *devaddr = (uint8_t) sysfs_attr; + *devaddr = __read_sysfs_attr(ctx, sys_name, "devnum"); + if (0 > *devaddr) + return *devaddr; usbi_dbg("bus=%d dev=%d", *busnum, *devaddr); + if (*busnum > 255 || *devaddr > 255) + return LIBUSB_ERROR_INVALID_PARAM; return LIBUSB_SUCCESS; } @@ -1090,7 +1072,7 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na usbi_mutex_static_unlock(&active_contexts_lock); } -void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name) +void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name) { struct libusb_context *ctx; struct libusb_device *dev; @@ -1265,20 +1247,8 @@ static int op_open(struct libusb_device_handle *handle) int r; hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0); - if (hpriv->fd < 0) { - if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) { - /* device will still be marked as attached if hotplug monitor thread - * hasn't processed remove event yet */ - usbi_mutex_static_lock(&linux_hotplug_lock); - if (handle->dev->attached) { - usbi_dbg("open failed with no device, but device still attached"); - linux_device_disconnected(handle->dev->bus_number, - handle->dev->device_address, NULL); - } - usbi_mutex_static_unlock(&linux_hotplug_lock); - } + if (hpriv->fd < 0) return hpriv->fd; - } r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); if (r < 0) { @@ -2512,13 +2482,6 @@ static int op_handle_events(struct libusb_context *ctx, if (pollfd->revents & POLLERR) { usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); usbi_handle_disconnect(handle); - /* device will still be marked as attached if hotplug monitor thread - * hasn't processed remove event yet */ - usbi_mutex_static_lock(&linux_hotplug_lock); - if (handle->dev->attached) - linux_device_disconnected(handle->dev->bus_number, - handle->dev->device_address, NULL); - usbi_mutex_static_unlock(&linux_hotplug_lock); continue; } diff --git a/third_party/libusb/src/libusb/os/linux_usbfs.h b/third_party/libusb/src/libusb/os/linux_usbfs.h index 1f5b191..499bab7 100644 --- a/third_party/libusb/src/libusb/os/linux_usbfs.h +++ b/third_party/libusb/src/libusb/os/linux_usbfs.h @@ -170,7 +170,7 @@ void linux_netlink_hotplug_poll(void); #endif void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name); -void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name); +void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name); int linux_get_device_address (struct libusb_context *ctx, int detached, uint8_t *busnum, uint8_t *devaddr, const char *dev_node, diff --git a/third_party/libusb/src/libusb/os/openbsd_usb.c b/third_party/libusb/src/libusb/os/openbsd_usb.c index 2997e53..f4fd454 100644 --- a/third_party/libusb/src/libusb/os/openbsd_usb.c +++ b/third_party/libusb/src/libusb/os/openbsd_usb.c @@ -1,5 +1,5 @@ /* - * Copyright © 2011-2013 Martin Pieuchot <mpi@openbsd.org> + * Copyright © 2011 Martin Pieuchot <mpi@openbsd.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,8 +32,8 @@ #include "libusbi.h" struct device_priv { - char *devname; /* name of the ugen(4) node */ - int fd; /* device file descriptor */ + char devnode[16]; + int fd; unsigned char *cdesc; /* active config descriptor */ usb_device_descriptor_t ddesc; /* usb device descriptor */ @@ -82,14 +82,11 @@ static int obsd_clock_gettime(int, struct timespec *); * Private functions */ static int _errno_to_libusb(int); -static int _cache_active_config_descriptor(struct libusb_device *); +static int _cache_active_config_descriptor(struct libusb_device *, int); static int _sync_control_transfer(struct usbi_transfer *); static int _sync_gen_transfer(struct usbi_transfer *); static int _access_endpoint(struct libusb_transfer *); -static int _bus_open(int); - - const struct usbi_os_backend openbsd_backend = { "Synchronous OpenBSD backend", 0, @@ -134,105 +131,79 @@ const struct usbi_os_backend openbsd_backend = { 0, /* add_iso_packet_size */ }; -#define DEVPATH "/dev/" -#define USBDEV DEVPATH "usb" - int obsd_get_device_list(struct libusb_context * ctx, struct discovered_devs **discdevs) { - struct discovered_devs *ddd; struct libusb_device *dev; struct device_priv *dpriv; struct usb_device_info di; - struct usb_device_ddesc dd; unsigned long session_id; - char devices[USB_MAX_DEVICES]; - char busnode[16]; - char *udevname; - int fd, addr, i, j; + char devnode[16]; + int fd, err, i; usbi_dbg(""); - for (i = 0; i < 8; i++) { - snprintf(busnode, sizeof(busnode), USBDEV "%d", i); + /* Only ugen(4) is supported */ + for (i = 0; i < USB_MAX_DEVICES; i++) { + /* Control endpoint is always .00 */ + snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i); - if ((fd = open(busnode, O_RDWR)) < 0) { + if ((fd = open(devnode, O_RDONLY)) < 0) { if (errno != ENOENT && errno != ENXIO) - usbi_err(ctx, "could not open %s", busnode); + usbi_err(ctx, "could not open %s", devnode); continue; } - bzero(devices, sizeof(devices)); - for (addr = 1; addr < USB_MAX_DEVICES; addr++) { - if (devices[addr]) - continue; - - di.udi_addr = addr; - if (ioctl(fd, USB_DEVICEINFO, &di) < 0) - continue; - - /* - * XXX If ugen(4) is attached to the USB device - * it will be used. - */ - udevname = NULL; - for (j = 0; j < USB_MAX_DEVNAMES; j++) - if (!strncmp("ugen", di.udi_devnames[j], 4)) { - udevname = strdup(di.udi_devnames[j]); - break; - } - - session_id = (di.udi_bus << 8 | di.udi_addr); - dev = usbi_get_device_by_session_id(ctx, session_id); - - if (dev == NULL) { - dev = usbi_alloc_device(ctx, session_id); - if (dev == NULL) { - close(fd); - return (LIBUSB_ERROR_NO_MEM); - } - - dev->bus_number = di.udi_bus; - dev->device_address = di.udi_addr; - dev->speed = di.udi_speed; - - dpriv = (struct device_priv *)dev->os_priv; - dpriv->fd = -1; - dpriv->cdesc = NULL; - dpriv->devname = udevname; - - dd.udd_bus = di.udi_bus; - dd.udd_addr = di.udi_addr; - if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) { - libusb_unref_device(dev); - continue; - } - dpriv->ddesc = dd.udd_desc; - - if (_cache_active_config_descriptor(dev)) { - libusb_unref_device(dev); - continue; - } - - if (usbi_sanitize_device(dev)) - libusb_unref_device(dev); - } + if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0) + continue; + + session_id = (di.udi_bus << 8 | di.udi_addr); + dev = usbi_get_device_by_session_id(ctx, session_id); - ddd = discovered_devs_append(*discdevs, dev); - if (ddd == NULL) { - close(fd); + if (dev) { + dev = libusb_ref_device(dev); + } else { + dev = usbi_alloc_device(ctx, session_id); + if (dev == NULL) return (LIBUSB_ERROR_NO_MEM); + + dev->bus_number = di.udi_bus; + dev->device_address = di.udi_addr; + dev->speed = di.udi_speed; + + dpriv = (struct device_priv *)dev->os_priv; + strlcpy(dpriv->devnode, devnode, sizeof(devnode)); + dpriv->fd = -1; + + if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) { + err = errno; + goto error; } - *discdevs = ddd; - devices[addr] = 1; - } + dpriv->cdesc = NULL; + if (_cache_active_config_descriptor(dev, fd)) { + err = errno; + goto error; + } + if ((err = usbi_sanitize_device(dev))) + goto error; + } close(fd); + + if (discovered_devs_append(*discdevs, dev) == NULL) + return (LIBUSB_ERROR_NO_MEM); + + libusb_unref_device(dev); } return (LIBUSB_SUCCESS); + +error: + close(fd); + libusb_unref_device(dev); + return _errno_to_libusb(err); } int @@ -240,22 +211,16 @@ obsd_open(struct libusb_device_handle *handle) { struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; - char devnode[16]; - if (dpriv->devname) { - /* - * Only open ugen(4) attached devices read-write, all - * read-only operations are done through the bus node. - */ - snprintf(devnode, sizeof(devnode), DEVPATH "%s.00", - dpriv->devname); - dpriv->fd = open(devnode, O_RDWR); + dpriv->fd = open(dpriv->devnode, O_RDWR); + if (dpriv->fd < 0) { + dpriv->fd = open(dpriv->devnode, O_RDONLY); if (dpriv->fd < 0) return _errno_to_libusb(errno); - - usbi_dbg("open %s: fd %d", devnode, dpriv->fd); } + usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd); + if (pipe(hpriv->pipe) < 0) return _errno_to_libusb(errno); @@ -268,12 +233,10 @@ obsd_close(struct libusb_device_handle *handle) struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv; struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; - if (dpriv->devname) { - usbi_dbg("close: fd %d", dpriv->fd); + usbi_dbg("close: fd %d", dpriv->fd); - close(dpriv->fd); - dpriv->fd = -1; - } + close(dpriv->fd); + dpriv->fd = -1; usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]); @@ -301,8 +264,9 @@ obsd_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buf, size_t len, int *host_endian) { struct device_priv *dpriv = (struct device_priv *)dev->os_priv; - usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; + usb_config_descriptor_t *ucd; + ucd = (usb_config_descriptor_t *) dpriv->cdesc; len = MIN(len, UGETW(ucd->wTotalLength)); usbi_dbg("len %d", len); @@ -311,48 +275,58 @@ obsd_get_active_config_descriptor(struct libusb_device *dev, *host_endian = 0; - return (len); + return len; } int obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx, unsigned char *buf, size_t len, int *host_endian) { - struct usb_device_fdesc udf; + struct device_priv *dpriv = (struct device_priv *)dev->os_priv; + struct usb_full_desc ufd; int fd, err; - if ((fd = _bus_open(dev->bus_number)) < 0) - return _errno_to_libusb(errno); + usbi_dbg("index %d, len %d", idx, len); - udf.udf_bus = dev->bus_number; - udf.udf_addr = dev->device_address; - udf.udf_config_index = idx; - udf.udf_size = len; - udf.udf_data = buf; + /* A config descriptor may be requested before opening the device */ + if (dpriv->fd >= 0) { + fd = dpriv->fd; + } else { + fd = open(dpriv->devnode, O_RDONLY); + if (fd < 0) + return _errno_to_libusb(errno); + } - usbi_dbg("index %d, len %d", udf.udf_config_index, len); + ufd.ufd_config_index = idx; + ufd.ufd_size = len; + ufd.ufd_data = buf; - if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { err = errno; - close(fd); + if (dpriv->fd < 0) + close(fd); return _errno_to_libusb(err); } - close(fd); + + if (dpriv->fd < 0) + close(fd); *host_endian = 0; - return (len); + return len; } int obsd_get_configuration(struct libusb_device_handle *handle, int *config) { struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; - usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc; - *config = ucd->bConfigurationValue; + usbi_dbg(""); - usbi_dbg("bConfigurationValue %d", *config); + if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0) + return _errno_to_libusb(errno); + + usbi_dbg("configuration %d", *config); return (LIBUSB_SUCCESS); } @@ -362,15 +336,12 @@ obsd_set_configuration(struct libusb_device_handle *handle, int config) { struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; - if (dpriv->devname == NULL) - return (LIBUSB_ERROR_NOT_SUPPORTED); - - usbi_dbg("bConfigurationValue %d", config); + usbi_dbg("configuration %d", config); if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0) return _errno_to_libusb(errno); - return _cache_active_config_descriptor(handle->dev); + return _cache_active_config_descriptor(handle->dev, dpriv->fd); } int @@ -405,9 +376,6 @@ obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; struct usb_alt_interface intf; - if (dpriv->devname == NULL) - return (LIBUSB_ERROR_NOT_SUPPORTED); - usbi_dbg("iface %d, setting %d", iface, altsetting); memset(&intf, 0, sizeof(intf)); @@ -424,27 +392,19 @@ obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface, int obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint) { + struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv; struct usb_ctl_request req; - int fd, err; - - if ((fd = _bus_open(handle->dev->bus_number)) < 0) - return _errno_to_libusb(errno); usbi_dbg(""); - req.ucr_addr = handle->dev->device_address; req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; req.ucr_request.bRequest = UR_CLEAR_FEATURE; USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT); USETW(req.ucr_request.wIndex, endpoint); USETW(req.ucr_request.wLength, 0); - if (ioctl(fd, USB_REQUEST, &req) < 0) { - err = errno; - close(fd); - return _errno_to_libusb(err); - } - close(fd); + if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0) + return _errno_to_libusb(errno); return (LIBUSB_SUCCESS); } @@ -465,7 +425,6 @@ obsd_destroy_device(struct libusb_device *dev) usbi_dbg(""); free(dpriv->cdesc); - free(dpriv->devname); } int @@ -605,8 +564,6 @@ obsd_clock_gettime(int clkid, struct timespec *tp) int _errno_to_libusb(int err) { - usbi_dbg("error: %s (%d)", strerror(err), err); - switch (err) { case EIO: return (LIBUSB_ERROR_IO); @@ -616,64 +573,52 @@ _errno_to_libusb(int err) return (LIBUSB_ERROR_NO_DEVICE); case ENOMEM: return (LIBUSB_ERROR_NO_MEM); - case ETIMEDOUT: - return (LIBUSB_ERROR_TIMEOUT); } + usbi_dbg("error: %s", strerror(err)); + return (LIBUSB_ERROR_OTHER); } int -_cache_active_config_descriptor(struct libusb_device *dev) +_cache_active_config_descriptor(struct libusb_device *dev, int fd) { struct device_priv *dpriv = (struct device_priv *)dev->os_priv; - struct usb_device_cdesc udc; - struct usb_device_fdesc udf; + struct usb_config_desc ucd; + struct usb_full_desc ufd; unsigned char* buf; - int fd, len, err; + int len; - if ((fd = _bus_open(dev->bus_number)) < 0) - return _errno_to_libusb(errno); + usbi_dbg("fd %d", fd); - usbi_dbg("fd %d, addr %d", fd, dev->device_address); + ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX; - udc.udc_bus = dev->bus_number; - udc.udc_addr = dev->device_address; - udc.udc_config_index = USB_CURRENT_CONFIG_INDEX; - if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) { - err = errno; - close(fd); + if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0) return _errno_to_libusb(errno); - } - usbi_dbg("active bLength %d", udc.udc_desc.bLength); + usbi_dbg("active bLength %d", ucd.ucd_desc.bLength); - len = UGETW(udc.udc_desc.wTotalLength); + len = UGETW(ucd.ucd_desc.wTotalLength); buf = malloc(len); if (buf == NULL) return (LIBUSB_ERROR_NO_MEM); - udf.udf_bus = dev->bus_number; - udf.udf_addr = dev->device_address; - udf.udf_config_index = udc.udc_config_index; - udf.udf_size = len; - udf.udf_data = buf; + ufd.ufd_config_index = ucd.ucd_config_index; + ufd.ufd_size = len; + ufd.ufd_data = buf; - usbi_dbg("index %d, len %d", udf.udf_config_index, len); + usbi_dbg("index %d, len %d", ufd.ufd_config_index, len); - if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) { - err = errno; - close(fd); + if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) { free(buf); - return _errno_to_libusb(err); + return _errno_to_libusb(errno); } - close(fd); if (dpriv->cdesc) free(dpriv->cdesc); dpriv->cdesc = buf; - return (LIBUSB_SUCCESS); + return (0); } int @@ -688,13 +633,12 @@ _sync_control_transfer(struct usbi_transfer *itransfer) dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; setup = (struct libusb_control_setup *)transfer->buffer; - usbi_dbg("type %x request %x value %x index %d length %d timeout %d", + usbi_dbg("type %d request %d value %d index %d length %d timeout %d", setup->bmRequestType, setup->bRequest, libusb_le16_to_cpu(setup->wValue), libusb_le16_to_cpu(setup->wIndex), libusb_le16_to_cpu(setup->wLength), transfer->timeout); - req.ucr_addr = transfer->dev_handle->dev->device_address; req.ucr_request.bmRequestType = setup->bmRequestType; req.ucr_request.bRequest = setup->bRequest; /* Don't use USETW, libusbx already deals with the endianness */ @@ -706,30 +650,11 @@ _sync_control_transfer(struct usbi_transfer *itransfer) if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0) req.ucr_flags = USBD_SHORT_XFER_OK; - if (dpriv->devname == NULL) { - /* - * XXX If the device is not attached to ugen(4) it is - * XXX still possible to submit a control transfer but - * XXX with the default timeout only. - */ - int fd, err; - - if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0) - return _errno_to_libusb(errno); - - if ((ioctl(fd, USB_REQUEST, &req)) < 0) { - err = errno; - close(fd); - return _errno_to_libusb(err); - } - close(fd); - } else { - if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) - return _errno_to_libusb(errno); + if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0) + return _errno_to_libusb(errno); - if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) - return _errno_to_libusb(errno); - } + if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0) + return _errno_to_libusb(errno); itransfer->transferred = req.ucr_actlen; @@ -743,7 +668,7 @@ _access_endpoint(struct libusb_transfer *transfer) { struct handle_priv *hpriv; struct device_priv *dpriv; - char devnode[16]; + char *s, devnode[16]; int fd, endpt; mode_t mode; @@ -756,9 +681,10 @@ _access_endpoint(struct libusb_transfer *transfer) usbi_dbg("endpoint %d mode %d", endpt, mode); if (hpriv->endpoints[endpt] < 0) { - /* Pick the right endpoint node */ - snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", - dpriv->devname, endpt); + /* Pick the right node given the control one */ + strlcpy(devnode, dpriv->devnode, sizeof(devnode)); + s = strchr(devnode, '.'); + snprintf(s, 4, ".%02d", endpt); /* We may need to read/write to the same endpoint later. */ if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) @@ -775,14 +701,9 @@ int _sync_gen_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer; - struct device_priv *dpriv; int fd, nr = 1; transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; - - if (dpriv->devname == NULL) - return (LIBUSB_ERROR_NOT_SUPPORTED); /* * Bulk, Interrupt or Isochronous transfer depends on the @@ -811,13 +732,3 @@ _sync_gen_transfer(struct usbi_transfer *itransfer) return (0); } - -int -_bus_open(int number) -{ - char busnode[16]; - - snprintf(busnode, sizeof(busnode), USBDEV "%d", number); - - return open(busnode, O_RDWR); -} diff --git a/third_party/libusb/src/libusb/os/poll_posix.h b/third_party/libusb/src/libusb/os/poll_posix.h index 5b4b2c9..64c9bb7 100644 --- a/third_party/libusb/src/libusb/os/poll_posix.h +++ b/third_party/libusb/src/libusb/os/poll_posix.h @@ -1,3 +1,19 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + #ifndef LIBUSB_POLL_POSIX_H #define LIBUSB_POLL_POSIX_H diff --git a/third_party/libusb/src/libusb/os/poll_windows.c b/third_party/libusb/src/libusb/os/poll_windows.c index abe8761..7ed19ba 100644 --- a/third_party/libusb/src/libusb/os/poll_windows.c +++ b/third_party/libusb/src/libusb/os/poll_windows.c @@ -428,7 +428,7 @@ struct winfd fd_to_winfd(int fd) CHECK_INIT_POLLING; - if (fd < 0) + if (fd <= 0) return INVALID_WINFD; for (i=0; i<MAX_FDS; i++) { diff --git a/third_party/libusb/src/libusb/os/threads_posix.c b/third_party/libusb/src/libusb/os/threads_posix.c index cd985fa..46f6db7 100644 --- a/third_party/libusb/src/libusb/os/threads_posix.c +++ b/third_party/libusb/src/libusb/os/threads_posix.c @@ -58,9 +58,7 @@ finish: int usbi_get_tid(void) { int ret = -1; -#if defined(__ANDROID__) - ret = gettid(); -#elif defined(__linux__) +#if defined(__linux__) ret = syscall(SYS_gettid); #elif defined(__OpenBSD__) /* The following only works with OpenBSD > 5.1 as it requires diff --git a/third_party/libusb/src/libusb/os/wince_usb.c b/third_party/libusb/src/libusb/os/wince_usb.c index 90c129b..e4a6633 100644 --- a/third_party/libusb/src/libusb/os/wince_usb.c +++ b/third_party/libusb/src/libusb/os/wince_usb.c @@ -234,12 +234,6 @@ static int wince_init(struct libusb_context *ctx) usbi_err(ctx, "Unable to create timer thread - aborting"); goto init_exit; } - - // Wait for timer thread to init before continuing. - if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) { - usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting"); - goto init_exit; - } } // At this stage, either we went through full init successfully, or didn't need to r = LIBUSB_SUCCESS; @@ -883,11 +877,6 @@ unsigned __stdcall wince_clock_gettime_threaded(void* param) usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); } - // Signal wince_init() that we're ready to service requests - if (ReleaseSemaphore(timer_response, 1, NULL) == 0) { - usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0)); - } - // Main loop - wait for requests while (1) { timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0; @@ -922,7 +911,7 @@ unsigned __stdcall wince_clock_gettime_threaded(void* param) nb_responses = InterlockedExchange((LONG*)&request_count[0], 0); if ( (nb_responses) && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) { - usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0)); + usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0)); } continue; case 1: // time to quit diff --git a/third_party/libusb/src/libusb/os/windows_usb.c b/third_party/libusb/src/libusb/os/windows_usb.c index 9ae11b1..51ce55d 100644 --- a/third_party/libusb/src/libusb/os/windows_usb.c +++ b/third_party/libusb/src/libusb/os/windows_usb.c @@ -886,12 +886,6 @@ static int windows_init(struct libusb_context *ctx) } SetThreadAffinityMask(timer_thread, 0); - // Wait for timer thread to init before continuing. - if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) { - usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting"); - goto init_exit; - } - // Create a hash table to store session ids. Second parameter is better if prime htab_create(ctx, HTAB_SIZE); } @@ -1765,7 +1759,7 @@ static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t conf memcpy(buffer, priv->config_descriptor[config_index], size); *host_endian = 0; - return (int)size; + return size; } /* @@ -2179,11 +2173,6 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param) usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); } - // Signal windows_init() that we're ready to service requests - if (ReleaseSemaphore(timer_response, 1, NULL) == 0) { - usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0)); - } - // Main loop - wait for requests while (1) { timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0; @@ -2218,7 +2207,7 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param) nb_responses = InterlockedExchange((LONG*)&request_count[0], 0); if ( (nb_responses) && (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) { - usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0)); + usbi_dbg("unable to release timer semaphore %d: %s", windows_error_str(0)); } continue; case 1: // time to quit diff --git a/third_party/libusb/src/libusb/strerror.c b/third_party/libusb/src/libusb/strerror.c index 0212df8..a3c3afa 100644 --- a/third_party/libusb/src/libusb/strerror.c +++ b/third_party/libusb/src/libusb/strerror.c @@ -53,7 +53,7 @@ static size_t usbi_locale = 0; * } * };\endcode </li> * <li> Translate each of the English messages from the section you copied into your language </li> - * <li> Save the file (in UTF-8 format) and send it to \c libusbx-devel\@lists.sourceforge.net </li> + * <li> Save the file (in UTF-8 format) and send it to \c libusbx-devel@lists.sourceforge.net </li> * </ol> */ diff --git a/third_party/libusb/src/libusb/version.h b/third_party/libusb/src/libusb/version.h index 09d9a9f..fbb9f4c 100644 --- a/third_party/libusb/src/libusb/version.h +++ b/third_party/libusb/src/libusb/version.h @@ -1,3 +1,19 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + /* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */ #include "version_nano.h" #ifndef LIBUSB_MAJOR @@ -7,7 +23,7 @@ #define LIBUSB_MINOR 0 #endif #ifndef LIBUSB_MICRO -#define LIBUSB_MICRO 17 +#define LIBUSB_MICRO 16 #endif #ifndef LIBUSB_NANO #define LIBUSB_NANO 0 diff --git a/third_party/libusb/src/libusb/version_nano.h b/third_party/libusb/src/libusb/version_nano.h index dfa5664..522c6fd 100644 --- a/third_party/libusb/src/libusb/version_nano.h +++ b/third_party/libusb/src/libusb/version_nano.h @@ -1 +1,17 @@ -#define LIBUSB_NANO 10830 +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define LIBUSB_NANO 10774 |