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.
- package/CHANGELOG.md +12 -0
- package/README.md +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/usb/bindings.d.ts +4 -0
- package/dist/usb/device.js +5 -0
- package/dist/usb/device.js.map +1 -1
- package/libusb/.gitattributes +2 -6
- package/libusb/.private/appveyor_build.sh +22 -0
- package/libusb/.private/bm.sh +1 -1
- package/libusb/.private/ci-build.sh +67 -0
- package/libusb/.private/post-rewrite.sh +5 -1
- package/libusb/.private/pre-commit.sh +5 -1
- package/libusb/.private/wbs.txt +4 -19
- package/libusb/.travis.yml +32 -23
- package/libusb/AUTHORS +76 -3
- package/libusb/ChangeLog +41 -3
- package/libusb/INSTALL_WIN.txt +22 -44
- package/libusb/Makefile.am +32 -10
- package/libusb/{README.md → README} +2 -2
- package/libusb/README.git +3 -3
- package/libusb/Xcode/common.xcconfig +23 -19
- package/libusb/Xcode/config.h +25 -13
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +511 -109
- package/libusb/android/README +90 -54
- package/libusb/android/config.h +23 -43
- package/libusb/android/examples/unrooted_android.c +301 -0
- package/libusb/android/examples/unrooted_android.h +36 -0
- package/libusb/android/jni/Android.mk +1 -1
- package/libusb/android/jni/Application.mk +16 -0
- package/libusb/android/jni/examples.mk +63 -29
- package/libusb/android/jni/libusb.mk +14 -8
- package/libusb/android/jni/tests.mk +13 -24
- package/libusb/appveyor.yml +69 -30
- package/libusb/autogen.sh +5 -3
- package/libusb/bootstrap.sh +6 -2
- package/libusb/configure.ac +302 -228
- package/libusb/doc/Makefile.in +22 -0
- package/libusb/doc/doxygen.cfg.in +460 -223
- package/libusb/examples/Makefile.am +6 -13
- package/libusb/examples/dpfp.c +276 -73
- package/libusb/examples/ezusb.c +18 -8
- package/libusb/examples/ezusb.h +6 -17
- package/libusb/examples/fxload.c +4 -5
- package/libusb/examples/hotplugtest.c +1 -1
- package/libusb/examples/sam3u_benchmark.c +59 -24
- package/libusb/examples/testlibusb.c +138 -104
- package/libusb/examples/xusb.c +26 -22
- package/libusb/libusb/Makefile.am +57 -70
- package/libusb/libusb/Makefile.am.extra +26 -0
- package/libusb/libusb/core.c +420 -423
- package/libusb/libusb/descriptor.c +365 -419
- package/libusb/libusb/hotplug.c +197 -104
- package/libusb/libusb/io.c +491 -528
- package/libusb/libusb/libusb-1.0.def +7 -3
- package/libusb/libusb/libusb-1.0.rc +1 -9
- package/libusb/libusb/libusb.h +295 -226
- package/libusb/libusb/libusbi.h +587 -314
- package/libusb/libusb/os/darwin_usb.c +634 -317
- package/libusb/libusb/os/darwin_usb.h +39 -15
- package/libusb/libusb/os/events_posix.c +300 -0
- package/libusb/libusb/os/events_posix.h +59 -0
- package/libusb/libusb/os/events_windows.c +214 -0
- package/libusb/{msvc/missing.h → libusb/os/events_windows.h} +25 -11
- package/libusb/libusb/os/haiku_pollfs.cpp +14 -9
- package/libusb/libusb/os/haiku_usb.h +12 -12
- package/libusb/libusb/os/haiku_usb_backend.cpp +36 -37
- package/libusb/libusb/os/haiku_usb_raw.cpp +80 -116
- package/libusb/libusb/os/linux_netlink.c +55 -63
- package/libusb/libusb/os/linux_udev.c +61 -69
- package/libusb/libusb/os/linux_usbfs.c +926 -1015
- package/libusb/libusb/os/linux_usbfs.h +74 -57
- package/libusb/libusb/os/netbsd_usb.c +103 -168
- package/libusb/libusb/os/null_usb.c +111 -0
- package/libusb/libusb/os/openbsd_usb.c +71 -120
- package/libusb/libusb/os/sunos_usb.c +289 -375
- package/libusb/libusb/os/sunos_usb.h +0 -1
- package/libusb/libusb/os/threads_posix.c +81 -32
- package/libusb/libusb/os/threads_posix.h +19 -23
- package/libusb/libusb/os/threads_windows.c +9 -95
- package/libusb/libusb/os/threads_windows.h +33 -31
- package/libusb/libusb/os/windows_common.c +904 -0
- package/libusb/libusb/os/windows_common.h +329 -42
- package/libusb/libusb/os/windows_usbdk.c +161 -267
- package/libusb/libusb/os/windows_usbdk.h +5 -2
- package/libusb/libusb/os/windows_winusb.c +1326 -1190
- package/libusb/libusb/os/windows_winusb.h +167 -167
- package/libusb/libusb/strerror.c +20 -30
- package/libusb/libusb/sync.c +20 -21
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/msvc/.gitattributes +3 -0
- package/libusb/msvc/config.h +27 -20
- package/libusb/msvc/{hotplugtest_2012.vcxproj → dpfp_2013.vcxproj} +14 -10
- package/libusb/msvc/dpfp_2013.vcxproj.filters +26 -0
- package/libusb/msvc/{listdevs_2010.vcxproj → dpfp_2015.vcxproj} +14 -9
- package/libusb/msvc/dpfp_2015.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_2017.vcxproj +106 -0
- package/libusb/msvc/dpfp_2017.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_2019.vcxproj +106 -0
- package/libusb/msvc/dpfp_2019.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2013.vcxproj +87 -0
- package/libusb/msvc/dpfp_threaded_2013.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2015.vcxproj +87 -0
- package/libusb/msvc/dpfp_threaded_2015.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2017.vcxproj +106 -0
- package/libusb/msvc/dpfp_threaded_2017.vcxproj.filters +26 -0
- package/libusb/msvc/{fxload_2012.vcxproj → dpfp_threaded_2019.vcxproj} +32 -17
- package/libusb/msvc/dpfp_threaded_2019.vcxproj.filters +26 -0
- package/libusb/msvc/fxload_2013.vcxproj +6 -3
- package/libusb/msvc/fxload_2013.vcxproj.filters +35 -0
- package/libusb/msvc/fxload_2015.vcxproj +6 -3
- package/libusb/msvc/fxload_2015.vcxproj.filters +35 -0
- package/libusb/msvc/fxload_2017.vcxproj +6 -7
- package/libusb/msvc/fxload_2017.vcxproj.filters +35 -0
- package/libusb/msvc/{fxload_2010.vcxproj → fxload_2019.vcxproj} +29 -6
- package/libusb/msvc/fxload_2019.vcxproj.filters +35 -0
- package/libusb/{examples → msvc}/getopt/getopt.c +0 -0
- package/libusb/{examples → msvc}/getopt/getopt.h +0 -0
- package/libusb/{examples → msvc}/getopt/getopt1.c +0 -0
- package/libusb/msvc/getopt_2013.vcxproj +4 -5
- package/libusb/msvc/getopt_2013.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2015.vcxproj +4 -4
- package/libusb/msvc/getopt_2015.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2017.vcxproj +4 -10
- package/libusb/msvc/getopt_2017.vcxproj.filters +26 -0
- package/libusb/msvc/{getopt_2012.vcxproj → getopt_2019.vcxproj} +25 -6
- package/libusb/msvc/getopt_2019.vcxproj.filters +26 -0
- package/libusb/msvc/hotplugtest_2013.vcxproj +6 -3
- package/libusb/msvc/hotplugtest_2013.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2015.vcxproj +6 -3
- package/libusb/msvc/hotplugtest_2015.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +6 -7
- package/libusb/msvc/hotplugtest_2017.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2019.vcxproj +105 -0
- package/libusb/msvc/hotplugtest_2019.vcxproj.filters +23 -0
- package/libusb/msvc/libusb_2013.sln +50 -20
- package/libusb/msvc/libusb_2015.sln +51 -21
- package/libusb/msvc/libusb_2017.sln +90 -36
- package/libusb/msvc/libusb_2019.sln +240 -0
- package/libusb/msvc/libusb_dll_2013.vcxproj +6 -9
- package/libusb/msvc/libusb_dll_2013.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_dll_2015.vcxproj +6 -8
- package/libusb/msvc/libusb_dll_2015.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +6 -16
- package/libusb/msvc/libusb_dll_2017.vcxproj.filters +94 -0
- package/libusb/msvc/{libusb_dll_2010.vcxproj → libusb_dll_2019.vcxproj} +27 -9
- package/libusb/msvc/libusb_dll_2019.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_static_2013.vcxproj +5 -9
- package/libusb/msvc/libusb_static_2013.vcxproj.filters +80 -0
- package/libusb/msvc/libusb_static_2015.vcxproj +5 -8
- package/libusb/msvc/libusb_static_2015.vcxproj.filters +80 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +5 -8
- package/libusb/msvc/libusb_static_2017.vcxproj.filters +80 -0
- package/libusb/msvc/{libusb_static_2010.vcxproj → libusb_static_2019.vcxproj} +26 -9
- package/libusb/msvc/libusb_static_2019.vcxproj.filters +80 -0
- package/libusb/msvc/listdevs_2013.vcxproj +6 -3
- package/libusb/msvc/listdevs_2013.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2015.vcxproj +6 -3
- package/libusb/msvc/listdevs_2015.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2017.vcxproj +6 -7
- package/libusb/msvc/listdevs_2017.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2019.vcxproj +105 -0
- package/libusb/msvc/listdevs_2019.vcxproj.filters +23 -0
- package/libusb/msvc/{listdevs_2012.vcxproj → sam3u_benchmark_2013.vcxproj} +13 -9
- package/libusb/msvc/sam3u_benchmark_2013.vcxproj.filters +26 -0
- package/libusb/msvc/{hotplugtest_2010.vcxproj → sam3u_benchmark_2015.vcxproj} +13 -8
- package/libusb/msvc/sam3u_benchmark_2015.vcxproj.filters +26 -0
- package/libusb/msvc/sam3u_benchmark_2017.vcxproj +106 -0
- package/libusb/msvc/sam3u_benchmark_2017.vcxproj.filters +26 -0
- package/libusb/msvc/sam3u_benchmark_2019.vcxproj +106 -0
- package/libusb/msvc/sam3u_benchmark_2019.vcxproj.filters +26 -0
- package/libusb/msvc/stress_2013.vcxproj +4 -2
- package/libusb/msvc/stress_2013.vcxproj.filters +32 -0
- package/libusb/msvc/stress_2015.vcxproj +4 -2
- package/libusb/msvc/stress_2015.vcxproj.filters +32 -0
- package/libusb/msvc/stress_2017.vcxproj +4 -6
- package/libusb/msvc/stress_2017.vcxproj.filters +32 -0
- package/libusb/msvc/{stress_2010.vcxproj → stress_2019.vcxproj} +26 -4
- package/libusb/msvc/stress_2019.vcxproj.filters +32 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +6 -3
- package/libusb/msvc/testlibusb_2013.vcxproj.filters +23 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +6 -3
- package/libusb/msvc/testlibusb_2015.vcxproj.filters +23 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +6 -7
- package/libusb/msvc/testlibusb_2017.vcxproj.filters +23 -0
- package/libusb/msvc/{testlibusb_2010.vcxproj → testlibusb_2019.vcxproj} +28 -5
- package/libusb/msvc/testlibusb_2019.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2013.vcxproj +6 -3
- package/libusb/msvc/xusb_2013.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2015.vcxproj +6 -3
- package/libusb/msvc/xusb_2015.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2017.vcxproj +6 -7
- package/libusb/msvc/xusb_2017.vcxproj.filters +23 -0
- package/libusb/msvc/{xusb_2010.vcxproj → xusb_2019.vcxproj} +28 -5
- package/libusb/msvc/xusb_2019.vcxproj.filters +23 -0
- package/libusb/tests/Makefile.am +1 -0
- package/libusb/tests/libusb_testlib.h +12 -43
- package/libusb/tests/stress.c +59 -50
- package/libusb/tests/testlib.c +78 -171
- package/libusb.gypi +10 -11
- package/package.json +1 -1
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +12 -7
- package/src/node_usb.cc +10 -0
- package/test/usb.coffee +6 -0
- package/tsc/index.ts +2 -0
- package/tsc/usb/bindings.ts +5 -0
- package/tsc/usb/device.ts +6 -0
- package/libusb/.private/bd.cmd +0 -89
- package/libusb/.private/bwince.cmd +0 -57
- package/libusb/.private/wbs_wince.txt +0 -42
- package/libusb/Brewfile +0 -4
- package/libusb/appveyor_cygwin.bat +0 -11
- package/libusb/appveyor_minGW.bat +0 -19
- package/libusb/doc/Makefile.am +0 -9
- package/libusb/examples/dpfp_threaded.c +0 -557
- package/libusb/libusb/hotplug.h +0 -99
- package/libusb/libusb/os/poll_posix.c +0 -84
- package/libusb/libusb/os/poll_posix.h +0 -14
- package/libusb/libusb/os/poll_windows.c +0 -447
- package/libusb/libusb/os/poll_windows.h +0 -98
- package/libusb/libusb/os/wince_usb.c +0 -888
- package/libusb/libusb/os/wince_usb.h +0 -126
- package/libusb/libusb/os/windows_nt_common.c +0 -1010
- package/libusb/libusb/os/windows_nt_common.h +0 -110
- package/libusb/libusb/os/windows_nt_shared_types.h +0 -147
- package/libusb/msvc/appveyor.bat +0 -27
- package/libusb/msvc/ddk_build.cmd +0 -219
- package/libusb/msvc/errno.h +0 -102
- package/libusb/msvc/fxload_sources +0 -23
- package/libusb/msvc/getopt_2005.vcproj +0 -288
- package/libusb/msvc/getopt_2010.vcxproj +0 -72
- package/libusb/msvc/getopt_sources +0 -24
- package/libusb/msvc/hotplugtest_sources +0 -20
- package/libusb/msvc/inttypes.h +0 -295
- package/libusb/msvc/libusb.dsw +0 -71
- package/libusb/msvc/libusb_2005.sln +0 -95
- package/libusb/msvc/libusb_2010.sln +0 -105
- package/libusb/msvc/libusb_2012.sln +0 -105
- package/libusb/msvc/libusb_dll.dsp +0 -194
- package/libusb/msvc/libusb_dll_2005.vcproj +0 -464
- package/libusb/msvc/libusb_dll_2012.vcxproj +0 -107
- package/libusb/msvc/libusb_dll_wince.vcproj +0 -1251
- package/libusb/msvc/libusb_sources +0 -43
- package/libusb/msvc/libusb_static.dsp +0 -174
- package/libusb/msvc/libusb_static_2005.vcproj +0 -390
- package/libusb/msvc/libusb_static_2012.vcxproj +0 -98
- package/libusb/msvc/libusb_static_wince.vcproj +0 -1179
- package/libusb/msvc/libusb_wince.sln +0 -246
- package/libusb/msvc/listdevs.dsp +0 -103
- package/libusb/msvc/listdevs_2005.vcproj +0 -360
- package/libusb/msvc/listdevs_sources +0 -20
- package/libusb/msvc/listdevs_wince.vcproj +0 -1120
- package/libusb/msvc/missing.c +0 -80
- package/libusb/msvc/stdint.h +0 -256
- package/libusb/msvc/stress_2005.vcproj +0 -390
- package/libusb/msvc/stress_2012.vcxproj +0 -87
- package/libusb/msvc/stress_sources +0 -21
- package/libusb/msvc/stress_wince.vcproj +0 -1128
- package/libusb/msvc/testlibusb_2012.vcxproj +0 -83
- package/libusb/msvc/testlibusb_sources +0 -20
- package/libusb/msvc/xusb.dsp +0 -102
- package/libusb/msvc/xusb_2005.vcproj +0 -344
- package/libusb/msvc/xusb_2012.vcxproj +0 -83
- package/libusb/msvc/xusb_sources +0 -20
- package/libusb/msvc/xusb_wince.vcproj +0 -1120
- package/libusb/travis-autogen.sh +0 -39
package/libusb/libusb/core.c
CHANGED
|
@@ -20,41 +20,32 @@
|
|
|
20
20
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
#include "
|
|
23
|
+
#include "libusbi.h"
|
|
24
|
+
#include "version.h"
|
|
24
25
|
|
|
25
|
-
#
|
|
26
|
-
#include <
|
|
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
|
|
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
|
|
52
|
-
|
|
53
|
-
static
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
753
|
-
|
|
754
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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*
|
|
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
|
-
*
|
|
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*
|
|
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
|
|
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(
|
|
1124
|
-
if (speed
|
|
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
|
|
1143
|
+
if (speed < LIBUSB_SPEED_SUPER || r < 0) {
|
|
1134
1144
|
val = ep->wMaxPacketSize;
|
|
1135
|
-
ep_type = (enum
|
|
1145
|
+
ep_type = (enum libusb_endpoint_transfer_type) (ep->bmAttributes & 0x3);
|
|
1136
1146
|
|
|
1137
1147
|
r = val & 0x07ff;
|
|
1138
|
-
if (ep_type ==
|
|
1139
|
-
|| ep_type ==
|
|
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
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
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
|
-
|
|
1181
|
+
long refcnt;
|
|
1170
1182
|
|
|
1171
1183
|
if (!dev)
|
|
1172
1184
|
return;
|
|
1173
1185
|
|
|
1174
|
-
|
|
1175
|
-
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 %
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1513
|
-
ctx->device_close
|
|
1514
|
-
|
|
1515
|
-
|
|
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
|
-
|
|
1531
|
-
if (!
|
|
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,
|
|
1547
|
+
r = usbi_backend.get_configuration(dev_handle, &tmp);
|
|
1581
1548
|
|
|
1582
1549
|
if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
|
|
1583
|
-
|
|
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 ==
|
|
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
|
-
|
|
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 %
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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)
|
|
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
|
|
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 (
|
|
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
|
|
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().
|
|
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
|
|
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
|
-
|
|
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
|
|
2146
|
+
#if !defined(ENABLE_DEBUG_LOGGING)
|
|
2150
2147
|
if (mode & LIBUSB_LOG_CB_CONTEXT) {
|
|
2151
|
-
|
|
2148
|
+
ctx = usbi_get_context(ctx);
|
|
2152
2149
|
ctx->log_handler = cb;
|
|
2153
2150
|
}
|
|
2154
2151
|
#else
|
|
2155
2152
|
UNUSED(ctx);
|
|
2156
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
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
|
-
|
|
2240
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2214
2241
|
}
|
|
2215
|
-
va_end(ap);
|
|
2216
2242
|
|
|
2217
|
-
return
|
|
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
|
|
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 **
|
|
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 *
|
|
2258
|
-
|
|
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 (!
|
|
2264
|
-
|
|
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
|
-
|
|
2275
|
-
if (!
|
|
2276
|
-
|
|
2277
|
-
|
|
2294
|
+
/* check for first init */
|
|
2295
|
+
if (!active_contexts_list.next) {
|
|
2296
|
+
list_init(&active_contexts_list);
|
|
2297
|
+
usbi_get_monotonic_time(×tamp_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
|
|
2282
|
-
|
|
2283
|
-
|
|
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
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
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
|
-
|
|
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(
|
|
2352
|
+
r = usbi_backend.init(_ctx);
|
|
2314
2353
|
if (r)
|
|
2315
|
-
goto
|
|
2354
|
+
goto err_io_exit;
|
|
2316
2355
|
}
|
|
2317
2356
|
|
|
2318
|
-
|
|
2319
|
-
|
|
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
|
-
|
|
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
|
|
2366
|
+
list_del(&_ctx->list);
|
|
2340
2367
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
2341
2368
|
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
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(&
|
|
2350
|
-
usbi_mutex_destroy(&
|
|
2351
|
-
|
|
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(
|
|
2394
|
+
void API_EXPORTED libusb_exit(libusb_context *ctx)
|
|
2365
2395
|
{
|
|
2366
|
-
struct
|
|
2367
|
-
struct
|
|
2368
|
-
int destroying_default_context = 0;
|
|
2396
|
+
struct libusb_context *_ctx;
|
|
2397
|
+
struct libusb_device *dev;
|
|
2369
2398
|
|
|
2370
|
-
|
|
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
|
-
|
|
2376
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2419
|
+
usbi_dbg(ctx, " ");
|
|
2420
|
+
_ctx = ctx;
|
|
2421
|
+
}
|
|
2395
2422
|
|
|
2396
2423
|
usbi_mutex_static_lock(&active_contexts_lock);
|
|
2397
|
-
list_del
|
|
2424
|
+
list_del(&_ctx->list);
|
|
2398
2425
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
2399
2426
|
|
|
2400
|
-
if (
|
|
2401
|
-
|
|
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
|
-
|
|
2416
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2431
|
-
|
|
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
|
-
|
|
2435
|
-
|
|
2436
|
-
usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
|
|
2437
|
-
free(ctx);
|
|
2438
|
+
usbi_hotplug_exit(_ctx);
|
|
2439
|
+
usbi_io_exit(_ctx);
|
|
2438
2440
|
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
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
|
|
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
|
|
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
|
|
2494
|
+
va_list args;
|
|
2485
2495
|
int ret;
|
|
2486
2496
|
|
|
2487
|
-
va_start(
|
|
2488
|
-
ret = usbi_vsnprintf(str, size, format,
|
|
2489
|
-
va_end(
|
|
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
|
|
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,
|
|
2508
|
+
ret = _vsnprintf(str, size, format, args);
|
|
2499
2509
|
if (ret < 0 || ret == (int)size) {
|
|
2500
|
-
/* Output is truncated, ensure buffer is
|
|
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,
|
|
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
|
|
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(
|
|
2515
|
-
|
|
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(
|
|
2533
|
-
|
|
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
|
|
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
|
|
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
|
|
2575
|
+
enum libusb_log_level ctx_level;
|
|
2570
2576
|
|
|
2571
|
-
|
|
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
|
|
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(×tamp);
|
|
2619
|
+
TIMESPEC_SUB(×tamp, ×tamp_origin, ×tamp);
|
|
2620
|
+
|
|
2623
2621
|
header_len = snprintf(buf, sizeof(buf),
|
|
2624
2622
|
"[%2ld.%06ld] [%08x] libusb: %s [%s] ",
|
|
2625
|
-
(long)
|
|
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
|
-
|
|
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
|
-
|
|
2648
|
+
log_str(level, buf);
|
|
2652
2649
|
|
|
2653
|
-
/* Per
|
|
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
|
|
2666
|
-
|
|
2667
|
-
va_end
|
|
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 */
|