libusb 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
*
|