libusb 0.3.4 → 0.4.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -0
- data/History.md +10 -0
- data/README.md +19 -6
- data/Rakefile +1 -1
- data/ext/extconf.rb +17 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
- data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
- data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
- data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
- data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
- data/ext/libusbx-1.0.17/android/README +114 -0
- data/ext/libusbx-1.0.17/android/config.h +90 -0
- data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
- data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
- data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
- data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
- data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
- data/ext/libusbx-1.0.17/compile +347 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
- data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
- data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
- data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
- data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
- data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
- data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
- data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
- data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
- data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
- data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
- data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
- data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
- data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
- data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
- data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
- data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
- data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
- data/ext/libusbx-1.0.17/missing +215 -0
- data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
- data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
- data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
- data/ext/libusbx-1.0.17/tests/stress.c +160 -0
- data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
- data/lib/libusb.rb +4 -0
- data/lib/libusb/call.rb +43 -1
- data/lib/libusb/constants.rb +5 -0
- data/lib/libusb/context.rb +100 -0
- data/lib/libusb/dev_handle.rb +27 -0
- data/lib/libusb/device.rb +10 -4
- data/lib/libusb/version_gem.rb +1 -1
- data/test/test_libusb_capability.rb +2 -2
- data/test/test_libusb_compat.rb +2 -2
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +4 -2
- data/test/test_libusb_event_machine.rb +2 -2
- data/test/test_libusb_gc.rb +2 -2
- data/test/test_libusb_hotplug.rb +115 -0
- data/test/test_libusb_iso_transfer.rb +3 -3
- data/test/test_libusb_mass_storage.rb +6 -16
- data/test/test_libusb_mass_storage2.rb +26 -3
- data/test/test_libusb_structs.rb +2 -2
- data/test/test_libusb_threads.rb +2 -2
- data/test/test_libusb_version.rb +2 -2
- metadata +127 -68
- metadata.gz.sig +0 -0
- data/ext/libusbx-1.0.14/THANKS +0 -7
- data/ext/libusbx-1.0.14/compile +0 -143
- data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
- data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
- data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
- data/ext/libusbx-1.0.14/missing +0 -376
@@ -1,5 +1,7 @@
|
|
1
|
+
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
1
2
|
/*
|
2
3
|
* Core functions for libusbx
|
4
|
+
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@cs.unm.edu>
|
3
5
|
* Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org>
|
4
6
|
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
5
7
|
*
|
@@ -18,20 +20,29 @@
|
|
18
20
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19
21
|
*/
|
20
22
|
|
21
|
-
#include
|
23
|
+
#include "config.h"
|
22
24
|
|
23
25
|
#include <errno.h>
|
24
26
|
#include <stdarg.h>
|
25
27
|
#include <stdio.h>
|
26
28
|
#include <stdlib.h>
|
27
29
|
#include <string.h>
|
30
|
+
#ifdef HAVE_SYS_TYPES_H
|
28
31
|
#include <sys/types.h>
|
29
|
-
|
32
|
+
#endif
|
30
33
|
#ifdef HAVE_SYS_TIME_H
|
31
34
|
#include <sys/time.h>
|
32
35
|
#endif
|
36
|
+
#ifdef HAVE_SYSLOG_H
|
37
|
+
#include <syslog.h>
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#ifdef __ANDROID__
|
41
|
+
#include <android/log.h>
|
42
|
+
#endif
|
33
43
|
|
34
44
|
#include "libusbi.h"
|
45
|
+
#include "hotplug.h"
|
35
46
|
|
36
47
|
#if defined(OS_LINUX)
|
37
48
|
const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend;
|
@@ -39,20 +50,27 @@ const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend;
|
|
39
50
|
const struct usbi_os_backend * const usbi_backend = &darwin_backend;
|
40
51
|
#elif defined(OS_OPENBSD)
|
41
52
|
const struct usbi_os_backend * const usbi_backend = &openbsd_backend;
|
53
|
+
#elif defined(OS_NETBSD)
|
54
|
+
const struct usbi_os_backend * const usbi_backend = &netbsd_backend;
|
42
55
|
#elif defined(OS_WINDOWS)
|
43
56
|
const struct usbi_os_backend * const usbi_backend = &windows_backend;
|
57
|
+
#elif defined(OS_WINCE)
|
58
|
+
const struct usbi_os_backend * const usbi_backend = &wince_backend;
|
44
59
|
#else
|
45
60
|
#error "Unsupported OS"
|
46
61
|
#endif
|
47
62
|
|
48
63
|
struct libusb_context *usbi_default_context = NULL;
|
49
|
-
const struct libusb_version libusb_version_internal =
|
64
|
+
static const struct libusb_version libusb_version_internal =
|
50
65
|
{ LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO,
|
51
66
|
LIBUSB_RC, "http://libusbx.org" };
|
52
67
|
static int default_context_refcnt = 0;
|
53
68
|
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
|
54
69
|
static struct timeval timestamp_origin = { 0, 0 };
|
55
70
|
|
71
|
+
usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
|
72
|
+
struct list_head active_contexts_list;
|
73
|
+
|
56
74
|
/**
|
57
75
|
* \mainpage libusbx-1.0 API Reference
|
58
76
|
*
|
@@ -84,6 +102,7 @@ static struct timeval timestamp_origin = { 0, 0 };
|
|
84
102
|
* usually won't need to thread)
|
85
103
|
* - Lightweight with lean API
|
86
104
|
* - Compatible with libusb-0.1 through the libusb-compat-0.1 translation layer
|
105
|
+
* - Hotplug support (on some platforms). See \ref hotplug.
|
87
106
|
*
|
88
107
|
* \section gettingstarted Getting Started
|
89
108
|
*
|
@@ -185,19 +204,6 @@ static struct timeval timestamp_origin = { 0, 0 };
|
|
185
204
|
* - Clearing of halt/stall condition (libusb_clear_halt())
|
186
205
|
* - Device resets (libusb_reset_device())
|
187
206
|
*
|
188
|
-
* \section nohotplug No hotplugging
|
189
|
-
*
|
190
|
-
* libusbx-1.0 lacks functionality for providing notifications of when devices
|
191
|
-
* are added or removed. This functionality is planned to be implemented
|
192
|
-
* in a later version of libusbx.
|
193
|
-
*
|
194
|
-
* That said, there is basic disconnection handling for open device handles:
|
195
|
-
* - If there are ongoing transfers, libusbx's handle_events loop will detect
|
196
|
-
* disconnections and complete ongoing transfers with the
|
197
|
-
* LIBUSB_TRANSFER_NO_DEVICE status code.
|
198
|
-
* - Many functions such as libusb_set_configuration() return the special
|
199
|
-
* LIBUSB_ERROR_NO_DEVICE error code when the device has been disconnected.
|
200
|
-
*
|
201
207
|
* \section configsel Configuration selection and handling
|
202
208
|
*
|
203
209
|
* When libusbx presents a device handle to an application, there is a chance
|
@@ -517,12 +523,66 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
|
|
517
523
|
dev->refcnt = 1;
|
518
524
|
dev->session_data = session_id;
|
519
525
|
dev->speed = LIBUSB_SPEED_UNKNOWN;
|
520
|
-
|
526
|
+
|
527
|
+
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
528
|
+
usbi_connect_device (dev);
|
529
|
+
}
|
530
|
+
|
531
|
+
return dev;
|
532
|
+
}
|
533
|
+
|
534
|
+
void usbi_connect_device(struct libusb_device *dev)
|
535
|
+
{
|
536
|
+
libusb_hotplug_message message;
|
537
|
+
ssize_t ret;
|
538
|
+
|
539
|
+
memset(&message, 0, sizeof(message));
|
540
|
+
message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
|
541
|
+
message.device = dev;
|
542
|
+
dev->attached = 1;
|
543
|
+
|
544
|
+
usbi_mutex_lock(&dev->ctx->usb_devs_lock);
|
545
|
+
list_add(&dev->list, &dev->ctx->usb_devs);
|
546
|
+
usbi_mutex_unlock(&dev->ctx->usb_devs_lock);
|
547
|
+
|
548
|
+
/* Signal that an event has occurred for this device if we support hotplug AND
|
549
|
+
* the hotplug pipe is ready. This prevents an event from getting raised during
|
550
|
+
* initial enumeration. */
|
551
|
+
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) {
|
552
|
+
ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message));
|
553
|
+
if (sizeof (message) != ret) {
|
554
|
+
usbi_err(DEVICE_CTX(dev), "error writing hotplug message");
|
555
|
+
}
|
556
|
+
}
|
557
|
+
}
|
558
|
+
|
559
|
+
void usbi_disconnect_device(struct libusb_device *dev)
|
560
|
+
{
|
561
|
+
libusb_hotplug_message message;
|
562
|
+
struct libusb_context *ctx = dev->ctx;
|
563
|
+
ssize_t ret;
|
564
|
+
|
565
|
+
memset(&message, 0, sizeof(message));
|
566
|
+
message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
|
567
|
+
message.device = dev;
|
568
|
+
usbi_mutex_lock(&dev->lock);
|
569
|
+
dev->attached = 0;
|
570
|
+
usbi_mutex_unlock(&dev->lock);
|
521
571
|
|
522
572
|
usbi_mutex_lock(&ctx->usb_devs_lock);
|
523
|
-
|
573
|
+
list_del(&dev->list);
|
524
574
|
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
525
|
-
|
575
|
+
|
576
|
+
/* Signal that an event has occurred for this device if we support hotplug AND
|
577
|
+
* the hotplug pipe is ready. This prevents an event from getting raised during
|
578
|
+
* initial enumeration. libusb_handle_events will take care of dereferencing the
|
579
|
+
* device. */
|
580
|
+
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) {
|
581
|
+
ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message));
|
582
|
+
if (sizeof(message) != ret) {
|
583
|
+
usbi_err(DEVICE_CTX(dev), "error writing hotplug message");
|
584
|
+
}
|
585
|
+
}
|
526
586
|
}
|
527
587
|
|
528
588
|
/* Perform some final sanity checks on a newly discovered device. If this
|
@@ -531,15 +591,13 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
|
|
531
591
|
int usbi_sanitize_device(struct libusb_device *dev)
|
532
592
|
{
|
533
593
|
int r;
|
534
|
-
unsigned char raw_desc[DEVICE_DESC_LENGTH];
|
535
594
|
uint8_t num_configurations;
|
536
|
-
int host_endian;
|
537
595
|
|
538
|
-
r =
|
596
|
+
r = usbi_device_cache_descriptor(dev);
|
539
597
|
if (r < 0)
|
540
598
|
return r;
|
541
599
|
|
542
|
-
num_configurations =
|
600
|
+
num_configurations = dev->device_descriptor.bNumConfigurations;
|
543
601
|
if (num_configurations > USB_MAXCONFIG) {
|
544
602
|
usbi_err(DEVICE_CTX(dev), "too many configurations");
|
545
603
|
return LIBUSB_ERROR_IO;
|
@@ -603,7 +661,28 @@ ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
|
|
603
661
|
if (!discdevs)
|
604
662
|
return LIBUSB_ERROR_NO_MEM;
|
605
663
|
|
606
|
-
|
664
|
+
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
665
|
+
/* backend provides hotplug support */
|
666
|
+
struct libusb_device *dev;
|
667
|
+
|
668
|
+
if (usbi_backend->hotplug_poll)
|
669
|
+
usbi_backend->hotplug_poll();
|
670
|
+
|
671
|
+
usbi_mutex_lock(&ctx->usb_devs_lock);
|
672
|
+
list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) {
|
673
|
+
discdevs = discovered_devs_append(discdevs, dev);
|
674
|
+
|
675
|
+
if (!discdevs) {
|
676
|
+
r = LIBUSB_ERROR_NO_MEM;
|
677
|
+
break;
|
678
|
+
}
|
679
|
+
}
|
680
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
681
|
+
} else {
|
682
|
+
/* backend does not provide hotplug support */
|
683
|
+
r = usbi_backend->get_device_list(ctx, &discdevs);
|
684
|
+
}
|
685
|
+
|
607
686
|
if (r < 0) {
|
608
687
|
len = r;
|
609
688
|
goto out;
|
@@ -663,7 +742,16 @@ uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev)
|
|
663
742
|
}
|
664
743
|
|
665
744
|
/** \ingroup dev
|
666
|
-
* Get the number of the port that a device is connected to
|
745
|
+
* Get the number of the port that a device is connected to.
|
746
|
+
* Unless the OS does something funky, or you are hot-plugging USB extension cards,
|
747
|
+
* the port number returned by this call is usually guaranteed to be uniquely tied
|
748
|
+
* to a physical port, meaning that different devices plugged on the same physical
|
749
|
+
* port should return the same port number.
|
750
|
+
*
|
751
|
+
* But outside of this, there is no guarantee that the port number returned by this
|
752
|
+
* call will remain the same, or even match the order in which ports have been
|
753
|
+
* numbered by the HUB/HCD manufacturer.
|
754
|
+
*
|
667
755
|
* \param dev a device
|
668
756
|
* \returns the port number (0 if not available)
|
669
757
|
*/
|
@@ -674,24 +762,19 @@ uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev)
|
|
674
762
|
|
675
763
|
/** \ingroup dev
|
676
764
|
* Get the list of all port numbers from root for the specified device
|
677
|
-
*
|
765
|
+
*
|
766
|
+
* Since version 1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102
|
678
767
|
* \param dev a device
|
679
|
-
* \param
|
680
|
-
* \param
|
768
|
+
* \param port_numbers the array that should contain the port numbers
|
769
|
+
* \param port_numbers_len the maximum length of the array. As per the USB 3.0
|
681
770
|
* specs, the current maximum limit for the depth is 7.
|
682
771
|
* \returns the number of elements filled
|
683
772
|
* \returns LIBUSB_ERROR_OVERFLOW if the array is too small
|
684
773
|
*/
|
685
|
-
int API_EXPORTED
|
774
|
+
int API_EXPORTED libusb_get_port_numbers(libusb_device *dev,
|
775
|
+
uint8_t* port_numbers, int port_numbers_len)
|
686
776
|
{
|
687
|
-
int i =
|
688
|
-
ssize_t r;
|
689
|
-
struct libusb_device **devs = NULL;
|
690
|
-
|
691
|
-
/* The device needs to be open, else the parents may have been destroyed */
|
692
|
-
r = libusb_get_device_list(ctx, &devs);
|
693
|
-
if (r < 0)
|
694
|
-
return (int)r;
|
777
|
+
int i = port_numbers_len;
|
695
778
|
|
696
779
|
while(dev) {
|
697
780
|
// HCDs can be listed as devices and would have port #0
|
@@ -700,24 +783,35 @@ int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev, u
|
|
700
783
|
break;
|
701
784
|
i--;
|
702
785
|
if (i < 0) {
|
703
|
-
|
786
|
+
usbi_warn(DEVICE_CTX(dev),
|
787
|
+
"port numbers array too small");
|
704
788
|
return LIBUSB_ERROR_OVERFLOW;
|
705
789
|
}
|
706
|
-
|
790
|
+
port_numbers[i] = dev->port_number;
|
707
791
|
dev = dev->parent_dev;
|
708
792
|
}
|
709
|
-
|
710
|
-
|
711
|
-
return path_len-i;
|
793
|
+
memmove(port_numbers, &port_numbers[i], port_numbers_len - i);
|
794
|
+
return port_numbers_len - i;
|
712
795
|
}
|
713
796
|
|
714
797
|
/** \ingroup dev
|
715
|
-
*
|
798
|
+
* Deprecated please use libusb_get_port_numbers instead.
|
799
|
+
*/
|
800
|
+
int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev,
|
801
|
+
uint8_t* port_numbers, uint8_t port_numbers_len)
|
802
|
+
{
|
803
|
+
UNUSED(ctx);
|
804
|
+
|
805
|
+
return libusb_get_port_numbers(dev, port_numbers, port_numbers_len);
|
806
|
+
}
|
807
|
+
|
808
|
+
/** \ingroup dev
|
809
|
+
* Get the the parent from the specified device.
|
716
810
|
* \param dev a device
|
717
811
|
* \returns the device parent or NULL if not available
|
718
|
-
* You should issue a libusb_get_device_list() before calling this
|
812
|
+
* You should issue a \ref libusb_get_device_list() before calling this
|
719
813
|
* function and make sure that you only access the parent before issuing
|
720
|
-
* libusb_free_device_list(). The reason is that libusbx currently does
|
814
|
+
* \ref libusb_free_device_list(). The reason is that libusbx currently does
|
721
815
|
* not maintain a permanent list of device instances, and therefore can
|
722
816
|
* only guarantee that parents are fully instantiated within a
|
723
817
|
* libusb_get_device_list() - libusb_free_device_list() block.
|
@@ -817,7 +911,7 @@ int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev,
|
|
817
911
|
* Calculate the maximum packet size which a specific endpoint is capable is
|
818
912
|
* sending or receiving in the duration of 1 microframe
|
819
913
|
*
|
820
|
-
* Only the active
|
914
|
+
* Only the active configuration is examined. The calculation is based on the
|
821
915
|
* wMaxPacketSize field in the endpoint descriptor as described in section
|
822
916
|
* 9.6.6 in the USB 2.0 specifications.
|
823
917
|
*
|
@@ -903,12 +997,15 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
|
|
903
997
|
if (refcnt == 0) {
|
904
998
|
usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address);
|
905
999
|
|
1000
|
+
libusb_unref_device(dev->parent_dev);
|
1001
|
+
|
906
1002
|
if (usbi_backend->destroy_device)
|
907
1003
|
usbi_backend->destroy_device(dev);
|
908
1004
|
|
909
|
-
|
910
|
-
|
911
|
-
|
1005
|
+
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
1006
|
+
/* backend does not support hotplug */
|
1007
|
+
usbi_disconnect_device(dev);
|
1008
|
+
}
|
912
1009
|
|
913
1010
|
usbi_mutex_destroy(&dev->lock);
|
914
1011
|
free(dev);
|
@@ -987,6 +1084,10 @@ int API_EXPORTED libusb_open(libusb_device *dev,
|
|
987
1084
|
int r;
|
988
1085
|
usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
|
989
1086
|
|
1087
|
+
if (!dev->attached) {
|
1088
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1089
|
+
}
|
1090
|
+
|
990
1091
|
_handle = malloc(sizeof(*_handle) + priv_size);
|
991
1092
|
if (!_handle)
|
992
1093
|
return LIBUSB_ERROR_NO_MEM;
|
@@ -998,12 +1099,13 @@ int API_EXPORTED libusb_open(libusb_device *dev,
|
|
998
1099
|
}
|
999
1100
|
|
1000
1101
|
_handle->dev = libusb_ref_device(dev);
|
1102
|
+
_handle->auto_detach_kernel_driver = 0;
|
1001
1103
|
_handle->claimed_interfaces = 0;
|
1002
1104
|
memset(&_handle->os_priv, 0, priv_size);
|
1003
1105
|
|
1004
1106
|
r = usbi_backend->open(_handle);
|
1005
1107
|
if (r < 0) {
|
1006
|
-
usbi_dbg("
|
1108
|
+
usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
|
1007
1109
|
libusb_unref_device(dev);
|
1008
1110
|
usbi_mutex_destroy(&_handle->lock);
|
1009
1111
|
free(_handle);
|
@@ -1092,7 +1194,7 @@ static void do_close(struct libusb_context *ctx,
|
|
1092
1194
|
/* safe iteration because transfers may be being deleted */
|
1093
1195
|
list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) {
|
1094
1196
|
struct libusb_transfer *transfer =
|
1095
|
-
|
1197
|
+
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
1096
1198
|
|
1097
1199
|
if (transfer->dev_handle != dev_handle)
|
1098
1200
|
continue;
|
@@ -1280,7 +1382,14 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev,
|
|
1280
1382
|
* endpoint halts cleared, toggles reset).
|
1281
1383
|
*
|
1282
1384
|
* You cannot change/reset configuration if your application has claimed
|
1283
|
-
* interfaces
|
1385
|
+
* interfaces. It is advised to set the desired configuration before claiming
|
1386
|
+
* interfaces.
|
1387
|
+
*
|
1388
|
+
* Alternatively you can call libusb_release_interface() first. Note if you
|
1389
|
+
* do things this way you must ensure that auto_detach_kernel_driver for
|
1390
|
+
* <tt>dev</tt> is 0, otherwise the kernel driver will be re-attached when you
|
1391
|
+
* release the interface(s).
|
1392
|
+
*
|
1284
1393
|
* You cannot change/reset configuration if other applications or drivers have
|
1285
1394
|
* claimed interfaces.
|
1286
1395
|
*
|
@@ -1302,6 +1411,7 @@ int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev,
|
|
1302
1411
|
* \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed
|
1303
1412
|
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
|
1304
1413
|
* \returns another LIBUSB_ERROR code on other failure
|
1414
|
+
* \see libusb_set_auto_detach_kernel_driver()
|
1305
1415
|
*/
|
1306
1416
|
int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev,
|
1307
1417
|
int configuration)
|
@@ -1317,6 +1427,9 @@ int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev,
|
|
1317
1427
|
* It is legal to attempt to claim an already-claimed interface, in which
|
1318
1428
|
* case libusbx just returns 0 without doing anything.
|
1319
1429
|
*
|
1430
|
+
* If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel driver
|
1431
|
+
* will be detached if necessary, on failure the detach error is returned.
|
1432
|
+
*
|
1320
1433
|
* Claiming of interfaces is a purely logical operation; it does not cause
|
1321
1434
|
* any requests to be sent over the bus. Interface claiming is used to
|
1322
1435
|
* instruct the underlying operating system that your application wishes
|
@@ -1333,6 +1446,7 @@ int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev,
|
|
1333
1446
|
* interface
|
1334
1447
|
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
|
1335
1448
|
* \returns a LIBUSB_ERROR code on other failure
|
1449
|
+
* \see libusb_set_auto_detach_kernel_driver()
|
1336
1450
|
*/
|
1337
1451
|
int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev,
|
1338
1452
|
int interface_number)
|
@@ -1343,6 +1457,9 @@ int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev,
|
|
1343
1457
|
if (interface_number >= USB_MAXINTERFACES)
|
1344
1458
|
return LIBUSB_ERROR_INVALID_PARAM;
|
1345
1459
|
|
1460
|
+
if (!dev->dev->attached)
|
1461
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1462
|
+
|
1346
1463
|
usbi_mutex_lock(&dev->lock);
|
1347
1464
|
if (dev->claimed_interfaces & (1 << interface_number))
|
1348
1465
|
goto out;
|
@@ -1363,6 +1480,9 @@ out:
|
|
1363
1480
|
* This is a blocking function. A SET_INTERFACE control request will be sent
|
1364
1481
|
* to the device, resetting interface state to the first alternate setting.
|
1365
1482
|
*
|
1483
|
+
* If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel
|
1484
|
+
* driver will be re-attached after releasing the interface.
|
1485
|
+
*
|
1366
1486
|
* \param dev a device handle
|
1367
1487
|
* \param interface_number the <tt>bInterfaceNumber</tt> of the
|
1368
1488
|
* previously-claimed interface
|
@@ -1370,6 +1490,7 @@ out:
|
|
1370
1490
|
* \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed
|
1371
1491
|
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
|
1372
1492
|
* \returns another LIBUSB_ERROR code on other failure
|
1493
|
+
* \see libusb_set_auto_detach_kernel_driver()
|
1373
1494
|
*/
|
1374
1495
|
int API_EXPORTED libusb_release_interface(libusb_device_handle *dev,
|
1375
1496
|
int interface_number)
|
@@ -1425,6 +1546,11 @@ int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev,
|
|
1425
1546
|
return LIBUSB_ERROR_INVALID_PARAM;
|
1426
1547
|
|
1427
1548
|
usbi_mutex_lock(&dev->lock);
|
1549
|
+
if (!dev->dev->attached) {
|
1550
|
+
usbi_mutex_unlock(&dev->lock);
|
1551
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1552
|
+
}
|
1553
|
+
|
1428
1554
|
if (!(dev->claimed_interfaces & (1 << interface_number))) {
|
1429
1555
|
usbi_mutex_unlock(&dev->lock);
|
1430
1556
|
return LIBUSB_ERROR_NOT_FOUND;
|
@@ -1455,6 +1581,9 @@ int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev,
|
|
1455
1581
|
unsigned char endpoint)
|
1456
1582
|
{
|
1457
1583
|
usbi_dbg("endpoint %x", endpoint);
|
1584
|
+
if (!dev->dev->attached)
|
1585
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1586
|
+
|
1458
1587
|
return usbi_backend->clear_halt(dev, endpoint);
|
1459
1588
|
}
|
1460
1589
|
|
@@ -1480,6 +1609,9 @@ int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev,
|
|
1480
1609
|
int API_EXPORTED libusb_reset_device(libusb_device_handle *dev)
|
1481
1610
|
{
|
1482
1611
|
usbi_dbg("");
|
1612
|
+
if (!dev->dev->attached)
|
1613
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1614
|
+
|
1483
1615
|
return usbi_backend->reset_device(dev);
|
1484
1616
|
}
|
1485
1617
|
|
@@ -1504,6 +1636,10 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev,
|
|
1504
1636
|
int interface_number)
|
1505
1637
|
{
|
1506
1638
|
usbi_dbg("interface %d", interface_number);
|
1639
|
+
|
1640
|
+
if (!dev->dev->attached)
|
1641
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1642
|
+
|
1507
1643
|
if (usbi_backend->kernel_driver_active)
|
1508
1644
|
return usbi_backend->kernel_driver_active(dev, interface_number);
|
1509
1645
|
else
|
@@ -1535,6 +1671,10 @@ int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev,
|
|
1535
1671
|
int interface_number)
|
1536
1672
|
{
|
1537
1673
|
usbi_dbg("interface %d", interface_number);
|
1674
|
+
|
1675
|
+
if (!dev->dev->attached)
|
1676
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1677
|
+
|
1538
1678
|
if (usbi_backend->detach_kernel_driver)
|
1539
1679
|
return usbi_backend->detach_kernel_driver(dev, interface_number);
|
1540
1680
|
else
|
@@ -1565,12 +1705,48 @@ int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev,
|
|
1565
1705
|
int interface_number)
|
1566
1706
|
{
|
1567
1707
|
usbi_dbg("interface %d", interface_number);
|
1708
|
+
|
1709
|
+
if (!dev->dev->attached)
|
1710
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
1711
|
+
|
1568
1712
|
if (usbi_backend->attach_kernel_driver)
|
1569
1713
|
return usbi_backend->attach_kernel_driver(dev, interface_number);
|
1570
1714
|
else
|
1571
1715
|
return LIBUSB_ERROR_NOT_SUPPORTED;
|
1572
1716
|
}
|
1573
1717
|
|
1718
|
+
/** \ingroup dev
|
1719
|
+
* Enable/disable libusbx's automatic kernel driver detachment. When this is
|
1720
|
+
* enabled libusbx will automatically detach the kernel driver on an interface
|
1721
|
+
* when claiming the interface, and attach it when releasing the interface.
|
1722
|
+
*
|
1723
|
+
* Automatic kernel driver detachment is disabled on newly opened device
|
1724
|
+
* handles by default.
|
1725
|
+
*
|
1726
|
+
* On platforms which do not have LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER
|
1727
|
+
* this function will return LIBUSB_ERROR_NOT_SUPPORTED, and libusbx will
|
1728
|
+
* continue as if this function was never called.
|
1729
|
+
*
|
1730
|
+
* \param dev a device handle
|
1731
|
+
* \param enable whether to enable or disable auto kernel driver detachment
|
1732
|
+
*
|
1733
|
+
* \returns LIBUSB_SUCCESS on success
|
1734
|
+
* \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality
|
1735
|
+
* is not available
|
1736
|
+
* \see libusb_claim_interface()
|
1737
|
+
* \see libusb_release_interface()
|
1738
|
+
* \see libusb_set_configuration()
|
1739
|
+
*/
|
1740
|
+
int API_EXPORTED libusb_set_auto_detach_kernel_driver(
|
1741
|
+
libusb_device_handle *dev, int enable)
|
1742
|
+
{
|
1743
|
+
if (!(usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER))
|
1744
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
1745
|
+
|
1746
|
+
dev->auto_detach_kernel_driver = enable;
|
1747
|
+
return LIBUSB_SUCCESS;
|
1748
|
+
}
|
1749
|
+
|
1574
1750
|
/** \ingroup lib
|
1575
1751
|
* Set log message verbosity.
|
1576
1752
|
*
|
@@ -1618,8 +1794,10 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level)
|
|
1618
1794
|
*/
|
1619
1795
|
int API_EXPORTED libusb_init(libusb_context **context)
|
1620
1796
|
{
|
1621
|
-
|
1797
|
+
struct libusb_device *dev, *next;
|
1798
|
+
char *dbg = getenv("LIBUSB_DEBUG");
|
1622
1799
|
struct libusb_context *ctx;
|
1800
|
+
static int first_init = 1;
|
1623
1801
|
int r = 0;
|
1624
1802
|
|
1625
1803
|
usbi_mutex_static_lock(&default_context_lock);
|
@@ -1645,7 +1823,6 @@ int API_EXPORTED libusb_init(libusb_context **context)
|
|
1645
1823
|
ctx->debug = LIBUSB_LOG_LEVEL_DEBUG;
|
1646
1824
|
#endif
|
1647
1825
|
|
1648
|
-
dbg = getenv("LIBUSB_DEBUG");
|
1649
1826
|
if (dbg) {
|
1650
1827
|
ctx->debug = atoi(dbg);
|
1651
1828
|
if (ctx->debug)
|
@@ -1655,45 +1832,67 @@ int API_EXPORTED libusb_init(libusb_context **context)
|
|
1655
1832
|
/* default context should be initialized before calling usbi_dbg */
|
1656
1833
|
if (!usbi_default_context) {
|
1657
1834
|
usbi_default_context = ctx;
|
1835
|
+
default_context_refcnt++;
|
1658
1836
|
usbi_dbg("created default context");
|
1659
1837
|
}
|
1660
1838
|
|
1661
1839
|
usbi_dbg("libusbx v%d.%d.%d.%d", libusb_version_internal.major, libusb_version_internal.minor,
|
1662
1840
|
libusb_version_internal.micro, libusb_version_internal.nano);
|
1663
1841
|
|
1664
|
-
if (usbi_backend->init) {
|
1665
|
-
r = usbi_backend->init(ctx);
|
1666
|
-
if (r)
|
1667
|
-
goto err_free_ctx;
|
1668
|
-
}
|
1669
|
-
|
1670
1842
|
usbi_mutex_init(&ctx->usb_devs_lock, NULL);
|
1671
1843
|
usbi_mutex_init(&ctx->open_devs_lock, NULL);
|
1844
|
+
usbi_mutex_init(&ctx->hotplug_cbs_lock, NULL);
|
1672
1845
|
list_init(&ctx->usb_devs);
|
1673
1846
|
list_init(&ctx->open_devs);
|
1847
|
+
list_init(&ctx->hotplug_cbs);
|
1674
1848
|
|
1675
|
-
|
1676
|
-
if (
|
1677
|
-
|
1678
|
-
|
1679
|
-
goto err_destroy_mutex;
|
1849
|
+
usbi_mutex_static_lock(&active_contexts_lock);
|
1850
|
+
if (first_init) {
|
1851
|
+
first_init = 0;
|
1852
|
+
list_init (&active_contexts_list);
|
1680
1853
|
}
|
1854
|
+
list_add (&ctx->list, &active_contexts_list);
|
1855
|
+
usbi_mutex_static_unlock(&active_contexts_lock);
|
1681
1856
|
|
1682
|
-
if (
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
usbi_default_context = ctx;
|
1687
|
-
default_context_refcnt++;
|
1857
|
+
if (usbi_backend->init) {
|
1858
|
+
r = usbi_backend->init(ctx);
|
1859
|
+
if (r)
|
1860
|
+
goto err_free_ctx;
|
1688
1861
|
}
|
1862
|
+
|
1863
|
+
r = usbi_io_init(ctx);
|
1864
|
+
if (r < 0)
|
1865
|
+
goto err_backend_exit;
|
1866
|
+
|
1689
1867
|
usbi_mutex_static_unlock(&default_context_lock);
|
1690
1868
|
|
1869
|
+
if (context)
|
1870
|
+
*context = ctx;
|
1871
|
+
|
1691
1872
|
return 0;
|
1692
1873
|
|
1693
|
-
|
1874
|
+
err_backend_exit:
|
1875
|
+
if (usbi_backend->exit)
|
1876
|
+
usbi_backend->exit();
|
1877
|
+
err_free_ctx:
|
1878
|
+
if (ctx == usbi_default_context)
|
1879
|
+
usbi_default_context = NULL;
|
1880
|
+
|
1881
|
+
usbi_mutex_static_lock(&active_contexts_lock);
|
1882
|
+
list_del (&ctx->list);
|
1883
|
+
usbi_mutex_static_unlock(&active_contexts_lock);
|
1884
|
+
|
1885
|
+
usbi_mutex_lock(&ctx->usb_devs_lock);
|
1886
|
+
list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
|
1887
|
+
list_del(&dev->list);
|
1888
|
+
libusb_unref_device(dev);
|
1889
|
+
}
|
1890
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
1891
|
+
|
1694
1892
|
usbi_mutex_destroy(&ctx->open_devs_lock);
|
1695
1893
|
usbi_mutex_destroy(&ctx->usb_devs_lock);
|
1696
|
-
|
1894
|
+
usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
|
1895
|
+
|
1697
1896
|
free(ctx);
|
1698
1897
|
err_unlock:
|
1699
1898
|
usbi_mutex_static_unlock(&default_context_lock);
|
@@ -1707,13 +1906,15 @@ err_unlock:
|
|
1707
1906
|
*/
|
1708
1907
|
void API_EXPORTED libusb_exit(struct libusb_context *ctx)
|
1709
1908
|
{
|
1909
|
+
struct libusb_device *dev, *next;
|
1910
|
+
|
1710
1911
|
usbi_dbg("");
|
1711
1912
|
USBI_GET_CONTEXT(ctx);
|
1712
1913
|
|
1713
1914
|
/* if working with default context, only actually do the deinitialization
|
1714
1915
|
* if we're the last user */
|
1916
|
+
usbi_mutex_static_lock(&default_context_lock);
|
1715
1917
|
if (ctx == usbi_default_context) {
|
1716
|
-
usbi_mutex_static_lock(&default_context_lock);
|
1717
1918
|
if (--default_context_refcnt > 0) {
|
1718
1919
|
usbi_dbg("not destroying default context");
|
1719
1920
|
usbi_mutex_static_unlock(&default_context_lock);
|
@@ -1721,11 +1922,27 @@ void API_EXPORTED libusb_exit(struct libusb_context *ctx)
|
|
1721
1922
|
}
|
1722
1923
|
usbi_dbg("destroying default context");
|
1723
1924
|
usbi_default_context = NULL;
|
1724
|
-
usbi_mutex_static_unlock(&default_context_lock);
|
1725
1925
|
}
|
1926
|
+
usbi_mutex_static_unlock(&default_context_lock);
|
1726
1927
|
|
1727
|
-
|
1728
|
-
|
1928
|
+
usbi_mutex_static_lock(&active_contexts_lock);
|
1929
|
+
list_del (&ctx->list);
|
1930
|
+
usbi_mutex_static_unlock(&active_contexts_lock);
|
1931
|
+
|
1932
|
+
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
|
1933
|
+
usbi_hotplug_deregister_all(ctx);
|
1934
|
+
usbi_mutex_lock(&ctx->usb_devs_lock);
|
1935
|
+
list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
|
1936
|
+
list_del(&dev->list);
|
1937
|
+
libusb_unref_device(dev);
|
1938
|
+
}
|
1939
|
+
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
/* a few sanity checks. don't bother with locking because unless
|
1943
|
+
* there is an application bug, nobody will be accessing these. */
|
1944
|
+
if (!list_empty(&ctx->usb_devs))
|
1945
|
+
usbi_warn(ctx, "some libusb_devices were leaked");
|
1729
1946
|
if (!list_empty(&ctx->open_devs))
|
1730
1947
|
usbi_warn(ctx, "application left some devices open");
|
1731
1948
|
|
@@ -1735,20 +1952,29 @@ void API_EXPORTED libusb_exit(struct libusb_context *ctx)
|
|
1735
1952
|
|
1736
1953
|
usbi_mutex_destroy(&ctx->open_devs_lock);
|
1737
1954
|
usbi_mutex_destroy(&ctx->usb_devs_lock);
|
1955
|
+
usbi_mutex_destroy(&ctx->hotplug_cbs_lock);
|
1738
1956
|
free(ctx);
|
1739
1957
|
}
|
1740
1958
|
|
1741
1959
|
/** \ingroup misc
|
1742
1960
|
* Check at runtime if the loaded library has a given capability.
|
1961
|
+
* This call should be performed after \ref libusb_init(), to ensure the
|
1962
|
+
* backend has updated its capability set.
|
1743
1963
|
*
|
1744
1964
|
* \param capability the \ref libusb_capability to check for
|
1745
|
-
* \returns
|
1965
|
+
* \returns nonzero if the running library has the capability, 0 otherwise
|
1746
1966
|
*/
|
1747
1967
|
int API_EXPORTED libusb_has_capability(uint32_t capability)
|
1748
1968
|
{
|
1749
1969
|
switch (capability) {
|
1750
1970
|
case LIBUSB_CAP_HAS_CAPABILITY:
|
1751
1971
|
return 1;
|
1972
|
+
case LIBUSB_CAP_HAS_HOTPLUG:
|
1973
|
+
return !(usbi_backend->get_device_list);
|
1974
|
+
case LIBUSB_CAP_HAS_HID_ACCESS:
|
1975
|
+
return (usbi_backend->caps & USBI_CAP_HAS_HID_ACCESS);
|
1976
|
+
case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER:
|
1977
|
+
return (usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER);
|
1752
1978
|
}
|
1753
1979
|
return 0;
|
1754
1980
|
}
|
@@ -1789,7 +2015,13 @@ int usbi_gettimeofday(struct timeval *tp, void *tzp)
|
|
1789
2015
|
UNUSED(tzp);
|
1790
2016
|
|
1791
2017
|
if(tp) {
|
2018
|
+
#if defined(OS_WINCE)
|
2019
|
+
SYSTEMTIME st;
|
2020
|
+
GetSystemTime(&st);
|
2021
|
+
SystemTimeToFileTime(&st, &_now.ft);
|
2022
|
+
#else
|
1792
2023
|
GetSystemTimeAsFileTime (&_now.ft);
|
2024
|
+
#endif
|
1793
2025
|
tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 );
|
1794
2026
|
tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
|
1795
2027
|
}
|
@@ -1799,12 +2031,51 @@ int usbi_gettimeofday(struct timeval *tp, void *tzp)
|
|
1799
2031
|
}
|
1800
2032
|
#endif
|
1801
2033
|
|
2034
|
+
static void usbi_log_str(struct libusb_context *ctx,
|
2035
|
+
enum libusb_log_level level, const char * str)
|
2036
|
+
{
|
2037
|
+
#if defined(USE_SYSTEM_LOGGING_FACILITY)
|
2038
|
+
#if defined(OS_WINDOWS) || defined(OS_WINCE)
|
2039
|
+
/* Windows CE only supports the Unicode version of OutputDebugString. */
|
2040
|
+
WCHAR wbuf[USBI_MAX_LOG_LEN];
|
2041
|
+
MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf));
|
2042
|
+
OutputDebugStringW(wbuf);
|
2043
|
+
#elif defined(__ANDROID__)
|
2044
|
+
int priority = ANDROID_LOG_UNKNOWN;
|
2045
|
+
switch (level) {
|
2046
|
+
case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break;
|
2047
|
+
case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break;
|
2048
|
+
case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break;
|
2049
|
+
case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break;
|
2050
|
+
}
|
2051
|
+
__android_log_write(priority, "libusb", str);
|
2052
|
+
#elif defined(HAVE_SYSLOG_FUNC)
|
2053
|
+
int syslog_level = LOG_INFO;
|
2054
|
+
switch (level) {
|
2055
|
+
case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break;
|
2056
|
+
case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break;
|
2057
|
+
case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break;
|
2058
|
+
case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break;
|
2059
|
+
}
|
2060
|
+
syslog(syslog_level, "%s", str);
|
2061
|
+
#else /* All of gcc, Clang, XCode seem to use #warning */
|
2062
|
+
#warning System logging is not supported on this platform. Logging to stderr will be used instead.
|
2063
|
+
fputs(str, stderr);
|
2064
|
+
#endif
|
2065
|
+
#else
|
2066
|
+
fputs(str, stderr);
|
2067
|
+
#endif /* USE_SYSTEM_LOGGING_FACILITY */
|
2068
|
+
UNUSED(ctx);
|
2069
|
+
UNUSED(level);
|
2070
|
+
}
|
2071
|
+
|
1802
2072
|
void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
|
1803
2073
|
const char *function, const char *format, va_list args)
|
1804
2074
|
{
|
1805
2075
|
const char *prefix = "";
|
2076
|
+
char buf[USBI_MAX_LOG_LEN];
|
1806
2077
|
struct timeval now;
|
1807
|
-
int global_debug;
|
2078
|
+
int global_debug, header_len, text_len;
|
1808
2079
|
static int has_debug_header_been_displayed = 0;
|
1809
2080
|
|
1810
2081
|
#ifdef ENABLE_DEBUG_LOGGING
|
@@ -1828,8 +2099,8 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
|
|
1828
2099
|
usbi_gettimeofday(&now, NULL);
|
1829
2100
|
if ((global_debug) && (!has_debug_header_been_displayed)) {
|
1830
2101
|
has_debug_header_been_displayed = 1;
|
1831
|
-
|
1832
|
-
|
2102
|
+
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>\n");
|
2103
|
+
usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------\n");
|
1833
2104
|
}
|
1834
2105
|
if (now.tv_usec < timestamp_origin.tv_usec) {
|
1835
2106
|
now.tv_sec--;
|
@@ -1852,22 +2123,42 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
|
|
1852
2123
|
prefix = "debug";
|
1853
2124
|
break;
|
1854
2125
|
case LIBUSB_LOG_LEVEL_NONE:
|
1855
|
-
|
2126
|
+
return;
|
1856
2127
|
default:
|
1857
2128
|
prefix = "unknown";
|
1858
2129
|
break;
|
1859
2130
|
}
|
1860
2131
|
|
1861
2132
|
if (global_debug) {
|
1862
|
-
|
2133
|
+
header_len = snprintf(buf, sizeof(buf),
|
2134
|
+
"[%2d.%06d] [%08x] libusbx: %s [%s] ",
|
1863
2135
|
(int)now.tv_sec, (int)now.tv_usec, usbi_get_tid(), prefix, function);
|
1864
2136
|
} else {
|
1865
|
-
|
2137
|
+
header_len = snprintf(buf, sizeof(buf),
|
2138
|
+
"libusbx: %s [%s] ", prefix, function);
|
1866
2139
|
}
|
1867
2140
|
|
1868
|
-
|
2141
|
+
if (header_len < 0 || header_len >= sizeof(buf)) {
|
2142
|
+
/* Somehow snprintf failed to write to the buffer,
|
2143
|
+
* remove the header so something useful is output. */
|
2144
|
+
header_len = 0;
|
2145
|
+
}
|
2146
|
+
/* Make sure buffer is NUL terminated */
|
2147
|
+
buf[header_len] = '\0';
|
2148
|
+
text_len = vsnprintf(buf + header_len, sizeof(buf) - header_len,
|
2149
|
+
format, args);
|
2150
|
+
if (text_len < 0 || text_len + header_len >= sizeof(buf)) {
|
2151
|
+
/* Truncated log output. On some platforms a -1 return value means
|
2152
|
+
* that the output was truncated. */
|
2153
|
+
text_len = sizeof(buf) - header_len;
|
2154
|
+
}
|
2155
|
+
if (header_len + text_len + sizeof(USBI_LOG_LINE_END) >= sizeof(buf)) {
|
2156
|
+
/* Need to truncate the text slightly to fit on the terminator. */
|
2157
|
+
text_len -= (header_len + text_len + sizeof(USBI_LOG_LINE_END)) - sizeof(buf);
|
2158
|
+
}
|
2159
|
+
strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
|
1869
2160
|
|
1870
|
-
|
2161
|
+
usbi_log_str(ctx, level, buf);
|
1871
2162
|
}
|
1872
2163
|
|
1873
2164
|
void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
|
@@ -1881,7 +2172,7 @@ void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
|
|
1881
2172
|
}
|
1882
2173
|
|
1883
2174
|
/** \ingroup misc
|
1884
|
-
* Returns a constant NULL-terminated string with the ASCII name of a
|
2175
|
+
* Returns a constant NULL-terminated string with the ASCII name of a libusbx
|
1885
2176
|
* error or transfer status code. The caller must not free() the returned
|
1886
2177
|
* string.
|
1887
2178
|
*
|