Index: third_party/libusb/src/libusb/libusbi.h |
diff --git a/third_party/libusb/src/libusb/libusbi.h b/third_party/libusb/src/libusb/libusbi.h |
index 976be0d13b6bf41a4685664563bebe5f1f7e8477..02efae300d87af3a8ee2efc1853667351895899f 100644 |
--- a/third_party/libusb/src/libusb/libusbi.h |
+++ b/third_party/libusb/src/libusb/libusbi.h |
@@ -1,7 +1,7 @@ |
/* |
- * Internal header for libusb |
- * Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org> |
- * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> |
+ * Internal header for libusbx |
+ * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org> |
+ * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com> |
* |
* This library is free software; you can redistribute it and/or |
* modify it under the terms of the GNU Lesser General Public |
@@ -21,7 +21,7 @@ |
#ifndef LIBUSBI_H |
#define LIBUSBI_H |
-#include <config.h> |
+#include "config.h" |
#include <stddef.h> |
#include <stdint.h> |
@@ -31,14 +31,17 @@ |
#include <poll.h> |
#endif |
-#include <libusb.h> |
-#include <version.h> |
+#ifdef HAVE_MISSING_H |
+#include "missing.h" |
+#endif |
+#include "libusb.h" |
+#include "version.h" |
-/* Inside the libusb code, mark all public functions as follows: |
+/* Inside the libusbx code, mark all public functions as follows: |
* return_type API_EXPORTED function_name(params) { ... } |
* But if the function returns a pointer, mark it as follows: |
* DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... } |
- * In the libusb public header, mark all declarations as: |
+ * In the libusbx public header, mark all declarations as: |
* return_type LIBUSB_CALL function_name(params); |
*/ |
#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY |
@@ -49,23 +52,39 @@ |
#define USB_MAXINTERFACES 32 |
#define USB_MAXCONFIG 8 |
+/* Backend specific capabilities */ |
+#define USBI_CAP_HAS_HID_ACCESS 0x00010000 |
+#define USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 0x00020000 |
+ |
+/* Maximum number of bytes in a log line */ |
+#define USBI_MAX_LOG_LEN 1024 |
+/* Terminator for log lines */ |
+#define USBI_LOG_LINE_END "\n" |
+ |
+/* The following is used to silence warnings for unused variables */ |
+#define UNUSED(var) do { (void)(var); } while(0) |
+ |
+#if !defined(ARRAYSIZE) |
+#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0])) |
+#endif |
+ |
struct list_head { |
struct list_head *prev, *next; |
}; |
/* Get an entry from the list |
- * ptr - the address of this list_head element in "type" |
- * type - the data type that contains "member" |
- * member - the list_head element in "type" |
+ * ptr - the address of this list_head element in "type" |
+ * type - the data type that contains "member" |
+ * member - the list_head element in "type" |
*/ |
#define list_entry(ptr, type, member) \ |
- ((type *)((uintptr_t)(ptr) - (uintptr_t)(&((type *)0L)->member))) |
+ ((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member))) |
/* Get each entry from a list |
- * pos - A structure pointer has a "member" element |
- * head - list head |
- * member - the list_head element in "pos" |
- * type - the type of the first parameter |
+ * pos - A structure pointer has a "member" element |
+ * head - list head |
+ * member - the list_head element in "pos" |
+ * type - the type of the first parameter |
*/ |
#define list_for_each_entry(pos, head, member, type) \ |
for (pos = list_entry((head)->next, type, member); \ |
@@ -108,6 +127,15 @@ static inline void list_del(struct list_head *entry) |
{ |
entry->next->prev = entry->prev; |
entry->prev->next = entry->next; |
+ entry->next = entry->prev = NULL; |
+} |
+ |
+static inline void *usbi_reallocf(void *ptr, size_t size) |
+{ |
+ void *ret = realloc(ptr, size); |
+ if (!ret) |
+ free(ptr); |
+ return ret; |
} |
#define container_of(ptr, type, member) ({ \ |
@@ -119,93 +147,52 @@ static inline void list_del(struct list_head *entry) |
#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0) |
-enum usbi_log_level { |
- LOG_LEVEL_DEBUG, |
- LOG_LEVEL_INFO, |
- LOG_LEVEL_WARNING, |
- LOG_LEVEL_ERROR, |
-}; |
- |
-void usbi_log(struct libusb_context *ctx, enum usbi_log_level level, |
+void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, |
const char *function, const char *format, ...); |
-void usbi_log_v(struct libusb_context *ctx, enum usbi_log_level level, |
+void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, |
const char *function, const char *format, va_list args); |
#if !defined(_MSC_VER) || _MSC_VER >= 1400 |
#ifdef ENABLE_LOGGING |
#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__) |
+#define usbi_dbg(...) _usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__) |
#else |
#define _usbi_log(ctx, level, ...) do { (void)(ctx); } while(0) |
-#endif |
- |
-#ifdef ENABLE_DEBUG_LOGGING |
-#define usbi_dbg(...) _usbi_log(NULL, LOG_LEVEL_DEBUG, __VA_ARGS__) |
-#else |
#define usbi_dbg(...) do {} while(0) |
#endif |
-#define usbi_info(ctx, ...) _usbi_log(ctx, LOG_LEVEL_INFO, __VA_ARGS__) |
-#define usbi_warn(ctx, ...) _usbi_log(ctx, LOG_LEVEL_WARNING, __VA_ARGS__) |
-#define usbi_err(ctx, ...) _usbi_log(ctx, LOG_LEVEL_ERROR, __VA_ARGS__) |
+#define usbi_info(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__) |
+#define usbi_warn(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__) |
+#define usbi_err(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__) |
#else /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ |
-/* Old MS compilers don't support variadic macros. The code is simple, so we |
- * repeat it for each loglevel. Note that the debug case is special. |
- * |
- * Support for variadic macros was introduced in Visual C++ 2005. |
- * http://msdn.microsoft.com/en-us/library/ms177415%28v=VS.80%29.aspx |
- */ |
- |
-static inline void usbi_info(struct libusb_context *ctx, const char *fmt, ...) |
-{ |
#ifdef ENABLE_LOGGING |
- va_list args; |
- va_start(args, fmt); |
- usbi_log_v(ctx, LOG_LEVEL_INFO, "", fmt, args); |
- va_end(args); |
-#else |
- (void)ctx; |
-#endif |
+#define LOG_BODY(ctxt, level) \ |
+{ \ |
+ va_list args; \ |
+ va_start (args, format); \ |
+ usbi_log_v(ctxt, level, "", format, args); \ |
+ va_end(args); \ |
} |
- |
-static inline void usbi_warn(struct libusb_context *ctx, const char *fmt, ...) |
-{ |
-#ifdef ENABLE_LOGGING |
- va_list args; |
- va_start(args, fmt); |
- usbi_log_v(ctx, LOG_LEVEL_WARNING, "", fmt, args); |
- va_end(args); |
#else |
- (void)ctx; |
+#define LOG_BODY(ctxt, level) do { (void)(ctxt); } while(0) |
#endif |
-} |
-static inline void usbi_err(struct libusb_context *ctx, const char *fmt, ...) |
-{ |
-#ifdef ENABLE_LOGGING |
- va_list args; |
- va_start(args, fmt); |
- usbi_log_v(ctx, LOG_LEVEL_ERROR, "", fmt, args); |
- va_end(args); |
-#else |
- (void)ctx; |
-#endif |
-} |
+static inline void usbi_info(struct libusb_context *ctx, const char *format, |
+ ...) |
+ LOG_BODY(ctx,LIBUSB_LOG_LEVEL_INFO) |
+static inline void usbi_warn(struct libusb_context *ctx, const char *format, |
+ ...) |
+ LOG_BODY(ctx,LIBUSB_LOG_LEVEL_WARNING) |
+static inline void usbi_err( struct libusb_context *ctx, const char *format, |
+ ...) |
+ LOG_BODY(ctx,LIBUSB_LOG_LEVEL_ERROR) |
-static inline void usbi_dbg(const char *fmt, ...) |
-{ |
-#ifdef ENABLE_DEBUG_LOGGING |
- va_list args; |
- va_start(args, fmt); |
- usbi_log_v(NULL, LOG_LEVEL_DEBUG, "", fmt, args); |
- va_end(args); |
-#else |
- (void)fmt; |
-#endif |
-} |
+static inline void usbi_dbg(const char *format, ...) |
+ LOG_BODY(NULL,LIBUSB_LOG_LEVEL_DEBUG) |
#endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ |
@@ -221,32 +208,13 @@ static inline void usbi_dbg(const char *fmt, ...) |
#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN)) |
#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer)) |
-/* Internal abstractions for thread synchronization and poll */ |
+/* Internal abstraction for thread synchronization */ |
#if defined(THREADS_POSIX) |
-#include <os/threads_posix.h> |
-#elif defined(OS_WINDOWS) |
+#include "os/threads_posix.h" |
+#elif defined(OS_WINDOWS) || defined(OS_WINCE) |
#include <os/threads_windows.h> |
#endif |
-#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) |
-#include <unistd.h> |
-#include <os/poll_posix.h> |
-#elif defined(OS_WINDOWS) |
-#include <os/poll_windows.h> |
-#endif |
- |
-#if defined(OS_WINDOWS) && !defined(__GCC__) |
-#undef HAVE_GETTIMEOFDAY |
-int usbi_gettimeofday(struct timeval *tp, void *tzp); |
-#define LIBUSB_GETTIMEOFDAY_WIN32 |
-#define HAVE_USBI_GETTIMEOFDAY |
-#else |
-#ifdef HAVE_GETTIMEOFDAY |
-#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz)) |
-#define HAVE_USBI_GETTIMEOFDAY |
-#endif |
-#endif |
- |
extern struct libusb_context *usbi_default_context; |
struct libusb_context { |
@@ -265,6 +233,11 @@ struct libusb_context { |
struct list_head open_devs; |
usbi_mutex_t open_devs_lock; |
+ /* A list of registered hotplug callbacks */ |
+ struct list_head hotplug_cbs; |
+ usbi_mutex_t hotplug_cbs_lock; |
+ int hotplug_pipe[2]; |
+ |
/* this is a list of in-flight transfer handles, sorted by timeout |
* expiration. URBs to timeout the soonest are placed at the beginning of |
* the list, URBs that will time out later are placed after, and urbs with |
@@ -302,6 +275,8 @@ struct libusb_context { |
* this timerfd is maintained to trigger on the next pending timeout */ |
int timerfd; |
#endif |
+ |
+ struct list_head list; |
}; |
#ifdef USBI_TIMERFD_AVAILABLE |
@@ -319,13 +294,25 @@ struct libusb_device { |
struct libusb_context *ctx; |
uint8_t bus_number; |
+ uint8_t port_number; |
+ struct libusb_device* parent_dev; |
uint8_t device_address; |
uint8_t num_configurations; |
enum libusb_speed speed; |
struct list_head list; |
unsigned long session_data; |
- unsigned char os_priv[0]; |
+ |
+ struct libusb_device_descriptor device_descriptor; |
+ int attached; |
+ |
+ unsigned char os_priv |
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
+ [] /* valid C99 code */ |
+#else |
+ [0] /* non-standard, but usually working code */ |
+#endif |
+ ; |
}; |
struct libusb_device_handle { |
@@ -335,7 +322,14 @@ struct libusb_device_handle { |
struct list_head list; |
struct libusb_device *dev; |
- unsigned char os_priv[0]; |
+ int auto_detach_kernel_driver; |
+ unsigned char os_priv |
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
+ [] /* valid C99 code */ |
+#else |
+ [0] /* non-standard, but usually working code */ |
+#endif |
+ ; |
}; |
enum { |
@@ -385,6 +379,9 @@ enum usbi_transfer_flags { |
/* Operation on the transfer failed because the device disappeared */ |
USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3, |
+ |
+ /* Set by backend submit_transfer() if the fds in use have been updated */ |
+ USBI_TRANSFER_UPDATED_FDS = 1 << 4, |
}; |
#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ |
@@ -426,12 +423,35 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, |
enum libusb_transfer_status status); |
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); |
-int usbi_parse_descriptor(unsigned char *source, const char *descriptor, |
+int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, |
void *dest, int host_endian); |
+int usbi_device_cache_descriptor(libusb_device *dev); |
int usbi_get_config_index_by_value(struct libusb_device *dev, |
uint8_t bConfigurationValue, int *idx); |
-/* polling */ |
+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) |
+#include <unistd.h> |
+#include "os/poll_posix.h" |
+#elif defined(OS_WINDOWS) || defined(OS_WINCE) |
+#include "os/poll_windows.h" |
+#endif |
+ |
+#if (defined(OS_WINDOWS) || defined(OS_WINCE)) && !defined(__GNUC__) |
+#define snprintf _snprintf |
+#define vsnprintf _vsnprintf |
+int usbi_gettimeofday(struct timeval *tp, void *tzp); |
+#define LIBUSB_GETTIMEOFDAY_WIN32 |
+#define HAVE_USBI_GETTIMEOFDAY |
+#else |
+#ifdef HAVE_GETTIMEOFDAY |
+#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz)) |
+#define HAVE_USBI_GETTIMEOFDAY |
+#endif |
+#endif |
struct usbi_pollfd { |
/* must come first */ |
@@ -454,7 +474,13 @@ void usbi_fd_notification(struct libusb_context *ctx); |
struct discovered_devs { |
size_t len; |
size_t capacity; |
- struct libusb_device *devices[0]; |
+ struct libusb_device *devices |
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
+ [] /* valid C99 code */ |
+#else |
+ [0] /* non-standard, but usually working code */ |
+#endif |
+ ; |
}; |
struct discovered_devs *discovered_devs_append( |
@@ -468,11 +494,14 @@ struct usbi_os_backend { |
/* A human-readable name for your backend, e.g. "Linux usbfs" */ |
const char *name; |
+ /* Binary mask for backend specific capabilities */ |
+ uint32_t caps; |
+ |
/* Perform initialization of your backend. You might use this function |
* to determine specific capabilities of the system, allocate required |
* data structures for later, etc. |
* |
- * This function is called when a libusb user initializes the library |
+ * This function is called when a libusbx user initializes the library |
* prior to use. |
* |
* Return 0 on success, or a LIBUSB_ERROR code on failure. |
@@ -502,7 +531,7 @@ struct usbi_os_backend { |
* but that is an unlikely case. |
* |
* After computing a session ID for a device, call |
- * usbi_get_device_by_session_id(). This function checks if libusb already |
+ * usbi_get_device_by_session_id(). This function checks if libusbx already |
* knows about the device, and if so, it provides you with a libusb_device |
* structure for it. |
* |
@@ -533,18 +562,37 @@ struct usbi_os_backend { |
* This function is executed when the user wishes to retrieve a list |
* of USB devices connected to the system. |
* |
+ * If the backend has hotplug support, this function is not used! |
+ * |
* Return 0 on success, or a LIBUSB_ERROR code on failure. |
*/ |
int (*get_device_list)(struct libusb_context *ctx, |
struct discovered_devs **discdevs); |
+ /* Apps which were written before hotplug support, may listen for |
+ * hotplug events on their own and call libusb_get_device_list on |
+ * device addition. In this case libusb_get_device_list will likely |
+ * return a list without the new device in there, as the hotplug |
+ * event thread will still be busy enumerating the device, which may |
+ * take a while, or may not even have seen the event yet. |
+ * |
+ * To avoid this libusb_get_device_list will call this optional |
+ * function for backends with hotplug support before copying |
+ * ctx->usb_devs to the user. In this function the backend should |
+ * ensure any pending hotplug events are fully processed before |
+ * returning. |
+ * |
+ * Optional, should be implemented by backends with hotplug support. |
+ */ |
+ void (*hotplug_poll)(void); |
+ |
/* Open a device for I/O and other USB operations. The device handle |
* is preallocated for you, you can retrieve the device in question |
* through handle->dev. |
* |
* Your backend should allocate any internal resources required for I/O |
* and other operations so that those operations can happen (hopefully) |
- * without hiccup. This is also a good place to inform libusb that it |
+ * without hiccup. This is also a good place to inform libusbx that it |
* should monitor certain file descriptors related to this device - |
* see the usbi_add_pollfd() function. |
* |
@@ -568,7 +616,7 @@ struct usbi_os_backend { |
/* Close a device such that the handle cannot be used again. Your backend |
* should destroy any resources that were allocated in the open path. |
* This may also be a good place to call usbi_remove_pollfd() to inform |
- * libusb of any file descriptors associated with this device that should |
+ * libusbx of any file descriptors associated with this device that should |
* no longer be monitored. |
* |
* This function is called when the user closes a device handle. |
@@ -647,13 +695,29 @@ struct usbi_os_backend { |
uint8_t config_index, unsigned char *buffer, size_t len, |
int *host_endian); |
+ /* Like get_config_descriptor but then by bConfigurationValue instead |
+ * of by index. |
+ * |
+ * Optional, if not present the core will call get_config_descriptor |
+ * for all configs until it finds the desired bConfigurationValue. |
+ * |
+ * Returns a pointer to the raw-descriptor in *buffer, this memory |
+ * is valid as long as device is valid. |
+ * |
+ * Returns the length of the returned raw-descriptor on success, |
+ * or a LIBUSB_ERROR code on failure. |
+ */ |
+ int (*get_config_descriptor_by_value)(struct libusb_device *device, |
+ uint8_t bConfigurationValue, unsigned char **buffer, |
+ int *host_endian); |
+ |
/* Get the bConfigurationValue for the active configuration for a device. |
* Optional. This should only be implemented if you can retrieve it from |
* cache (don't generate I/O). |
* |
* If you cannot retrieve this from cache, either do not implement this |
* function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause |
- * libusb to retrieve the information through a standard control transfer. |
+ * libusbx to retrieve the information through a standard control transfer. |
* |
* This function must be non-blocking. |
* Return: |
@@ -830,6 +894,8 @@ struct usbi_os_backend { |
* |
* This function must not block. |
* |
+ * This function gets called with the flying_transfers_lock locked! |
+ * |
* Return: |
* - 0 on success |
* - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
@@ -850,7 +916,7 @@ struct usbi_os_backend { |
* all private data from the transfer as if you were just about to report |
* completion or cancellation. |
* |
- * This function might seem a bit out of place. It is used when libusb |
+ * This function might seem a bit out of place. It is used when libusbx |
* detects a disconnected device - it calls this function for all pending |
* transfers before reporting completion (with the disconnect code) to |
* the user. Maybe we can improve upon this internal interface in future. |
@@ -930,6 +996,9 @@ 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 windows_backend; |
+extern const struct usbi_os_backend wince_backend; |
-#endif |
+extern struct list_head active_contexts_list; |
+extern usbi_mutex_static_t active_contexts_lock; |
+#endif |