libusb 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +1 -0
  5. data/History.md +8 -0
  6. data/README.md +5 -15
  7. data/Rakefile +8 -1
  8. data/ext/extconf.rb +49 -12
  9. data/ext/{libusb-1.0.19 → libusb-1.0.20}/AUTHORS +12 -1
  10. data/ext/{libusb-1.0.19 → libusb-1.0.20}/COPYING +0 -0
  11. data/ext/{libusb-1.0.19 → libusb-1.0.20}/ChangeLog +18 -2
  12. data/ext/{libusb-1.0.19 → libusb-1.0.20}/INSTALL +0 -0
  13. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Makefile.am +0 -0
  14. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Makefile.in +31 -18
  15. data/ext/{libusb-1.0.19 → libusb-1.0.20}/NEWS +0 -0
  16. data/ext/{libusb-1.0.19 → libusb-1.0.20}/PORTING +0 -0
  17. data/ext/{libusb-1.0.19 → libusb-1.0.20}/README +5 -3
  18. data/ext/{libusb-1.0.19 → libusb-1.0.20}/TODO +0 -0
  19. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/common.xcconfig +0 -0
  20. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/config.h +0 -0
  21. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/debug.xcconfig +0 -0
  22. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb.xcconfig +0 -0
  23. data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +865 -0
  24. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb_debug.xcconfig +0 -0
  25. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/libusb_release.xcconfig +0 -0
  26. data/ext/{libusb-1.0.19 → libusb-1.0.20}/Xcode/release.xcconfig +0 -0
  27. data/ext/{libusb-1.0.19 → libusb-1.0.20}/aclocal.m4 +35 -32
  28. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/README +0 -0
  29. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/config.h +0 -0
  30. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/Android.mk +0 -0
  31. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/Application.mk +0 -0
  32. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/examples.mk +0 -0
  33. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/libusb.mk +0 -0
  34. data/ext/{libusb-1.0.19 → libusb-1.0.20}/android/jni/tests.mk +0 -0
  35. data/ext/{libusb-1.0.19 → libusb-1.0.20}/compile +1 -1
  36. data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.guess +13 -160
  37. data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.h.in +6 -0
  38. data/ext/{libusb-1.0.19 → libusb-1.0.20}/config.sub +26 -12
  39. data/ext/{libusb-1.0.19 → libusb-1.0.20}/configure +244 -20
  40. data/ext/{libusb-1.0.19 → libusb-1.0.20}/configure.ac +27 -4
  41. data/ext/{libusb-1.0.19 → libusb-1.0.20}/depcomp +1 -1
  42. data/ext/{libusb-1.0.19 → libusb-1.0.20}/doc/Makefile.am +0 -0
  43. data/ext/{libusb-1.0.19 → libusb-1.0.20}/doc/Makefile.in +19 -6
  44. data/ext/libusb-1.0.20/doc/doxygen.cfg.in +2334 -0
  45. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/Makefile.am +0 -0
  46. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/Makefile.in +19 -6
  47. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/dpfp.c +0 -0
  48. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/dpfp_threaded.c +15 -10
  49. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/ezusb.c +0 -0
  50. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/ezusb.h +0 -0
  51. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/fxload.c +28 -7
  52. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/getopt/getopt1.c +0 -0
  55. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/hotplugtest.c +21 -3
  56. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/listdevs.c +0 -0
  57. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/sam3u_benchmark.c +0 -0
  58. data/ext/{libusb-1.0.19 → libusb-1.0.20}/examples/xusb.c +2 -1
  59. data/ext/{libusb-1.0.19 → libusb-1.0.20}/install-sh +170 -196
  60. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb-1.0.pc.in +0 -0
  61. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/Makefile.am +15 -0
  62. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/Makefile.in +192 -53
  63. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/core.c +218 -100
  64. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/descriptor.c +3 -1
  65. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/hotplug.c +26 -9
  66. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/hotplug.h +8 -0
  67. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/io.c +432 -290
  68. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb-1.0.def +2 -0
  69. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb-1.0.rc +0 -0
  70. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusb.h +11 -10
  71. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/libusbi.h +106 -29
  72. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/darwin_usb.c +27 -67
  73. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/darwin_usb.h +3 -7
  74. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +5 -0
  75. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +810 -0
  76. data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +1193 -0
  77. data/ext/libusb-1.0.20/libusb/os/haiku/compile +347 -0
  78. data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +1421 -0
  79. data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +1807 -0
  80. data/ext/libusb-1.0.20/libusb/os/haiku/configure +17579 -0
  81. data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +8 -0
  82. data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +791 -0
  83. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +378 -0
  84. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +112 -0
  85. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +550 -0
  86. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +255 -0
  87. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +180 -0
  88. data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +501 -0
  89. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/ltmain.sh +0 -0
  90. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/libtool.m4 +0 -0
  91. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltoptions.m4 +0 -0
  92. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltsugar.m4 +0 -0
  93. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/ltversion.m4 +0 -0
  94. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/m4/lt~obsolete.m4 +0 -0
  95. data/ext/{libusb-1.0.19 → libusb-1.0.20/libusb/os/haiku}/missing +1 -1
  96. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_netlink.c +4 -4
  97. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_udev.c +1 -2
  98. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_usbfs.c +46 -49
  99. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/linux_usbfs.h +1 -1
  100. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/netbsd_usb.c +9 -73
  101. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/openbsd_usb.c +9 -73
  102. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_posix.c +2 -0
  103. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_posix.h +0 -0
  104. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_windows.c +3 -1
  105. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/poll_windows.h +0 -0
  106. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_posix.c +3 -3
  107. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_posix.h +0 -0
  108. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_windows.c +3 -1
  109. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/threads_windows.h +0 -0
  110. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/wince_usb.c +87 -250
  111. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/wince_usb.h +0 -0
  112. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_common.h +1 -1
  113. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_usb.c +267 -181
  114. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/os/windows_usb.h +22 -7
  115. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/strerror.c +5 -2
  116. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/sync.c +2 -1
  117. data/ext/{libusb-1.0.19 → libusb-1.0.20}/libusb/version.h +1 -1
  118. data/ext/libusb-1.0.20/libusb/version_nano.h +1 -0
  119. data/ext/libusb-1.0.20/ltmain.sh +9655 -0
  120. data/ext/libusb-1.0.20/m4/libtool.m4 +7992 -0
  121. data/ext/libusb-1.0.20/m4/ltoptions.m4 +384 -0
  122. data/ext/libusb-1.0.20/m4/ltsugar.m4 +123 -0
  123. data/ext/libusb-1.0.20/m4/ltversion.m4 +23 -0
  124. data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +98 -0
  125. data/ext/libusb-1.0.20/missing +215 -0
  126. data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/Makefile.am +0 -0
  127. data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/Makefile.in +19 -6
  128. data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/libusb_testlib.h +0 -0
  129. data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/stress.c +0 -0
  130. data/ext/{libusb-1.0.19 → libusb-1.0.20}/tests/testlib.c +0 -0
  131. data/lib/libusb.rb +1 -0
  132. data/lib/libusb/call.rb +1 -0
  133. data/lib/libusb/context.rb +5 -2
  134. data/lib/libusb/stdio.rb +25 -0
  135. data/lib/libusb/version_gem.rb +1 -1
  136. data/libusb.gemspec +2 -1
  137. metadata +152 -115
  138. metadata.gz.sig +0 -0
  139. data/ext/libusb-1.0.19/Xcode/libusb.xcodeproj/project.pbxproj +0 -1
  140. data/ext/libusb-1.0.19/doc/doxygen.cfg.in +0 -1288
  141. data/ext/libusb-1.0.19/libusb/version_nano.h +0 -1
@@ -80,6 +80,8 @@ EXPORTS
80
80
  libusb_get_parent@4 = libusb_get_parent
81
81
  libusb_get_pollfds
82
82
  libusb_get_pollfds@4 = libusb_get_pollfds
83
+ libusb_free_pollfds
84
+ libusb_free_pollfds@4 = libusb_free_pollfds
83
85
  libusb_get_port_number
84
86
  libusb_get_port_number@4 = libusb_get_port_number
85
87
  libusb_get_port_numbers
@@ -54,7 +54,7 @@ typedef unsigned __int32 uint32_t;
54
54
  #include <sys/types.h>
55
55
  #endif
56
56
 
57
- #if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__)
57
+ #if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__)
58
58
  #include <sys/time.h>
59
59
  #endif
60
60
 
@@ -90,7 +90,7 @@ typedef unsigned __int32 uint32_t;
90
90
  * Under Windows, the selection of available compilers and configurations
91
91
  * means that, unlike other platforms, there is not <em>one true calling
92
92
  * convention</em> (calling convention: the manner in which parameters are
93
- * passed to funcions in the generated assembly code).
93
+ * passed to functions in the generated assembly code).
94
94
  *
95
95
  * Matching the Windows API itself, libusb uses the WINAPI convention (which
96
96
  * translates to the <tt>stdcall</tt> convention) and guarantees that the
@@ -138,13 +138,10 @@ typedef unsigned __int32 uint32_t;
138
138
  * #endif
139
139
  * \endcode
140
140
  *
141
- * Another feature of LIBUSB_API_VERSION is that it can be used to detect
142
- * whether you are compiling against the libusb or the libusb library.
143
- *
144
141
  * Internally, LIBUSB_API_VERSION is defined as follows:
145
142
  * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental)
146
143
  */
147
- #define LIBUSB_API_VERSION 0x01000103
144
+ #define LIBUSB_API_VERSION 0x01000104
148
145
 
149
146
  /* The following is kept for compatibility, but will be deprecated in the future */
150
147
  #define LIBUSBX_API_VERSION LIBUSB_API_VERSION
@@ -668,8 +665,9 @@ struct libusb_config_descriptor {
668
665
  uint8_t bmAttributes;
669
666
 
670
667
  /** Maximum power consumption of the USB device from this bus in this
671
- * configuration when the device is fully opreation. Expressed in units
672
- * of 2 mA. */
668
+ * configuration when the device is fully operation. Expressed in units
669
+ * of 2 mA when the device is operating in high-speed mode and in units
670
+ * of 8 mA when the device is operating in super-speed mode. */
673
671
  uint8_t MaxPower;
674
672
 
675
673
  /** Array of interfaces supported by this configuration. The length of
@@ -900,7 +898,6 @@ struct libusb_control_setup {
900
898
  struct libusb_context;
901
899
  struct libusb_device;
902
900
  struct libusb_device_handle;
903
- struct libusb_hotplug_callback;
904
901
 
905
902
  /** \ingroup lib
906
903
  * Structure providing the version of the libusb runtime
@@ -1860,6 +1857,7 @@ typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data);
1860
1857
 
1861
1858
  const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
1862
1859
  libusb_context *ctx);
1860
+ void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds);
1863
1861
  void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
1864
1862
  libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
1865
1863
  void *user_data);
@@ -1884,8 +1882,11 @@ typedef int libusb_hotplug_callback_handle;
1884
1882
  *
1885
1883
  * Flags for hotplug events */
1886
1884
  typedef enum {
1885
+ /** Default value when not using any flags. */
1886
+ LIBUSB_HOTPLUG_NO_FLAGS = 0,
1887
+
1887
1888
  /** Arm the callback and fire it for all matching currently attached devices. */
1888
- LIBUSB_HOTPLUG_ENUMERATE = 1,
1889
+ LIBUSB_HOTPLUG_ENUMERATE = 1<<0,
1889
1890
  } libusb_hotplug_flag;
1890
1891
 
1891
1892
  /** \ingroup hotplug
@@ -21,7 +21,7 @@
21
21
  #ifndef LIBUSBI_H
22
22
  #define LIBUSBI_H
23
23
 
24
- #include "config.h"
24
+ #include <config.h>
25
25
 
26
26
  #include <stdlib.h>
27
27
 
@@ -32,10 +32,10 @@
32
32
  #ifdef HAVE_POLL_H
33
33
  #include <poll.h>
34
34
  #endif
35
-
36
35
  #ifdef HAVE_MISSING_H
37
- #include "missing.h"
36
+ #include <missing.h>
38
37
  #endif
38
+
39
39
  #include "libusb.h"
40
40
  #include "version.h"
41
41
 
@@ -48,6 +48,10 @@
48
48
  */
49
49
  #define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY
50
50
 
51
+ #ifdef __cplusplus
52
+ extern "C" {
53
+ #endif
54
+
51
55
  #define DEVICE_DESC_LENGTH 18
52
56
 
53
57
  #define USB_MAXENDPOINTS 32
@@ -82,6 +86,9 @@ struct list_head {
82
86
  #define list_entry(ptr, type, member) \
83
87
  ((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
84
88
 
89
+ #define list_first_entry(ptr, type, member) \
90
+ list_entry((ptr)->next, type, member)
91
+
85
92
  /* Get each entry from a list
86
93
  * pos - A structure pointer has a "member" element
87
94
  * head - list head
@@ -144,8 +151,12 @@ static inline void *usbi_reallocf(void *ptr, size_t size)
144
151
  const typeof( ((type *)0)->member ) *mptr = (ptr); \
145
152
  (type *)( (char *)mptr - offsetof(type,member) );})
146
153
 
154
+ #ifndef MIN
147
155
  #define MIN(a, b) ((a) < (b) ? (a) : (b))
156
+ #endif
157
+ #ifndef MAX
148
158
  #define MAX(a, b) ((a) > (b) ? (a) : (b))
159
+ #endif
149
160
 
150
161
  #define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)
151
162
 
@@ -228,13 +239,15 @@ static inline void usbi_dbg(const char *format, ...)
228
239
 
229
240
  extern struct libusb_context *usbi_default_context;
230
241
 
242
+ /* Forward declaration for use in context (fully defined inside poll abstraction) */
243
+ struct pollfd;
244
+
231
245
  struct libusb_context {
232
246
  int debug;
233
247
  int debug_fixed;
234
248
 
235
- /* internal control pipe, used for interrupting event handling when
236
- * something needs to modify poll fds. */
237
- int ctrl_pipe[2];
249
+ /* internal event pipe, used for signalling occurrence of an internal event. */
250
+ int event_pipe[2];
238
251
 
239
252
  struct list_head usb_devs;
240
253
  usbi_mutex_t usb_devs_lock;
@@ -247,7 +260,6 @@ struct libusb_context {
247
260
  /* A list of registered hotplug callbacks */
248
261
  struct list_head hotplug_cbs;
249
262
  usbi_mutex_t hotplug_cbs_lock;
250
- int hotplug_pipe[2];
251
263
 
252
264
  /* this is a list of in-flight transfer handles, sorted by timeout
253
265
  * expiration. URBs to timeout the soonest are placed at the beginning of
@@ -256,15 +268,6 @@ struct libusb_context {
256
268
  struct list_head flying_transfers;
257
269
  usbi_mutex_t flying_transfers_lock;
258
270
 
259
- /* list of poll fds */
260
- struct list_head pollfds;
261
- usbi_mutex_t pollfds_lock;
262
-
263
- /* a counter that is set when we want to interrupt event handling, in order
264
- * to modify the poll fd set. and a lock to protect it. */
265
- unsigned int pollfd_modify;
266
- usbi_mutex_t pollfd_modify_lock;
267
-
268
271
  /* user callbacks for pollfd changes */
269
272
  libusb_pollfd_added_cb fd_added_cb;
270
273
  libusb_pollfd_removed_cb fd_removed_cb;
@@ -281,6 +284,28 @@ struct libusb_context {
281
284
  usbi_mutex_t event_waiters_lock;
282
285
  usbi_cond_t event_waiters_cond;
283
286
 
287
+ /* A lock to protect internal context event data. */
288
+ usbi_mutex_t event_data_lock;
289
+
290
+ /* A counter that is set when we want to interrupt and prevent event handling,
291
+ * in order to safely close a device. Protected by event_data_lock. */
292
+ unsigned int device_close;
293
+
294
+ /* list and count of poll fds and an array of poll fd structures that is
295
+ * (re)allocated as necessary prior to polling, and a flag to indicate
296
+ * when the list of poll fds has changed since the last poll.
297
+ * Protected by event_data_lock. */
298
+ struct list_head ipollfds;
299
+ struct pollfd *pollfds;
300
+ POLL_NFDS_TYPE pollfds_cnt;
301
+ unsigned int pollfds_modified;
302
+
303
+ /* A list of pending hotplug messages. Protected by event_data_lock. */
304
+ struct list_head hotplug_msgs;
305
+
306
+ /* A list of pending completed transfers. Protected by event_data_lock. */
307
+ struct list_head completed_transfers;
308
+
284
309
  #ifdef USBI_TIMERFD_AVAILABLE
285
310
  /* used for timeout handling, if supported by OS.
286
311
  * this timerfd is maintained to trigger on the next pending timeout */
@@ -290,6 +315,11 @@ struct libusb_context {
290
315
  struct list_head list;
291
316
  };
292
317
 
318
+ /* Update the following macro if new event sources are added */
319
+ #define usbi_pending_events(ctx) \
320
+ ((ctx)->device_close || (ctx)->pollfds_modified \
321
+ || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers))
322
+
293
323
  #ifdef USBI_TIMERFD_AVAILABLE
294
324
  #define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0)
295
325
  #else
@@ -364,6 +394,7 @@ enum {
364
394
  struct usbi_transfer {
365
395
  int num_iso_packets;
366
396
  struct list_head list;
397
+ struct list_head completed_list;
367
398
  struct timeval timeout;
368
399
  int transferred;
369
400
  uint32_t stream_id;
@@ -377,6 +408,10 @@ struct usbi_transfer {
377
408
  * its completion (presumably there would be races within your OS backend
378
409
  * if this were possible). */
379
410
  usbi_mutex_t lock;
411
+
412
+ /* this lock should be held whenever viewing or modifying flags
413
+ * relating to the transfer state */
414
+ usbi_mutex_t flags_lock;
380
415
  };
381
416
 
382
417
  enum usbi_transfer_flags {
@@ -392,8 +427,17 @@ enum usbi_transfer_flags {
392
427
  /* Operation on the transfer failed because the device disappeared */
393
428
  USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3,
394
429
 
395
- /* Set by backend submit_transfer() if the fds in use have been updated */
396
- USBI_TRANSFER_UPDATED_FDS = 1 << 4,
430
+ /* Transfer is currently being submitted */
431
+ USBI_TRANSFER_SUBMITTING = 1 << 4,
432
+
433
+ /* Transfer successfully submitted by backend */
434
+ USBI_TRANSFER_IN_FLIGHT = 1 << 5,
435
+
436
+ /* Completion handler has run */
437
+ USBI_TRANSFER_COMPLETED = 1 << 6,
438
+
439
+ /* The transfer timeout has been handled */
440
+ USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7,
397
441
  };
398
442
 
399
443
  #define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \
@@ -434,6 +478,7 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle);
434
478
  int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
435
479
  enum libusb_transfer_status status);
436
480
  int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);
481
+ void usbi_signal_transfer_completion(struct usbi_transfer *transfer);
437
482
 
438
483
  int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
439
484
  void *dest, int host_endian);
@@ -444,8 +489,11 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
444
489
  void usbi_connect_device (struct libusb_device *dev);
445
490
  void usbi_disconnect_device (struct libusb_device *dev);
446
491
 
492
+ int usbi_signal_event(struct libusb_context *ctx);
493
+ int usbi_clear_event(struct libusb_context *ctx);
494
+
447
495
  /* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
448
- #if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD)
496
+ #if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU)
449
497
  #include <unistd.h>
450
498
  #include "os/poll_posix.h"
451
499
  #elif defined(OS_WINDOWS) || defined(OS_WINCE)
@@ -474,7 +522,6 @@ struct usbi_pollfd {
474
522
 
475
523
  int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
476
524
  void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
477
- void usbi_fd_notification(struct libusb_context *ctx);
478
525
 
479
526
  /* device discovery */
480
527
 
@@ -765,7 +812,7 @@ struct usbi_os_backend {
765
812
  * This function should not generate any bus I/O and should not block.
766
813
  * Interface claiming is a logical operation that simply ensures that
767
814
  * no other drivers/applications are using the interface, and after
768
- * claiming, no other drivers/applicatiosn can use the interface because
815
+ * claiming, no other drivers/applications can use the interface because
769
816
  * we now "own" it.
770
817
  *
771
818
  * Return:
@@ -943,8 +990,14 @@ struct usbi_os_backend {
943
990
  */
944
991
  void (*clear_transfer_priv)(struct usbi_transfer *itransfer);
945
992
 
946
- /* Handle any pending events. This involves monitoring any active
947
- * transfers and processing their completion or cancellation.
993
+ /* Handle any pending events on file descriptors. Optional.
994
+ *
995
+ * Provide this function when file descriptors directly indicate device
996
+ * or transfer activity. If your backend does not have such file descriptors,
997
+ * implement the handle_transfer_completion function below.
998
+ *
999
+ * This involves monitoring any active transfers and processing their
1000
+ * completion or cancellation.
948
1001
  *
949
1002
  * The function is passed an array of pollfd structures (size nfds)
950
1003
  * as a result of the poll() system call. The num_ready parameter
@@ -972,6 +1025,31 @@ struct usbi_os_backend {
972
1025
  int (*handle_events)(struct libusb_context *ctx,
973
1026
  struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready);
974
1027
 
1028
+ /* Handle transfer completion. Optional.
1029
+ *
1030
+ * Provide this function when there are no file descriptors available
1031
+ * that directly indicate device or transfer activity. If your backend does
1032
+ * have such file descriptors, implement the handle_events function above.
1033
+ *
1034
+ * Your backend must tell the library when a transfer has completed by
1035
+ * calling usbi_signal_transfer_completion(). You should store any private
1036
+ * information about the transfer and its completion status in the transfer's
1037
+ * private backend data.
1038
+ *
1039
+ * During event handling, this function will be called on each transfer for
1040
+ * which usbi_signal_transfer_completion() was called.
1041
+ *
1042
+ * For any cancelled transfers, call usbi_handle_transfer_cancellation().
1043
+ * For completed transfers, call usbi_handle_transfer_completion().
1044
+ * For control/bulk/interrupt transfers, populate the "transferred"
1045
+ * element of the appropriate usbi_transfer structure before calling the
1046
+ * above functions. For isochronous transfers, populate the status and
1047
+ * transferred fields of the iso packet descriptors of the transfer.
1048
+ *
1049
+ * Return 0 on success, or a LIBUSB_ERROR code on failure.
1050
+ */
1051
+ int (*handle_transfer_completion)(struct usbi_transfer *itransfer);
1052
+
975
1053
  /* Get time from specified clock. At least two clocks must be implemented
976
1054
  by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
977
1055
 
@@ -1002,12 +1080,6 @@ struct usbi_os_backend {
1002
1080
  * usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance.
1003
1081
  */
1004
1082
  size_t transfer_priv_size;
1005
-
1006
- /* Mumber of additional bytes for os_priv for each iso packet.
1007
- * Can your backend use this? */
1008
- /* FIXME: linux can't use this any more. if other OS's cannot either,
1009
- * then remove this */
1010
- size_t add_iso_packet_size;
1011
1083
  };
1012
1084
 
1013
1085
  extern const struct usbi_os_backend * const usbi_backend;
@@ -1018,8 +1090,13 @@ extern const struct usbi_os_backend openbsd_backend;
1018
1090
  extern const struct usbi_os_backend netbsd_backend;
1019
1091
  extern const struct usbi_os_backend windows_backend;
1020
1092
  extern const struct usbi_os_backend wince_backend;
1093
+ extern const struct usbi_os_backend haiku_usb_raw_backend;
1021
1094
 
1022
1095
  extern struct list_head active_contexts_list;
1023
1096
  extern usbi_mutex_static_t active_contexts_lock;
1024
1097
 
1098
+ #ifdef __cplusplus
1099
+ }
1100
+ #endif
1101
+
1025
1102
  #endif
@@ -246,7 +246,7 @@ static usb_device_t **darwin_device_from_service (io_service_t service)
246
246
  &score);
247
247
 
248
248
  if (kIOReturnSuccess != result || !plugInInterface) {
249
- usbi_dbg ("could not set up plugin for service: %s\n", darwin_error_str (result));
249
+ usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (result));
250
250
  return NULL;
251
251
  }
252
252
 
@@ -279,6 +279,7 @@ static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
279
279
  static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
280
280
  struct libusb_device *dev = NULL;
281
281
  struct libusb_context *ctx;
282
+ struct darwin_cached_device *old_device;
282
283
 
283
284
  io_service_t device;
284
285
  UInt64 session;
@@ -293,6 +294,17 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
293
294
  if (!ret)
294
295
  continue;
295
296
 
297
+ /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
298
+ otherwise no cached device will ever get freed */
299
+ usbi_mutex_lock(&darwin_cached_devices_lock);
300
+ list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
301
+ if (old_device->session == session) {
302
+ darwin_deref_cached_device (old_device);
303
+ break;
304
+ }
305
+ }
306
+ usbi_mutex_unlock(&darwin_cached_devices_lock);
307
+
296
308
  list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
297
309
  usbi_dbg ("notifying context %p of device disconnect", ctx);
298
310
 
@@ -973,14 +985,6 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
973
985
  /* device opened successfully */
974
986
  dpriv->open_count++;
975
987
 
976
- /* create a file descriptor for notifications */
977
- pipe (priv->fds);
978
-
979
- /* set the pipe to be non-blocking */
980
- fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
981
-
982
- usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
983
-
984
988
  usbi_dbg ("device open for access");
985
989
 
986
990
  return 0;
@@ -994,7 +998,7 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
994
998
 
995
999
  if (dpriv->open_count == 0) {
996
1000
  /* something is probably very wrong if this is the case */
997
- usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!\n");
1001
+ usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
998
1002
  return;
999
1003
  }
1000
1004
 
@@ -1024,13 +1028,6 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
1024
1028
  }
1025
1029
  }
1026
1030
  }
1027
-
1028
- /* file descriptors are maintained per-instance */
1029
- usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
1030
- close (priv->fds[1]);
1031
- close (priv->fds[0]);
1032
-
1033
- priv->fds[0] = priv->fds[1] = -1;
1034
1031
  }
1035
1032
 
1036
1033
  static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
@@ -1761,9 +1758,7 @@ static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) {
1761
1758
  static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
1762
1759
  struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
1763
1760
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1764
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1765
- struct darwin_msg_async_io_complete message = {.itransfer = itransfer, .result = result,
1766
- .size = (UInt32) (uintptr_t) arg0};
1761
+ struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1767
1762
 
1768
1763
  usbi_dbg ("an async io operation has completed");
1769
1764
 
@@ -1777,8 +1772,11 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
1777
1772
  (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
1778
1773
  }
1779
1774
 
1780
- /* send a completion message to the device's file descriptor */
1781
- write (priv->fds[1], &message, sizeof (message));
1775
+ tpriv->result = result;
1776
+ tpriv->size = (UInt32) (uintptr_t) arg0;
1777
+
1778
+ /* signal the core that this transfer is complete */
1779
+ usbi_signal_transfer_completion(itransfer);
1782
1780
  }
1783
1781
 
1784
1782
  static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
@@ -1807,7 +1805,7 @@ static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_
1807
1805
  }
1808
1806
  }
1809
1807
 
1810
- static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
1808
+ static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
1811
1809
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1812
1810
  struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1813
1811
  int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
@@ -1818,13 +1816,13 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
1818
1816
 
1819
1817
  if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
1820
1818
  usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1821
- return;
1819
+ return LIBUSB_ERROR_INVALID_PARAM;
1822
1820
  }
1823
1821
 
1824
1822
  usbi_dbg ("handling %s completion with kernel status %d",
1825
- isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", result);
1823
+ isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
1826
1824
 
1827
- if (kIOReturnSuccess == result || kIOReturnUnderrun == result) {
1825
+ if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
1828
1826
  if (isIsoc && tpriv->isoc_framelist) {
1829
1827
  /* copy isochronous results back */
1830
1828
 
@@ -1834,48 +1832,11 @@ static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return
1834
1832
  lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
1835
1833
  }
1836
1834
  } else if (!isIsoc)
1837
- itransfer->transferred += io_size;
1835
+ itransfer->transferred += tpriv->size;
1838
1836
  }
1839
1837
 
1840
1838
  /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
1841
- usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
1842
- }
1843
-
1844
- static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
1845
- struct darwin_msg_async_io_complete message;
1846
- POLL_NFDS_TYPE i = 0;
1847
- ssize_t ret;
1848
-
1849
- usbi_mutex_lock(&ctx->open_devs_lock);
1850
-
1851
- for (i = 0; i < nfds && num_ready > 0; i++) {
1852
- struct pollfd *pollfd = &fds[i];
1853
-
1854
- usbi_dbg ("checking fd %i with revents = %x", pollfd->fd, pollfd->revents);
1855
-
1856
- if (!pollfd->revents)
1857
- continue;
1858
-
1859
- num_ready--;
1860
-
1861
- if (pollfd->revents & POLLERR) {
1862
- /* this probably will never happen so ignore the error an move on. */
1863
- continue;
1864
- }
1865
-
1866
- /* there is only one type of message */
1867
- ret = read (pollfd->fd, &message, sizeof (message));
1868
- if (ret < (ssize_t) sizeof (message)) {
1869
- usbi_dbg ("WARNING: short read on async io completion pipe\n");
1870
- continue;
1871
- }
1872
-
1873
- darwin_handle_callback (message.itransfer, message.result, message.size);
1874
- }
1875
-
1876
- usbi_mutex_unlock(&ctx->open_devs_lock);
1877
-
1878
- return 0;
1839
+ return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
1879
1840
  }
1880
1841
 
1881
1842
  static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
@@ -1998,12 +1959,11 @@ const struct usbi_os_backend darwin_backend = {
1998
1959
  .cancel_transfer = darwin_cancel_transfer,
1999
1960
  .clear_transfer_priv = darwin_clear_transfer_priv,
2000
1961
 
2001
- .handle_events = op_handle_events,
1962
+ .handle_transfer_completion = darwin_handle_transfer_completion,
2002
1963
 
2003
1964
  .clock_gettime = darwin_clock_gettime,
2004
1965
 
2005
1966
  .device_priv_size = sizeof(struct darwin_device_priv),
2006
1967
  .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2007
1968
  .transfer_priv_size = sizeof(struct darwin_transfer_priv),
2008
- .add_iso_packet_size = 0,
2009
1969
  };