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
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
#include <stdlib.h>
|
|
34
34
|
#include <string.h>
|
|
35
35
|
#include <sys/ioctl.h>
|
|
36
|
+
#include <sys/mman.h>
|
|
36
37
|
#include <sys/stat.h>
|
|
37
38
|
#include <sys/types.h>
|
|
38
39
|
#include <sys/utsname.h>
|
|
39
|
-
#include <
|
|
40
|
+
#include <time.h>
|
|
40
41
|
|
|
41
|
-
#include "libusb.h"
|
|
42
42
|
#include "libusbi.h"
|
|
43
43
|
#include "linux_usbfs.h"
|
|
44
44
|
|
|
@@ -81,6 +81,19 @@ static const char *usbfs_path = NULL;
|
|
|
81
81
|
/* use usbdev*.* device names in /dev instead of the usbfs bus directories */
|
|
82
82
|
static int usbdev_names = 0;
|
|
83
83
|
|
|
84
|
+
/* Linux has changed the maximum length of an individual isochronous packet
|
|
85
|
+
* over time. Initially this limit was 1,023 bytes, but Linux 2.6.18
|
|
86
|
+
* (commit 3612242e527eb47ee4756b5350f8bdf791aa5ede) increased this value to
|
|
87
|
+
* 8,192 bytes to support higher bandwidth devices. Linux 3.10
|
|
88
|
+
* (commit e2e2f0ea1c935edcf53feb4c4c8fdb4f86d57dd9) further increased this
|
|
89
|
+
* value to 49,152 bytes to support super speed devices.
|
|
90
|
+
*/
|
|
91
|
+
static unsigned int max_iso_packet_len = 0;
|
|
92
|
+
|
|
93
|
+
/* Linux 2.6.23 adds support for O_CLOEXEC when opening files, which marks the
|
|
94
|
+
* close-on-exec flag in the underlying file descriptor. */
|
|
95
|
+
static int supports_flag_cloexec = -1;
|
|
96
|
+
|
|
84
97
|
/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically
|
|
85
98
|
* allows us to mark URBs as being part of a specific logical transfer when
|
|
86
99
|
* we submit them to the kernel. then, on any error except a cancellation, all
|
|
@@ -122,7 +135,7 @@ static int sysfs_has_descriptors = -1;
|
|
|
122
135
|
static int init_count = 0;
|
|
123
136
|
|
|
124
137
|
/* Serialize hotplug start/stop */
|
|
125
|
-
usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER;
|
|
138
|
+
static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER;
|
|
126
139
|
/* Serialize scan-devices, event-thread, and poll */
|
|
127
140
|
usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER;
|
|
128
141
|
|
|
@@ -136,6 +149,12 @@ static int detach_kernel_driver_and_claim(struct libusb_device_handle *, int);
|
|
|
136
149
|
static int linux_default_scan_devices (struct libusb_context *ctx);
|
|
137
150
|
#endif
|
|
138
151
|
|
|
152
|
+
struct kernel_version {
|
|
153
|
+
int major;
|
|
154
|
+
int minor;
|
|
155
|
+
int sublevel;
|
|
156
|
+
};
|
|
157
|
+
|
|
139
158
|
struct linux_device_priv {
|
|
140
159
|
char *sysfs_dir;
|
|
141
160
|
unsigned char *descriptors;
|
|
@@ -145,6 +164,8 @@ struct linux_device_priv {
|
|
|
145
164
|
|
|
146
165
|
struct linux_device_handle_priv {
|
|
147
166
|
int fd;
|
|
167
|
+
int fd_removed;
|
|
168
|
+
int fd_keep;
|
|
148
169
|
uint32_t caps;
|
|
149
170
|
};
|
|
150
171
|
|
|
@@ -179,6 +200,16 @@ struct linux_transfer_priv {
|
|
|
179
200
|
int iso_packet_offset;
|
|
180
201
|
};
|
|
181
202
|
|
|
203
|
+
static int _open(const char *path, int flags)
|
|
204
|
+
{
|
|
205
|
+
#if defined(O_CLOEXEC)
|
|
206
|
+
if (supports_flag_cloexec)
|
|
207
|
+
return open(path, flags | O_CLOEXEC);
|
|
208
|
+
else
|
|
209
|
+
#endif
|
|
210
|
+
return open(path, flags);
|
|
211
|
+
}
|
|
212
|
+
|
|
182
213
|
static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
183
214
|
{
|
|
184
215
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
@@ -193,18 +224,18 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
|
193
224
|
snprintf(path, PATH_MAX, "%s/%03d/%03d",
|
|
194
225
|
usbfs_path, dev->bus_number, dev->device_address);
|
|
195
226
|
|
|
196
|
-
fd =
|
|
227
|
+
fd = _open(path, mode);
|
|
197
228
|
if (fd != -1)
|
|
198
229
|
return fd; /* Success */
|
|
199
230
|
|
|
200
231
|
if (errno == ENOENT) {
|
|
201
232
|
if (!silent)
|
|
202
|
-
usbi_err(ctx, "File doesn't exist, wait %d ms and try again
|
|
233
|
+
usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000);
|
|
203
234
|
|
|
204
235
|
/* Wait 10ms for USB device path creation.*/
|
|
205
|
-
|
|
236
|
+
nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL);
|
|
206
237
|
|
|
207
|
-
fd =
|
|
238
|
+
fd = _open(path, mode);
|
|
208
239
|
if (fd != -1)
|
|
209
240
|
return fd; /* Success */
|
|
210
241
|
}
|
|
@@ -308,6 +339,16 @@ static const char *find_usbfs_path(void)
|
|
|
308
339
|
}
|
|
309
340
|
}
|
|
310
341
|
|
|
342
|
+
/* On udev based systems without any usb-devices /dev/bus/usb will not
|
|
343
|
+
* exist. So if we've not found anything and we're using udev for hotplug
|
|
344
|
+
* simply assume /dev/bus/usb rather then making libusb_init fail.
|
|
345
|
+
* Make the same assumption for Android where SELinux policies might block us
|
|
346
|
+
* from reading /dev on newer devices. */
|
|
347
|
+
#if defined(USE_UDEV) || defined(__ANDROID__)
|
|
348
|
+
if (ret == NULL)
|
|
349
|
+
ret = "/dev/bus/usb";
|
|
350
|
+
#endif
|
|
351
|
+
|
|
311
352
|
if (ret != NULL)
|
|
312
353
|
usbi_dbg("found usbfs at %s", ret);
|
|
313
354
|
|
|
@@ -333,39 +374,59 @@ static clockid_t find_monotonic_clock(void)
|
|
|
333
374
|
return CLOCK_REALTIME;
|
|
334
375
|
}
|
|
335
376
|
|
|
336
|
-
static int
|
|
377
|
+
static int get_kernel_version(struct libusb_context *ctx,
|
|
378
|
+
struct kernel_version *ver)
|
|
337
379
|
{
|
|
338
380
|
struct utsname uts;
|
|
339
|
-
int atoms
|
|
381
|
+
int atoms;
|
|
340
382
|
|
|
341
|
-
if (uname(&uts) < 0)
|
|
383
|
+
if (uname(&uts) < 0) {
|
|
384
|
+
usbi_err(ctx, "uname failed, errno %d", errno);
|
|
342
385
|
return -1;
|
|
343
|
-
|
|
344
|
-
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
atoms = sscanf(uts.release, "%d.%d.%d", &ver->major, &ver->minor, &ver->sublevel);
|
|
389
|
+
if (atoms < 1) {
|
|
390
|
+
usbi_err(ctx, "failed to parse uname release '%s'", uts.release);
|
|
345
391
|
return -1;
|
|
392
|
+
}
|
|
346
393
|
|
|
347
|
-
if (
|
|
394
|
+
if (atoms < 2)
|
|
395
|
+
ver->minor = -1;
|
|
396
|
+
if (atoms < 3)
|
|
397
|
+
ver->sublevel = -1;
|
|
398
|
+
|
|
399
|
+
usbi_dbg("reported kernel version is %s", uts.release);
|
|
400
|
+
|
|
401
|
+
return 0;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
static int kernel_version_ge(const struct kernel_version *ver,
|
|
405
|
+
int major, int minor, int sublevel)
|
|
406
|
+
{
|
|
407
|
+
if (ver->major > major)
|
|
348
408
|
return 1;
|
|
349
|
-
if (
|
|
409
|
+
else if (ver->major < major)
|
|
350
410
|
return 0;
|
|
351
411
|
|
|
352
412
|
/* kmajor == major */
|
|
353
|
-
if (
|
|
413
|
+
if (ver->minor == -1 && ver->sublevel == -1)
|
|
354
414
|
return 0 == minor && 0 == sublevel;
|
|
355
|
-
if (
|
|
415
|
+
else if (ver->minor > minor)
|
|
356
416
|
return 1;
|
|
357
|
-
if (
|
|
417
|
+
else if (ver->minor < minor)
|
|
358
418
|
return 0;
|
|
359
419
|
|
|
360
420
|
/* kminor == minor */
|
|
361
|
-
if (
|
|
421
|
+
if (ver->sublevel == -1)
|
|
362
422
|
return 0 == sublevel;
|
|
363
423
|
|
|
364
|
-
return
|
|
424
|
+
return ver->sublevel >= sublevel;
|
|
365
425
|
}
|
|
366
426
|
|
|
367
427
|
static int op_init(struct libusb_context *ctx)
|
|
368
428
|
{
|
|
429
|
+
struct kernel_version kversion;
|
|
369
430
|
struct stat statbuf;
|
|
370
431
|
int r;
|
|
371
432
|
|
|
@@ -378,13 +439,17 @@ static int op_init(struct libusb_context *ctx)
|
|
|
378
439
|
if (monotonic_clkid == -1)
|
|
379
440
|
monotonic_clkid = find_monotonic_clock();
|
|
380
441
|
|
|
442
|
+
if (get_kernel_version(ctx, &kversion) < 0)
|
|
443
|
+
return LIBUSB_ERROR_OTHER;
|
|
444
|
+
|
|
445
|
+
if (supports_flag_cloexec == -1) {
|
|
446
|
+
/* O_CLOEXEC flag available from Linux 2.6.23 */
|
|
447
|
+
supports_flag_cloexec = kernel_version_ge(&kversion,2,6,23);
|
|
448
|
+
}
|
|
449
|
+
|
|
381
450
|
if (supports_flag_bulk_continuation == -1) {
|
|
382
451
|
/* bulk continuation URB flag available from Linux 2.6.32 */
|
|
383
|
-
supports_flag_bulk_continuation = kernel_version_ge(2,6,32);
|
|
384
|
-
if (supports_flag_bulk_continuation == -1) {
|
|
385
|
-
usbi_err(ctx, "error checking for bulk continuation support");
|
|
386
|
-
return LIBUSB_ERROR_OTHER;
|
|
387
|
-
}
|
|
452
|
+
supports_flag_bulk_continuation = kernel_version_ge(&kversion,2,6,32);
|
|
388
453
|
}
|
|
389
454
|
|
|
390
455
|
if (supports_flag_bulk_continuation)
|
|
@@ -392,32 +457,31 @@ static int op_init(struct libusb_context *ctx)
|
|
|
392
457
|
|
|
393
458
|
if (-1 == supports_flag_zero_packet) {
|
|
394
459
|
/* zero length packet URB flag fixed since Linux 2.6.31 */
|
|
395
|
-
supports_flag_zero_packet = kernel_version_ge(2,6,31);
|
|
396
|
-
if (-1 == supports_flag_zero_packet) {
|
|
397
|
-
usbi_err(ctx, "error checking for zero length packet support");
|
|
398
|
-
return LIBUSB_ERROR_OTHER;
|
|
399
|
-
}
|
|
460
|
+
supports_flag_zero_packet = kernel_version_ge(&kversion,2,6,31);
|
|
400
461
|
}
|
|
401
462
|
|
|
402
463
|
if (supports_flag_zero_packet)
|
|
403
464
|
usbi_dbg("zero length packet flag supported");
|
|
404
465
|
|
|
466
|
+
if (!max_iso_packet_len) {
|
|
467
|
+
if (kernel_version_ge(&kversion,3,10,0))
|
|
468
|
+
max_iso_packet_len = 49152;
|
|
469
|
+
else if (kernel_version_ge(&kversion,2,6,18))
|
|
470
|
+
max_iso_packet_len = 8192;
|
|
471
|
+
else
|
|
472
|
+
max_iso_packet_len = 1023;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len);
|
|
476
|
+
|
|
405
477
|
if (-1 == sysfs_has_descriptors) {
|
|
406
478
|
/* sysfs descriptors has all descriptors since Linux 2.6.26 */
|
|
407
|
-
sysfs_has_descriptors = kernel_version_ge(2,6,26);
|
|
408
|
-
if (-1 == sysfs_has_descriptors) {
|
|
409
|
-
usbi_err(ctx, "error checking for sysfs descriptors");
|
|
410
|
-
return LIBUSB_ERROR_OTHER;
|
|
411
|
-
}
|
|
479
|
+
sysfs_has_descriptors = kernel_version_ge(&kversion,2,6,26);
|
|
412
480
|
}
|
|
413
481
|
|
|
414
482
|
if (-1 == sysfs_can_relate_devices) {
|
|
415
483
|
/* sysfs has busnum since Linux 2.6.22 */
|
|
416
|
-
sysfs_can_relate_devices = kernel_version_ge(2,6,22);
|
|
417
|
-
if (-1 == sysfs_can_relate_devices) {
|
|
418
|
-
usbi_err(ctx, "error checking for sysfs busnum");
|
|
419
|
-
return LIBUSB_ERROR_OTHER;
|
|
420
|
-
}
|
|
484
|
+
sysfs_can_relate_devices = kernel_version_ge(&kversion,2,6,22);
|
|
421
485
|
}
|
|
422
486
|
|
|
423
487
|
if (sysfs_can_relate_devices || sysfs_has_descriptors) {
|
|
@@ -454,8 +518,9 @@ static int op_init(struct libusb_context *ctx)
|
|
|
454
518
|
return r;
|
|
455
519
|
}
|
|
456
520
|
|
|
457
|
-
static void op_exit(
|
|
521
|
+
static void op_exit(struct libusb_context *ctx)
|
|
458
522
|
{
|
|
523
|
+
UNUSED(ctx);
|
|
459
524
|
usbi_mutex_static_lock(&linux_hotplug_startstop_lock);
|
|
460
525
|
assert(init_count != 0);
|
|
461
526
|
if (!--init_count) {
|
|
@@ -469,8 +534,10 @@ static int linux_start_event_monitor(void)
|
|
|
469
534
|
{
|
|
470
535
|
#if defined(USE_UDEV)
|
|
471
536
|
return linux_udev_start_event_monitor();
|
|
472
|
-
#
|
|
537
|
+
#elif !defined(__ANDROID__)
|
|
473
538
|
return linux_netlink_start_event_monitor();
|
|
539
|
+
#else
|
|
540
|
+
return LIBUSB_SUCCESS;
|
|
474
541
|
#endif
|
|
475
542
|
}
|
|
476
543
|
|
|
@@ -478,20 +545,22 @@ static int linux_stop_event_monitor(void)
|
|
|
478
545
|
{
|
|
479
546
|
#if defined(USE_UDEV)
|
|
480
547
|
return linux_udev_stop_event_monitor();
|
|
481
|
-
#
|
|
548
|
+
#elif !defined(__ANDROID__)
|
|
482
549
|
return linux_netlink_stop_event_monitor();
|
|
550
|
+
#else
|
|
551
|
+
return LIBUSB_SUCCESS;
|
|
483
552
|
#endif
|
|
484
553
|
}
|
|
485
554
|
|
|
486
555
|
static int linux_scan_devices(struct libusb_context *ctx)
|
|
487
556
|
{
|
|
488
|
-
int ret;
|
|
557
|
+
int ret = 0;
|
|
489
558
|
|
|
490
559
|
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
491
560
|
|
|
492
561
|
#if defined(USE_UDEV)
|
|
493
562
|
ret = linux_udev_scan_devices(ctx);
|
|
494
|
-
#
|
|
563
|
+
#elif !defined(__ANDROID__)
|
|
495
564
|
ret = linux_default_scan_devices(ctx);
|
|
496
565
|
#endif
|
|
497
566
|
|
|
@@ -504,7 +573,7 @@ static void op_hotplug_poll(void)
|
|
|
504
573
|
{
|
|
505
574
|
#if defined(USE_UDEV)
|
|
506
575
|
linux_udev_hotplug_poll();
|
|
507
|
-
#
|
|
576
|
+
#elif !defined(__ANDROID__)
|
|
508
577
|
linux_netlink_hotplug_poll();
|
|
509
578
|
#endif
|
|
510
579
|
}
|
|
@@ -517,7 +586,7 @@ static int _open_sysfs_attr(struct libusb_device *dev, const char *attr)
|
|
|
517
586
|
|
|
518
587
|
snprintf(filename, PATH_MAX, "%s/%s/%s",
|
|
519
588
|
SYSFS_DEVICE_PATH, priv->sysfs_dir, attr);
|
|
520
|
-
fd =
|
|
589
|
+
fd = _open(filename, O_RDONLY);
|
|
521
590
|
if (fd < 0) {
|
|
522
591
|
usbi_err(DEVICE_CTX(dev),
|
|
523
592
|
"open %s failed ret=%d errno=%d", filename, fd, errno);
|
|
@@ -533,12 +602,12 @@ static int __read_sysfs_attr(struct libusb_context *ctx,
|
|
|
533
602
|
{
|
|
534
603
|
char filename[PATH_MAX];
|
|
535
604
|
FILE *f;
|
|
536
|
-
int r, value;
|
|
605
|
+
int fd, r, value;
|
|
537
606
|
|
|
538
607
|
snprintf(filename, PATH_MAX, "%s/%s/%s", SYSFS_DEVICE_PATH,
|
|
539
608
|
devname, attr);
|
|
540
|
-
|
|
541
|
-
if (
|
|
609
|
+
fd = _open(filename, O_RDONLY);
|
|
610
|
+
if (fd == -1) {
|
|
542
611
|
if (errno == ENOENT) {
|
|
543
612
|
/* File doesn't exist. Assume the device has been
|
|
544
613
|
disconnected (see trac ticket #70). */
|
|
@@ -548,6 +617,13 @@ static int __read_sysfs_attr(struct libusb_context *ctx,
|
|
|
548
617
|
return LIBUSB_ERROR_IO;
|
|
549
618
|
}
|
|
550
619
|
|
|
620
|
+
f = fdopen(fd, "r");
|
|
621
|
+
if (f == NULL) {
|
|
622
|
+
usbi_err(ctx, "fdopen %s failed errno=%d", filename, errno);
|
|
623
|
+
close(fd);
|
|
624
|
+
return LIBUSB_ERROR_OTHER;
|
|
625
|
+
}
|
|
626
|
+
|
|
551
627
|
r = fscanf(f, "%d", &value);
|
|
552
628
|
fclose(f);
|
|
553
629
|
if (r != 1) {
|
|
@@ -567,7 +643,7 @@ static int op_get_device_descriptor(struct libusb_device *dev,
|
|
|
567
643
|
{
|
|
568
644
|
struct linux_device_priv *priv = _device_priv(dev);
|
|
569
645
|
|
|
570
|
-
*host_endian = sysfs_has_descriptors ? 0 : 1;
|
|
646
|
+
*host_endian = (priv->sysfs_dir && sysfs_has_descriptors) ? 0 : 1;
|
|
571
647
|
memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH);
|
|
572
648
|
|
|
573
649
|
return 0;
|
|
@@ -590,7 +666,7 @@ static int sysfs_get_active_config(struct libusb_device *dev, int *config)
|
|
|
590
666
|
close(fd);
|
|
591
667
|
if (r < 0) {
|
|
592
668
|
usbi_err(DEVICE_CTX(dev),
|
|
593
|
-
"read bConfigurationValue failed ret=%
|
|
669
|
+
"read bConfigurationValue failed ret=%zd errno=%d", r, errno);
|
|
594
670
|
return LIBUSB_ERROR_IO;
|
|
595
671
|
} else if (r == 0) {
|
|
596
672
|
usbi_dbg("device unconfigured");
|
|
@@ -618,23 +694,34 @@ static int sysfs_get_active_config(struct libusb_device *dev, int *config)
|
|
|
618
694
|
|
|
619
695
|
int linux_get_device_address (struct libusb_context *ctx, int detached,
|
|
620
696
|
uint8_t *busnum, uint8_t *devaddr,const char *dev_node,
|
|
621
|
-
const char *sys_name)
|
|
697
|
+
const char *sys_name, int fd)
|
|
622
698
|
{
|
|
699
|
+
char proc_path[PATH_MAX], fd_path[PATH_MAX];
|
|
623
700
|
int sysfs_attr;
|
|
701
|
+
ssize_t r;
|
|
624
702
|
|
|
625
703
|
usbi_dbg("getting address for device: %s detached: %d", sys_name, detached);
|
|
626
704
|
/* can't use sysfs to read the bus and device number if the
|
|
627
705
|
* device has been detached */
|
|
628
706
|
if (!sysfs_can_relate_devices || detached || NULL == sys_name) {
|
|
707
|
+
if (NULL == dev_node && fd >= 0) {
|
|
708
|
+
/* try to retrieve the device node from fd */
|
|
709
|
+
snprintf(proc_path, PATH_MAX, "/proc/self/fd/%d", fd);
|
|
710
|
+
r = readlink(proc_path, fd_path, PATH_MAX);
|
|
711
|
+
if (r > 0)
|
|
712
|
+
dev_node = fd_path;
|
|
713
|
+
}
|
|
629
714
|
if (NULL == dev_node) {
|
|
630
715
|
return LIBUSB_ERROR_OTHER;
|
|
631
716
|
}
|
|
632
717
|
|
|
633
718
|
/* will this work with all supported kernel versions? */
|
|
634
719
|
if (!strncmp(dev_node, "/dev/bus/usb", 12)) {
|
|
635
|
-
sscanf (dev_node, "/dev/bus/usb/%
|
|
720
|
+
sscanf (dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr);
|
|
636
721
|
} else if (!strncmp(dev_node, "/proc/bus/usb", 13)) {
|
|
637
|
-
sscanf (dev_node, "/proc/bus/usb/%
|
|
722
|
+
sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr);
|
|
723
|
+
} else {
|
|
724
|
+
return LIBUSB_ERROR_OTHER;
|
|
638
725
|
}
|
|
639
726
|
|
|
640
727
|
return LIBUSB_SUCCESS;
|
|
@@ -687,9 +774,11 @@ static int seek_to_next_descriptor(struct libusb_context *ctx,
|
|
|
687
774
|
}
|
|
688
775
|
|
|
689
776
|
/* Return offset to next config */
|
|
690
|
-
static int seek_to_next_config(struct
|
|
777
|
+
static int seek_to_next_config(struct libusb_device *dev,
|
|
691
778
|
unsigned char *buffer, int size)
|
|
692
779
|
{
|
|
780
|
+
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
781
|
+
struct linux_device_priv *priv = _device_priv(dev);
|
|
693
782
|
struct libusb_config_descriptor config;
|
|
694
783
|
|
|
695
784
|
if (size == 0)
|
|
@@ -716,7 +805,7 @@ static int seek_to_next_config(struct libusb_context *ctx,
|
|
|
716
805
|
* config descriptor with verified bLength fields, with descriptors
|
|
717
806
|
* with an invalid bLength removed.
|
|
718
807
|
*/
|
|
719
|
-
if (sysfs_has_descriptors) {
|
|
808
|
+
if (priv->sysfs_dir && sysfs_has_descriptors) {
|
|
720
809
|
int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG,
|
|
721
810
|
buffer, size);
|
|
722
811
|
if (next == LIBUSB_ERROR_NOT_FOUND)
|
|
@@ -745,7 +834,6 @@ static int seek_to_next_config(struct libusb_context *ctx,
|
|
|
745
834
|
static int op_get_config_descriptor_by_value(struct libusb_device *dev,
|
|
746
835
|
uint8_t value, unsigned char **buffer, int *host_endian)
|
|
747
836
|
{
|
|
748
|
-
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
749
837
|
struct linux_device_priv *priv = _device_priv(dev);
|
|
750
838
|
unsigned char *descriptors = priv->descriptors;
|
|
751
839
|
int size = priv->descriptors_len;
|
|
@@ -761,7 +849,7 @@ static int op_get_config_descriptor_by_value(struct libusb_device *dev,
|
|
|
761
849
|
|
|
762
850
|
/* Seek till the config is found, or till "EOF" */
|
|
763
851
|
while (1) {
|
|
764
|
-
int next = seek_to_next_config(
|
|
852
|
+
int next = seek_to_next_config(dev, descriptors, size);
|
|
765
853
|
if (next < 0)
|
|
766
854
|
return next;
|
|
767
855
|
config = (struct libusb_config_descriptor *)descriptors;
|
|
@@ -777,16 +865,16 @@ static int op_get_config_descriptor_by_value(struct libusb_device *dev,
|
|
|
777
865
|
static int op_get_active_config_descriptor(struct libusb_device *dev,
|
|
778
866
|
unsigned char *buffer, size_t len, int *host_endian)
|
|
779
867
|
{
|
|
868
|
+
struct linux_device_priv *priv = _device_priv(dev);
|
|
780
869
|
int r, config;
|
|
781
870
|
unsigned char *config_desc;
|
|
782
871
|
|
|
783
|
-
if (sysfs_can_relate_devices) {
|
|
872
|
+
if (priv->sysfs_dir && sysfs_can_relate_devices) {
|
|
784
873
|
r = sysfs_get_active_config(dev, &config);
|
|
785
874
|
if (r < 0)
|
|
786
875
|
return r;
|
|
787
876
|
} else {
|
|
788
877
|
/* Use cached bConfigurationValue */
|
|
789
|
-
struct linux_device_priv *priv = _device_priv(dev);
|
|
790
878
|
config = priv->active_config;
|
|
791
879
|
}
|
|
792
880
|
if (config == -1)
|
|
@@ -797,7 +885,7 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
|
|
|
797
885
|
if (r < 0)
|
|
798
886
|
return r;
|
|
799
887
|
|
|
800
|
-
len = MIN(len, r);
|
|
888
|
+
len = MIN(len, (size_t)r);
|
|
801
889
|
memcpy(buffer, config_desc, len);
|
|
802
890
|
return len;
|
|
803
891
|
}
|
|
@@ -818,7 +906,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
|
|
|
818
906
|
|
|
819
907
|
/* Seek till the config is found, or till "EOF" */
|
|
820
908
|
for (i = 0; ; i++) {
|
|
821
|
-
r = seek_to_next_config(
|
|
909
|
+
r = seek_to_next_config(dev, descriptors, size);
|
|
822
910
|
if (r < 0)
|
|
823
911
|
return r;
|
|
824
912
|
if (i == config_index)
|
|
@@ -827,7 +915,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
|
|
|
827
915
|
descriptors += r;
|
|
828
916
|
}
|
|
829
917
|
|
|
830
|
-
len = MIN(len, r);
|
|
918
|
+
len = MIN(len, (size_t)r);
|
|
831
919
|
memcpy(buffer, descriptors, len);
|
|
832
920
|
return len;
|
|
833
921
|
}
|
|
@@ -835,6 +923,7 @@ static int op_get_config_descriptor(struct libusb_device *dev,
|
|
|
835
923
|
/* send a control message to retrieve active configuration */
|
|
836
924
|
static int usbfs_get_active_config(struct libusb_device *dev, int fd)
|
|
837
925
|
{
|
|
926
|
+
struct linux_device_priv *priv = _device_priv(dev);
|
|
838
927
|
unsigned char active_config = 0;
|
|
839
928
|
int r;
|
|
840
929
|
|
|
@@ -856,14 +945,27 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
|
|
|
856
945
|
/* we hit this error path frequently with buggy devices :( */
|
|
857
946
|
usbi_warn(DEVICE_CTX(dev),
|
|
858
947
|
"get_configuration failed ret=%d errno=%d", r, errno);
|
|
859
|
-
|
|
948
|
+
priv->active_config = -1;
|
|
949
|
+
} else {
|
|
950
|
+
if (active_config > 0) {
|
|
951
|
+
priv->active_config = active_config;
|
|
952
|
+
} else {
|
|
953
|
+
/* some buggy devices have a configuration 0, but we're
|
|
954
|
+
* reaching into the corner of a corner case here, so let's
|
|
955
|
+
* not support buggy devices in these circumstances.
|
|
956
|
+
* stick to the specs: a configuration value of 0 means
|
|
957
|
+
* unconfigured. */
|
|
958
|
+
usbi_warn(DEVICE_CTX(dev),
|
|
959
|
+
"active cfg 0? assuming unconfigured device");
|
|
960
|
+
priv->active_config = -1;
|
|
961
|
+
}
|
|
860
962
|
}
|
|
861
963
|
|
|
862
|
-
return
|
|
964
|
+
return LIBUSB_SUCCESS;
|
|
863
965
|
}
|
|
864
966
|
|
|
865
967
|
static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
866
|
-
uint8_t devaddr, const char *sysfs_dir)
|
|
968
|
+
uint8_t devaddr, const char *sysfs_dir, int wrapped_fd)
|
|
867
969
|
{
|
|
868
970
|
struct linux_device_priv *priv = _device_priv(dev);
|
|
869
971
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
@@ -875,10 +977,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
875
977
|
dev->device_address = devaddr;
|
|
876
978
|
|
|
877
979
|
if (sysfs_dir) {
|
|
878
|
-
priv->sysfs_dir =
|
|
980
|
+
priv->sysfs_dir = strdup(sysfs_dir);
|
|
879
981
|
if (!priv->sysfs_dir)
|
|
880
982
|
return LIBUSB_ERROR_NO_MEM;
|
|
881
|
-
strcpy(priv->sysfs_dir, sysfs_dir);
|
|
882
983
|
|
|
883
984
|
/* Note speed can contain 1.5, in this case __read_sysfs_attr
|
|
884
985
|
will stop parsing at the '.' and return 1 */
|
|
@@ -889,6 +990,7 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
889
990
|
case 12: dev->speed = LIBUSB_SPEED_FULL; break;
|
|
890
991
|
case 480: dev->speed = LIBUSB_SPEED_HIGH; break;
|
|
891
992
|
case 5000: dev->speed = LIBUSB_SPEED_SUPER; break;
|
|
993
|
+
case 10000: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
|
|
892
994
|
default:
|
|
893
995
|
usbi_warn(DEVICE_CTX(dev), "Unknown device speed: %d Mbps", speed);
|
|
894
996
|
}
|
|
@@ -896,10 +998,18 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
896
998
|
}
|
|
897
999
|
|
|
898
1000
|
/* cache descriptors in memory */
|
|
899
|
-
if (sysfs_has_descriptors)
|
|
1001
|
+
if (sysfs_dir && sysfs_has_descriptors) {
|
|
900
1002
|
fd = _open_sysfs_attr(dev, "descriptors");
|
|
901
|
-
else
|
|
1003
|
+
} else if (wrapped_fd < 0) {
|
|
902
1004
|
fd = _get_usbfs_fd(dev, O_RDONLY, 0);
|
|
1005
|
+
} else {
|
|
1006
|
+
fd = wrapped_fd;
|
|
1007
|
+
r = lseek(fd, 0, SEEK_SET);
|
|
1008
|
+
if (r < 0) {
|
|
1009
|
+
usbi_err(ctx, "seek failed ret=%zd errno=%d", r, errno);
|
|
1010
|
+
return LIBUSB_ERROR_IO;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
903
1013
|
if (fd < 0)
|
|
904
1014
|
return fd;
|
|
905
1015
|
|
|
@@ -908,11 +1018,12 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
908
1018
|
priv->descriptors = usbi_reallocf(priv->descriptors,
|
|
909
1019
|
descriptors_size);
|
|
910
1020
|
if (!priv->descriptors) {
|
|
911
|
-
|
|
1021
|
+
if (fd != wrapped_fd)
|
|
1022
|
+
close(fd);
|
|
912
1023
|
return LIBUSB_ERROR_NO_MEM;
|
|
913
1024
|
}
|
|
914
1025
|
/* usbfs has holes in the file */
|
|
915
|
-
if (!sysfs_has_descriptors) {
|
|
1026
|
+
if (!(sysfs_dir && sysfs_has_descriptors)) {
|
|
916
1027
|
memset(priv->descriptors + priv->descriptors_len,
|
|
917
1028
|
0, descriptors_size - priv->descriptors_len);
|
|
918
1029
|
}
|
|
@@ -921,13 +1032,15 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
921
1032
|
if (r < 0) {
|
|
922
1033
|
usbi_err(ctx, "read descriptor failed ret=%d errno=%d",
|
|
923
1034
|
fd, errno);
|
|
924
|
-
|
|
1035
|
+
if (fd != wrapped_fd)
|
|
1036
|
+
close(fd);
|
|
925
1037
|
return LIBUSB_ERROR_IO;
|
|
926
1038
|
}
|
|
927
1039
|
priv->descriptors_len += r;
|
|
928
1040
|
} while (priv->descriptors_len == descriptors_size);
|
|
929
1041
|
|
|
930
|
-
|
|
1042
|
+
if (fd != wrapped_fd)
|
|
1043
|
+
close(fd);
|
|
931
1044
|
|
|
932
1045
|
if (priv->descriptors_len < DEVICE_DESC_LENGTH) {
|
|
933
1046
|
usbi_err(ctx, "short descriptor read (%d)",
|
|
@@ -935,11 +1048,14 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
935
1048
|
return LIBUSB_ERROR_IO;
|
|
936
1049
|
}
|
|
937
1050
|
|
|
938
|
-
if (sysfs_can_relate_devices)
|
|
1051
|
+
if (sysfs_dir && sysfs_can_relate_devices)
|
|
939
1052
|
return LIBUSB_SUCCESS;
|
|
940
1053
|
|
|
941
1054
|
/* cache active config */
|
|
942
|
-
|
|
1055
|
+
if (wrapped_fd < 0)
|
|
1056
|
+
fd = _get_usbfs_fd(dev, O_RDWR, 1);
|
|
1057
|
+
else
|
|
1058
|
+
fd = wrapped_fd;
|
|
943
1059
|
if (fd < 0) {
|
|
944
1060
|
/* cannot send a control message to determine the active
|
|
945
1061
|
* config. just assume the first one is active. */
|
|
@@ -959,28 +1075,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
959
1075
|
}
|
|
960
1076
|
|
|
961
1077
|
r = usbfs_get_active_config(dev, fd);
|
|
962
|
-
if (
|
|
963
|
-
|
|
964
|
-
r = LIBUSB_SUCCESS;
|
|
965
|
-
} else if (r == 0) {
|
|
966
|
-
/* some buggy devices have a configuration 0, but we're
|
|
967
|
-
* reaching into the corner of a corner case here, so let's
|
|
968
|
-
* not support buggy devices in these circumstances.
|
|
969
|
-
* stick to the specs: a configuration value of 0 means
|
|
970
|
-
* unconfigured. */
|
|
971
|
-
usbi_dbg("active cfg 0? assuming unconfigured device");
|
|
972
|
-
priv->active_config = -1;
|
|
973
|
-
r = LIBUSB_SUCCESS;
|
|
974
|
-
} else if (r == LIBUSB_ERROR_IO) {
|
|
975
|
-
/* buggy devices sometimes fail to report their active config.
|
|
976
|
-
* assume unconfigured and continue the probing */
|
|
977
|
-
usbi_warn(ctx, "couldn't query active configuration, assuming"
|
|
978
|
-
" unconfigured");
|
|
979
|
-
priv->active_config = -1;
|
|
980
|
-
r = LIBUSB_SUCCESS;
|
|
981
|
-
} /* else r < 0, just return the error code */
|
|
1078
|
+
if (wrapped_fd < 0)
|
|
1079
|
+
close(fd);
|
|
982
1080
|
|
|
983
|
-
close(fd);
|
|
984
1081
|
return r;
|
|
985
1082
|
}
|
|
986
1083
|
|
|
@@ -998,6 +1095,9 @@ static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_di
|
|
|
998
1095
|
}
|
|
999
1096
|
|
|
1000
1097
|
parent_sysfs_dir = strdup(sysfs_dir);
|
|
1098
|
+
if (NULL == parent_sysfs_dir) {
|
|
1099
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
1100
|
+
}
|
|
1001
1101
|
if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) ||
|
|
1002
1102
|
NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) {
|
|
1003
1103
|
dev->port_number = atoi(tmp + 1);
|
|
@@ -1024,9 +1124,11 @@ retry:
|
|
|
1024
1124
|
usbi_mutex_lock(&ctx->usb_devs_lock);
|
|
1025
1125
|
list_for_each_entry(it, &ctx->usb_devs, list, struct libusb_device) {
|
|
1026
1126
|
struct linux_device_priv *priv = _device_priv(it);
|
|
1027
|
-
if (
|
|
1028
|
-
|
|
1029
|
-
|
|
1127
|
+
if (priv->sysfs_dir) {
|
|
1128
|
+
if (0 == strcmp (priv->sysfs_dir, parent_sysfs_dir)) {
|
|
1129
|
+
dev->parent_dev = libusb_ref_device(it);
|
|
1130
|
+
break;
|
|
1131
|
+
}
|
|
1030
1132
|
}
|
|
1031
1133
|
}
|
|
1032
1134
|
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
@@ -1075,7 +1177,7 @@ int linux_enumerate_device(struct libusb_context *ctx,
|
|
|
1075
1177
|
if (!dev)
|
|
1076
1178
|
return LIBUSB_ERROR_NO_MEM;
|
|
1077
1179
|
|
|
1078
|
-
r = initialize_device(dev, busnum, devaddr, sysfs_dir);
|
|
1180
|
+
r = initialize_device(dev, busnum, devaddr, sysfs_dir, -1);
|
|
1079
1181
|
if (r < 0)
|
|
1080
1182
|
goto out;
|
|
1081
1183
|
r = usbi_sanitize_device(dev);
|
|
@@ -1105,7 +1207,7 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na
|
|
|
1105
1207
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
1106
1208
|
}
|
|
1107
1209
|
|
|
1108
|
-
void linux_device_disconnected(uint8_t busnum, uint8_t devaddr
|
|
1210
|
+
void linux_device_disconnected(uint8_t busnum, uint8_t devaddr)
|
|
1109
1211
|
{
|
|
1110
1212
|
struct libusb_context *ctx;
|
|
1111
1213
|
struct libusb_device *dev;
|
|
@@ -1118,7 +1220,7 @@ void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_
|
|
|
1118
1220
|
usbi_disconnect_device (dev);
|
|
1119
1221
|
libusb_unref_device(dev);
|
|
1120
1222
|
} else {
|
|
1121
|
-
usbi_dbg("device not found for session %
|
|
1223
|
+
usbi_dbg("device not found for session %lx", session_id);
|
|
1122
1224
|
}
|
|
1123
1225
|
}
|
|
1124
1226
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
@@ -1218,7 +1320,7 @@ static int sysfs_scan_device(struct libusb_context *ctx, const char *devname)
|
|
|
1218
1320
|
uint8_t busnum, devaddr;
|
|
1219
1321
|
int ret;
|
|
1220
1322
|
|
|
1221
|
-
ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname);
|
|
1323
|
+
ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname, -1);
|
|
1222
1324
|
if (LIBUSB_SUCCESS != ret) {
|
|
1223
1325
|
return ret;
|
|
1224
1326
|
}
|
|
@@ -1232,11 +1334,12 @@ static int sysfs_get_device_list(struct libusb_context *ctx)
|
|
|
1232
1334
|
{
|
|
1233
1335
|
DIR *devices = opendir(SYSFS_DEVICE_PATH);
|
|
1234
1336
|
struct dirent *entry;
|
|
1235
|
-
int
|
|
1337
|
+
int num_devices = 0;
|
|
1338
|
+
int num_enumerated = 0;
|
|
1236
1339
|
|
|
1237
1340
|
if (!devices) {
|
|
1238
1341
|
usbi_err(ctx, "opendir devices failed errno=%d", errno);
|
|
1239
|
-
return
|
|
1342
|
+
return LIBUSB_ERROR_IO;
|
|
1240
1343
|
}
|
|
1241
1344
|
|
|
1242
1345
|
while ((entry = readdir(devices))) {
|
|
@@ -1244,16 +1347,23 @@ static int sysfs_get_device_list(struct libusb_context *ctx)
|
|
|
1244
1347
|
|| strchr(entry->d_name, ':'))
|
|
1245
1348
|
continue;
|
|
1246
1349
|
|
|
1350
|
+
num_devices++;
|
|
1351
|
+
|
|
1247
1352
|
if (sysfs_scan_device(ctx, entry->d_name)) {
|
|
1248
1353
|
usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
|
|
1249
1354
|
continue;
|
|
1250
1355
|
}
|
|
1251
1356
|
|
|
1252
|
-
|
|
1357
|
+
num_enumerated++;
|
|
1253
1358
|
}
|
|
1254
1359
|
|
|
1255
1360
|
closedir(devices);
|
|
1256
|
-
|
|
1361
|
+
|
|
1362
|
+
/* successful if at least one device was enumerated or no devices were found */
|
|
1363
|
+
if (num_enumerated || !num_devices)
|
|
1364
|
+
return LIBUSB_SUCCESS;
|
|
1365
|
+
else
|
|
1366
|
+
return LIBUSB_ERROR_IO;
|
|
1257
1367
|
}
|
|
1258
1368
|
|
|
1259
1369
|
static int linux_default_scan_devices (struct libusb_context *ctx)
|
|
@@ -1275,28 +1385,14 @@ static int linux_default_scan_devices (struct libusb_context *ctx)
|
|
|
1275
1385
|
}
|
|
1276
1386
|
#endif
|
|
1277
1387
|
|
|
1278
|
-
static int
|
|
1388
|
+
static int initialize_handle(struct libusb_device_handle *handle, int fd)
|
|
1279
1389
|
{
|
|
1280
1390
|
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
|
|
1281
1391
|
int r;
|
|
1282
1392
|
|
|
1283
|
-
hpriv->fd =
|
|
1284
|
-
if (hpriv->fd < 0) {
|
|
1285
|
-
if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) {
|
|
1286
|
-
/* device will still be marked as attached if hotplug monitor thread
|
|
1287
|
-
* hasn't processed remove event yet */
|
|
1288
|
-
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
1289
|
-
if (handle->dev->attached) {
|
|
1290
|
-
usbi_dbg("open failed with no device, but device still attached");
|
|
1291
|
-
linux_device_disconnected(handle->dev->bus_number,
|
|
1292
|
-
handle->dev->device_address, NULL);
|
|
1293
|
-
}
|
|
1294
|
-
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
1295
|
-
}
|
|
1296
|
-
return hpriv->fd;
|
|
1297
|
-
}
|
|
1393
|
+
hpriv->fd = fd;
|
|
1298
1394
|
|
|
1299
|
-
r = ioctl(
|
|
1395
|
+
r = ioctl(fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
|
|
1300
1396
|
if (r < 0) {
|
|
1301
1397
|
if (errno == ENOTTY)
|
|
1302
1398
|
usbi_dbg("getcap not available");
|
|
@@ -1312,23 +1408,106 @@ static int op_open(struct libusb_device_handle *handle)
|
|
|
1312
1408
|
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
|
|
1313
1409
|
}
|
|
1314
1410
|
|
|
1411
|
+
static int op_wrap_sys_device(struct libusb_context *ctx,
|
|
1412
|
+
struct libusb_device_handle *handle, intptr_t sys_dev)
|
|
1413
|
+
{
|
|
1414
|
+
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
|
|
1415
|
+
int fd = (int)sys_dev;
|
|
1416
|
+
uint8_t busnum, devaddr;
|
|
1417
|
+
struct usbfs_connectinfo ci;
|
|
1418
|
+
struct libusb_device *dev;
|
|
1419
|
+
int r;
|
|
1420
|
+
|
|
1421
|
+
r = linux_get_device_address(ctx, 1, &busnum, &devaddr, NULL, NULL, fd);
|
|
1422
|
+
if (r < 0) {
|
|
1423
|
+
r = ioctl(fd, IOCTL_USBFS_CONNECTINFO, &ci);
|
|
1424
|
+
if (r < 0) {
|
|
1425
|
+
usbi_err(ctx, "connectinfo failed (%d)", errno);
|
|
1426
|
+
return LIBUSB_ERROR_IO;
|
|
1427
|
+
}
|
|
1428
|
+
/* There is no ioctl to get the bus number. We choose 0 here
|
|
1429
|
+
* as linux starts numbering buses from 1. */
|
|
1430
|
+
busnum = 0;
|
|
1431
|
+
devaddr = ci.devnum;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
/* Session id is unused as we do not add the device to the list of
|
|
1435
|
+
* connected devices. */
|
|
1436
|
+
usbi_dbg("allocating new device for fd %d", fd);
|
|
1437
|
+
dev = usbi_alloc_device(ctx, 0);
|
|
1438
|
+
if (!dev)
|
|
1439
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
1440
|
+
|
|
1441
|
+
r = initialize_device(dev, busnum, devaddr, NULL, fd);
|
|
1442
|
+
if (r < 0)
|
|
1443
|
+
goto out;
|
|
1444
|
+
r = usbi_sanitize_device(dev);
|
|
1445
|
+
if (r < 0)
|
|
1446
|
+
goto out;
|
|
1447
|
+
/* Consider the device as connected, but do not add it to the managed
|
|
1448
|
+
* device list. */
|
|
1449
|
+
dev->attached = 1;
|
|
1450
|
+
handle->dev = dev;
|
|
1451
|
+
|
|
1452
|
+
r = initialize_handle(handle, fd);
|
|
1453
|
+
hpriv->fd_keep = 1;
|
|
1454
|
+
|
|
1455
|
+
out:
|
|
1456
|
+
if (r < 0)
|
|
1457
|
+
libusb_unref_device(dev);
|
|
1458
|
+
return r;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
static int op_open(struct libusb_device_handle *handle)
|
|
1462
|
+
{
|
|
1463
|
+
int fd, r;
|
|
1464
|
+
|
|
1465
|
+
fd = _get_usbfs_fd(handle->dev, O_RDWR, 0);
|
|
1466
|
+
if (fd < 0) {
|
|
1467
|
+
if (fd == LIBUSB_ERROR_NO_DEVICE) {
|
|
1468
|
+
/* device will still be marked as attached if hotplug monitor thread
|
|
1469
|
+
* hasn't processed remove event yet */
|
|
1470
|
+
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
1471
|
+
if (handle->dev->attached) {
|
|
1472
|
+
usbi_dbg("open failed with no device, but device still attached");
|
|
1473
|
+
linux_device_disconnected(handle->dev->bus_number,
|
|
1474
|
+
handle->dev->device_address);
|
|
1475
|
+
}
|
|
1476
|
+
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
1477
|
+
}
|
|
1478
|
+
return fd;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
r = initialize_handle(handle, fd);
|
|
1482
|
+
if (r < 0)
|
|
1483
|
+
close(fd);
|
|
1484
|
+
|
|
1485
|
+
return r;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1315
1488
|
static void op_close(struct libusb_device_handle *dev_handle)
|
|
1316
1489
|
{
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1490
|
+
struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle);
|
|
1491
|
+
/* fd may have already been removed by POLLERR condition in op_handle_events() */
|
|
1492
|
+
if (!hpriv->fd_removed)
|
|
1493
|
+
usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd);
|
|
1494
|
+
if (!hpriv->fd_keep)
|
|
1495
|
+
close(hpriv->fd);
|
|
1320
1496
|
}
|
|
1321
1497
|
|
|
1322
1498
|
static int op_get_configuration(struct libusb_device_handle *handle,
|
|
1323
1499
|
int *config)
|
|
1324
1500
|
{
|
|
1501
|
+
struct linux_device_priv *priv = _device_priv(handle->dev);
|
|
1325
1502
|
int r;
|
|
1326
1503
|
|
|
1327
|
-
if (sysfs_can_relate_devices) {
|
|
1504
|
+
if (priv->sysfs_dir && sysfs_can_relate_devices) {
|
|
1328
1505
|
r = sysfs_get_active_config(handle->dev, config);
|
|
1329
1506
|
} else {
|
|
1330
1507
|
r = usbfs_get_active_config(handle->dev,
|
|
1331
1508
|
_device_handle_priv(handle)->fd);
|
|
1509
|
+
if (r == LIBUSB_SUCCESS)
|
|
1510
|
+
*config = priv->active_config;
|
|
1332
1511
|
}
|
|
1333
1512
|
if (r < 0)
|
|
1334
1513
|
return r;
|
|
@@ -1545,6 +1724,32 @@ static int op_free_streams(struct libusb_device_handle *handle,
|
|
|
1545
1724
|
endpoints, num_endpoints);
|
|
1546
1725
|
}
|
|
1547
1726
|
|
|
1727
|
+
static unsigned char *op_dev_mem_alloc(struct libusb_device_handle *handle,
|
|
1728
|
+
size_t len)
|
|
1729
|
+
{
|
|
1730
|
+
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
|
|
1731
|
+
unsigned char *buffer = (unsigned char *)mmap(NULL, len,
|
|
1732
|
+
PROT_READ | PROT_WRITE, MAP_SHARED, hpriv->fd, 0);
|
|
1733
|
+
if (buffer == MAP_FAILED) {
|
|
1734
|
+
usbi_err(HANDLE_CTX(handle), "alloc dev mem failed errno %d",
|
|
1735
|
+
errno);
|
|
1736
|
+
return NULL;
|
|
1737
|
+
}
|
|
1738
|
+
return buffer;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
static int op_dev_mem_free(struct libusb_device_handle *handle,
|
|
1742
|
+
unsigned char *buffer, size_t len)
|
|
1743
|
+
{
|
|
1744
|
+
if (munmap(buffer, len) != 0) {
|
|
1745
|
+
usbi_err(HANDLE_CTX(handle), "free dev mem failed errno %d",
|
|
1746
|
+
errno);
|
|
1747
|
+
return LIBUSB_ERROR_OTHER;
|
|
1748
|
+
} else {
|
|
1749
|
+
return LIBUSB_SUCCESS;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1548
1753
|
static int op_kernel_driver_active(struct libusb_device_handle *handle,
|
|
1549
1754
|
int interface)
|
|
1550
1755
|
{
|
|
@@ -1644,10 +1849,7 @@ static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle,
|
|
|
1644
1849
|
strcpy(dc.driver, "usbfs");
|
|
1645
1850
|
dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER;
|
|
1646
1851
|
r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc);
|
|
1647
|
-
if (r
|
|
1648
|
-
if (r == 0)
|
|
1649
|
-
return 0;
|
|
1650
|
-
|
|
1852
|
+
if (r != 0 && errno != ENOTTY) {
|
|
1651
1853
|
switch (errno) {
|
|
1652
1854
|
case EBUSY:
|
|
1653
1855
|
return LIBUSB_ERROR_BUSY;
|
|
@@ -1659,7 +1861,8 @@ static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle,
|
|
|
1659
1861
|
usbi_err(HANDLE_CTX(handle),
|
|
1660
1862
|
"disconnect-and-claim failed errno %d", errno);
|
|
1661
1863
|
return LIBUSB_ERROR_OTHER;
|
|
1662
|
-
}
|
|
1864
|
+
} else if (r == 0)
|
|
1865
|
+
return 0;
|
|
1663
1866
|
|
|
1664
1867
|
/* Fallback code for kernels which don't support the
|
|
1665
1868
|
disconnect-and-claim ioctl */
|
|
@@ -1765,10 +1968,6 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
1765
1968
|
int bulk_buffer_len, use_bulk_continuation;
|
|
1766
1969
|
int r;
|
|
1767
1970
|
int i;
|
|
1768
|
-
size_t alloc_size;
|
|
1769
|
-
|
|
1770
|
-
if (tpriv->urbs)
|
|
1771
|
-
return LIBUSB_ERROR_BUSY;
|
|
1772
1971
|
|
|
1773
1972
|
if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) &&
|
|
1774
1973
|
!(dpriv->caps & USBFS_CAP_ZERO_PACKET))
|
|
@@ -1827,8 +2026,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
1827
2026
|
}
|
|
1828
2027
|
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
|
1829
2028
|
transfer->length);
|
|
1830
|
-
|
|
1831
|
-
urbs = calloc(1, alloc_size);
|
|
2029
|
+
urbs = calloc(num_urbs, sizeof(struct usbfs_urb));
|
|
1832
2030
|
if (!urbs)
|
|
1833
2031
|
return LIBUSB_ERROR_NO_MEM;
|
|
1834
2032
|
tpriv->urbs = urbs;
|
|
@@ -1937,45 +2135,45 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
1937
2135
|
struct linux_device_handle_priv *dpriv =
|
|
1938
2136
|
_device_handle_priv(transfer->dev_handle);
|
|
1939
2137
|
struct usbfs_urb **urbs;
|
|
1940
|
-
size_t alloc_size;
|
|
1941
2138
|
int num_packets = transfer->num_iso_packets;
|
|
1942
|
-
int
|
|
1943
|
-
int
|
|
1944
|
-
int num_urbs
|
|
1945
|
-
int packet_offset = 0;
|
|
2139
|
+
int num_packets_remaining;
|
|
2140
|
+
int i, j;
|
|
2141
|
+
int num_urbs;
|
|
1946
2142
|
unsigned int packet_len;
|
|
2143
|
+
unsigned int total_len = 0;
|
|
1947
2144
|
unsigned char *urb_buffer = transfer->buffer;
|
|
1948
2145
|
|
|
1949
|
-
if (
|
|
1950
|
-
return
|
|
2146
|
+
if (num_packets < 1)
|
|
2147
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1951
2148
|
|
|
1952
|
-
/* usbfs places
|
|
1953
|
-
*
|
|
1954
|
-
*
|
|
1955
|
-
*
|
|
1956
|
-
*
|
|
1957
|
-
* Newer kernels lift the 32k limit (USBFS_CAP_NO_PACKET_SIZE_LIM),
|
|
1958
|
-
* using arbritary large transfers is still be a bad idea though, as
|
|
1959
|
-
* the kernel needs to allocate physical contiguous memory for this,
|
|
1960
|
-
* which may fail for large buffers.
|
|
2149
|
+
/* usbfs places arbitrary limits on iso URBs. this limit has changed
|
|
2150
|
+
* at least three times, but we attempt to detect this limit during
|
|
2151
|
+
* init and check it here. if the kernel rejects the request due to
|
|
2152
|
+
* its size, we return an error indicating such to the user.
|
|
1961
2153
|
*/
|
|
1962
|
-
|
|
1963
|
-
/* calculate how many URBs we need */
|
|
1964
2154
|
for (i = 0; i < num_packets; i++) {
|
|
1965
|
-
unsigned int space_remaining = MAX_ISO_BUFFER_LENGTH - this_urb_len;
|
|
1966
2155
|
packet_len = transfer->iso_packet_desc[i].length;
|
|
1967
2156
|
|
|
1968
|
-
if (packet_len >
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2157
|
+
if (packet_len > max_iso_packet_len) {
|
|
2158
|
+
usbi_warn(TRANSFER_CTX(transfer),
|
|
2159
|
+
"iso packet length of %u bytes exceeds maximum of %u bytes",
|
|
2160
|
+
packet_len, max_iso_packet_len);
|
|
2161
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1973
2162
|
}
|
|
2163
|
+
|
|
2164
|
+
total_len += packet_len;
|
|
1974
2165
|
}
|
|
1975
|
-
usbi_dbg("need %d 32k URBs for transfer", num_urbs);
|
|
1976
2166
|
|
|
1977
|
-
|
|
1978
|
-
|
|
2167
|
+
if (transfer->length < (int)total_len)
|
|
2168
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2169
|
+
|
|
2170
|
+
/* usbfs limits the number of iso packets per URB */
|
|
2171
|
+
num_urbs = (num_packets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB;
|
|
2172
|
+
|
|
2173
|
+
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
|
2174
|
+
transfer->length);
|
|
2175
|
+
|
|
2176
|
+
urbs = calloc(num_urbs, sizeof(*urbs));
|
|
1979
2177
|
if (!urbs)
|
|
1980
2178
|
return LIBUSB_ERROR_NO_MEM;
|
|
1981
2179
|
|
|
@@ -1986,31 +2184,15 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
1986
2184
|
tpriv->iso_packet_offset = 0;
|
|
1987
2185
|
|
|
1988
2186
|
/* allocate + initialize each URB with the correct number of packets */
|
|
1989
|
-
|
|
2187
|
+
num_packets_remaining = num_packets;
|
|
2188
|
+
for (i = 0, j = 0; i < num_urbs; i++) {
|
|
2189
|
+
int num_packets_in_urb = MIN(num_packets_remaining, MAX_ISO_PACKETS_PER_URB);
|
|
1990
2190
|
struct usbfs_urb *urb;
|
|
1991
|
-
|
|
1992
|
-
int urb_packet_offset = 0;
|
|
1993
|
-
unsigned char *urb_buffer_orig = urb_buffer;
|
|
1994
|
-
int j;
|
|
2191
|
+
size_t alloc_size;
|
|
1995
2192
|
int k;
|
|
1996
2193
|
|
|
1997
|
-
/* swallow up all the packets we can fit into this URB */
|
|
1998
|
-
while (packet_offset < transfer->num_iso_packets) {
|
|
1999
|
-
packet_len = transfer->iso_packet_desc[packet_offset].length;
|
|
2000
|
-
if (packet_len <= space_remaining_in_urb) {
|
|
2001
|
-
/* throw it in */
|
|
2002
|
-
urb_packet_offset++;
|
|
2003
|
-
packet_offset++;
|
|
2004
|
-
space_remaining_in_urb -= packet_len;
|
|
2005
|
-
urb_buffer += packet_len;
|
|
2006
|
-
} else {
|
|
2007
|
-
/* it can't fit, save it for the next URB */
|
|
2008
|
-
break;
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
2194
|
alloc_size = sizeof(*urb)
|
|
2013
|
-
+ (
|
|
2195
|
+
+ (num_packets_in_urb * sizeof(struct usbfs_iso_packet_desc));
|
|
2014
2196
|
urb = calloc(1, alloc_size);
|
|
2015
2197
|
if (!urb) {
|
|
2016
2198
|
free_iso_urbs(tpriv);
|
|
@@ -2019,10 +2201,10 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2019
2201
|
urbs[i] = urb;
|
|
2020
2202
|
|
|
2021
2203
|
/* populate packet lengths */
|
|
2022
|
-
for (
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
urb->iso_frame_desc[
|
|
2204
|
+
for (k = 0; k < num_packets_in_urb; j++, k++) {
|
|
2205
|
+
packet_len = transfer->iso_packet_desc[j].length;
|
|
2206
|
+
urb->buffer_length += packet_len;
|
|
2207
|
+
urb->iso_frame_desc[k].length = packet_len;
|
|
2026
2208
|
}
|
|
2027
2209
|
|
|
2028
2210
|
urb->usercontext = itransfer;
|
|
@@ -2030,8 +2212,11 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2030
2212
|
/* FIXME: interface for non-ASAP data? */
|
|
2031
2213
|
urb->flags = USBFS_URB_ISO_ASAP;
|
|
2032
2214
|
urb->endpoint = transfer->endpoint;
|
|
2033
|
-
urb->number_of_packets =
|
|
2034
|
-
urb->buffer =
|
|
2215
|
+
urb->number_of_packets = num_packets_in_urb;
|
|
2216
|
+
urb->buffer = urb_buffer;
|
|
2217
|
+
|
|
2218
|
+
urb_buffer += urb->buffer_length;
|
|
2219
|
+
num_packets_remaining -= num_packets_in_urb;
|
|
2035
2220
|
}
|
|
2036
2221
|
|
|
2037
2222
|
/* submit URBs */
|
|
@@ -2040,6 +2225,14 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2040
2225
|
if (r < 0) {
|
|
2041
2226
|
if (errno == ENODEV) {
|
|
2042
2227
|
r = LIBUSB_ERROR_NO_DEVICE;
|
|
2228
|
+
} else if (errno == EINVAL) {
|
|
2229
|
+
usbi_warn(TRANSFER_CTX(transfer),
|
|
2230
|
+
"submiturb failed, transfer too large");
|
|
2231
|
+
r = LIBUSB_ERROR_INVALID_PARAM;
|
|
2232
|
+
} else if (errno == EMSGSIZE) {
|
|
2233
|
+
usbi_warn(TRANSFER_CTX(transfer),
|
|
2234
|
+
"submiturb failed, iso packet length too large");
|
|
2235
|
+
r = LIBUSB_ERROR_INVALID_PARAM;
|
|
2043
2236
|
} else {
|
|
2044
2237
|
usbi_err(TRANSFER_CTX(transfer),
|
|
2045
2238
|
"submiturb failed error %d errno=%d", r, errno);
|
|
@@ -2093,9 +2286,6 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
|
|
|
2093
2286
|
struct usbfs_urb *urb;
|
|
2094
2287
|
int r;
|
|
2095
2288
|
|
|
2096
|
-
if (tpriv->urbs)
|
|
2097
|
-
return LIBUSB_ERROR_BUSY;
|
|
2098
|
-
|
|
2099
2289
|
if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH)
|
|
2100
2290
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2101
2291
|
|
|
@@ -2153,6 +2343,14 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
|
|
2153
2343
|
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
|
2154
2344
|
struct libusb_transfer *transfer =
|
|
2155
2345
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2346
|
+
int r;
|
|
2347
|
+
|
|
2348
|
+
if (!tpriv->urbs)
|
|
2349
|
+
return LIBUSB_ERROR_NOT_FOUND;
|
|
2350
|
+
|
|
2351
|
+
r = discard_urbs(itransfer, 0, tpriv->num_urbs);
|
|
2352
|
+
if (r != 0)
|
|
2353
|
+
return r;
|
|
2156
2354
|
|
|
2157
2355
|
switch (transfer->type) {
|
|
2158
2356
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
@@ -2160,21 +2358,11 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
|
|
2160
2358
|
if (tpriv->reap_action == ERROR)
|
|
2161
2359
|
break;
|
|
2162
2360
|
/* else, fall through */
|
|
2163
|
-
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
2164
|
-
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2165
|
-
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2166
|
-
tpriv->reap_action = CANCELLED;
|
|
2167
|
-
break;
|
|
2168
2361
|
default:
|
|
2169
|
-
|
|
2170
|
-
"unknown endpoint type %d", transfer->type);
|
|
2171
|
-
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2362
|
+
tpriv->reap_action = CANCELLED;
|
|
2172
2363
|
}
|
|
2173
2364
|
|
|
2174
|
-
|
|
2175
|
-
return LIBUSB_ERROR_NOT_FOUND;
|
|
2176
|
-
|
|
2177
|
-
return discard_urbs(itransfer, 0, tpriv->num_urbs);
|
|
2365
|
+
return 0;
|
|
2178
2366
|
}
|
|
2179
2367
|
|
|
2180
2368
|
static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
@@ -2183,23 +2371,21 @@ static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
|
2183
2371
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2184
2372
|
struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
|
|
2185
2373
|
|
|
2186
|
-
/* urbs can be freed also in submit_transfer so lock mutex first */
|
|
2187
2374
|
switch (transfer->type) {
|
|
2188
2375
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
2189
2376
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
2190
2377
|
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2191
2378
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2192
|
-
|
|
2193
|
-
if (tpriv->urbs)
|
|
2379
|
+
if (tpriv->urbs) {
|
|
2194
2380
|
free(tpriv->urbs);
|
|
2195
|
-
|
|
2196
|
-
|
|
2381
|
+
tpriv->urbs = NULL;
|
|
2382
|
+
}
|
|
2197
2383
|
break;
|
|
2198
2384
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2199
|
-
|
|
2200
|
-
if (tpriv->iso_urbs)
|
|
2385
|
+
if (tpriv->iso_urbs) {
|
|
2201
2386
|
free_iso_urbs(tpriv);
|
|
2202
|
-
|
|
2387
|
+
tpriv->iso_urbs = NULL;
|
|
2388
|
+
}
|
|
2203
2389
|
break;
|
|
2204
2390
|
default:
|
|
2205
2391
|
usbi_err(TRANSFER_CTX(transfer),
|
|
@@ -2244,7 +2430,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
|
|
2244
2430
|
unsigned char *target = transfer->buffer + itransfer->transferred;
|
|
2245
2431
|
usbi_dbg("received %d bytes of surplus data", urb->actual_length);
|
|
2246
2432
|
if (urb->buffer != target) {
|
|
2247
|
-
usbi_dbg("moving surplus data from offset %
|
|
2433
|
+
usbi_dbg("moving surplus data from offset %zd to offset %zd",
|
|
2248
2434
|
(unsigned char *) urb->buffer - transfer->buffer,
|
|
2249
2435
|
target - transfer->buffer);
|
|
2250
2436
|
memmove(target, urb->buffer, urb->actual_length);
|
|
@@ -2530,7 +2716,7 @@ static int reap_for_handle(struct libusb_device_handle *handle)
|
|
|
2530
2716
|
{
|
|
2531
2717
|
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
|
|
2532
2718
|
int r;
|
|
2533
|
-
struct usbfs_urb *urb;
|
|
2719
|
+
struct usbfs_urb *urb = NULL;
|
|
2534
2720
|
struct usbi_transfer *itransfer;
|
|
2535
2721
|
struct libusb_transfer *transfer;
|
|
2536
2722
|
|
|
@@ -2591,21 +2777,33 @@ static int op_handle_events(struct libusb_context *ctx,
|
|
|
2591
2777
|
}
|
|
2592
2778
|
|
|
2593
2779
|
if (!hpriv || hpriv->fd != pollfd->fd) {
|
|
2594
|
-
usbi_err(ctx, "cannot find handle for fd %d
|
|
2780
|
+
usbi_err(ctx, "cannot find handle for fd %d",
|
|
2595
2781
|
pollfd->fd);
|
|
2596
2782
|
continue;
|
|
2597
2783
|
}
|
|
2598
2784
|
|
|
2599
2785
|
if (pollfd->revents & POLLERR) {
|
|
2786
|
+
/* remove the fd from the pollfd set so that it doesn't continuously
|
|
2787
|
+
* trigger an event, and flag that it has been removed so op_close()
|
|
2788
|
+
* doesn't try to remove it a second time */
|
|
2600
2789
|
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd);
|
|
2601
|
-
|
|
2790
|
+
hpriv->fd_removed = 1;
|
|
2791
|
+
|
|
2602
2792
|
/* device will still be marked as attached if hotplug monitor thread
|
|
2603
2793
|
* hasn't processed remove event yet */
|
|
2604
2794
|
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
2605
2795
|
if (handle->dev->attached)
|
|
2606
2796
|
linux_device_disconnected(handle->dev->bus_number,
|
|
2607
|
-
handle->dev->device_address
|
|
2797
|
+
handle->dev->device_address);
|
|
2608
2798
|
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
2799
|
+
|
|
2800
|
+
if (hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT) {
|
|
2801
|
+
do {
|
|
2802
|
+
r = reap_for_handle(handle);
|
|
2803
|
+
} while (r == 0);
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
usbi_handle_disconnect(handle);
|
|
2609
2807
|
continue;
|
|
2610
2808
|
}
|
|
2611
2809
|
|
|
@@ -2644,9 +2842,9 @@ static clockid_t op_get_timerfd_clockid(void)
|
|
|
2644
2842
|
}
|
|
2645
2843
|
#endif
|
|
2646
2844
|
|
|
2647
|
-
const struct usbi_os_backend
|
|
2845
|
+
const struct usbi_os_backend usbi_backend = {
|
|
2648
2846
|
.name = "Linux usbfs",
|
|
2649
|
-
.caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER
|
|
2847
|
+
.caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
|
|
2650
2848
|
.init = op_init,
|
|
2651
2849
|
.exit = op_exit,
|
|
2652
2850
|
.get_device_list = NULL,
|
|
@@ -2656,6 +2854,7 @@ const struct usbi_os_backend linux_usbfs_backend = {
|
|
|
2656
2854
|
.get_config_descriptor = op_get_config_descriptor,
|
|
2657
2855
|
.get_config_descriptor_by_value = op_get_config_descriptor_by_value,
|
|
2658
2856
|
|
|
2857
|
+
.wrap_sys_device = op_wrap_sys_device,
|
|
2659
2858
|
.open = op_open,
|
|
2660
2859
|
.close = op_close,
|
|
2661
2860
|
.get_configuration = op_get_configuration,
|
|
@@ -2670,6 +2869,9 @@ const struct usbi_os_backend linux_usbfs_backend = {
|
|
|
2670
2869
|
.alloc_streams = op_alloc_streams,
|
|
2671
2870
|
.free_streams = op_free_streams,
|
|
2672
2871
|
|
|
2872
|
+
.dev_mem_alloc = op_dev_mem_alloc,
|
|
2873
|
+
.dev_mem_free = op_dev_mem_free,
|
|
2874
|
+
|
|
2673
2875
|
.kernel_driver_active = op_kernel_driver_active,
|
|
2674
2876
|
.detach_kernel_driver = op_detach_kernel_driver,
|
|
2675
2877
|
.attach_kernel_driver = op_attach_kernel_driver,
|
|
@@ -2691,5 +2893,4 @@ const struct usbi_os_backend linux_usbfs_backend = {
|
|
|
2691
2893
|
.device_priv_size = sizeof(struct linux_device_priv),
|
|
2692
2894
|
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
|
|
2693
2895
|
.transfer_priv_size = sizeof(struct linux_transfer_priv),
|
|
2694
|
-
.add_iso_packet_size = 0,
|
|
2695
2896
|
};
|