libusb 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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
  };