usb 1.7.2 → 1.8.1-libusb.4
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/.gitmodules +1 -1
- package/Readme.md +2 -2
- package/binding.gyp +2 -2
- package/libusb/.private/pre-commit.sh +7 -1
- package/libusb/.travis.yml +49 -0
- package/libusb/AUTHORS +44 -3
- package/libusb/Brewfile +4 -0
- package/libusb/ChangeLog +74 -2
- package/libusb/README.md +32 -0
- package/libusb/TODO +1 -1
- package/libusb/Xcode/common.xcconfig +12 -0
- package/libusb/Xcode/config.h +25 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +75 -0
- package/libusb/appveyor.yml +41 -0
- package/libusb/appveyor_cygwin.bat +11 -0
- package/libusb/appveyor_minGW.bat +19 -0
- package/libusb/autogen.sh +1 -1
- package/libusb/bootstrap.sh +3 -16
- package/libusb/configure.ac +108 -80
- package/libusb/doc/doxygen.cfg.in +1785 -739
- package/libusb/examples/Makefile.am +1 -1
- package/libusb/examples/dpfp.c +3 -1
- package/libusb/examples/dpfp_threaded.c +23 -10
- package/libusb/examples/ezusb.c +3 -3
- package/libusb/examples/ezusb.h +2 -2
- package/libusb/examples/fxload.c +31 -9
- package/libusb/examples/hotplugtest.c +35 -7
- package/libusb/examples/listdevs.c +3 -1
- package/libusb/examples/sam3u_benchmark.c +3 -3
- package/libusb/examples/testlibusb.c +277 -0
- package/libusb/examples/xusb.c +40 -34
- package/libusb/libusb/Makefile.am +49 -23
- package/libusb/libusb/core.c +855 -457
- package/libusb/libusb/descriptor.c +72 -78
- package/libusb/libusb/hotplug.c +122 -76
- package/libusb/libusb/hotplug.h +42 -25
- package/libusb/libusb/io.c +625 -390
- package/libusb/libusb/libusb-1.0.def +12 -0
- package/libusb/libusb/libusb.h +218 -150
- package/libusb/libusb/libusbi.h +346 -176
- package/libusb/libusb/os/darwin_usb.c +604 -319
- package/libusb/libusb/os/darwin_usb.h +61 -20
- package/libusb/libusb/os/haiku_pollfs.cpp +367 -0
- package/libusb/libusb/os/haiku_usb.h +113 -0
- package/libusb/libusb/os/haiku_usb_backend.cpp +533 -0
- package/libusb/libusb/os/haiku_usb_raw.cpp +267 -0
- package/libusb/libusb/os/haiku_usb_raw.h +188 -0
- package/libusb/libusb/os/linux_netlink.c +186 -146
- package/libusb/libusb/os/linux_udev.c +36 -14
- package/libusb/libusb/os/linux_usbfs.c +426 -225
- package/libusb/libusb/os/linux_usbfs.h +5 -3
- package/libusb/libusb/os/netbsd_usb.c +21 -77
- package/libusb/libusb/os/openbsd_usb.c +32 -115
- package/libusb/libusb/os/poll_posix.c +38 -5
- package/libusb/libusb/os/poll_posix.h +3 -0
- package/libusb/libusb/os/poll_windows.c +277 -626
- package/libusb/libusb/os/poll_windows.h +11 -44
- package/libusb/libusb/os/sunos_usb.c +1695 -0
- package/libusb/libusb/os/sunos_usb.h +80 -0
- package/libusb/libusb/os/threads_posix.c +24 -26
- package/libusb/libusb/os/threads_posix.h +73 -21
- package/libusb/libusb/os/threads_windows.c +71 -157
- package/libusb/libusb/os/threads_windows.h +68 -44
- package/libusb/libusb/os/wince_usb.c +276 -420
- package/libusb/libusb/os/wince_usb.h +23 -28
- package/libusb/libusb/os/windows_common.h +78 -58
- package/libusb/libusb/os/windows_nt_common.c +1010 -0
- package/libusb/libusb/os/windows_nt_common.h +110 -0
- package/libusb/libusb/os/windows_nt_shared_types.h +147 -0
- package/libusb/libusb/os/windows_usbdk.c +830 -0
- package/libusb/libusb/os/windows_usbdk.h +103 -0
- package/libusb/libusb/os/windows_winusb.c +4391 -0
- package/libusb/libusb/os/windows_winusb.h +783 -0
- package/libusb/libusb/strerror.c +41 -7
- package/libusb/libusb/sync.c +41 -13
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/libusb-1.0.pc.in +1 -1
- package/libusb/msvc/appveyor.bat +27 -0
- package/libusb/msvc/config.h +5 -4
- package/libusb/msvc/ddk_build.cmd +87 -43
- package/libusb/msvc/fxload_2010.vcxproj +24 -104
- package/libusb/msvc/fxload_2012.vcxproj +24 -107
- package/libusb/msvc/fxload_2013.vcxproj +24 -107
- package/libusb/msvc/fxload_2015.vcxproj +91 -0
- package/libusb/msvc/fxload_2017.vcxproj +114 -0
- package/libusb/msvc/fxload_sources +1 -1
- package/libusb/msvc/getopt_2010.vcxproj +16 -75
- package/libusb/msvc/getopt_2012.vcxproj +16 -79
- package/libusb/msvc/getopt_2013.vcxproj +16 -79
- package/libusb/msvc/getopt_2015.vcxproj +73 -0
- package/libusb/msvc/getopt_2017.vcxproj +98 -0
- package/libusb/msvc/getopt_sources +6 -2
- package/libusb/msvc/hotplugtest_2010.vcxproj +18 -99
- package/libusb/msvc/hotplugtest_2012.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2013.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2015.vcxproj +83 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +106 -0
- package/libusb/msvc/hotplugtest_sources +1 -1
- package/libusb/msvc/libusb_2005.sln +20 -20
- package/libusb/msvc/libusb_2010.sln +57 -46
- package/libusb/msvc/libusb_2012.sln +57 -46
- package/libusb/msvc/libusb_2013.sln +57 -50
- package/libusb/msvc/libusb_2015.sln +59 -52
- package/libusb/msvc/libusb_2017.sln +186 -0
- package/libusb/msvc/libusb_dll.dsp +2 -2
- package/libusb/msvc/libusb_dll_2005.vcproj +30 -2
- package/libusb/msvc/libusb_dll_2010.vcxproj +26 -90
- package/libusb/msvc/libusb_dll_2012.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2013.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2015.vcxproj +107 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +134 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +9 -1
- package/libusb/msvc/libusb_sources +10 -5
- package/libusb/msvc/libusb_static.dsp +2 -2
- package/libusb/msvc/libusb_static_2005.vcproj +32 -4
- package/libusb/msvc/libusb_static_2010.vcxproj +24 -83
- package/libusb/msvc/libusb_static_2012.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2013.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2015.vcxproj +98 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +117 -0
- package/libusb/msvc/libusb_static_wince.vcproj +20 -26
- package/libusb/msvc/libusb_wince.sln +88 -88
- package/libusb/msvc/listdevs_2010.vcxproj +16 -99
- package/libusb/msvc/listdevs_2012.vcxproj +16 -102
- package/libusb/msvc/listdevs_2013.vcxproj +16 -102
- package/libusb/msvc/listdevs_2015.vcxproj +83 -0
- package/libusb/msvc/listdevs_2017.vcxproj +106 -0
- package/libusb/msvc/listdevs_sources +2 -1
- package/libusb/msvc/stress_2010.vcxproj +20 -101
- package/libusb/msvc/stress_2012.vcxproj +20 -104
- package/libusb/msvc/stress_2013.vcxproj +20 -104
- package/libusb/msvc/stress_2015.vcxproj +87 -0
- package/libusb/msvc/stress_2017.vcxproj +110 -0
- package/libusb/msvc/stress_sources +21 -0
- package/libusb/msvc/testlibusb_2010.vcxproj +82 -0
- package/libusb/msvc/testlibusb_2012.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +106 -0
- package/libusb/msvc/testlibusb_sources +20 -0
- package/libusb/msvc/xusb_2010.vcxproj +17 -98
- package/libusb/msvc/xusb_2012.vcxproj +17 -101
- package/libusb/msvc/xusb_2013.vcxproj +17 -101
- package/libusb/msvc/xusb_2015.vcxproj +83 -0
- package/libusb/msvc/xusb_2017.vcxproj +106 -0
- package/libusb/msvc/xusb_sources +1 -1
- package/libusb/tests/stress.c +2 -2
- package/libusb/tests/testlib.c +0 -4
- package/libusb/travis-autogen.sh +39 -0
- package/libusb.gypi +13 -2
- package/package.json +20 -11
- 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 +1 -1
- package/usb.js +51 -5
- package/.github/workflows/prebuild.yml +0 -49
- package/libusb/INSTALL +0 -234
- package/libusb/README +0 -28
- package/libusb/libusb/os/windows_usb.c +0 -5347
- package/libusb/libusb/os/windows_usb.h +0 -971
- package/libusb/msvc/fxload_2010.vcxproj.filters +0 -25
- package/libusb/msvc/fxload_2012.vcxproj.filters +0 -25
- package/libusb/msvc/getopt_2010.vcxproj.filters +0 -26
- package/libusb/msvc/getopt_2012.vcxproj.filters +0 -26
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +0 -14
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +0 -14
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +0 -81
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +0 -84
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +0 -74
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +0 -74
- package/libusb/msvc/listdevs_2010.vcxproj.filters +0 -14
- package/libusb/msvc/listdevs_2012.vcxproj.filters +0 -14
- package/libusb/msvc/stress_2010.vcxproj.filters +0 -25
- package/libusb/msvc/stress_2012.vcxproj.filters +0 -25
- package/libusb/msvc/xusb_2010.vcxproj.filters +0 -14
- package/libusb/msvc/xusb_2012.vcxproj.filters +0 -14
package/libusb/examples/dpfp.c
CHANGED
|
@@ -411,13 +411,15 @@ static int alloc_transfers(void)
|
|
|
411
411
|
|
|
412
412
|
static void sighandler(int signum)
|
|
413
413
|
{
|
|
414
|
+
(void)signum;
|
|
415
|
+
|
|
414
416
|
do_exit = 1;
|
|
415
417
|
}
|
|
416
418
|
|
|
417
419
|
int main(void)
|
|
418
420
|
{
|
|
419
421
|
struct sigaction sigact;
|
|
420
|
-
int r
|
|
422
|
+
int r;
|
|
421
423
|
|
|
422
424
|
r = libusb_init(NULL);
|
|
423
425
|
if (r < 0) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libusb example program to manipulate U.are.U 4000B fingerprint scanner.
|
|
3
3
|
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
|
|
4
|
+
* Copyright © 2016 Nathan Hjelm <hjelmn@mac.com>
|
|
4
5
|
*
|
|
5
6
|
* Basic image capture program only, does not consider the powerup quirks or
|
|
6
7
|
* the fact that image encryption may be enabled. Not expected to work
|
|
@@ -23,10 +24,12 @@
|
|
|
23
24
|
|
|
24
25
|
#include <errno.h>
|
|
25
26
|
#include <pthread.h>
|
|
27
|
+
#include <semaphore.h>
|
|
26
28
|
#include <signal.h>
|
|
27
29
|
#include <string.h>
|
|
28
30
|
#include <stdio.h>
|
|
29
31
|
#include <stdlib.h>
|
|
32
|
+
#include <fcntl.h>
|
|
30
33
|
|
|
31
34
|
#include "libusb.h"
|
|
32
35
|
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
|
|
37
40
|
#define USB_RQ 0x04
|
|
38
41
|
#define INTR_LENGTH 64
|
|
42
|
+
#define SEM_NAME "/org.libusb.example.dpfp_threaded"
|
|
39
43
|
|
|
40
44
|
enum {
|
|
41
45
|
MODE_INIT = 0x00,
|
|
@@ -64,16 +68,15 @@ static unsigned char irqbuf[INTR_LENGTH];
|
|
|
64
68
|
static struct libusb_transfer *img_transfer = NULL;
|
|
65
69
|
static struct libusb_transfer *irq_transfer = NULL;
|
|
66
70
|
static int img_idx = 0;
|
|
67
|
-
static
|
|
71
|
+
static volatile sig_atomic_t do_exit = 0;
|
|
68
72
|
|
|
69
73
|
static pthread_t poll_thread;
|
|
70
|
-
static
|
|
71
|
-
static pthread_mutex_t exit_cond_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
74
|
+
static sem_t *exit_sem;
|
|
72
75
|
|
|
73
|
-
static void request_exit(
|
|
76
|
+
static void request_exit(sig_atomic_t code)
|
|
74
77
|
{
|
|
75
78
|
do_exit = code;
|
|
76
|
-
|
|
79
|
+
sem_post(exit_sem);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
static void *poll_thread_main(void *arg)
|
|
@@ -81,6 +84,8 @@ static void *poll_thread_main(void *arg)
|
|
|
81
84
|
int r = 0;
|
|
82
85
|
printf("poll thread running\n");
|
|
83
86
|
|
|
87
|
+
(void)arg;
|
|
88
|
+
|
|
84
89
|
while (!do_exit) {
|
|
85
90
|
struct timeval tv = { 1, 0 };
|
|
86
91
|
r = libusb_handle_events_timeout(NULL, &tv);
|
|
@@ -438,6 +443,8 @@ static int alloc_transfers(void)
|
|
|
438
443
|
|
|
439
444
|
static void sighandler(int signum)
|
|
440
445
|
{
|
|
446
|
+
(void)signum;
|
|
447
|
+
|
|
441
448
|
request_exit(1);
|
|
442
449
|
}
|
|
443
450
|
|
|
@@ -446,6 +453,15 @@ int main(void)
|
|
|
446
453
|
struct sigaction sigact;
|
|
447
454
|
int r = 1;
|
|
448
455
|
|
|
456
|
+
exit_sem = sem_open (SEM_NAME, O_CREAT, 0);
|
|
457
|
+
if (!exit_sem) {
|
|
458
|
+
fprintf(stderr, "failed to initialise semaphore error %d", errno);
|
|
459
|
+
exit(1);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* only using this semaphore in this process so go ahead and unlink it now */
|
|
463
|
+
sem_unlink (SEM_NAME);
|
|
464
|
+
|
|
449
465
|
r = libusb_init(NULL);
|
|
450
466
|
if (r < 0) {
|
|
451
467
|
fprintf(stderr, "failed to initialise libusb\n");
|
|
@@ -500,11 +516,8 @@ int main(void)
|
|
|
500
516
|
goto out_deinit;
|
|
501
517
|
}
|
|
502
518
|
|
|
503
|
-
while (!do_exit)
|
|
504
|
-
|
|
505
|
-
pthread_cond_wait(&exit_cond, &exit_cond_lock);
|
|
506
|
-
pthread_mutex_unlock(&exit_cond_lock);
|
|
507
|
-
}
|
|
519
|
+
while (!do_exit)
|
|
520
|
+
sem_wait(exit_sem);
|
|
508
521
|
|
|
509
522
|
printf("shutting down...\n");
|
|
510
523
|
pthread_join(poll_thread, NULL);
|
package/libusb/examples/ezusb.c
CHANGED
|
@@ -133,7 +133,7 @@ static int ezusb_write(libusb_device_handle *device, const char *label,
|
|
|
133
133
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
|
134
134
|
opcode, addr & 0xFFFF, addr >> 16,
|
|
135
135
|
(unsigned char*)data, (uint16_t)len, 1000);
|
|
136
|
-
if (status != len) {
|
|
136
|
+
if (status != (signed)len) {
|
|
137
137
|
if (status < 0)
|
|
138
138
|
logerror("%s: %s\n", label, libusb_error_name(status));
|
|
139
139
|
else
|
|
@@ -156,7 +156,7 @@ static int ezusb_read(libusb_device_handle *device, const char *label,
|
|
|
156
156
|
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
|
|
157
157
|
opcode, addr & 0xFFFF, addr >> 16,
|
|
158
158
|
(unsigned char*)data, (uint16_t)len, 1000);
|
|
159
|
-
if (status != len) {
|
|
159
|
+
if (status != (signed)len) {
|
|
160
160
|
if (status < 0)
|
|
161
161
|
logerror("%s: %s\n", label, libusb_error_name(status));
|
|
162
162
|
else
|
|
@@ -299,7 +299,7 @@ static int parse_ihex(FILE *image, void *context,
|
|
|
299
299
|
/* Read the target offset (address up to 64KB) */
|
|
300
300
|
tmp = buf[7];
|
|
301
301
|
buf[7] = 0;
|
|
302
|
-
off = (int)strtoul(buf+3, NULL, 16);
|
|
302
|
+
off = (unsigned int)strtoul(buf+3, NULL, 16);
|
|
303
303
|
buf[7] = tmp;
|
|
304
304
|
|
|
305
305
|
/* Initialize data_addr */
|
package/libusb/examples/ezusb.h
CHANGED
package/libusb/examples/fxload.c
CHANGED
|
@@ -65,8 +65,9 @@ void logerror(const char *format, ...)
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
static int print_usage(int error_code) {
|
|
68
|
-
fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] -i firmware\n");
|
|
68
|
+
fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] [-s loader] -i firmware\n");
|
|
69
69
|
fprintf(stderr, " -i <path> -- Firmware to upload\n");
|
|
70
|
+
fprintf(stderr, " -s <path> -- Second stage loader\n");
|
|
70
71
|
fprintf(stderr, " -t <type> -- Target type: an21, fx, fx2, fx2lp, fx3\n");
|
|
71
72
|
fprintf(stderr, " -d <vid:pid> -- Target device, as an USB VID:PID\n");
|
|
72
73
|
fprintf(stderr, " -p <bus,addr> -- Target device, as a libusb bus number and device address path\n");
|
|
@@ -88,14 +89,15 @@ int main(int argc, char*argv[])
|
|
|
88
89
|
const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
|
|
89
90
|
const char *ext, *img_name[] = IMG_TYPE_NAMES;
|
|
90
91
|
int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
|
|
91
|
-
int
|
|
92
|
+
int opt, status;
|
|
93
|
+
unsigned int i, j;
|
|
92
94
|
unsigned vid = 0, pid = 0;
|
|
93
95
|
unsigned busnum = 0, devaddr = 0, _busnum, _devaddr;
|
|
94
96
|
libusb_device *dev, **devs;
|
|
95
97
|
libusb_device_handle *device = NULL;
|
|
96
98
|
struct libusb_device_descriptor desc;
|
|
97
99
|
|
|
98
|
-
while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:t:")) != EOF)
|
|
100
|
+
while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:s:S:t:")) != EOF)
|
|
99
101
|
switch (opt) {
|
|
100
102
|
|
|
101
103
|
case 'd':
|
|
@@ -119,6 +121,11 @@ int main(int argc, char*argv[])
|
|
|
119
121
|
path[FIRMWARE] = optarg;
|
|
120
122
|
break;
|
|
121
123
|
|
|
124
|
+
case 's':
|
|
125
|
+
case 'S':
|
|
126
|
+
path[LOADER] = optarg;
|
|
127
|
+
break;
|
|
128
|
+
|
|
122
129
|
case 'V':
|
|
123
130
|
puts(FXLOAD_VERSION);
|
|
124
131
|
return 0;
|
|
@@ -171,7 +178,7 @@ int main(int argc, char*argv[])
|
|
|
171
178
|
logerror("libusb_init() failed: %s\n", libusb_error_name(status));
|
|
172
179
|
return -1;
|
|
173
180
|
}
|
|
174
|
-
|
|
181
|
+
libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, verbose);
|
|
175
182
|
|
|
176
183
|
/* try to pick up missing parameters from known devices */
|
|
177
184
|
if ((type == NULL) || (device_id == NULL) || (device_path != NULL)) {
|
|
@@ -224,15 +231,16 @@ int main(int argc, char*argv[])
|
|
|
224
231
|
}
|
|
225
232
|
if (dev == NULL) {
|
|
226
233
|
libusb_free_device_list(devs, 1);
|
|
234
|
+
libusb_exit(NULL);
|
|
227
235
|
logerror("could not find a known device - please specify type and/or vid:pid and/or bus,dev\n");
|
|
228
236
|
return print_usage(-1);
|
|
229
237
|
}
|
|
230
238
|
status = libusb_open(dev, &device);
|
|
239
|
+
libusb_free_device_list(devs, 1);
|
|
231
240
|
if (status < 0) {
|
|
232
241
|
logerror("libusb_open() failed: %s\n", libusb_error_name(status));
|
|
233
242
|
goto err;
|
|
234
243
|
}
|
|
235
|
-
libusb_free_device_list(devs, 1);
|
|
236
244
|
} else if (device_id != NULL) {
|
|
237
245
|
device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
|
|
238
246
|
if (device == NULL) {
|
|
@@ -245,6 +253,7 @@ int main(int argc, char*argv[])
|
|
|
245
253
|
libusb_set_auto_detach_kernel_driver(device, 1);
|
|
246
254
|
status = libusb_claim_interface(device, 0);
|
|
247
255
|
if (status != LIBUSB_SUCCESS) {
|
|
256
|
+
libusb_close(device);
|
|
248
257
|
logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
|
|
249
258
|
goto err;
|
|
250
259
|
}
|
|
@@ -272,10 +281,23 @@ int main(int argc, char*argv[])
|
|
|
272
281
|
logerror("%s: type %s\n", path[i], img_name[img_type[i]]);
|
|
273
282
|
}
|
|
274
283
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
284
|
+
if (path[LOADER] == NULL) {
|
|
285
|
+
/* single stage, put into internal memory */
|
|
286
|
+
if (verbose > 1)
|
|
287
|
+
logerror("single stage: load on-chip memory\n");
|
|
288
|
+
status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);
|
|
289
|
+
} else {
|
|
290
|
+
/* two-stage, put loader into internal memory */
|
|
291
|
+
if (verbose > 1)
|
|
292
|
+
logerror("1st stage: load 2nd stage loader\n");
|
|
293
|
+
status = ezusb_load_ram(device, path[LOADER], fx_type, img_type[LOADER], 0);
|
|
294
|
+
if (status == 0) {
|
|
295
|
+
/* two-stage, put firmware into internal memory */
|
|
296
|
+
if (verbose > 1)
|
|
297
|
+
logerror("2nd state: load on-chip memory\n");
|
|
298
|
+
status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 1);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
279
301
|
|
|
280
302
|
libusb_release_interface(device, 0);
|
|
281
303
|
libusb_close(device);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
|
2
2
|
/*
|
|
3
3
|
* libusb example program for hotplug API
|
|
4
|
-
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.
|
|
4
|
+
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
|
|
5
5
|
*
|
|
6
6
|
* This library is free software; you can redistribute it and/or
|
|
7
7
|
* modify it under the terms of the GNU Lesser General Public
|
|
@@ -24,13 +24,18 @@
|
|
|
24
24
|
#include "libusb.h"
|
|
25
25
|
|
|
26
26
|
int done = 0;
|
|
27
|
-
libusb_device_handle *handle;
|
|
27
|
+
libusb_device_handle *handle = NULL;
|
|
28
28
|
|
|
29
29
|
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
|
30
30
|
{
|
|
31
31
|
struct libusb_device_descriptor desc;
|
|
32
32
|
int rc;
|
|
33
33
|
|
|
34
|
+
(void)ctx;
|
|
35
|
+
(void)dev;
|
|
36
|
+
(void)event;
|
|
37
|
+
(void)user_data;
|
|
38
|
+
|
|
34
39
|
rc = libusb_get_device_descriptor(dev, &desc);
|
|
35
40
|
if (LIBUSB_SUCCESS != rc) {
|
|
36
41
|
fprintf (stderr, "Error getting device descriptor\n");
|
|
@@ -38,7 +43,15 @@ static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev,
|
|
|
38
43
|
|
|
39
44
|
printf ("Device attached: %04x:%04x\n", desc.idVendor, desc.idProduct);
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
if (handle) {
|
|
47
|
+
libusb_close (handle);
|
|
48
|
+
handle = NULL;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
rc = libusb_open (dev, &handle);
|
|
52
|
+
if (LIBUSB_SUCCESS != rc) {
|
|
53
|
+
fprintf (stderr, "Error opening device\n");
|
|
54
|
+
}
|
|
42
55
|
|
|
43
56
|
done++;
|
|
44
57
|
|
|
@@ -47,11 +60,20 @@ static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev,
|
|
|
47
60
|
|
|
48
61
|
static int LIBUSB_CALL hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
|
|
49
62
|
{
|
|
63
|
+
(void)ctx;
|
|
64
|
+
(void)dev;
|
|
65
|
+
(void)event;
|
|
66
|
+
(void)user_data;
|
|
67
|
+
|
|
50
68
|
printf ("Device detached\n");
|
|
51
69
|
|
|
52
|
-
|
|
70
|
+
if (handle) {
|
|
71
|
+
libusb_close (handle);
|
|
72
|
+
handle = NULL;
|
|
73
|
+
}
|
|
53
74
|
|
|
54
75
|
done++;
|
|
76
|
+
|
|
55
77
|
return 0;
|
|
56
78
|
}
|
|
57
79
|
|
|
@@ -61,9 +83,9 @@ int main(int argc, char *argv[])
|
|
|
61
83
|
int product_id, vendor_id, class_id;
|
|
62
84
|
int rc;
|
|
63
85
|
|
|
64
|
-
vendor_id = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a;
|
|
65
|
-
product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005;
|
|
66
|
-
class_id = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;
|
|
86
|
+
vendor_id = (argc > 1) ? (int)strtol (argv[1], NULL, 0) : 0x045a;
|
|
87
|
+
product_id = (argc > 2) ? (int)strtol (argv[2], NULL, 0) : 0x5005;
|
|
88
|
+
class_id = (argc > 3) ? (int)strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;
|
|
67
89
|
|
|
68
90
|
rc = libusb_init (NULL);
|
|
69
91
|
if (rc < 0)
|
|
@@ -100,5 +122,11 @@ int main(int argc, char *argv[])
|
|
|
100
122
|
printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc));
|
|
101
123
|
}
|
|
102
124
|
|
|
125
|
+
if (handle) {
|
|
126
|
+
libusb_close (handle);
|
|
127
|
+
}
|
|
128
|
+
|
|
103
129
|
libusb_exit (NULL);
|
|
130
|
+
|
|
131
|
+
return EXIT_SUCCESS;
|
|
104
132
|
}
|
|
@@ -42,7 +42,7 @@ static struct timeval tv_start;
|
|
|
42
42
|
|
|
43
43
|
static void LIBUSB_CALL cb_xfr(struct libusb_transfer *xfr)
|
|
44
44
|
{
|
|
45
|
-
|
|
45
|
+
int i;
|
|
46
46
|
|
|
47
47
|
if (xfr->status != LIBUSB_TRANSFER_COMPLETED) {
|
|
48
48
|
fprintf(stderr, "transfer status %d\n", xfr->status);
|
|
@@ -55,11 +55,11 @@ static void LIBUSB_CALL cb_xfr(struct libusb_transfer *xfr)
|
|
|
55
55
|
struct libusb_iso_packet_descriptor *pack = &xfr->iso_packet_desc[i];
|
|
56
56
|
|
|
57
57
|
if (pack->status != LIBUSB_TRANSFER_COMPLETED) {
|
|
58
|
-
fprintf(stderr, "Error: pack %
|
|
58
|
+
fprintf(stderr, "Error: pack %d status %d\n", i, pack->status);
|
|
59
59
|
exit(5);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
printf("pack%
|
|
62
|
+
printf("pack%d length:%u, actual_length:%u\n", i, pack->length, pack->actual_length);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Test suite program based of libusb-0.1-compat testlibusb
|
|
3
|
+
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.ccom>
|
|
4
|
+
*
|
|
5
|
+
* This library is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
* License as published by the Free Software Foundation; either
|
|
8
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This library is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this library; if not, write to the Free Software
|
|
17
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include <stdio.h>
|
|
21
|
+
#include <string.h>
|
|
22
|
+
#include "libusb.h"
|
|
23
|
+
|
|
24
|
+
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
25
|
+
#define snprintf _snprintf
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
int verbose = 0;
|
|
29
|
+
|
|
30
|
+
static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp)
|
|
31
|
+
{
|
|
32
|
+
printf(" USB 3.0 Endpoint Companion:\n");
|
|
33
|
+
printf(" bMaxBurst: %d\n", ep_comp->bMaxBurst);
|
|
34
|
+
printf(" bmAttributes: 0x%02x\n", ep_comp->bmAttributes);
|
|
35
|
+
printf(" wBytesPerInterval: %d\n", ep_comp->wBytesPerInterval);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)
|
|
39
|
+
{
|
|
40
|
+
int i, ret;
|
|
41
|
+
|
|
42
|
+
printf(" Endpoint:\n");
|
|
43
|
+
printf(" bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);
|
|
44
|
+
printf(" bmAttributes: %02xh\n", endpoint->bmAttributes);
|
|
45
|
+
printf(" wMaxPacketSize: %d\n", endpoint->wMaxPacketSize);
|
|
46
|
+
printf(" bInterval: %d\n", endpoint->bInterval);
|
|
47
|
+
printf(" bRefresh: %d\n", endpoint->bRefresh);
|
|
48
|
+
printf(" bSynchAddress: %d\n", endpoint->bSynchAddress);
|
|
49
|
+
|
|
50
|
+
for (i = 0; i < endpoint->extra_length;) {
|
|
51
|
+
if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) {
|
|
52
|
+
struct libusb_ss_endpoint_companion_descriptor *ep_comp;
|
|
53
|
+
|
|
54
|
+
ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);
|
|
55
|
+
if (LIBUSB_SUCCESS != ret) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
print_endpoint_comp(ep_comp);
|
|
60
|
+
|
|
61
|
+
libusb_free_ss_endpoint_companion_descriptor(ep_comp);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
i += endpoint->extra[i];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static void print_altsetting(const struct libusb_interface_descriptor *interface)
|
|
69
|
+
{
|
|
70
|
+
uint8_t i;
|
|
71
|
+
|
|
72
|
+
printf(" Interface:\n");
|
|
73
|
+
printf(" bInterfaceNumber: %d\n", interface->bInterfaceNumber);
|
|
74
|
+
printf(" bAlternateSetting: %d\n", interface->bAlternateSetting);
|
|
75
|
+
printf(" bNumEndpoints: %d\n", interface->bNumEndpoints);
|
|
76
|
+
printf(" bInterfaceClass: %d\n", interface->bInterfaceClass);
|
|
77
|
+
printf(" bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);
|
|
78
|
+
printf(" bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);
|
|
79
|
+
printf(" iInterface: %d\n", interface->iInterface);
|
|
80
|
+
|
|
81
|
+
for (i = 0; i < interface->bNumEndpoints; i++)
|
|
82
|
+
print_endpoint(&interface->endpoint[i]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static void print_2_0_ext_cap(struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap)
|
|
86
|
+
{
|
|
87
|
+
printf(" USB 2.0 Extension Capabilities:\n");
|
|
88
|
+
printf(" bDevCapabilityType: %d\n", usb_2_0_ext_cap->bDevCapabilityType);
|
|
89
|
+
printf(" bmAttributes: 0x%x\n", usb_2_0_ext_cap->bmAttributes);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static void print_ss_usb_cap(struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap)
|
|
93
|
+
{
|
|
94
|
+
printf(" USB 3.0 Capabilities:\n");
|
|
95
|
+
printf(" bDevCapabilityType: %d\n", ss_usb_cap->bDevCapabilityType);
|
|
96
|
+
printf(" bmAttributes: 0x%x\n", ss_usb_cap->bmAttributes);
|
|
97
|
+
printf(" wSpeedSupported: 0x%x\n", ss_usb_cap->wSpeedSupported);
|
|
98
|
+
printf(" bFunctionalitySupport: %d\n", ss_usb_cap->bFunctionalitySupport);
|
|
99
|
+
printf(" bU1devExitLat: %d\n", ss_usb_cap->bU1DevExitLat);
|
|
100
|
+
printf(" bU2devExitLat: %d\n", ss_usb_cap->bU2DevExitLat);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static void print_bos(libusb_device_handle *handle)
|
|
104
|
+
{
|
|
105
|
+
struct libusb_bos_descriptor *bos;
|
|
106
|
+
int ret;
|
|
107
|
+
|
|
108
|
+
ret = libusb_get_bos_descriptor(handle, &bos);
|
|
109
|
+
if (0 > ret) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
printf(" Binary Object Store (BOS):\n");
|
|
114
|
+
printf(" wTotalLength: %d\n", bos->wTotalLength);
|
|
115
|
+
printf(" bNumDeviceCaps: %d\n", bos->bNumDeviceCaps);
|
|
116
|
+
|
|
117
|
+
if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) {
|
|
118
|
+
|
|
119
|
+
struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension;
|
|
120
|
+
ret = libusb_get_usb_2_0_extension_descriptor(NULL, bos->dev_capability[0],&usb_2_0_extension);
|
|
121
|
+
if (0 > ret) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
print_2_0_ext_cap(usb_2_0_extension);
|
|
126
|
+
libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
|
|
130
|
+
|
|
131
|
+
struct libusb_ss_usb_device_capability_descriptor *dev_cap;
|
|
132
|
+
ret = libusb_get_ss_usb_device_capability_descriptor(NULL, bos->dev_capability[0],&dev_cap);
|
|
133
|
+
if (0 > ret) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
print_ss_usb_cap(dev_cap);
|
|
138
|
+
libusb_free_ss_usb_device_capability_descriptor(dev_cap);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
libusb_free_bos_descriptor(bos);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static void print_interface(const struct libusb_interface *interface)
|
|
145
|
+
{
|
|
146
|
+
int i;
|
|
147
|
+
|
|
148
|
+
for (i = 0; i < interface->num_altsetting; i++)
|
|
149
|
+
print_altsetting(&interface->altsetting[i]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static void print_configuration(struct libusb_config_descriptor *config)
|
|
153
|
+
{
|
|
154
|
+
uint8_t i;
|
|
155
|
+
|
|
156
|
+
printf(" Configuration:\n");
|
|
157
|
+
printf(" wTotalLength: %d\n", config->wTotalLength);
|
|
158
|
+
printf(" bNumInterfaces: %d\n", config->bNumInterfaces);
|
|
159
|
+
printf(" bConfigurationValue: %d\n", config->bConfigurationValue);
|
|
160
|
+
printf(" iConfiguration: %d\n", config->iConfiguration);
|
|
161
|
+
printf(" bmAttributes: %02xh\n", config->bmAttributes);
|
|
162
|
+
printf(" MaxPower: %d\n", config->MaxPower);
|
|
163
|
+
|
|
164
|
+
for (i = 0; i < config->bNumInterfaces; i++)
|
|
165
|
+
print_interface(&config->interface[i]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static int print_device(libusb_device *dev, int level)
|
|
169
|
+
{
|
|
170
|
+
struct libusb_device_descriptor desc;
|
|
171
|
+
libusb_device_handle *handle = NULL;
|
|
172
|
+
char description[260];
|
|
173
|
+
char string[256];
|
|
174
|
+
int ret;
|
|
175
|
+
uint8_t i;
|
|
176
|
+
|
|
177
|
+
ret = libusb_get_device_descriptor(dev, &desc);
|
|
178
|
+
if (ret < 0) {
|
|
179
|
+
fprintf(stderr, "failed to get device descriptor");
|
|
180
|
+
return -1;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
ret = libusb_open(dev, &handle);
|
|
184
|
+
if (LIBUSB_SUCCESS == ret) {
|
|
185
|
+
if (desc.iManufacturer) {
|
|
186
|
+
ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string));
|
|
187
|
+
if (ret > 0)
|
|
188
|
+
snprintf(description, sizeof(description), "%s - ", string);
|
|
189
|
+
else
|
|
190
|
+
snprintf(description, sizeof(description), "%04X - ",
|
|
191
|
+
desc.idVendor);
|
|
192
|
+
}
|
|
193
|
+
else
|
|
194
|
+
snprintf(description, sizeof(description), "%04X - ",
|
|
195
|
+
desc.idVendor);
|
|
196
|
+
|
|
197
|
+
if (desc.iProduct) {
|
|
198
|
+
ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string));
|
|
199
|
+
if (ret > 0)
|
|
200
|
+
snprintf(description + strlen(description), sizeof(description) -
|
|
201
|
+
strlen(description), "%s", string);
|
|
202
|
+
else
|
|
203
|
+
snprintf(description + strlen(description), sizeof(description) -
|
|
204
|
+
strlen(description), "%04X", desc.idProduct);
|
|
205
|
+
}
|
|
206
|
+
else
|
|
207
|
+
snprintf(description + strlen(description), sizeof(description) -
|
|
208
|
+
strlen(description), "%04X", desc.idProduct);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
snprintf(description, sizeof(description), "%04X - %04X",
|
|
212
|
+
desc.idVendor, desc.idProduct);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
printf("%.*sDev (bus %d, device %d): %s\n", level * 2, " ",
|
|
216
|
+
libusb_get_bus_number(dev), libusb_get_device_address(dev), description);
|
|
217
|
+
|
|
218
|
+
if (handle && verbose) {
|
|
219
|
+
if (desc.iSerialNumber) {
|
|
220
|
+
ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string));
|
|
221
|
+
if (ret > 0)
|
|
222
|
+
printf("%.*s - Serial Number: %s\n", level * 2,
|
|
223
|
+
" ", string);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (verbose) {
|
|
228
|
+
for (i = 0; i < desc.bNumConfigurations; i++) {
|
|
229
|
+
struct libusb_config_descriptor *config;
|
|
230
|
+
ret = libusb_get_config_descriptor(dev, i, &config);
|
|
231
|
+
if (LIBUSB_SUCCESS != ret) {
|
|
232
|
+
printf(" Couldn't retrieve descriptors\n");
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
print_configuration(config);
|
|
237
|
+
|
|
238
|
+
libusb_free_config_descriptor(config);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (handle && desc.bcdUSB >= 0x0201) {
|
|
242
|
+
print_bos(handle);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (handle)
|
|
247
|
+
libusb_close(handle);
|
|
248
|
+
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
int main(int argc, char *argv[])
|
|
253
|
+
{
|
|
254
|
+
libusb_device **devs;
|
|
255
|
+
ssize_t cnt;
|
|
256
|
+
int r, i;
|
|
257
|
+
|
|
258
|
+
if (argc > 1 && !strcmp(argv[1], "-v"))
|
|
259
|
+
verbose = 1;
|
|
260
|
+
|
|
261
|
+
r = libusb_init(NULL);
|
|
262
|
+
if (r < 0)
|
|
263
|
+
return r;
|
|
264
|
+
|
|
265
|
+
cnt = libusb_get_device_list(NULL, &devs);
|
|
266
|
+
if (cnt < 0)
|
|
267
|
+
return (int)cnt;
|
|
268
|
+
|
|
269
|
+
for (i = 0; devs[i]; ++i) {
|
|
270
|
+
print_device(devs[i], 0);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
libusb_free_device_list(devs, 1);
|
|
274
|
+
|
|
275
|
+
libusb_exit(NULL);
|
|
276
|
+
return 0;
|
|
277
|
+
}
|