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
@@ -20,41 +20,32 @@
20
20
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  */
22
22
 
23
- #include "config.h"
23
+ #include "libusbi.h"
24
+ #include "version.h"
24
25
 
25
- #include <errno.h>
26
- #include <stdarg.h>
26
+ #ifdef __ANDROID__
27
+ #include <android/log.h>
28
+ #endif
27
29
  #include <stdio.h>
28
- #include <stdlib.h>
29
30
  #include <string.h>
30
- #ifdef HAVE_SYS_TYPES_H
31
- #include <sys/types.h>
32
- #endif
33
- #ifdef HAVE_SYS_TIME_H
34
- #include <sys/time.h>
35
- #endif
36
- #ifdef HAVE_SYSLOG_H
31
+ #ifdef HAVE_SYSLOG
37
32
  #include <syslog.h>
38
33
  #endif
39
34
 
40
- #ifdef __ANDROID__
41
- #include <android/log.h>
42
- #endif
43
-
44
- #include "libusbi.h"
45
- #include "hotplug.h"
46
-
47
- struct libusb_context *usbi_default_context = NULL;
48
35
  static const struct libusb_version libusb_version_internal =
49
36
  { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO,
50
37
  LIBUSB_RC, "http://libusb.info" };
51
- static int default_context_refcnt = 0;
52
- static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
53
- static struct timespec timestamp_origin = { 0, 0 };
54
- #ifndef USE_SYSTEM_LOGGING_FACILITY
55
- static libusb_log_cb log_handler = NULL;
38
+ static struct timespec timestamp_origin;
39
+ #if defined(ENABLE_LOGGING) && !defined(USE_SYSTEM_LOGGING_FACILITY)
40
+ static libusb_log_cb log_handler;
56
41
  #endif
57
42
 
43
+ struct libusb_context *usbi_default_context;
44
+ static int default_context_refcnt;
45
+ static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
46
+ static struct usbi_option default_context_options[LIBUSB_OPTION_MAX];
47
+
48
+
58
49
  usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
59
50
  struct list_head active_contexts_list;
60
51
 
@@ -64,7 +55,7 @@ struct list_head active_contexts_list;
64
55
  * \section intro Introduction
65
56
  *
66
57
  * libusb is an open source library that allows you to communicate with USB
67
- * devices from userspace. For more info, see the
58
+ * devices from user space. For more info, see the
68
59
  * <a href="http://libusb.info">libusb homepage</a>.
69
60
  *
70
61
  * This documentation is aimed at application developers wishing to
@@ -168,6 +159,36 @@ struct list_head active_contexts_list;
168
159
  /**
169
160
  * \page libusb_caveats Caveats
170
161
  *
162
+ * \section threadsafety Thread safety
163
+ *
164
+ * libusb is designed to be completely thread-safe, but as with any API it
165
+ * cannot prevent a user from sabotaging themselves, either intentionally or
166
+ * otherwise.
167
+ *
168
+ * Observe the following general guidelines:
169
+ *
170
+ * - Calls to functions that release a resource (e.g. libusb_close(),
171
+ * libusb_free_config_descriptor()) should not be called concurrently on
172
+ * the same resource. This is no different than concurrently calling free()
173
+ * on the same allocated pointer.
174
+ * - Each individual \ref libusb_transfer should be prepared by a single
175
+ * thread. In other words, no two threads should ever be concurrently
176
+ * filling out the fields of a \ref libusb_transfer. You can liken this to
177
+ * calling sprintf() with the same destination buffer from multiple threads.
178
+ * The results will likely not be what you want unless the input parameters
179
+ * are all the same, but its best to avoid this situation entirely.
180
+ * - Both the \ref libusb_transfer structure and its associated data buffer
181
+ * should not be accessed between the time the transfer is submitted and the
182
+ * time the completion callback is invoked. You can think of "ownership" of
183
+ * these things as being transferred to libusb while the transfer is active.
184
+ * - The various "setter" functions (e.g. libusb_set_log_cb(),
185
+ * libusb_set_pollfd_notifiers()) should not be called concurrently on the
186
+ * resource. Though doing so will not lead to any undefined behavior, it
187
+ * will likely produce results that the application does not expect.
188
+ *
189
+ * Rules for multiple threads and asynchronous I/O are detailed
190
+ * \ref libusb_mtasync "here".
191
+ *
171
192
  * \section fork Fork considerations
172
193
  *
173
194
  * libusb is <em>not</em> designed to work across fork() calls. Depending on
@@ -194,12 +215,12 @@ struct list_head active_contexts_list;
194
215
  * you when this has happened, so if someone else resets your device it will
195
216
  * not be clear to your own program why the device state has changed.
196
217
  *
197
- * Ultimately, this is a limitation of writing drivers in userspace.
218
+ * Ultimately, this is a limitation of writing drivers in user space.
198
219
  * Separation from the USB stack in the underlying kernel makes it difficult
199
220
  * for the operating system to deliver such notifications to your program.
200
221
  * The Linux kernel USB stack allows such reset notifications to be delivered
201
222
  * to in-kernel USB drivers, but it is not clear how such notifications could
202
- * be delivered to second-class drivers that live in userspace.
223
+ * be delivered to second-class drivers that live in user space.
203
224
  *
204
225
  * \section blockonly Blocking-only functionality
205
226
  *
@@ -291,7 +312,8 @@ if (cfg != desired)
291
312
  * - libusb is able to send a packet of zero length to an endpoint simply by
292
313
  * submitting a transfer of zero length.
293
314
  * - The \ref libusb_transfer_flags::LIBUSB_TRANSFER_ADD_ZERO_PACKET
294
- * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently only supported on Linux.
315
+ * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently supported on Linux,
316
+ * Darwin and Windows (WinUSB).
295
317
  */
296
318
 
297
319
  /**
@@ -442,6 +464,7 @@ if (cfg != desired)
442
464
  * - libusb_unlock_event_waiters()
443
465
  * - libusb_unref_device()
444
466
  * - libusb_wait_for_event()
467
+ * - libusb_wrap_sys_device()
445
468
  *
446
469
  * \section Structures
447
470
  * - libusb_bos_descriptor
@@ -470,6 +493,7 @@ if (cfg != desired)
470
493
  * - \ref libusb_class_code
471
494
  * - \ref libusb_descriptor_type
472
495
  * - \ref libusb_endpoint_direction
496
+ * - \ref libusb_endpoint_transfer_type
473
497
  * - \ref libusb_error
474
498
  * - \ref libusb_iso_sync_type
475
499
  * - \ref libusb_iso_usage_type
@@ -556,7 +580,9 @@ libusb_free_device_list(list, 1);
556
580
  *
557
581
  * The libusb_get_device_list() function can be used to obtain a list of
558
582
  * devices currently connected to the system. This is known as device
559
- * discovery.
583
+ * discovery. Devices can also be discovered with the hotplug mechanism,
584
+ * whereby a callback function registered with libusb_hotplug_register_callback()
585
+ * will be called when a device of interest is connected or disconnected.
560
586
  *
561
587
  * Just because you have a reference to a device does not mean it is
562
588
  * necessarily usable. The device may have been unplugged, you may not have
@@ -587,7 +613,7 @@ libusb_free_device_list(list, 1);
587
613
  *
588
614
  * With the above information in mind, the process of opening a device can
589
615
  * be viewed as follows:
590
- * -# Discover devices using libusb_get_device_list().
616
+ * -# Discover devices using libusb_get_device_list() or libusb_hotplug_register_callback().
591
617
  * -# Choose the device that you want to operate, and call libusb_open().
592
618
  * -# Unref all devices in the discovered device list.
593
619
  * -# Free the discovered device list.
@@ -612,7 +638,7 @@ libusb_free_device_list(list, 1);
612
638
  * which grows when required. it can be freed once discovery has completed,
613
639
  * eliminating the need for a list node in the libusb_device structure
614
640
  * itself. */
615
- #define DISCOVERED_DEVICES_SIZE_STEP 8
641
+ #define DISCOVERED_DEVICES_SIZE_STEP 16
616
642
 
617
643
  static struct discovered_devs *discovered_devs_alloc(void)
618
644
  {
@@ -653,7 +679,7 @@ struct discovered_devs *discovered_devs_append(
653
679
  }
654
680
 
655
681
  /* exceeded capacity, need to grow */
656
- usbi_dbg("need to increase capacity");
682
+ usbi_dbg(DEVICE_CTX(dev), "need to increase capacity");
657
683
  capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP;
658
684
  /* can't use usbi_reallocf here because in failure cases it would
659
685
  * free the existing discdevs without unreferencing its devices. */
@@ -678,26 +704,19 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
678
704
  unsigned long session_id)
679
705
  {
680
706
  size_t priv_size = usbi_backend.device_priv_size;
681
- struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size);
682
- int r;
707
+ struct libusb_device *dev = calloc(1, PTR_ALIGN(sizeof(*dev)) + priv_size);
683
708
 
684
709
  if (!dev)
685
710
  return NULL;
686
711
 
687
- r = usbi_mutex_init(&dev->lock);
688
- if (r) {
689
- free(dev);
690
- return NULL;
691
- }
712
+ usbi_atomic_store(&dev->refcnt, 1);
692
713
 
693
714
  dev->ctx = ctx;
694
- dev->refcnt = 1;
695
715
  dev->session_data = session_id;
696
716
  dev->speed = LIBUSB_SPEED_UNKNOWN;
697
717
 
698
- if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
699
- usbi_connect_device (dev);
700
- }
718
+ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
719
+ usbi_connect_device(dev);
701
720
 
702
721
  return dev;
703
722
  }
@@ -706,39 +725,26 @@ void usbi_connect_device(struct libusb_device *dev)
706
725
  {
707
726
  struct libusb_context *ctx = DEVICE_CTX(dev);
708
727
 
709
- dev->attached = 1;
728
+ usbi_atomic_store(&dev->attached, 1);
710
729
 
711
730
  usbi_mutex_lock(&dev->ctx->usb_devs_lock);
712
731
  list_add(&dev->list, &dev->ctx->usb_devs);
713
732
  usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
714
733
 
715
- /* Signal that an event has occurred for this device if we support hotplug AND
716
- * the hotplug message list is ready. This prevents an event from getting raised
717
- * during initial enumeration. */
718
- if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
719
- usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
720
- }
734
+ usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
721
735
  }
722
736
 
723
737
  void usbi_disconnect_device(struct libusb_device *dev)
724
738
  {
725
739
  struct libusb_context *ctx = DEVICE_CTX(dev);
726
740
 
727
- usbi_mutex_lock(&dev->lock);
728
- dev->attached = 0;
729
- usbi_mutex_unlock(&dev->lock);
741
+ usbi_atomic_store(&dev->attached, 0);
730
742
 
731
743
  usbi_mutex_lock(&ctx->usb_devs_lock);
732
744
  list_del(&dev->list);
733
745
  usbi_mutex_unlock(&ctx->usb_devs_lock);
734
746
 
735
- /* Signal that an event has occurred for this device if we support hotplug AND
736
- * the hotplug message list is ready. This prevents an event from getting raised
737
- * during initial enumeration. libusb_handle_events will take care of dereferencing
738
- * the device. */
739
- if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) {
740
- usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
741
- }
747
+ usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT);
742
748
  }
743
749
 
744
750
  /* Perform some final sanity checks on a newly discovered device. If this
@@ -746,21 +752,22 @@ void usbi_disconnect_device(struct libusb_device *dev)
746
752
  * to the discovered device list. */
747
753
  int usbi_sanitize_device(struct libusb_device *dev)
748
754
  {
749
- int r;
750
755
  uint8_t num_configurations;
751
756
 
752
- r = usbi_device_cache_descriptor(dev);
753
- if (r < 0)
754
- return r;
757
+ if (dev->device_descriptor.bLength != LIBUSB_DT_DEVICE_SIZE ||
758
+ dev->device_descriptor.bDescriptorType != LIBUSB_DT_DEVICE) {
759
+ usbi_err(DEVICE_CTX(dev), "invalid device descriptor");
760
+ return LIBUSB_ERROR_IO;
761
+ }
755
762
 
756
763
  num_configurations = dev->device_descriptor.bNumConfigurations;
757
764
  if (num_configurations > USB_MAXCONFIG) {
758
765
  usbi_err(DEVICE_CTX(dev), "too many configurations");
759
766
  return LIBUSB_ERROR_IO;
760
- } else if (0 == num_configurations)
761
- usbi_dbg("zero configurations, maybe an unauthorized device");
767
+ } else if (0 == num_configurations) {
768
+ usbi_dbg(DEVICE_CTX(dev), "zero configurations, maybe an unauthorized device");
769
+ }
762
770
 
763
- dev->num_configurations = num_configurations;
764
771
  return 0;
765
772
  }
766
773
 
@@ -774,11 +781,12 @@ struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
774
781
  struct libusb_device *ret = NULL;
775
782
 
776
783
  usbi_mutex_lock(&ctx->usb_devs_lock);
777
- list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device)
784
+ for_each_device(ctx, dev) {
778
785
  if (dev->session_data == session_id) {
779
786
  ret = libusb_ref_device(dev);
780
787
  break;
781
788
  }
789
+ }
782
790
  usbi_mutex_unlock(&ctx->usb_devs_lock);
783
791
 
784
792
  return ret;
@@ -811,12 +819,14 @@ ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
811
819
  struct libusb_device **ret;
812
820
  int r = 0;
813
821
  ssize_t i, len;
814
- USBI_GET_CONTEXT(ctx);
815
- usbi_dbg("");
822
+
823
+ usbi_dbg(ctx, " ");
816
824
 
817
825
  if (!discdevs)
818
826
  return LIBUSB_ERROR_NO_MEM;
819
827
 
828
+ ctx = usbi_get_context(ctx);
829
+
820
830
  if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
821
831
  /* backend provides hotplug support */
822
832
  struct libusb_device *dev;
@@ -825,7 +835,7 @@ ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
825
835
  usbi_backend.hotplug_poll();
826
836
 
827
837
  usbi_mutex_lock(&ctx->usb_devs_lock);
828
- list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) {
838
+ for_each_device(ctx, dev) {
829
839
  discdevs = discovered_devs_append(discdevs, dev);
830
840
 
831
841
  if (!discdevs) {
@@ -929,7 +939,7 @@ uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev)
929
939
  * \returns LIBUSB_ERROR_OVERFLOW if the array is too small
930
940
  */
931
941
  int API_EXPORTED libusb_get_port_numbers(libusb_device *dev,
932
- uint8_t* port_numbers, int port_numbers_len)
942
+ uint8_t *port_numbers, int port_numbers_len)
933
943
  {
934
944
  int i = port_numbers_len;
935
945
  struct libusb_context *ctx = DEVICE_CTX(dev);
@@ -952,10 +962,10 @@ int API_EXPORTED libusb_get_port_numbers(libusb_device *dev,
952
962
  }
953
963
 
954
964
  /** \ingroup libusb_dev
955
- * Deprecated please use libusb_get_port_numbers instead.
965
+ * \deprecated Please use \ref libusb_get_port_numbers() instead.
956
966
  */
957
967
  int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev,
958
- uint8_t* port_numbers, uint8_t port_numbers_len)
968
+ uint8_t *port_numbers, uint8_t port_numbers_len)
959
969
  {
960
970
  UNUSED(ctx);
961
971
 
@@ -970,7 +980,7 @@ int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev,
970
980
  * function and make sure that you only access the parent before issuing
971
981
  * \ref libusb_free_device_list(). The reason is that libusb currently does
972
982
  * not maintain a permanent list of device instances, and therefore can
973
- * only guarantee that parents are fully instantiated within a
983
+ * only guarantee that parents are fully instantiated within a
974
984
  * libusb_get_device_list() - libusb_free_device_list() block.
975
985
  */
976
986
  DEFAULT_VISIBILITY
@@ -1102,7 +1112,7 @@ int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev,
1102
1112
  struct libusb_config_descriptor *config;
1103
1113
  const struct libusb_endpoint_descriptor *ep;
1104
1114
  struct libusb_ss_endpoint_companion_descriptor *ss_ep_cmp;
1105
- enum libusb_transfer_type ep_type;
1115
+ enum libusb_endpoint_transfer_type ep_type;
1106
1116
  uint16_t val;
1107
1117
  int r;
1108
1118
  int speed;
@@ -1120,8 +1130,8 @@ int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev,
1120
1130
  goto out;
1121
1131
  }
1122
1132
 
1123
- speed = libusb_get_device_speed( dev );
1124
- if (speed == LIBUSB_SPEED_SUPER) {
1133
+ speed = libusb_get_device_speed(dev);
1134
+ if (speed >= LIBUSB_SPEED_SUPER) {
1125
1135
  r = libusb_get_ss_endpoint_companion_descriptor(dev->ctx, ep, &ss_ep_cmp);
1126
1136
  if (r == LIBUSB_SUCCESS) {
1127
1137
  r = ss_ep_cmp->wBytesPerInterval;
@@ -1130,13 +1140,13 @@ int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev,
1130
1140
  }
1131
1141
 
1132
1142
  /* If the device isn't a SuperSpeed device or retrieving the SS endpoint didn't worked. */
1133
- if (speed != LIBUSB_SPEED_SUPER || r < 0) {
1143
+ if (speed < LIBUSB_SPEED_SUPER || r < 0) {
1134
1144
  val = ep->wMaxPacketSize;
1135
- ep_type = (enum libusb_transfer_type) (ep->bmAttributes & 0x3);
1145
+ ep_type = (enum libusb_endpoint_transfer_type) (ep->bmAttributes & 0x3);
1136
1146
 
1137
1147
  r = val & 0x07ff;
1138
- if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
1139
- || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT)
1148
+ if (ep_type == LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS
1149
+ || ep_type == LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT)
1140
1150
  r *= (1 + ((val >> 11) & 3));
1141
1151
  }
1142
1152
 
@@ -1153,9 +1163,11 @@ out:
1153
1163
  DEFAULT_VISIBILITY
1154
1164
  libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev)
1155
1165
  {
1156
- usbi_mutex_lock(&dev->lock);
1157
- dev->refcnt++;
1158
- usbi_mutex_unlock(&dev->lock);
1166
+ long refcnt;
1167
+
1168
+ refcnt = usbi_atomic_inc(&dev->refcnt);
1169
+ assert(refcnt >= 2);
1170
+
1159
1171
  return dev;
1160
1172
  }
1161
1173
 
@@ -1166,17 +1178,16 @@ libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev)
1166
1178
  */
1167
1179
  void API_EXPORTED libusb_unref_device(libusb_device *dev)
1168
1180
  {
1169
- int refcnt;
1181
+ long refcnt;
1170
1182
 
1171
1183
  if (!dev)
1172
1184
  return;
1173
1185
 
1174
- usbi_mutex_lock(&dev->lock);
1175
- refcnt = --dev->refcnt;
1176
- usbi_mutex_unlock(&dev->lock);
1186
+ refcnt = usbi_atomic_dec(&dev->refcnt);
1187
+ assert(refcnt >= 0);
1177
1188
 
1178
1189
  if (refcnt == 0) {
1179
- usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address);
1190
+ usbi_dbg(DEVICE_CTX(dev), "destroy device %d.%d", dev->bus_number, dev->device_address);
1180
1191
 
1181
1192
  libusb_unref_device(dev->parent_dev);
1182
1193
 
@@ -1188,54 +1199,20 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
1188
1199
  usbi_disconnect_device(dev);
1189
1200
  }
1190
1201
 
1191
- usbi_mutex_destroy(&dev->lock);
1192
1202
  free(dev);
1193
1203
  }
1194
1204
  }
1195
1205
 
1196
- /*
1197
- * Signal the event pipe so that the event handling thread will be
1198
- * interrupted to process an internal event.
1199
- */
1200
- int usbi_signal_event(struct libusb_context *ctx)
1201
- {
1202
- unsigned char dummy = 1;
1203
- ssize_t r;
1204
-
1205
- /* write some data on event pipe to interrupt event handlers */
1206
- r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy));
1207
- if (r != sizeof(dummy)) {
1208
- usbi_warn(ctx, "internal signalling write failed");
1209
- return LIBUSB_ERROR_IO;
1210
- }
1211
-
1212
- return 0;
1213
- }
1214
-
1215
- /*
1216
- * Clear the event pipe so that the event handling will no longer be
1217
- * interrupted.
1218
- */
1219
- int usbi_clear_event(struct libusb_context *ctx)
1220
- {
1221
- unsigned char dummy;
1222
- ssize_t r;
1223
-
1224
- /* read some data on event pipe to clear it */
1225
- r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
1226
- if (r != sizeof(dummy)) {
1227
- usbi_warn(ctx, "internal signalling read failed");
1228
- return LIBUSB_ERROR_IO;
1229
- }
1230
-
1231
- return 0;
1232
- }
1233
-
1234
1206
  /** \ingroup libusb_dev
1235
1207
  * Wrap a platform-specific system device handle and obtain a libusb device
1236
1208
  * handle for the underlying device. The handle allows you to use libusb to
1237
1209
  * perform I/O on the device in question.
1238
1210
  *
1211
+ * Call libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY) before
1212
+ * libusb_init() if you want to skip enumeration of USB devices. In particular,
1213
+ * this might be needed on Android if you don't have authority to access USB
1214
+ * devices in general.
1215
+ *
1239
1216
  * On Linux, the system device handle must be a valid file descriptor opened
1240
1217
  * on the device node.
1241
1218
  *
@@ -1248,6 +1225,8 @@ int usbi_clear_event(struct libusb_context *ctx)
1248
1225
  *
1249
1226
  * This is a non-blocking function; no requests are sent over the bus.
1250
1227
  *
1228
+ * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
1229
+ *
1251
1230
  * \param ctx the context to operate on, or NULL for the default context
1252
1231
  * \param sys_dev the platform-specific system device handle
1253
1232
  * \param dev_handle output location for the returned device handle pointer. Only
@@ -1265,31 +1244,23 @@ int API_EXPORTED libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev,
1265
1244
  struct libusb_device_handle *_dev_handle;
1266
1245
  size_t priv_size = usbi_backend.device_handle_priv_size;
1267
1246
  int r;
1268
- usbi_dbg("wrap_sys_device %p", (void *)sys_dev);
1269
1247
 
1270
- USBI_GET_CONTEXT(ctx);
1248
+ usbi_dbg(ctx, "wrap_sys_device 0x%" PRIxPTR, (uintptr_t)sys_dev);
1249
+
1250
+ ctx = usbi_get_context(ctx);
1271
1251
 
1272
1252
  if (!usbi_backend.wrap_sys_device)
1273
1253
  return LIBUSB_ERROR_NOT_SUPPORTED;
1274
1254
 
1275
- _dev_handle = malloc(sizeof(*_dev_handle) + priv_size);
1255
+ _dev_handle = calloc(1, PTR_ALIGN(sizeof(*_dev_handle)) + priv_size);
1276
1256
  if (!_dev_handle)
1277
1257
  return LIBUSB_ERROR_NO_MEM;
1278
1258
 
1279
- r = usbi_mutex_init(&_dev_handle->lock);
1280
- if (r) {
1281
- free(_dev_handle);
1282
- return LIBUSB_ERROR_OTHER;
1283
- }
1284
-
1285
- _dev_handle->dev = NULL;
1286
- _dev_handle->auto_detach_kernel_driver = 0;
1287
- _dev_handle->claimed_interfaces = 0;
1288
- memset(&_dev_handle->os_priv, 0, priv_size);
1259
+ usbi_mutex_init(&_dev_handle->lock);
1289
1260
 
1290
1261
  r = usbi_backend.wrap_sys_device(ctx, _dev_handle, sys_dev);
1291
1262
  if (r < 0) {
1292
- usbi_dbg("wrap_sys_device %p returns %d", (void *)sys_dev, r);
1263
+ usbi_dbg(ctx, "wrap_sys_device 0x%" PRIxPTR " returns %d", (uintptr_t)sys_dev, r);
1293
1264
  usbi_mutex_destroy(&_dev_handle->lock);
1294
1265
  free(_dev_handle);
1295
1266
  return r;
@@ -1329,30 +1300,23 @@ int API_EXPORTED libusb_open(libusb_device *dev,
1329
1300
  struct libusb_device_handle *_dev_handle;
1330
1301
  size_t priv_size = usbi_backend.device_handle_priv_size;
1331
1302
  int r;
1332
- usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
1333
1303
 
1334
- if (!dev->attached) {
1304
+ usbi_dbg(DEVICE_CTX(dev), "open %d.%d", dev->bus_number, dev->device_address);
1305
+
1306
+ if (!usbi_atomic_load(&dev->attached))
1335
1307
  return LIBUSB_ERROR_NO_DEVICE;
1336
- }
1337
1308
 
1338
- _dev_handle = malloc(sizeof(*_dev_handle) + priv_size);
1309
+ _dev_handle = calloc(1, PTR_ALIGN(sizeof(*_dev_handle)) + priv_size);
1339
1310
  if (!_dev_handle)
1340
1311
  return LIBUSB_ERROR_NO_MEM;
1341
1312
 
1342
- r = usbi_mutex_init(&_dev_handle->lock);
1343
- if (r) {
1344
- free(_dev_handle);
1345
- return LIBUSB_ERROR_OTHER;
1346
- }
1313
+ usbi_mutex_init(&_dev_handle->lock);
1347
1314
 
1348
1315
  _dev_handle->dev = libusb_ref_device(dev);
1349
- _dev_handle->auto_detach_kernel_driver = 0;
1350
- _dev_handle->claimed_interfaces = 0;
1351
- memset(&_dev_handle->os_priv, 0, priv_size);
1352
1316
 
1353
1317
  r = usbi_backend.open(_dev_handle);
1354
1318
  if (r < 0) {
1355
- usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
1319
+ usbi_dbg(DEVICE_CTX(dev), "open %d.%d returns %d", dev->bus_number, dev->device_address, r);
1356
1320
  libusb_unref_device(dev);
1357
1321
  usbi_mutex_destroy(&_dev_handle->lock);
1358
1322
  free(_dev_handle);
@@ -1429,7 +1393,7 @@ static void do_close(struct libusb_context *ctx,
1429
1393
  usbi_mutex_lock(&ctx->flying_transfers_lock);
1430
1394
 
1431
1395
  /* safe iteration because transfers may be being deleted */
1432
- list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) {
1396
+ for_each_transfer_safe(ctx, itransfer, tmp) {
1433
1397
  struct libusb_transfer *transfer =
1434
1398
  USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1435
1399
 
@@ -1458,7 +1422,7 @@ static void do_close(struct libusb_context *ctx,
1458
1422
  * just making sure that we don't attempt to process the transfer after
1459
1423
  * the device handle is invalid
1460
1424
  */
1461
- usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed",
1425
+ usbi_dbg(ctx, "Removed transfer %p from the in-flight list because device handle %p closed",
1462
1426
  transfer, dev_handle);
1463
1427
  }
1464
1428
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
@@ -1487,14 +1451,14 @@ static void do_close(struct libusb_context *ctx,
1487
1451
  void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
1488
1452
  {
1489
1453
  struct libusb_context *ctx;
1454
+ unsigned int event_flags;
1490
1455
  int handling_events;
1491
- int pending_events;
1492
1456
 
1493
1457
  if (!dev_handle)
1494
1458
  return;
1495
- usbi_dbg("");
1496
-
1497
1459
  ctx = HANDLE_CTX(dev_handle);
1460
+ usbi_dbg(ctx, " ");
1461
+
1498
1462
  handling_events = usbi_handling_events(ctx);
1499
1463
 
1500
1464
  /* Similarly to libusb_open(), we want to interrupt all event handlers
@@ -1509,10 +1473,11 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
1509
1473
  /* Record that we are closing a device.
1510
1474
  * Only signal an event if there are no prior pending events. */
1511
1475
  usbi_mutex_lock(&ctx->event_data_lock);
1512
- pending_events = usbi_pending_events(ctx);
1513
- ctx->device_close++;
1514
- if (!pending_events)
1515
- usbi_signal_event(ctx);
1476
+ event_flags = ctx->event_flags;
1477
+ if (!ctx->device_close++)
1478
+ ctx->event_flags |= USBI_EVENT_DEVICE_CLOSE;
1479
+ if (!event_flags)
1480
+ usbi_signal_event(&ctx->event);
1516
1481
  usbi_mutex_unlock(&ctx->event_data_lock);
1517
1482
 
1518
1483
  /* take event handling lock */
@@ -1526,10 +1491,10 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
1526
1491
  /* We're done with closing this device.
1527
1492
  * Clear the event pipe if there are no further pending events. */
1528
1493
  usbi_mutex_lock(&ctx->event_data_lock);
1529
- ctx->device_close--;
1530
- pending_events = usbi_pending_events(ctx);
1531
- if (!pending_events)
1532
- usbi_clear_event(ctx);
1494
+ if (!--ctx->device_close)
1495
+ ctx->event_flags &= ~USBI_EVENT_DEVICE_CLOSE;
1496
+ if (!ctx->event_flags)
1497
+ usbi_clear_event(&ctx->event);
1533
1498
  usbi_mutex_unlock(&ctx->event_data_lock);
1534
1499
 
1535
1500
  /* Release event handling lock and wake up event waiters */
@@ -1574,29 +1539,31 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle,
1574
1539
  int *config)
1575
1540
  {
1576
1541
  int r = LIBUSB_ERROR_NOT_SUPPORTED;
1542
+ uint8_t tmp = 0;
1543
+ struct libusb_context *ctx = HANDLE_CTX(dev_handle);
1577
1544
 
1578
- usbi_dbg("");
1545
+ usbi_dbg(ctx, " ");
1579
1546
  if (usbi_backend.get_configuration)
1580
- r = usbi_backend.get_configuration(dev_handle, config);
1547
+ r = usbi_backend.get_configuration(dev_handle, &tmp);
1581
1548
 
1582
1549
  if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
1583
- uint8_t tmp = 0;
1584
- usbi_dbg("falling back to control message");
1550
+ usbi_dbg(ctx, "falling back to control message");
1585
1551
  r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
1586
1552
  LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000);
1587
- if (r == 0) {
1588
- usbi_err(HANDLE_CTX(dev_handle), "zero bytes returned in ctrl transfer?");
1589
- r = LIBUSB_ERROR_IO;
1590
- } else if (r == 1) {
1553
+ if (r == 1) {
1591
1554
  r = 0;
1592
- *config = tmp;
1555
+ } else if (r == 0) {
1556
+ usbi_err(ctx, "zero bytes returned in ctrl transfer?");
1557
+ r = LIBUSB_ERROR_IO;
1593
1558
  } else {
1594
- usbi_dbg("control failed, error %d", r);
1559
+ usbi_dbg(ctx, "control failed, error %d", r);
1595
1560
  }
1596
1561
  }
1597
1562
 
1598
- if (r == 0)
1599
- usbi_dbg("active config %d", *config);
1563
+ if (r == 0) {
1564
+ usbi_dbg(ctx, "active config %u", tmp);
1565
+ *config = (int)tmp;
1566
+ }
1600
1567
 
1601
1568
  return r;
1602
1569
  }
@@ -1615,6 +1582,11 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle,
1615
1582
  * causing most USB-related device state to be reset (altsetting reset to zero,
1616
1583
  * endpoint halts cleared, toggles reset).
1617
1584
  *
1585
+ * Not all backends support setting the configuration from user space, which
1586
+ * will be indicated by the return code LIBUSB_ERROR_NOT_SUPPORTED. As this
1587
+ * suggests that the platform is handling the device configuration itself,
1588
+ * this error should generally be safe to ignore.
1589
+ *
1618
1590
  * You cannot change/reset configuration if your application has claimed
1619
1591
  * interfaces. It is advised to set the desired configuration before claiming
1620
1592
  * interfaces.
@@ -1644,6 +1616,8 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle,
1644
1616
  * \returns 0 on success
1645
1617
  * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist
1646
1618
  * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed
1619
+ * \returns LIBUSB_ERROR_NOT_SUPPORTED if setting or changing the configuration
1620
+ * is not supported by the backend
1647
1621
  * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
1648
1622
  * \returns another LIBUSB_ERROR code on other failure
1649
1623
  * \see libusb_set_auto_detach_kernel_driver()
@@ -1651,7 +1625,9 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev_handle,
1651
1625
  int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle,
1652
1626
  int configuration)
1653
1627
  {
1654
- usbi_dbg("configuration %d", configuration);
1628
+ usbi_dbg(HANDLE_CTX(dev_handle), "configuration %d", configuration);
1629
+ if (configuration < -1 || configuration > (int)UINT8_MAX)
1630
+ return LIBUSB_ERROR_INVALID_PARAM;
1655
1631
  return usbi_backend.set_configuration(dev_handle, configuration);
1656
1632
  }
1657
1633
 
@@ -1688,18 +1664,18 @@ int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle,
1688
1664
  {
1689
1665
  int r = 0;
1690
1666
 
1691
- usbi_dbg("interface %d", interface_number);
1692
- if (interface_number >= USB_MAXINTERFACES)
1667
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
1668
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
1693
1669
  return LIBUSB_ERROR_INVALID_PARAM;
1694
1670
 
1695
- if (!dev_handle->dev->attached)
1671
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1696
1672
  return LIBUSB_ERROR_NO_DEVICE;
1697
1673
 
1698
1674
  usbi_mutex_lock(&dev_handle->lock);
1699
1675
  if (dev_handle->claimed_interfaces & (1U << interface_number))
1700
1676
  goto out;
1701
1677
 
1702
- r = usbi_backend.claim_interface(dev_handle, interface_number);
1678
+ r = usbi_backend.claim_interface(dev_handle, (uint8_t)interface_number);
1703
1679
  if (r == 0)
1704
1680
  dev_handle->claimed_interfaces |= 1U << interface_number;
1705
1681
 
@@ -1732,8 +1708,8 @@ int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle,
1732
1708
  {
1733
1709
  int r;
1734
1710
 
1735
- usbi_dbg("interface %d", interface_number);
1736
- if (interface_number >= USB_MAXINTERFACES)
1711
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
1712
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
1737
1713
  return LIBUSB_ERROR_INVALID_PARAM;
1738
1714
 
1739
1715
  usbi_mutex_lock(&dev_handle->lock);
@@ -1742,7 +1718,7 @@ int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle,
1742
1718
  goto out;
1743
1719
  }
1744
1720
 
1745
- r = usbi_backend.release_interface(dev_handle, interface_number);
1721
+ r = usbi_backend.release_interface(dev_handle, (uint8_t)interface_number);
1746
1722
  if (r == 0)
1747
1723
  dev_handle->claimed_interfaces &= ~(1U << interface_number);
1748
1724
 
@@ -1775,25 +1751,27 @@ out:
1775
1751
  int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
1776
1752
  int interface_number, int alternate_setting)
1777
1753
  {
1778
- usbi_dbg("interface %d altsetting %d",
1754
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d altsetting %d",
1779
1755
  interface_number, alternate_setting);
1780
- if (interface_number >= USB_MAXINTERFACES)
1756
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
1757
+ return LIBUSB_ERROR_INVALID_PARAM;
1758
+ if (alternate_setting < 0 || alternate_setting > (int)UINT8_MAX)
1781
1759
  return LIBUSB_ERROR_INVALID_PARAM;
1782
1760
 
1783
- usbi_mutex_lock(&dev_handle->lock);
1784
- if (!dev_handle->dev->attached) {
1761
+ if (!usbi_atomic_load(&dev_handle->dev->attached)) {
1785
1762
  usbi_mutex_unlock(&dev_handle->lock);
1786
1763
  return LIBUSB_ERROR_NO_DEVICE;
1787
1764
  }
1788
1765
 
1766
+ usbi_mutex_lock(&dev_handle->lock);
1789
1767
  if (!(dev_handle->claimed_interfaces & (1U << interface_number))) {
1790
1768
  usbi_mutex_unlock(&dev_handle->lock);
1791
1769
  return LIBUSB_ERROR_NOT_FOUND;
1792
1770
  }
1793
1771
  usbi_mutex_unlock(&dev_handle->lock);
1794
1772
 
1795
- return usbi_backend.set_interface_altsetting(dev_handle, interface_number,
1796
- alternate_setting);
1773
+ return usbi_backend.set_interface_altsetting(dev_handle,
1774
+ (uint8_t)interface_number, (uint8_t)alternate_setting);
1797
1775
  }
1798
1776
 
1799
1777
  /** \ingroup libusb_dev
@@ -1815,8 +1793,8 @@ int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_hand
1815
1793
  int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle,
1816
1794
  unsigned char endpoint)
1817
1795
  {
1818
- usbi_dbg("endpoint %x", endpoint);
1819
- if (!dev_handle->dev->attached)
1796
+ usbi_dbg(HANDLE_CTX(dev_handle), "endpoint 0x%x", endpoint);
1797
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1820
1798
  return LIBUSB_ERROR_NO_DEVICE;
1821
1799
 
1822
1800
  return usbi_backend.clear_halt(dev_handle, endpoint);
@@ -1843,11 +1821,14 @@ int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle,
1843
1821
  */
1844
1822
  int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle)
1845
1823
  {
1846
- usbi_dbg("");
1847
- if (!dev_handle->dev->attached)
1824
+ usbi_dbg(HANDLE_CTX(dev_handle), " ");
1825
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1848
1826
  return LIBUSB_ERROR_NO_DEVICE;
1849
1827
 
1850
- return usbi_backend.reset_device(dev_handle);
1828
+ if (usbi_backend.reset_device)
1829
+ return usbi_backend.reset_device(dev_handle);
1830
+ else
1831
+ return LIBUSB_ERROR_NOT_SUPPORTED;
1851
1832
  }
1852
1833
 
1853
1834
  /** \ingroup libusb_asyncio
@@ -1874,9 +1855,12 @@ int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle)
1874
1855
  int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle,
1875
1856
  uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
1876
1857
  {
1877
- usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints);
1858
+ usbi_dbg(HANDLE_CTX(dev_handle), "streams %u eps %d", (unsigned)num_streams, num_endpoints);
1859
+
1860
+ if (!num_streams || !endpoints || num_endpoints <= 0)
1861
+ return LIBUSB_ERROR_INVALID_PARAM;
1878
1862
 
1879
- if (!dev_handle->dev->attached)
1863
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1880
1864
  return LIBUSB_ERROR_NO_DEVICE;
1881
1865
 
1882
1866
  if (usbi_backend.alloc_streams)
@@ -1901,9 +1885,12 @@ int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle,
1901
1885
  int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle,
1902
1886
  unsigned char *endpoints, int num_endpoints)
1903
1887
  {
1904
- usbi_dbg("eps %d", num_endpoints);
1888
+ usbi_dbg(HANDLE_CTX(dev_handle), "eps %d", num_endpoints);
1889
+
1890
+ if (!endpoints || num_endpoints <= 0)
1891
+ return LIBUSB_ERROR_INVALID_PARAM;
1905
1892
 
1906
- if (!dev_handle->dev->attached)
1893
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1907
1894
  return LIBUSB_ERROR_NO_DEVICE;
1908
1895
 
1909
1896
  if (usbi_backend.free_streams)
@@ -1925,7 +1912,7 @@ int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle,
1925
1912
  * the same cache lines) when a transfer is in progress, although it is legal
1926
1913
  * to have several transfers going on within the same memory block.
1927
1914
  *
1928
- * Will return NULL on failure. Many systems do not support such zerocopy
1915
+ * Will return NULL on failure. Many systems do not support such zero-copy
1929
1916
  * and will always return NULL. Memory allocated with this function must be
1930
1917
  * freed with \ref libusb_dev_mem_free. Specifically, this means that the
1931
1918
  * flag \ref LIBUSB_TRANSFER_FREE_BUFFER cannot be used to free memory allocated
@@ -1941,7 +1928,7 @@ DEFAULT_VISIBILITY
1941
1928
  unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle,
1942
1929
  size_t length)
1943
1930
  {
1944
- if (!dev_handle->dev->attached)
1931
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1945
1932
  return NULL;
1946
1933
 
1947
1934
  if (usbi_backend.dev_mem_alloc)
@@ -1987,13 +1974,16 @@ int API_EXPORTED libusb_dev_mem_free(libusb_device_handle *dev_handle,
1987
1974
  int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle,
1988
1975
  int interface_number)
1989
1976
  {
1990
- usbi_dbg("interface %d", interface_number);
1977
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
1991
1978
 
1992
- if (!dev_handle->dev->attached)
1979
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
1980
+ return LIBUSB_ERROR_INVALID_PARAM;
1981
+
1982
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
1993
1983
  return LIBUSB_ERROR_NO_DEVICE;
1994
1984
 
1995
1985
  if (usbi_backend.kernel_driver_active)
1996
- return usbi_backend.kernel_driver_active(dev_handle, interface_number);
1986
+ return usbi_backend.kernel_driver_active(dev_handle, (uint8_t)interface_number);
1997
1987
  else
1998
1988
  return LIBUSB_ERROR_NOT_SUPPORTED;
1999
1989
  }
@@ -2002,7 +1992,7 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle,
2002
1992
  * Detach a kernel driver from an interface. If successful, you will then be
2003
1993
  * able to claim the interface and perform I/O.
2004
1994
  *
2005
- * This functionality is not available on Darwin or Windows.
1995
+ * This functionality is not available on Windows.
2006
1996
  *
2007
1997
  * Note that libusb itself also talks to the device through a special kernel
2008
1998
  * driver, if this driver is already attached to the device, this call will
@@ -2022,23 +2012,25 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle,
2022
2012
  int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
2023
2013
  int interface_number)
2024
2014
  {
2025
- usbi_dbg("interface %d", interface_number);
2015
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
2016
+
2017
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
2018
+ return LIBUSB_ERROR_INVALID_PARAM;
2026
2019
 
2027
- if (!dev_handle->dev->attached)
2020
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
2028
2021
  return LIBUSB_ERROR_NO_DEVICE;
2029
2022
 
2030
2023
  if (usbi_backend.detach_kernel_driver)
2031
- return usbi_backend.detach_kernel_driver(dev_handle, interface_number);
2024
+ return usbi_backend.detach_kernel_driver(dev_handle, (uint8_t)interface_number);
2032
2025
  else
2033
2026
  return LIBUSB_ERROR_NOT_SUPPORTED;
2034
2027
  }
2035
2028
 
2036
2029
  /** \ingroup libusb_dev
2037
2030
  * Re-attach an interface's kernel driver, which was previously detached
2038
- * using libusb_detach_kernel_driver(). This call is only effective on
2039
- * Linux and returns LIBUSB_ERROR_NOT_SUPPORTED on all other platforms.
2031
+ * using libusb_detach_kernel_driver().
2040
2032
  *
2041
- * This functionality is not available on Darwin or Windows.
2033
+ * This functionality is not available on Windows.
2042
2034
  *
2043
2035
  * \param dev_handle a device handle
2044
2036
  * \param interface_number the interface to attach the driver from
@@ -2056,13 +2048,16 @@ int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
2056
2048
  int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
2057
2049
  int interface_number)
2058
2050
  {
2059
- usbi_dbg("interface %d", interface_number);
2051
+ usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
2052
+
2053
+ if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
2054
+ return LIBUSB_ERROR_INVALID_PARAM;
2060
2055
 
2061
- if (!dev_handle->dev->attached)
2056
+ if (!usbi_atomic_load(&dev_handle->dev->attached))
2062
2057
  return LIBUSB_ERROR_NO_DEVICE;
2063
2058
 
2064
2059
  if (usbi_backend.attach_kernel_driver)
2065
- return usbi_backend.attach_kernel_driver(dev_handle, interface_number);
2060
+ return usbi_backend.attach_kernel_driver(dev_handle, (uint8_t)interface_number);
2066
2061
  else
2067
2062
  return LIBUSB_ERROR_NOT_SUPPORTED;
2068
2063
  }
@@ -2106,7 +2101,7 @@ int API_EXPORTED libusb_set_auto_detach_kernel_driver(
2106
2101
  void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
2107
2102
  {
2108
2103
  #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
2109
- USBI_GET_CONTEXT(ctx);
2104
+ ctx = usbi_get_context(ctx);
2110
2105
  if (!ctx->debug_fixed) {
2111
2106
  level = CLAMP(level, LIBUSB_LOG_LEVEL_NONE, LIBUSB_LOG_LEVEL_DEBUG);
2112
2107
  ctx->debug = (enum libusb_log_level)level;
@@ -2129,6 +2124,8 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
2129
2124
  * If ENABLE_DEBUG_LOGGING is defined then per context callback function will
2130
2125
  * never be called.
2131
2126
  *
2127
+ * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
2128
+ *
2132
2129
  * \param ctx context on which to assign log handler, or NULL for the default
2133
2130
  * context. Parameter ignored if only LIBUSB_LOG_CB_GLOBAL mode is requested.
2134
2131
  * \param cb pointer to the callback function, or NULL to stop log
@@ -2141,23 +2138,24 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
2141
2138
  void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb,
2142
2139
  int mode)
2143
2140
  {
2141
+ #if defined(ENABLE_LOGGING) && (!defined(ENABLE_DEBUG_LOGGING) || !defined(USE_SYSTEM_LOGGING_FACILITY))
2144
2142
  #if !defined(USE_SYSTEM_LOGGING_FACILITY)
2145
- if (mode & LIBUSB_LOG_CB_GLOBAL) {
2143
+ if (mode & LIBUSB_LOG_CB_GLOBAL)
2146
2144
  log_handler = cb;
2147
- }
2148
2145
  #endif
2149
- #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
2146
+ #if !defined(ENABLE_DEBUG_LOGGING)
2150
2147
  if (mode & LIBUSB_LOG_CB_CONTEXT) {
2151
- USBI_GET_CONTEXT(ctx);
2148
+ ctx = usbi_get_context(ctx);
2152
2149
  ctx->log_handler = cb;
2153
2150
  }
2154
2151
  #else
2155
2152
  UNUSED(ctx);
2156
- #if defined(USE_SYSTEM_LOGGING_FACILITY)
2153
+ #endif
2154
+ #else
2155
+ UNUSED(ctx);
2157
2156
  UNUSED(cb);
2158
2157
  UNUSED(mode);
2159
2158
  #endif
2160
- #endif
2161
2159
  }
2162
2160
 
2163
2161
  /** \ingroup libusb_lib
@@ -2168,6 +2166,9 @@ void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb,
2168
2166
  * Some options require one or more arguments to be provided. Consult each
2169
2167
  * option's documentation for specific requirements.
2170
2168
  *
2169
+ * If the context ctx is NULL, the option will be added to a list of default
2170
+ * options that will be applied to all subsequently created contexts.
2171
+ *
2171
2172
  * Since version 1.0.22, \ref LIBUSB_API_VERSION >= 0x01000106
2172
2173
  *
2173
2174
  * \param ctx context on which to operate
@@ -2178,43 +2179,68 @@ void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb,
2178
2179
  * \returns LIBUSB_ERROR_INVALID_PARAM if the option or arguments are invalid
2179
2180
  * \returns LIBUSB_ERROR_NOT_SUPPORTED if the option is valid but not supported
2180
2181
  * on this platform
2182
+ * \returns LIBUSB_ERROR_NOT_FOUND if LIBUSB_OPTION_USE_USBDK is valid on this platform but UsbDk is not available
2181
2183
  */
2182
2184
  int API_EXPORTED libusb_set_option(libusb_context *ctx,
2183
2185
  enum libusb_option option, ...)
2184
2186
  {
2185
- int arg, r = LIBUSB_SUCCESS;
2187
+ int arg = 0, r = LIBUSB_SUCCESS;
2186
2188
  va_list ap;
2187
2189
 
2188
- USBI_GET_CONTEXT(ctx);
2189
-
2190
2190
  va_start(ap, option);
2191
- switch (option) {
2192
- case LIBUSB_OPTION_LOG_LEVEL:
2191
+ if (LIBUSB_OPTION_LOG_LEVEL == option) {
2193
2192
  arg = va_arg(ap, int);
2194
2193
  if (arg < LIBUSB_LOG_LEVEL_NONE || arg > LIBUSB_LOG_LEVEL_DEBUG) {
2195
2194
  r = LIBUSB_ERROR_INVALID_PARAM;
2196
- break;
2197
2195
  }
2196
+ }
2197
+ va_end(ap);
2198
+
2199
+ if (LIBUSB_SUCCESS != r) {
2200
+ return r;
2201
+ }
2202
+
2203
+ if (option >= LIBUSB_OPTION_MAX) {
2204
+ return LIBUSB_ERROR_INVALID_PARAM;
2205
+ }
2206
+
2207
+ if (NULL == ctx) {
2208
+ usbi_mutex_static_lock(&default_context_lock);
2209
+ default_context_options[option].is_set = 1;
2210
+ if (LIBUSB_OPTION_LOG_LEVEL == option) {
2211
+ default_context_options[option].arg.ival = arg;
2212
+ }
2213
+ usbi_mutex_static_unlock(&default_context_lock);
2214
+ }
2215
+
2216
+ ctx = usbi_get_context(ctx);
2217
+ if (NULL == ctx) {
2218
+ return LIBUSB_SUCCESS;
2219
+ }
2220
+
2221
+ switch (option) {
2222
+ case LIBUSB_OPTION_LOG_LEVEL:
2198
2223
  #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
2199
2224
  if (!ctx->debug_fixed)
2200
2225
  ctx->debug = (enum libusb_log_level)arg;
2201
2226
  #endif
2202
2227
  break;
2203
2228
 
2204
- /* Handle all backend-specific options here */
2229
+ /* Handle all backend-specific options here */
2205
2230
  case LIBUSB_OPTION_USE_USBDK:
2231
+ case LIBUSB_OPTION_NO_DEVICE_DISCOVERY:
2206
2232
  if (usbi_backend.set_option)
2207
- r = usbi_backend.set_option(ctx, option, ap);
2208
- else
2209
- r = LIBUSB_ERROR_NOT_SUPPORTED;
2233
+ return usbi_backend.set_option(ctx, option, ap);
2234
+
2235
+ return LIBUSB_ERROR_NOT_SUPPORTED;
2210
2236
  break;
2211
2237
 
2238
+ case LIBUSB_OPTION_MAX:
2212
2239
  default:
2213
- r = LIBUSB_ERROR_INVALID_PARAM;
2240
+ return LIBUSB_ERROR_INVALID_PARAM;
2214
2241
  }
2215
- va_end(ap);
2216
2242
 
2217
- return r;
2243
+ return LIBUSB_SUCCESS;;
2218
2244
  }
2219
2245
 
2220
2246
  #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
@@ -2245,114 +2271,118 @@ static enum libusb_log_level get_env_debug_level(void)
2245
2271
  * context will be created. If there was already a default context, it will
2246
2272
  * be reused (and nothing will be initialized/reinitialized).
2247
2273
  *
2248
- * \param context Optional output location for context pointer.
2274
+ * \param ctx Optional output location for context pointer.
2249
2275
  * Only valid on return code 0.
2250
2276
  * \returns 0 on success, or a LIBUSB_ERROR code on failure
2251
2277
  * \see libusb_contexts
2252
2278
  */
2253
- int API_EXPORTED libusb_init(libusb_context **context)
2279
+ int API_EXPORTED libusb_init(libusb_context **ctx)
2254
2280
  {
2255
- struct libusb_device *dev, *next;
2256
2281
  size_t priv_size = usbi_backend.context_priv_size;
2257
- struct libusb_context *ctx;
2258
- static int first_init = 1;
2259
- int r = 0;
2282
+ struct libusb_context *_ctx;
2283
+ int r;
2260
2284
 
2261
2285
  usbi_mutex_static_lock(&default_context_lock);
2262
2286
 
2263
- if (!timestamp_origin.tv_sec) {
2264
- usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timestamp_origin);
2265
- }
2266
-
2267
- if (!context && usbi_default_context) {
2268
- usbi_dbg("reusing default context");
2287
+ if (!ctx && usbi_default_context) {
2288
+ usbi_dbg(usbi_default_context, "reusing default context");
2269
2289
  default_context_refcnt++;
2270
2290
  usbi_mutex_static_unlock(&default_context_lock);
2271
2291
  return 0;
2272
2292
  }
2273
2293
 
2274
- ctx = calloc(1, sizeof(*ctx) + priv_size);
2275
- if (!ctx) {
2276
- r = LIBUSB_ERROR_NO_MEM;
2277
- goto err_unlock;
2294
+ /* check for first init */
2295
+ if (!active_contexts_list.next) {
2296
+ list_init(&active_contexts_list);
2297
+ usbi_get_monotonic_time(&timestamp_origin);
2298
+ }
2299
+
2300
+ _ctx = calloc(1, PTR_ALIGN(sizeof(*_ctx)) + priv_size);
2301
+ if (!_ctx) {
2302
+ usbi_mutex_static_unlock(&default_context_lock);
2303
+ return LIBUSB_ERROR_NO_MEM;
2278
2304
  }
2279
2305
 
2280
2306
  #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
2281
- ctx->debug = get_env_debug_level();
2282
- if (ctx->debug != LIBUSB_LOG_LEVEL_NONE)
2283
- ctx->debug_fixed = 1;
2307
+ if (NULL == ctx && default_context_options[LIBUSB_OPTION_LOG_LEVEL].is_set) {
2308
+ _ctx->debug = default_context_options[LIBUSB_OPTION_LOG_LEVEL].arg.ival;
2309
+ } else {
2310
+ _ctx->debug = get_env_debug_level();
2311
+ }
2312
+ if (_ctx->debug != LIBUSB_LOG_LEVEL_NONE)
2313
+ _ctx->debug_fixed = 1;
2284
2314
  #endif
2285
2315
 
2286
- /* default context should be initialized before calling usbi_dbg */
2287
- if (!usbi_default_context) {
2288
- usbi_default_context = ctx;
2289
- default_context_refcnt++;
2290
- usbi_dbg("created default context");
2316
+ usbi_mutex_init(&_ctx->usb_devs_lock);
2317
+ usbi_mutex_init(&_ctx->open_devs_lock);
2318
+ list_init(&_ctx->usb_devs);
2319
+ list_init(&_ctx->open_devs);
2320
+
2321
+ /* apply default options to all new contexts */
2322
+ for (enum libusb_option option = 0 ; option < LIBUSB_OPTION_MAX ; option++) {
2323
+ if (LIBUSB_OPTION_LOG_LEVEL == option || !default_context_options[option].is_set) {
2324
+ continue;
2325
+ }
2326
+ r = libusb_set_option(_ctx, option);
2327
+ if (LIBUSB_SUCCESS != r)
2328
+ goto err_free_ctx;
2291
2329
  }
2292
2330
 
2293
- usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor,
2331
+ /* default context must be initialized before calling usbi_dbg */
2332
+ if (!ctx) {
2333
+ usbi_default_context = _ctx;
2334
+ default_context_refcnt = 1;
2335
+ usbi_dbg(usbi_default_context, "created default context");
2336
+ }
2337
+
2338
+ usbi_dbg(_ctx, "libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor,
2294
2339
  libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc);
2295
2340
 
2296
- usbi_mutex_init(&ctx->usb_devs_lock);
2297
- usbi_mutex_init(&ctx->open_devs_lock);
2298
- usbi_mutex_init(&ctx->hotplug_cbs_lock);
2299
- list_init(&ctx->usb_devs);
2300
- list_init(&ctx->open_devs);
2301
- list_init(&ctx->hotplug_cbs);
2302
- ctx->next_hotplug_cb_handle = 1;
2341
+ r = usbi_io_init(_ctx);
2342
+ if (r < 0)
2343
+ goto err_free_ctx;
2303
2344
 
2304
2345
  usbi_mutex_static_lock(&active_contexts_lock);
2305
- if (first_init) {
2306
- first_init = 0;
2307
- list_init (&active_contexts_list);
2308
- }
2309
- list_add (&ctx->list, &active_contexts_list);
2346
+ list_add(&_ctx->list, &active_contexts_list);
2310
2347
  usbi_mutex_static_unlock(&active_contexts_lock);
2311
2348
 
2349
+ usbi_hotplug_init(_ctx);
2350
+
2312
2351
  if (usbi_backend.init) {
2313
- r = usbi_backend.init(ctx);
2352
+ r = usbi_backend.init(_ctx);
2314
2353
  if (r)
2315
- goto err_free_ctx;
2354
+ goto err_io_exit;
2316
2355
  }
2317
2356
 
2318
- r = usbi_io_init(ctx);
2319
- if (r < 0)
2320
- goto err_backend_exit;
2357
+ if (ctx)
2358
+ *ctx = _ctx;
2321
2359
 
2322
2360
  usbi_mutex_static_unlock(&default_context_lock);
2323
2361
 
2324
- if (context)
2325
- *context = ctx;
2326
-
2327
2362
  return 0;
2328
2363
 
2329
- err_backend_exit:
2330
- if (usbi_backend.exit)
2331
- usbi_backend.exit(ctx);
2332
- err_free_ctx:
2333
- if (ctx == usbi_default_context) {
2334
- usbi_default_context = NULL;
2335
- default_context_refcnt--;
2336
- }
2337
-
2364
+ err_io_exit:
2338
2365
  usbi_mutex_static_lock(&active_contexts_lock);
2339
- list_del (&ctx->list);
2366
+ list_del(&_ctx->list);
2340
2367
  usbi_mutex_static_unlock(&active_contexts_lock);
2341
2368
 
2342
- usbi_mutex_lock(&ctx->usb_devs_lock);
2343
- list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
2344
- list_del(&dev->list);
2345
- libusb_unref_device(dev);
2369
+ usbi_hotplug_exit(_ctx);
2370
+ usbi_io_exit(_ctx);
2371
+
2372
+ err_free_ctx:
2373
+ if (!ctx) {
2374
+ /* clear default context that was not fully initialized */
2375
+ usbi_default_context = NULL;
2376
+ default_context_refcnt = 0;
2346
2377
  }
2347
- usbi_mutex_unlock(&ctx->usb_devs_lock);
2348
2378
 
2349
- usbi_mutex_destroy(&ctx->open_devs_lock);
2350
- usbi_mutex_destroy(&ctx->usb_devs_lock);
2351
- usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
2379
+ usbi_mutex_destroy(&_ctx->open_devs_lock);
2380
+ usbi_mutex_destroy(&_ctx->usb_devs_lock);
2381
+
2382
+ free(_ctx);
2352
2383
 
2353
- free(ctx);
2354
- err_unlock:
2355
2384
  usbi_mutex_static_unlock(&default_context_lock);
2385
+
2356
2386
  return r;
2357
2387
  }
2358
2388
 
@@ -2361,85 +2391,65 @@ err_unlock:
2361
2391
  * before your application terminates.
2362
2392
  * \param ctx the context to deinitialize, or NULL for the default context
2363
2393
  */
2364
- void API_EXPORTED libusb_exit(struct libusb_context *ctx)
2394
+ void API_EXPORTED libusb_exit(libusb_context *ctx)
2365
2395
  {
2366
- struct libusb_device *dev, *next;
2367
- struct timeval tv = { 0, 0 };
2368
- int destroying_default_context = 0;
2396
+ struct libusb_context *_ctx;
2397
+ struct libusb_device *dev;
2369
2398
 
2370
- usbi_dbg("");
2371
- USBI_GET_CONTEXT(ctx);
2399
+ usbi_mutex_static_lock(&default_context_lock);
2372
2400
 
2373
2401
  /* if working with default context, only actually do the deinitialization
2374
2402
  * if we're the last user */
2375
- usbi_mutex_static_lock(&default_context_lock);
2376
- if (ctx == usbi_default_context) {
2403
+ if (!ctx) {
2404
+ if (!usbi_default_context) {
2405
+ usbi_dbg(ctx, "no default context, not initialized?");
2406
+ usbi_mutex_static_unlock(&default_context_lock);
2407
+ return;
2408
+ }
2409
+
2377
2410
  if (--default_context_refcnt > 0) {
2378
- usbi_dbg("not destroying default context");
2411
+ usbi_dbg(ctx, "not destroying default context");
2379
2412
  usbi_mutex_static_unlock(&default_context_lock);
2380
2413
  return;
2381
2414
  }
2382
- usbi_dbg("destroying default context");
2383
2415
 
2384
- /*
2385
- * Setting this flag without unlocking the default context, as
2386
- * we are actually destroying the default context.
2387
- * usbi_default_context is not set to NULL yet, as all activities
2388
- * would only stop after usbi_backend->exit() returns.
2389
- */
2390
- destroying_default_context = 1;
2416
+ usbi_dbg(ctx, "destroying default context");
2417
+ _ctx = usbi_default_context;
2391
2418
  } else {
2392
- // Unlock default context, as we're not modifying it.
2393
- usbi_mutex_static_unlock(&default_context_lock);
2394
- }
2419
+ usbi_dbg(ctx, " ");
2420
+ _ctx = ctx;
2421
+ }
2395
2422
 
2396
2423
  usbi_mutex_static_lock(&active_contexts_lock);
2397
- list_del (&ctx->list);
2424
+ list_del(&_ctx->list);
2398
2425
  usbi_mutex_static_unlock(&active_contexts_lock);
2399
2426
 
2400
- if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
2401
- usbi_hotplug_deregister(ctx, 1);
2402
-
2403
- /*
2404
- * Ensure any pending unplug events are read from the hotplug
2405
- * pipe. The usb_device-s hold in the events are no longer part
2406
- * of usb_devs, but the events still hold a reference!
2407
- *
2408
- * Note we don't do this if the application has left devices
2409
- * open (which implies a buggy app) to avoid packet completion
2410
- * handlers running when the app does not expect them to run.
2411
- */
2412
- if (list_empty(&ctx->open_devs))
2413
- libusb_handle_events_timeout(ctx, &tv);
2427
+ if (usbi_backend.exit)
2428
+ usbi_backend.exit(_ctx);
2414
2429
 
2415
- usbi_mutex_lock(&ctx->usb_devs_lock);
2416
- list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
2417
- list_del(&dev->list);
2418
- libusb_unref_device(dev);
2419
- }
2420
- usbi_mutex_unlock(&ctx->usb_devs_lock);
2421
- }
2430
+ if (!ctx)
2431
+ usbi_default_context = NULL;
2422
2432
 
2423
- /* a few sanity checks. don't bother with locking because unless
2424
- * there is an application bug, nobody will be accessing these. */
2425
- if (!list_empty(&ctx->usb_devs))
2426
- usbi_warn(ctx, "some libusb_devices were leaked");
2427
- if (!list_empty(&ctx->open_devs))
2428
- usbi_warn(ctx, "application left some devices open");
2433
+ usbi_mutex_static_unlock(&default_context_lock);
2429
2434
 
2430
- usbi_io_exit(ctx);
2431
- if (usbi_backend.exit)
2432
- usbi_backend.exit(ctx);
2435
+ /* Don't bother with locking after this point because unless there is
2436
+ * an application bug, nobody will be accessing the context. */
2433
2437
 
2434
- usbi_mutex_destroy(&ctx->open_devs_lock);
2435
- usbi_mutex_destroy(&ctx->usb_devs_lock);
2436
- usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
2437
- free(ctx);
2438
+ usbi_hotplug_exit(_ctx);
2439
+ usbi_io_exit(_ctx);
2438
2440
 
2439
- if (destroying_default_context) {
2440
- usbi_default_context = NULL;
2441
- usbi_mutex_static_unlock(&default_context_lock);
2441
+ for_each_device(_ctx, dev) {
2442
+ usbi_warn(_ctx, "device %d.%d still referenced",
2443
+ dev->bus_number, dev->device_address);
2442
2444
  }
2445
+
2446
+ if (!list_empty(&_ctx->open_devs))
2447
+ usbi_warn(_ctx, "application left some devices open");
2448
+
2449
+ usbi_mutex_destroy(&_ctx->open_devs_lock);
2450
+ usbi_mutex_destroy(&_ctx->usb_devs_lock);
2451
+
2452
+ free(_ctx);
2443
2453
  }
2444
2454
 
2445
2455
  /** \ingroup libusb_misc
@@ -2471,94 +2481,90 @@ int API_EXPORTED libusb_has_capability(uint32_t capability)
2471
2481
  #ifdef LIBUSB_PRINTF_WIN32
2472
2482
  /*
2473
2483
  * Prior to VS2015, Microsoft did not provide the snprintf() function and
2474
- * provided a vsnprintf() that did not guarantee NULL-terminated output.
2484
+ * provided a vsnprintf() that did not guarantee NUL-terminated output.
2475
2485
  * Microsoft did provide a _snprintf() function, but again it did not
2476
2486
  * guarantee NULL-terminated output.
2477
2487
  *
2478
- * The below implementations guarantee NULL-terminated output and are
2488
+ * The below implementations guarantee NUL-terminated output and are
2479
2489
  * C99 compliant.
2480
2490
  */
2481
2491
 
2482
2492
  int usbi_snprintf(char *str, size_t size, const char *format, ...)
2483
2493
  {
2484
- va_list ap;
2494
+ va_list args;
2485
2495
  int ret;
2486
2496
 
2487
- va_start(ap, format);
2488
- ret = usbi_vsnprintf(str, size, format, ap);
2489
- va_end(ap);
2497
+ va_start(args, format);
2498
+ ret = usbi_vsnprintf(str, size, format, args);
2499
+ va_end(args);
2490
2500
 
2491
2501
  return ret;
2492
2502
  }
2493
2503
 
2494
- int usbi_vsnprintf(char *str, size_t size, const char *format, va_list ap)
2504
+ int usbi_vsnprintf(char *str, size_t size, const char *format, va_list args)
2495
2505
  {
2496
2506
  int ret;
2497
2507
 
2498
- ret = _vsnprintf(str, size, format, ap);
2508
+ ret = _vsnprintf(str, size, format, args);
2499
2509
  if (ret < 0 || ret == (int)size) {
2500
- /* Output is truncated, ensure buffer is NULL-terminated and
2510
+ /* Output is truncated, ensure buffer is NUL-terminated and
2501
2511
  * determine how many characters would have been written. */
2502
2512
  str[size - 1] = '\0';
2503
2513
  if (ret < 0)
2504
- ret = _vsnprintf(NULL, 0, format, ap);
2514
+ ret = _vsnprintf(NULL, 0, format, args);
2505
2515
  }
2506
2516
 
2507
2517
  return ret;
2508
2518
  }
2509
2519
  #endif /* LIBUSB_PRINTF_WIN32 */
2510
2520
 
2511
- static void usbi_log_str(enum libusb_log_level level, const char *str)
2521
+ static void log_str(enum libusb_log_level level, const char *str)
2512
2522
  {
2513
2523
  #if defined(USE_SYSTEM_LOGGING_FACILITY)
2514
- #if defined(OS_WINDOWS) || defined(OS_WINCE)
2515
- #if !defined(UNICODE)
2516
- OutputDebugStringA(str);
2517
- #else
2518
- WCHAR wbuf[USBI_MAX_LOG_LEN];
2519
- if (MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)) != 0)
2520
- OutputDebugStringW(wbuf);
2521
- #endif
2522
- #elif defined(__ANDROID__)
2523
- int priority = ANDROID_LOG_UNKNOWN;
2524
+ #if defined(__ANDROID__)
2525
+ int priority;
2524
2526
  switch (level) {
2525
- case LIBUSB_LOG_LEVEL_NONE: return;
2527
+ case LIBUSB_LOG_LEVEL_NONE: return; /* Impossible, but keeps compiler happy */
2526
2528
  case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break;
2527
2529
  case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break;
2528
2530
  case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break;
2529
2531
  case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break;
2532
+ default: priority = ANDROID_LOG_UNKNOWN;
2530
2533
  }
2531
2534
  __android_log_write(priority, "libusb", str);
2532
- #elif defined(HAVE_SYSLOG_FUNC)
2533
- int syslog_level = LOG_INFO;
2535
+ #elif defined(_WIN32)
2536
+ UNUSED(level);
2537
+ OutputDebugStringA(str);
2538
+ #elif defined(HAVE_SYSLOG)
2539
+ int syslog_level;
2534
2540
  switch (level) {
2535
- case LIBUSB_LOG_LEVEL_NONE: return;
2541
+ case LIBUSB_LOG_LEVEL_NONE: return; /* Impossible, but keeps compiler happy */
2536
2542
  case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break;
2537
2543
  case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break;
2538
2544
  case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break;
2539
2545
  case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break;
2546
+ default: syslog_level = LOG_INFO;
2540
2547
  }
2541
2548
  syslog(syslog_level, "%s", str);
2542
2549
  #else /* All of gcc, Clang, Xcode seem to use #warning */
2543
2550
  #warning System logging is not supported on this platform. Logging to stderr will be used instead.
2551
+ UNUSED(level);
2544
2552
  fputs(str, stderr);
2545
2553
  #endif
2546
2554
  #else
2547
2555
  /* Global log handler */
2548
- if (log_handler != NULL)
2556
+ if (log_handler)
2549
2557
  log_handler(NULL, level, str);
2550
2558
  else
2551
2559
  fputs(str, stderr);
2552
2560
  #endif /* USE_SYSTEM_LOGGING_FACILITY */
2553
- UNUSED(level);
2554
2561
  }
2555
2562
 
2556
- void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
2563
+ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
2557
2564
  const char *function, const char *format, va_list args)
2558
2565
  {
2559
2566
  const char *prefix;
2560
2567
  char buf[USBI_MAX_LOG_LEN];
2561
- struct timespec now;
2562
2568
  int global_debug, header_len, text_len;
2563
2569
  static int has_debug_header_been_displayed = 0;
2564
2570
 
@@ -2566,41 +2572,22 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
2566
2572
  global_debug = 1;
2567
2573
  UNUSED(ctx);
2568
2574
  #else
2569
- enum libusb_log_level ctx_level = LIBUSB_LOG_LEVEL_NONE;
2575
+ enum libusb_log_level ctx_level;
2570
2576
 
2571
- USBI_GET_CONTEXT(ctx);
2577
+ ctx = usbi_get_context(ctx);
2572
2578
  if (ctx)
2573
2579
  ctx_level = ctx->debug;
2574
2580
  else
2575
2581
  ctx_level = get_env_debug_level();
2576
2582
 
2577
- if (ctx_level == LIBUSB_LOG_LEVEL_NONE)
2578
- return;
2579
- if (level == LIBUSB_LOG_LEVEL_WARNING && ctx_level < LIBUSB_LOG_LEVEL_WARNING)
2580
- return;
2581
- if (level == LIBUSB_LOG_LEVEL_INFO && ctx_level < LIBUSB_LOG_LEVEL_INFO)
2582
- return;
2583
- if (level == LIBUSB_LOG_LEVEL_DEBUG && ctx_level < LIBUSB_LOG_LEVEL_DEBUG)
2583
+ if (ctx_level < level)
2584
2584
  return;
2585
2585
 
2586
2586
  global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG);
2587
2587
  #endif
2588
2588
 
2589
- usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &now);
2590
- if ((global_debug) && (!has_debug_header_been_displayed)) {
2591
- has_debug_header_been_displayed = 1;
2592
- usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>" USBI_LOG_LINE_END);
2593
- usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END);
2594
- }
2595
- if (now.tv_nsec < timestamp_origin.tv_nsec) {
2596
- now.tv_sec--;
2597
- now.tv_nsec += 1000000000L;
2598
- }
2599
- now.tv_sec -= timestamp_origin.tv_sec;
2600
- now.tv_nsec -= timestamp_origin.tv_nsec;
2601
-
2602
2589
  switch (level) {
2603
- case LIBUSB_LOG_LEVEL_NONE:
2590
+ case LIBUSB_LOG_LEVEL_NONE: /* Impossible, but keeps compiler happy */
2604
2591
  return;
2605
2592
  case LIBUSB_LOG_LEVEL_ERROR:
2606
2593
  prefix = "error";
@@ -2620,21 +2607,31 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
2620
2607
  }
2621
2608
 
2622
2609
  if (global_debug) {
2610
+ struct timespec timestamp;
2611
+
2612
+ if (!has_debug_header_been_displayed) {
2613
+ has_debug_header_been_displayed = 1;
2614
+ log_str(LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>" USBI_LOG_LINE_END);
2615
+ log_str(LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END);
2616
+ }
2617
+
2618
+ usbi_get_monotonic_time(&timestamp);
2619
+ TIMESPEC_SUB(&timestamp, &timestamp_origin, &timestamp);
2620
+
2623
2621
  header_len = snprintf(buf, sizeof(buf),
2624
2622
  "[%2ld.%06ld] [%08x] libusb: %s [%s] ",
2625
- (long)now.tv_sec, (long)(now.tv_nsec / 1000L), usbi_get_tid(), prefix, function);
2623
+ (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000L), usbi_get_tid(), prefix, function);
2626
2624
  } else {
2627
2625
  header_len = snprintf(buf, sizeof(buf),
2628
2626
  "libusb: %s [%s] ", prefix, function);
2629
2627
  }
2630
2628
 
2631
2629
  if (header_len < 0 || header_len >= (int)sizeof(buf)) {
2632
- /* Somehow snprintf failed to write to the buffer,
2630
+ /* Somehow snprintf() failed to write to the buffer,
2633
2631
  * remove the header so something useful is output. */
2634
2632
  header_len = 0;
2635
2633
  }
2636
- /* Make sure buffer is NUL terminated */
2637
- buf[header_len] = '\0';
2634
+
2638
2635
  text_len = vsnprintf(buf + header_len, sizeof(buf) - (size_t)header_len,
2639
2636
  format, args);
2640
2637
  if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) {
@@ -2648,9 +2645,9 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
2648
2645
  }
2649
2646
  strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
2650
2647
 
2651
- usbi_log_str(level, buf);
2648
+ log_str(level, buf);
2652
2649
 
2653
- /* Per context log handler */
2650
+ /* Per-context log handler */
2654
2651
  #ifndef ENABLE_DEBUG_LOGGING
2655
2652
  if (ctx && ctx->log_handler)
2656
2653
  ctx->log_handler(ctx, level, buf);
@@ -2662,9 +2659,9 @@ void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
2662
2659
  {
2663
2660
  va_list args;
2664
2661
 
2665
- va_start (args, format);
2666
- usbi_log_v(ctx, level, function, format, args);
2667
- va_end (args);
2662
+ va_start(args, format);
2663
+ log_v(ctx, level, function, format, args);
2664
+ va_end(args);
2668
2665
  }
2669
2666
 
2670
2667
  #endif /* ENABLE_LOGGING */