usb 2.1.3 → 2.2.0

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 (279) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +3 -0
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/usb/bindings.d.ts +4 -0
  7. package/dist/usb/device.js +5 -0
  8. package/dist/usb/device.js.map +1 -1
  9. package/libusb/.gitattributes +2 -6
  10. package/libusb/.private/appveyor_build.sh +22 -0
  11. package/libusb/.private/bm.sh +1 -1
  12. package/libusb/.private/ci-build.sh +67 -0
  13. package/libusb/.private/post-rewrite.sh +5 -1
  14. package/libusb/.private/pre-commit.sh +5 -1
  15. package/libusb/.private/wbs.txt +4 -19
  16. package/libusb/.travis.yml +32 -23
  17. package/libusb/AUTHORS +76 -3
  18. package/libusb/ChangeLog +41 -3
  19. package/libusb/INSTALL_WIN.txt +22 -44
  20. package/libusb/Makefile.am +32 -10
  21. package/libusb/{README.md → README} +2 -2
  22. package/libusb/README.git +3 -3
  23. package/libusb/Xcode/common.xcconfig +23 -19
  24. package/libusb/Xcode/config.h +25 -13
  25. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +511 -109
  26. package/libusb/android/README +90 -54
  27. package/libusb/android/config.h +23 -43
  28. package/libusb/android/examples/unrooted_android.c +301 -0
  29. package/libusb/android/examples/unrooted_android.h +36 -0
  30. package/libusb/android/jni/Android.mk +1 -1
  31. package/libusb/android/jni/Application.mk +16 -0
  32. package/libusb/android/jni/examples.mk +63 -29
  33. package/libusb/android/jni/libusb.mk +14 -8
  34. package/libusb/android/jni/tests.mk +13 -24
  35. package/libusb/appveyor.yml +69 -30
  36. package/libusb/autogen.sh +5 -3
  37. package/libusb/bootstrap.sh +6 -2
  38. package/libusb/configure.ac +302 -228
  39. package/libusb/doc/Makefile.in +22 -0
  40. package/libusb/doc/doxygen.cfg.in +460 -223
  41. package/libusb/examples/Makefile.am +6 -13
  42. package/libusb/examples/dpfp.c +276 -73
  43. package/libusb/examples/ezusb.c +18 -8
  44. package/libusb/examples/ezusb.h +6 -17
  45. package/libusb/examples/fxload.c +4 -5
  46. package/libusb/examples/hotplugtest.c +1 -1
  47. package/libusb/examples/sam3u_benchmark.c +59 -24
  48. package/libusb/examples/testlibusb.c +138 -104
  49. package/libusb/examples/xusb.c +26 -22
  50. package/libusb/libusb/Makefile.am +57 -70
  51. package/libusb/libusb/Makefile.am.extra +26 -0
  52. package/libusb/libusb/core.c +420 -423
  53. package/libusb/libusb/descriptor.c +365 -419
  54. package/libusb/libusb/hotplug.c +197 -104
  55. package/libusb/libusb/io.c +491 -528
  56. package/libusb/libusb/libusb-1.0.def +7 -3
  57. package/libusb/libusb/libusb-1.0.rc +1 -9
  58. package/libusb/libusb/libusb.h +295 -226
  59. package/libusb/libusb/libusbi.h +587 -314
  60. package/libusb/libusb/os/darwin_usb.c +634 -317
  61. package/libusb/libusb/os/darwin_usb.h +39 -15
  62. package/libusb/libusb/os/events_posix.c +300 -0
  63. package/libusb/libusb/os/events_posix.h +59 -0
  64. package/libusb/libusb/os/events_windows.c +214 -0
  65. package/libusb/{msvc/missing.h → libusb/os/events_windows.h} +25 -11
  66. package/libusb/libusb/os/haiku_pollfs.cpp +14 -9
  67. package/libusb/libusb/os/haiku_usb.h +12 -12
  68. package/libusb/libusb/os/haiku_usb_backend.cpp +36 -37
  69. package/libusb/libusb/os/haiku_usb_raw.cpp +80 -116
  70. package/libusb/libusb/os/linux_netlink.c +55 -63
  71. package/libusb/libusb/os/linux_udev.c +61 -69
  72. package/libusb/libusb/os/linux_usbfs.c +926 -1015
  73. package/libusb/libusb/os/linux_usbfs.h +74 -57
  74. package/libusb/libusb/os/netbsd_usb.c +103 -168
  75. package/libusb/libusb/os/null_usb.c +111 -0
  76. package/libusb/libusb/os/openbsd_usb.c +71 -120
  77. package/libusb/libusb/os/sunos_usb.c +289 -375
  78. package/libusb/libusb/os/sunos_usb.h +0 -1
  79. package/libusb/libusb/os/threads_posix.c +81 -32
  80. package/libusb/libusb/os/threads_posix.h +19 -23
  81. package/libusb/libusb/os/threads_windows.c +9 -95
  82. package/libusb/libusb/os/threads_windows.h +33 -31
  83. package/libusb/libusb/os/windows_common.c +904 -0
  84. package/libusb/libusb/os/windows_common.h +329 -42
  85. package/libusb/libusb/os/windows_usbdk.c +161 -267
  86. package/libusb/libusb/os/windows_usbdk.h +5 -2
  87. package/libusb/libusb/os/windows_winusb.c +1326 -1190
  88. package/libusb/libusb/os/windows_winusb.h +167 -167
  89. package/libusb/libusb/strerror.c +20 -30
  90. package/libusb/libusb/sync.c +20 -21
  91. package/libusb/libusb/version.h +1 -1
  92. package/libusb/libusb/version_nano.h +1 -1
  93. package/libusb/msvc/.gitattributes +3 -0
  94. package/libusb/msvc/config.h +27 -20
  95. package/libusb/msvc/{hotplugtest_2012.vcxproj → dpfp_2013.vcxproj} +14 -10
  96. package/libusb/msvc/dpfp_2013.vcxproj.filters +26 -0
  97. package/libusb/msvc/{listdevs_2010.vcxproj → dpfp_2015.vcxproj} +14 -9
  98. package/libusb/msvc/dpfp_2015.vcxproj.filters +26 -0
  99. package/libusb/msvc/dpfp_2017.vcxproj +106 -0
  100. package/libusb/msvc/dpfp_2017.vcxproj.filters +26 -0
  101. package/libusb/msvc/dpfp_2019.vcxproj +106 -0
  102. package/libusb/msvc/dpfp_2019.vcxproj.filters +26 -0
  103. package/libusb/msvc/dpfp_threaded_2013.vcxproj +87 -0
  104. package/libusb/msvc/dpfp_threaded_2013.vcxproj.filters +26 -0
  105. package/libusb/msvc/dpfp_threaded_2015.vcxproj +87 -0
  106. package/libusb/msvc/dpfp_threaded_2015.vcxproj.filters +26 -0
  107. package/libusb/msvc/dpfp_threaded_2017.vcxproj +106 -0
  108. package/libusb/msvc/dpfp_threaded_2017.vcxproj.filters +26 -0
  109. package/libusb/msvc/{fxload_2012.vcxproj → dpfp_threaded_2019.vcxproj} +32 -17
  110. package/libusb/msvc/dpfp_threaded_2019.vcxproj.filters +26 -0
  111. package/libusb/msvc/fxload_2013.vcxproj +6 -3
  112. package/libusb/msvc/fxload_2013.vcxproj.filters +35 -0
  113. package/libusb/msvc/fxload_2015.vcxproj +6 -3
  114. package/libusb/msvc/fxload_2015.vcxproj.filters +35 -0
  115. package/libusb/msvc/fxload_2017.vcxproj +6 -7
  116. package/libusb/msvc/fxload_2017.vcxproj.filters +35 -0
  117. package/libusb/msvc/{fxload_2010.vcxproj → fxload_2019.vcxproj} +29 -6
  118. package/libusb/msvc/fxload_2019.vcxproj.filters +35 -0
  119. package/libusb/{examples → msvc}/getopt/getopt.c +0 -0
  120. package/libusb/{examples → msvc}/getopt/getopt.h +0 -0
  121. package/libusb/{examples → msvc}/getopt/getopt1.c +0 -0
  122. package/libusb/msvc/getopt_2013.vcxproj +4 -5
  123. package/libusb/msvc/getopt_2013.vcxproj.filters +26 -0
  124. package/libusb/msvc/getopt_2015.vcxproj +4 -4
  125. package/libusb/msvc/getopt_2015.vcxproj.filters +26 -0
  126. package/libusb/msvc/getopt_2017.vcxproj +4 -10
  127. package/libusb/msvc/getopt_2017.vcxproj.filters +26 -0
  128. package/libusb/msvc/{getopt_2012.vcxproj → getopt_2019.vcxproj} +25 -6
  129. package/libusb/msvc/getopt_2019.vcxproj.filters +26 -0
  130. package/libusb/msvc/hotplugtest_2013.vcxproj +6 -3
  131. package/libusb/msvc/hotplugtest_2013.vcxproj.filters +23 -0
  132. package/libusb/msvc/hotplugtest_2015.vcxproj +6 -3
  133. package/libusb/msvc/hotplugtest_2015.vcxproj.filters +23 -0
  134. package/libusb/msvc/hotplugtest_2017.vcxproj +6 -7
  135. package/libusb/msvc/hotplugtest_2017.vcxproj.filters +23 -0
  136. package/libusb/msvc/hotplugtest_2019.vcxproj +105 -0
  137. package/libusb/msvc/hotplugtest_2019.vcxproj.filters +23 -0
  138. package/libusb/msvc/libusb_2013.sln +50 -20
  139. package/libusb/msvc/libusb_2015.sln +51 -21
  140. package/libusb/msvc/libusb_2017.sln +90 -36
  141. package/libusb/msvc/libusb_2019.sln +240 -0
  142. package/libusb/msvc/libusb_dll_2013.vcxproj +6 -9
  143. package/libusb/msvc/libusb_dll_2013.vcxproj.filters +94 -0
  144. package/libusb/msvc/libusb_dll_2015.vcxproj +6 -8
  145. package/libusb/msvc/libusb_dll_2015.vcxproj.filters +94 -0
  146. package/libusb/msvc/libusb_dll_2017.vcxproj +6 -16
  147. package/libusb/msvc/libusb_dll_2017.vcxproj.filters +94 -0
  148. package/libusb/msvc/{libusb_dll_2010.vcxproj → libusb_dll_2019.vcxproj} +27 -9
  149. package/libusb/msvc/libusb_dll_2019.vcxproj.filters +94 -0
  150. package/libusb/msvc/libusb_static_2013.vcxproj +5 -9
  151. package/libusb/msvc/libusb_static_2013.vcxproj.filters +80 -0
  152. package/libusb/msvc/libusb_static_2015.vcxproj +5 -8
  153. package/libusb/msvc/libusb_static_2015.vcxproj.filters +80 -0
  154. package/libusb/msvc/libusb_static_2017.vcxproj +5 -8
  155. package/libusb/msvc/libusb_static_2017.vcxproj.filters +80 -0
  156. package/libusb/msvc/{libusb_static_2010.vcxproj → libusb_static_2019.vcxproj} +26 -9
  157. package/libusb/msvc/libusb_static_2019.vcxproj.filters +80 -0
  158. package/libusb/msvc/listdevs_2013.vcxproj +6 -3
  159. package/libusb/msvc/listdevs_2013.vcxproj.filters +23 -0
  160. package/libusb/msvc/listdevs_2015.vcxproj +6 -3
  161. package/libusb/msvc/listdevs_2015.vcxproj.filters +23 -0
  162. package/libusb/msvc/listdevs_2017.vcxproj +6 -7
  163. package/libusb/msvc/listdevs_2017.vcxproj.filters +23 -0
  164. package/libusb/msvc/listdevs_2019.vcxproj +105 -0
  165. package/libusb/msvc/listdevs_2019.vcxproj.filters +23 -0
  166. package/libusb/msvc/{listdevs_2012.vcxproj → sam3u_benchmark_2013.vcxproj} +13 -9
  167. package/libusb/msvc/sam3u_benchmark_2013.vcxproj.filters +26 -0
  168. package/libusb/msvc/{hotplugtest_2010.vcxproj → sam3u_benchmark_2015.vcxproj} +13 -8
  169. package/libusb/msvc/sam3u_benchmark_2015.vcxproj.filters +26 -0
  170. package/libusb/msvc/sam3u_benchmark_2017.vcxproj +106 -0
  171. package/libusb/msvc/sam3u_benchmark_2017.vcxproj.filters +26 -0
  172. package/libusb/msvc/sam3u_benchmark_2019.vcxproj +106 -0
  173. package/libusb/msvc/sam3u_benchmark_2019.vcxproj.filters +26 -0
  174. package/libusb/msvc/stress_2013.vcxproj +4 -2
  175. package/libusb/msvc/stress_2013.vcxproj.filters +32 -0
  176. package/libusb/msvc/stress_2015.vcxproj +4 -2
  177. package/libusb/msvc/stress_2015.vcxproj.filters +32 -0
  178. package/libusb/msvc/stress_2017.vcxproj +4 -6
  179. package/libusb/msvc/stress_2017.vcxproj.filters +32 -0
  180. package/libusb/msvc/{stress_2010.vcxproj → stress_2019.vcxproj} +26 -4
  181. package/libusb/msvc/stress_2019.vcxproj.filters +32 -0
  182. package/libusb/msvc/testlibusb_2013.vcxproj +6 -3
  183. package/libusb/msvc/testlibusb_2013.vcxproj.filters +23 -0
  184. package/libusb/msvc/testlibusb_2015.vcxproj +6 -3
  185. package/libusb/msvc/testlibusb_2015.vcxproj.filters +23 -0
  186. package/libusb/msvc/testlibusb_2017.vcxproj +6 -7
  187. package/libusb/msvc/testlibusb_2017.vcxproj.filters +23 -0
  188. package/libusb/msvc/{testlibusb_2010.vcxproj → testlibusb_2019.vcxproj} +28 -5
  189. package/libusb/msvc/testlibusb_2019.vcxproj.filters +23 -0
  190. package/libusb/msvc/xusb_2013.vcxproj +6 -3
  191. package/libusb/msvc/xusb_2013.vcxproj.filters +23 -0
  192. package/libusb/msvc/xusb_2015.vcxproj +6 -3
  193. package/libusb/msvc/xusb_2015.vcxproj.filters +23 -0
  194. package/libusb/msvc/xusb_2017.vcxproj +6 -7
  195. package/libusb/msvc/xusb_2017.vcxproj.filters +23 -0
  196. package/libusb/msvc/{xusb_2010.vcxproj → xusb_2019.vcxproj} +28 -5
  197. package/libusb/msvc/xusb_2019.vcxproj.filters +23 -0
  198. package/libusb/tests/Makefile.am +1 -0
  199. package/libusb/tests/libusb_testlib.h +12 -43
  200. package/libusb/tests/stress.c +59 -50
  201. package/libusb/tests/testlib.c +78 -171
  202. package/libusb.gypi +10 -11
  203. package/package.json +1 -1
  204. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  205. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  206. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  207. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  208. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  209. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  210. package/prebuilds/linux-ia32/node.napi.node +0 -0
  211. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  212. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  213. package/prebuilds/win32-ia32/node.napi.node +0 -0
  214. package/prebuilds/win32-x64/node.napi.node +0 -0
  215. package/src/device.cc +12 -7
  216. package/src/node_usb.cc +10 -0
  217. package/test/usb.coffee +6 -0
  218. package/tsc/index.ts +2 -0
  219. package/tsc/usb/bindings.ts +5 -0
  220. package/tsc/usb/device.ts +6 -0
  221. package/libusb/.private/bd.cmd +0 -89
  222. package/libusb/.private/bwince.cmd +0 -57
  223. package/libusb/.private/wbs_wince.txt +0 -42
  224. package/libusb/Brewfile +0 -4
  225. package/libusb/appveyor_cygwin.bat +0 -11
  226. package/libusb/appveyor_minGW.bat +0 -19
  227. package/libusb/doc/Makefile.am +0 -9
  228. package/libusb/examples/dpfp_threaded.c +0 -557
  229. package/libusb/libusb/hotplug.h +0 -99
  230. package/libusb/libusb/os/poll_posix.c +0 -84
  231. package/libusb/libusb/os/poll_posix.h +0 -14
  232. package/libusb/libusb/os/poll_windows.c +0 -447
  233. package/libusb/libusb/os/poll_windows.h +0 -98
  234. package/libusb/libusb/os/wince_usb.c +0 -888
  235. package/libusb/libusb/os/wince_usb.h +0 -126
  236. package/libusb/libusb/os/windows_nt_common.c +0 -1010
  237. package/libusb/libusb/os/windows_nt_common.h +0 -110
  238. package/libusb/libusb/os/windows_nt_shared_types.h +0 -147
  239. package/libusb/msvc/appveyor.bat +0 -27
  240. package/libusb/msvc/ddk_build.cmd +0 -219
  241. package/libusb/msvc/errno.h +0 -102
  242. package/libusb/msvc/fxload_sources +0 -23
  243. package/libusb/msvc/getopt_2005.vcproj +0 -288
  244. package/libusb/msvc/getopt_2010.vcxproj +0 -72
  245. package/libusb/msvc/getopt_sources +0 -24
  246. package/libusb/msvc/hotplugtest_sources +0 -20
  247. package/libusb/msvc/inttypes.h +0 -295
  248. package/libusb/msvc/libusb.dsw +0 -71
  249. package/libusb/msvc/libusb_2005.sln +0 -95
  250. package/libusb/msvc/libusb_2010.sln +0 -105
  251. package/libusb/msvc/libusb_2012.sln +0 -105
  252. package/libusb/msvc/libusb_dll.dsp +0 -194
  253. package/libusb/msvc/libusb_dll_2005.vcproj +0 -464
  254. package/libusb/msvc/libusb_dll_2012.vcxproj +0 -107
  255. package/libusb/msvc/libusb_dll_wince.vcproj +0 -1251
  256. package/libusb/msvc/libusb_sources +0 -43
  257. package/libusb/msvc/libusb_static.dsp +0 -174
  258. package/libusb/msvc/libusb_static_2005.vcproj +0 -390
  259. package/libusb/msvc/libusb_static_2012.vcxproj +0 -98
  260. package/libusb/msvc/libusb_static_wince.vcproj +0 -1179
  261. package/libusb/msvc/libusb_wince.sln +0 -246
  262. package/libusb/msvc/listdevs.dsp +0 -103
  263. package/libusb/msvc/listdevs_2005.vcproj +0 -360
  264. package/libusb/msvc/listdevs_sources +0 -20
  265. package/libusb/msvc/listdevs_wince.vcproj +0 -1120
  266. package/libusb/msvc/missing.c +0 -80
  267. package/libusb/msvc/stdint.h +0 -256
  268. package/libusb/msvc/stress_2005.vcproj +0 -390
  269. package/libusb/msvc/stress_2012.vcxproj +0 -87
  270. package/libusb/msvc/stress_sources +0 -21
  271. package/libusb/msvc/stress_wince.vcproj +0 -1128
  272. package/libusb/msvc/testlibusb_2012.vcxproj +0 -83
  273. package/libusb/msvc/testlibusb_sources +0 -20
  274. package/libusb/msvc/xusb.dsp +0 -102
  275. package/libusb/msvc/xusb_2005.vcproj +0 -344
  276. package/libusb/msvc/xusb_2012.vcxproj +0 -83
  277. package/libusb/msvc/xusb_sources +0 -20
  278. package/libusb/msvc/xusb_wince.vcproj +0 -1120
  279. package/libusb/travis-autogen.sh +0 -39
@@ -1,7 +1,7 @@
1
1
  /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2
2
  /*
3
3
  * Hotplug functions for libusb
4
- * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
4
+ * Copyright © 2012-2021 Nathan Hjelm <hjelmn@mac.com>
5
5
  * Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
6
6
  *
7
7
  * This library is free software; you can redistribute it and/or
@@ -19,19 +19,7 @@
19
19
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
  */
21
21
 
22
- #include <config.h>
23
-
24
- #include <errno.h>
25
- #include <stdio.h>
26
- #include <stdlib.h>
27
- #include <string.h>
28
- #ifdef HAVE_SYS_TYPES_H
29
- #include <sys/types.h>
30
- #endif
31
- #include <assert.h>
32
-
33
22
  #include "libusbi.h"
34
- #include "hotplug.h"
35
23
 
36
24
  /**
37
25
  * @defgroup libusb_hotplug Device hotplug event notification
@@ -48,7 +36,7 @@
48
36
  * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
49
37
  * for hotplug events on <b>some</b> platforms (you should test if your platform
50
38
  * supports hotplug notification by calling \ref libusb_has_capability() with
51
- * parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
39
+ * parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
52
40
  *
53
41
  * This interface allows you to request notification for the arrival and departure
54
42
  * of matching USB devices.
@@ -61,8 +49,8 @@
61
49
  * expecting additional events. Returning 0 will rearm the callback and 1 will cause
62
50
  * the callback to be deregistered. Note that when callbacks are called from
63
51
  * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE
64
- * flag, the callback return value is ignored, iow you cannot cause a callback
65
- * to be deregistered by returning 1 when it is called from
52
+ * flag, the callback return value is ignored. In other words, you cannot cause a
53
+ * callback to be deregistered by returning 1 when it is called from
66
54
  * libusb_hotplug_register_callback().
67
55
  *
68
56
  * Callbacks for a particular context are automatically deregistered by libusb_exit().
@@ -74,7 +62,7 @@
74
62
  * A hotplug event can listen for either or both of these events.
75
63
  *
76
64
  * Note: If you receive notification that a device has left and you have any
77
- * a libusb_device_handles for the device it is up to you to call libusb_close()
65
+ * libusb_device_handles for the device it is up to you to call libusb_close()
78
66
  * on each device handle to free up any remaining resources associated with the device.
79
67
  * Once a device has left any libusb_device_handle associated with the device
80
68
  * are invalid and will remain so even if the device comes back.
@@ -154,9 +142,77 @@ int main (void) {
154
142
  \endcode
155
143
  */
156
144
 
157
- static int usbi_hotplug_match_cb(struct libusb_context *ctx,
158
- struct libusb_device *dev, libusb_hotplug_event event,
159
- struct libusb_hotplug_callback *hotplug_cb)
145
+ #define VALID_HOTPLUG_EVENTS \
146
+ (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | \
147
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
148
+
149
+ #define VALID_HOTPLUG_FLAGS \
150
+ (LIBUSB_HOTPLUG_ENUMERATE)
151
+
152
+ void usbi_hotplug_init(struct libusb_context *ctx)
153
+ {
154
+ /* check for hotplug support */
155
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
156
+ return;
157
+
158
+ usbi_mutex_init(&ctx->hotplug_cbs_lock);
159
+ list_init(&ctx->hotplug_cbs);
160
+ ctx->next_hotplug_cb_handle = 1;
161
+ usbi_atomic_store(&ctx->hotplug_ready, 1);
162
+ }
163
+
164
+ void usbi_hotplug_exit(struct libusb_context *ctx)
165
+ {
166
+ struct usbi_hotplug_callback *hotplug_cb, *next_cb;
167
+ struct usbi_hotplug_message *msg;
168
+ struct libusb_device *dev, *next_dev;
169
+
170
+ /* check for hotplug support */
171
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
172
+ return;
173
+
174
+ /* free all registered hotplug callbacks */
175
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
176
+ list_del(&hotplug_cb->list);
177
+ free(hotplug_cb);
178
+ }
179
+
180
+ /* free all pending hotplug messages */
181
+ while (!list_empty(&ctx->hotplug_msgs)) {
182
+ msg = list_first_entry(&ctx->hotplug_msgs, struct usbi_hotplug_message, list);
183
+
184
+ /* if the device left, the message holds a reference
185
+ * and we must drop it */
186
+ if (msg->event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
187
+ libusb_unref_device(msg->device);
188
+
189
+ list_del(&msg->list);
190
+ free(msg);
191
+ }
192
+
193
+ /* free all discovered devices. due to parent references loop until no devices are freed. */
194
+ for_each_device_safe(ctx, dev, next_dev) {
195
+ /* remove the device from the usb_devs list only if there are no
196
+ * references held, otherwise leave it on the list so that a
197
+ * warning message will be shown */
198
+ if (usbi_atomic_load(&dev->refcnt) == 1) {
199
+ list_del(&dev->list);
200
+ }
201
+ if (dev->parent_dev && usbi_atomic_load(&dev->parent_dev->refcnt) == 1) {
202
+ /* the parent was before this device in the list and will be released.
203
+ remove it from the list. this is safe as parent_dev can not be
204
+ equal to next_dev. */
205
+ assert (dev->parent_dev != next_dev);
206
+ list_del(&dev->parent_dev->list);
207
+ }
208
+ libusb_unref_device(dev);
209
+ }
210
+
211
+ usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
212
+ }
213
+
214
+ static int usbi_hotplug_match_cb(struct libusb_device *dev,
215
+ libusb_hotplug_event event, struct usbi_hotplug_callback *hotplug_cb)
160
216
  {
161
217
  if (!(hotplug_cb->flags & event)) {
162
218
  return 0;
@@ -177,28 +233,82 @@ static int usbi_hotplug_match_cb(struct libusb_context *ctx,
177
233
  return 0;
178
234
  }
179
235
 
180
- return hotplug_cb->cb(ctx, dev, event, hotplug_cb->user_data);
236
+ return hotplug_cb->cb(DEVICE_CTX(dev), dev, event, hotplug_cb->user_data);
181
237
  }
182
238
 
183
- void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
239
+ void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
184
240
  libusb_hotplug_event event)
185
241
  {
186
- struct libusb_hotplug_callback *hotplug_cb, *next;
187
- int ret;
242
+ struct usbi_hotplug_message *msg;
243
+ unsigned int event_flags;
244
+
245
+ /* Only generate a notification if hotplug is ready. This prevents hotplug
246
+ * notifications from being generated during initial enumeration or if the
247
+ * backend does not support hotplug. */
248
+ if (!usbi_atomic_load(&ctx->hotplug_ready))
249
+ return;
250
+
251
+ msg = calloc(1, sizeof(*msg));
252
+ if (!msg) {
253
+ usbi_err(ctx, "error allocating hotplug message");
254
+ return;
255
+ }
256
+
257
+ msg->event = event;
258
+ msg->device = dev;
259
+
260
+ /* Take the event data lock and add this message to the list.
261
+ * Only signal an event if there are no prior pending events. */
262
+ usbi_mutex_lock(&ctx->event_data_lock);
263
+ event_flags = ctx->event_flags;
264
+ ctx->event_flags |= USBI_EVENT_HOTPLUG_MSG_PENDING;
265
+ list_add_tail(&msg->list, &ctx->hotplug_msgs);
266
+ if (!event_flags)
267
+ usbi_signal_event(&ctx->event);
268
+ usbi_mutex_unlock(&ctx->event_data_lock);
269
+ }
270
+
271
+ void usbi_hotplug_process(struct libusb_context *ctx, struct list_head *hotplug_msgs)
272
+ {
273
+ struct usbi_hotplug_callback *hotplug_cb, *next_cb;
274
+ struct usbi_hotplug_message *msg;
275
+ int r;
188
276
 
189
277
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
190
278
 
191
- list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
192
- if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
193
- /* process deregistration in usbi_hotplug_deregister() */
194
- continue;
279
+ /* dispatch all pending hotplug messages */
280
+ while (!list_empty(hotplug_msgs)) {
281
+ msg = list_first_entry(hotplug_msgs, struct usbi_hotplug_message, list);
282
+
283
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
284
+ /* skip callbacks that have unregistered */
285
+ if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)
286
+ continue;
287
+
288
+ usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
289
+ r = usbi_hotplug_match_cb(msg->device, msg->event, hotplug_cb);
290
+ usbi_mutex_lock(&ctx->hotplug_cbs_lock);
291
+
292
+ if (r) {
293
+ list_del(&hotplug_cb->list);
294
+ free(hotplug_cb);
295
+ }
195
296
  }
196
297
 
197
- usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
198
- ret = usbi_hotplug_match_cb(ctx, dev, event, hotplug_cb);
199
- usbi_mutex_lock(&ctx->hotplug_cbs_lock);
298
+ /* if the device left, the message holds a reference
299
+ * and we must drop it */
300
+ if (msg->event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
301
+ libusb_unref_device(msg->device);
302
+
303
+ list_del(&msg->list);
304
+ free(msg);
305
+ }
200
306
 
201
- if (ret) {
307
+ /* free any callbacks that have unregistered */
308
+ for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
309
+ if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
310
+ usbi_dbg(ctx, "freeing hotplug cb %p with handle %d",
311
+ hotplug_cb, hotplug_cb->handle);
202
312
  list_del(&hotplug_cb->list);
203
313
  free(hotplug_cb);
204
314
  }
@@ -207,41 +317,17 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
207
317
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
208
318
  }
209
319
 
210
- void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
211
- libusb_hotplug_event event)
212
- {
213
- int pending_events;
214
- struct libusb_hotplug_message *message = calloc(1, sizeof(*message));
215
-
216
- if (!message) {
217
- usbi_err(ctx, "error allocating hotplug message");
218
- return;
219
- }
220
-
221
- message->event = event;
222
- message->device = dev;
223
-
224
- /* Take the event data lock and add this message to the list.
225
- * Only signal an event if there are no prior pending events. */
226
- usbi_mutex_lock(&ctx->event_data_lock);
227
- pending_events = usbi_pending_events(ctx);
228
- list_add_tail(&message->list, &ctx->hotplug_msgs);
229
- if (!pending_events)
230
- usbi_signal_event(ctx);
231
- usbi_mutex_unlock(&ctx->event_data_lock);
232
- }
233
-
234
320
  int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
235
- libusb_hotplug_event events, libusb_hotplug_flag flags,
321
+ int events, int flags,
236
322
  int vendor_id, int product_id, int dev_class,
237
323
  libusb_hotplug_callback_fn cb_fn, void *user_data,
238
324
  libusb_hotplug_callback_handle *callback_handle)
239
325
  {
240
- struct libusb_hotplug_callback *new_callback;
326
+ struct usbi_hotplug_callback *hotplug_cb;
241
327
 
242
328
  /* check for sane values */
243
- if ((!events || (~(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) & events)) ||
244
- (flags && (~LIBUSB_HOTPLUG_ENUMERATE & flags)) ||
329
+ if (!events || (~VALID_HOTPLUG_EVENTS & events) ||
330
+ (~VALID_HOTPLUG_FLAGS & flags) ||
245
331
  (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
246
332
  (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
247
333
  (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
@@ -250,47 +336,45 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
250
336
  }
251
337
 
252
338
  /* check for hotplug support */
253
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
339
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
254
340
  return LIBUSB_ERROR_NOT_SUPPORTED;
255
- }
256
341
 
257
- USBI_GET_CONTEXT(ctx);
342
+ ctx = usbi_get_context(ctx);
258
343
 
259
- new_callback = calloc(1, sizeof(*new_callback));
260
- if (!new_callback) {
344
+ hotplug_cb = calloc(1, sizeof(*hotplug_cb));
345
+ if (!hotplug_cb)
261
346
  return LIBUSB_ERROR_NO_MEM;
262
- }
263
347
 
264
- new_callback->flags = (uint8_t)events;
348
+ hotplug_cb->flags = (uint8_t)events;
265
349
  if (LIBUSB_HOTPLUG_MATCH_ANY != vendor_id) {
266
- new_callback->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
267
- new_callback->vendor_id = (uint16_t)vendor_id;
350
+ hotplug_cb->flags |= USBI_HOTPLUG_VENDOR_ID_VALID;
351
+ hotplug_cb->vendor_id = (uint16_t)vendor_id;
268
352
  }
269
353
  if (LIBUSB_HOTPLUG_MATCH_ANY != product_id) {
270
- new_callback->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
271
- new_callback->product_id = (uint16_t)product_id;
354
+ hotplug_cb->flags |= USBI_HOTPLUG_PRODUCT_ID_VALID;
355
+ hotplug_cb->product_id = (uint16_t)product_id;
272
356
  }
273
357
  if (LIBUSB_HOTPLUG_MATCH_ANY != dev_class) {
274
- new_callback->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
275
- new_callback->dev_class = (uint8_t)dev_class;
358
+ hotplug_cb->flags |= USBI_HOTPLUG_DEV_CLASS_VALID;
359
+ hotplug_cb->dev_class = (uint8_t)dev_class;
276
360
  }
277
- new_callback->cb = cb_fn;
278
- new_callback->user_data = user_data;
361
+ hotplug_cb->cb = cb_fn;
362
+ hotplug_cb->user_data = user_data;
279
363
 
280
364
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
281
365
 
282
366
  /* protect the handle by the context hotplug lock */
283
- new_callback->handle = ctx->next_hotplug_cb_handle++;
367
+ hotplug_cb->handle = ctx->next_hotplug_cb_handle++;
284
368
 
285
369
  /* handle the unlikely case of overflow */
286
370
  if (ctx->next_hotplug_cb_handle < 0)
287
371
  ctx->next_hotplug_cb_handle = 1;
288
372
 
289
- list_add(&new_callback->list, &ctx->hotplug_cbs);
373
+ list_add(&hotplug_cb->list, &ctx->hotplug_cbs);
290
374
 
291
375
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
292
376
 
293
- usbi_dbg("new hotplug cb %p with handle %d", new_callback, new_callback->handle);
377
+ usbi_dbg(ctx, "new hotplug cb %p with handle %d", hotplug_cb, hotplug_cb->handle);
294
378
 
295
379
  if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
296
380
  ssize_t i, len;
@@ -298,76 +382,85 @@ int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
298
382
 
299
383
  len = libusb_get_device_list(ctx, &devs);
300
384
  if (len < 0) {
301
- libusb_hotplug_deregister_callback(ctx,
302
- new_callback->handle);
385
+ libusb_hotplug_deregister_callback(ctx, hotplug_cb->handle);
303
386
  return (int)len;
304
387
  }
305
388
 
306
389
  for (i = 0; i < len; i++) {
307
- usbi_hotplug_match_cb(ctx, devs[i],
390
+ usbi_hotplug_match_cb(devs[i],
308
391
  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
309
- new_callback);
392
+ hotplug_cb);
310
393
  }
311
394
 
312
395
  libusb_free_device_list(devs, 1);
313
396
  }
314
397
 
315
-
316
398
  if (callback_handle)
317
- *callback_handle = new_callback->handle;
399
+ *callback_handle = hotplug_cb->handle;
318
400
 
319
401
  return LIBUSB_SUCCESS;
320
402
  }
321
403
 
322
- void API_EXPORTED libusb_hotplug_deregister_callback(struct libusb_context *ctx,
404
+ void API_EXPORTED libusb_hotplug_deregister_callback(libusb_context *ctx,
323
405
  libusb_hotplug_callback_handle callback_handle)
324
406
  {
325
- struct libusb_hotplug_callback *hotplug_cb;
407
+ struct usbi_hotplug_callback *hotplug_cb;
326
408
  int deregistered = 0;
327
409
 
328
410
  /* check for hotplug support */
329
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
411
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
330
412
  return;
331
- }
332
413
 
333
- USBI_GET_CONTEXT(ctx);
414
+ usbi_dbg(ctx, "deregister hotplug cb %d", callback_handle);
334
415
 
335
- usbi_dbg("deregister hotplug cb %d", callback_handle);
416
+ ctx = usbi_get_context(ctx);
336
417
 
337
418
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
338
- list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
419
+ for_each_hotplug_cb(ctx, hotplug_cb) {
339
420
  if (callback_handle == hotplug_cb->handle) {
340
- /* Mark this callback for deregistration */
421
+ /* mark this callback for deregistration */
341
422
  hotplug_cb->flags |= USBI_HOTPLUG_NEEDS_FREE;
342
423
  deregistered = 1;
424
+ break;
343
425
  }
344
426
  }
345
427
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
346
428
 
347
429
  if (deregistered) {
348
- int pending_events;
430
+ unsigned int event_flags;
349
431
 
350
432
  usbi_mutex_lock(&ctx->event_data_lock);
351
- pending_events = usbi_pending_events(ctx);
433
+ event_flags = ctx->event_flags;
352
434
  ctx->event_flags |= USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
353
- if (!pending_events)
354
- usbi_signal_event(ctx);
435
+ if (!event_flags)
436
+ usbi_signal_event(&ctx->event);
355
437
  usbi_mutex_unlock(&ctx->event_data_lock);
356
438
  }
357
439
  }
358
440
 
359
- void usbi_hotplug_deregister(struct libusb_context *ctx, int forced)
441
+ DEFAULT_VISIBILITY
442
+ void * LIBUSB_CALL libusb_hotplug_get_user_data(libusb_context *ctx,
443
+ libusb_hotplug_callback_handle callback_handle)
360
444
  {
361
- struct libusb_hotplug_callback *hotplug_cb, *next;
445
+ struct usbi_hotplug_callback *hotplug_cb;
446
+ void *user_data = NULL;
447
+
448
+ /* check for hotplug support */
449
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
450
+ return NULL;
451
+
452
+ usbi_dbg(ctx, "get hotplug cb %d user data", callback_handle);
453
+
454
+ ctx = usbi_get_context(ctx);
362
455
 
363
456
  usbi_mutex_lock(&ctx->hotplug_cbs_lock);
364
- list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
365
- if (forced || (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE)) {
366
- usbi_dbg("freeing hotplug cb %p with handle %d", hotplug_cb,
367
- hotplug_cb->handle);
368
- list_del(&hotplug_cb->list);
369
- free(hotplug_cb);
457
+ for_each_hotplug_cb(ctx, hotplug_cb) {
458
+ if (callback_handle == hotplug_cb->handle) {
459
+ user_data = hotplug_cb->user_data;
460
+ break;
370
461
  }
371
462
  }
372
463
  usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
464
+
465
+ return user_data;
373
466
  }