usb 2.1.3 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +19 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/usb/bindings.d.ts +4 -0
- package/dist/usb/device.js +5 -0
- package/dist/usb/device.js.map +1 -1
- package/dist/usb/index.js +7 -16
- package/dist/usb/index.js.map +1 -1
- package/dist/webusb/webusb-device.d.ts +0 -1
- package/dist/webusb/webusb-device.js +149 -243
- package/dist/webusb/webusb-device.js.map +1 -1
- package/libusb/.gitattributes +2 -6
- package/libusb/.private/appveyor_build.sh +22 -0
- package/libusb/.private/bm.sh +1 -1
- package/libusb/.private/ci-build.sh +67 -0
- package/libusb/.private/ci-container-build.sh +70 -0
- package/libusb/.private/post-rewrite.sh +5 -1
- package/libusb/.private/pre-commit.sh +5 -1
- package/libusb/.private/wbs.txt +4 -19
- package/libusb/.travis.yml +32 -23
- package/libusb/AUTHORS +86 -3
- package/libusb/ChangeLog +54 -3
- package/libusb/INSTALL_WIN.txt +22 -44
- package/libusb/Makefile.am +32 -10
- package/libusb/{README.md → README} +2 -2
- package/libusb/README.git +3 -3
- package/libusb/Xcode/common.xcconfig +23 -19
- package/libusb/Xcode/config.h +25 -13
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +511 -109
- package/libusb/android/README +90 -54
- package/libusb/android/config.h +23 -43
- package/libusb/android/examples/unrooted_android.c +300 -0
- package/libusb/android/examples/unrooted_android.h +36 -0
- package/libusb/android/jni/Android.mk +1 -1
- package/libusb/android/jni/Application.mk +16 -0
- package/libusb/android/jni/examples.mk +63 -29
- package/libusb/android/jni/libusb.mk +14 -8
- package/libusb/android/jni/tests.mk +13 -24
- package/libusb/appveyor.yml +73 -30
- package/libusb/autogen.sh +5 -3
- package/libusb/bootstrap.sh +6 -2
- package/libusb/configure.ac +314 -227
- package/libusb/doc/Makefile.in +22 -0
- package/libusb/doc/doxygen.cfg.in +460 -223
- package/libusb/examples/Makefile.am +6 -13
- package/libusb/examples/dpfp.c +276 -73
- package/libusb/examples/ezusb.c +18 -8
- package/libusb/examples/ezusb.h +6 -17
- package/libusb/examples/fxload.c +4 -5
- package/libusb/examples/hotplugtest.c +1 -1
- package/libusb/examples/sam3u_benchmark.c +59 -24
- package/libusb/examples/testlibusb.c +138 -104
- package/libusb/examples/xusb.c +26 -22
- package/libusb/libusb/Makefile.am +57 -70
- package/libusb/libusb/Makefile.am.extra +26 -0
- package/libusb/libusb/core.c +432 -423
- package/libusb/libusb/descriptor.c +365 -419
- package/libusb/libusb/hotplug.c +200 -104
- package/libusb/libusb/io.c +522 -535
- package/libusb/libusb/libusb-1.0.def +7 -3
- package/libusb/libusb/libusb-1.0.rc +1 -9
- package/libusb/libusb/libusb.h +302 -226
- package/libusb/libusb/libusbi.h +607 -316
- package/libusb/libusb/os/darwin_usb.c +703 -329
- package/libusb/libusb/os/darwin_usb.h +39 -15
- package/libusb/libusb/os/events_posix.c +300 -0
- package/libusb/libusb/os/events_posix.h +59 -0
- package/libusb/libusb/os/events_windows.c +214 -0
- package/libusb/{msvc/missing.h → libusb/os/events_windows.h} +25 -11
- package/libusb/libusb/os/haiku_pollfs.cpp +14 -9
- package/libusb/libusb/os/haiku_usb.h +12 -12
- package/libusb/libusb/os/haiku_usb_backend.cpp +36 -37
- package/libusb/libusb/os/haiku_usb_raw.cpp +80 -116
- package/libusb/libusb/os/linux_netlink.c +55 -63
- package/libusb/libusb/os/linux_udev.c +61 -69
- package/libusb/libusb/os/linux_usbfs.c +926 -1015
- package/libusb/libusb/os/linux_usbfs.h +74 -57
- package/libusb/libusb/os/netbsd_usb.c +103 -168
- package/libusb/libusb/os/null_usb.c +111 -0
- package/libusb/libusb/os/openbsd_usb.c +71 -120
- package/libusb/libusb/os/sunos_usb.c +289 -375
- package/libusb/libusb/os/sunos_usb.h +0 -1
- package/libusb/libusb/os/threads_posix.c +81 -32
- package/libusb/libusb/os/threads_posix.h +19 -23
- package/libusb/libusb/os/threads_windows.c +9 -95
- package/libusb/libusb/os/threads_windows.h +33 -31
- package/libusb/libusb/os/windows_common.c +915 -0
- package/libusb/libusb/os/windows_common.h +330 -42
- package/libusb/libusb/os/windows_usbdk.c +161 -267
- package/libusb/libusb/os/windows_usbdk.h +5 -2
- package/libusb/libusb/os/windows_winusb.c +1355 -1192
- package/libusb/libusb/os/windows_winusb.h +167 -167
- package/libusb/libusb/strerror.c +20 -30
- package/libusb/libusb/sync.c +20 -21
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/msvc/.gitattributes +3 -0
- package/libusb/msvc/config.h +27 -20
- package/libusb/msvc/{hotplugtest_2012.vcxproj → dpfp_2013.vcxproj} +14 -10
- package/libusb/msvc/dpfp_2013.vcxproj.filters +26 -0
- package/libusb/msvc/{hotplugtest_2010.vcxproj → dpfp_2015.vcxproj} +14 -9
- package/libusb/msvc/dpfp_2015.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_2017.vcxproj +106 -0
- package/libusb/msvc/dpfp_2017.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_2019.vcxproj +106 -0
- package/libusb/msvc/dpfp_2019.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2013.vcxproj +87 -0
- package/libusb/msvc/dpfp_threaded_2013.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2015.vcxproj +87 -0
- package/libusb/msvc/dpfp_threaded_2015.vcxproj.filters +26 -0
- package/libusb/msvc/dpfp_threaded_2017.vcxproj +106 -0
- package/libusb/msvc/dpfp_threaded_2017.vcxproj.filters +26 -0
- package/libusb/msvc/{fxload_2012.vcxproj → dpfp_threaded_2019.vcxproj} +32 -17
- package/libusb/msvc/dpfp_threaded_2019.vcxproj.filters +26 -0
- package/libusb/msvc/fxload_2013.vcxproj +6 -3
- package/libusb/msvc/fxload_2013.vcxproj.filters +35 -0
- package/libusb/msvc/fxload_2015.vcxproj +6 -3
- package/libusb/msvc/fxload_2015.vcxproj.filters +35 -0
- package/libusb/msvc/fxload_2017.vcxproj +6 -7
- package/libusb/msvc/fxload_2017.vcxproj.filters +35 -0
- package/libusb/msvc/{fxload_2010.vcxproj → fxload_2019.vcxproj} +29 -6
- package/libusb/msvc/fxload_2019.vcxproj.filters +35 -0
- package/libusb/{examples → msvc}/getopt/getopt.c +0 -0
- package/libusb/{examples → msvc}/getopt/getopt.h +0 -0
- package/libusb/{examples → msvc}/getopt/getopt1.c +0 -0
- package/libusb/msvc/getopt_2013.vcxproj +4 -5
- package/libusb/msvc/getopt_2013.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2015.vcxproj +4 -4
- package/libusb/msvc/getopt_2015.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2017.vcxproj +4 -10
- package/libusb/msvc/getopt_2017.vcxproj.filters +26 -0
- package/libusb/msvc/{getopt_2010.vcxproj → getopt_2019.vcxproj} +25 -5
- package/libusb/msvc/getopt_2019.vcxproj.filters +26 -0
- package/libusb/msvc/hotplugtest_2013.vcxproj +6 -3
- package/libusb/msvc/hotplugtest_2013.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2015.vcxproj +6 -3
- package/libusb/msvc/hotplugtest_2015.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +6 -7
- package/libusb/msvc/hotplugtest_2017.vcxproj.filters +23 -0
- package/libusb/msvc/hotplugtest_2019.vcxproj +105 -0
- package/libusb/msvc/hotplugtest_2019.vcxproj.filters +23 -0
- package/libusb/msvc/libusb_2013.sln +50 -20
- package/libusb/msvc/libusb_2015.sln +51 -21
- package/libusb/msvc/libusb_2017.sln +90 -36
- package/libusb/msvc/libusb_2019.sln +240 -0
- package/libusb/msvc/libusb_dll_2013.vcxproj +6 -9
- package/libusb/msvc/libusb_dll_2013.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_dll_2015.vcxproj +6 -8
- package/libusb/msvc/libusb_dll_2015.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +6 -16
- package/libusb/msvc/libusb_dll_2017.vcxproj.filters +94 -0
- package/libusb/msvc/{libusb_dll_2010.vcxproj → libusb_dll_2019.vcxproj} +27 -9
- package/libusb/msvc/libusb_dll_2019.vcxproj.filters +94 -0
- package/libusb/msvc/libusb_static_2013.vcxproj +5 -9
- package/libusb/msvc/libusb_static_2013.vcxproj.filters +80 -0
- package/libusb/msvc/libusb_static_2015.vcxproj +5 -8
- package/libusb/msvc/libusb_static_2015.vcxproj.filters +80 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +5 -8
- package/libusb/msvc/libusb_static_2017.vcxproj.filters +80 -0
- package/libusb/msvc/{libusb_static_2010.vcxproj → libusb_static_2019.vcxproj} +26 -9
- package/libusb/msvc/libusb_static_2019.vcxproj.filters +80 -0
- package/libusb/msvc/listdevs_2013.vcxproj +6 -3
- package/libusb/msvc/listdevs_2013.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2015.vcxproj +6 -3
- package/libusb/msvc/listdevs_2015.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2017.vcxproj +6 -7
- package/libusb/msvc/listdevs_2017.vcxproj.filters +23 -0
- package/libusb/msvc/listdevs_2019.vcxproj +105 -0
- package/libusb/msvc/listdevs_2019.vcxproj.filters +23 -0
- package/libusb/msvc/{listdevs_2010.vcxproj → sam3u_benchmark_2013.vcxproj} +13 -8
- package/libusb/msvc/sam3u_benchmark_2013.vcxproj.filters +26 -0
- package/libusb/msvc/{listdevs_2012.vcxproj → sam3u_benchmark_2015.vcxproj} +13 -9
- package/libusb/msvc/sam3u_benchmark_2015.vcxproj.filters +26 -0
- package/libusb/msvc/sam3u_benchmark_2017.vcxproj +106 -0
- package/libusb/msvc/sam3u_benchmark_2017.vcxproj.filters +26 -0
- package/libusb/msvc/sam3u_benchmark_2019.vcxproj +106 -0
- package/libusb/msvc/sam3u_benchmark_2019.vcxproj.filters +26 -0
- package/libusb/msvc/stress_2013.vcxproj +4 -2
- package/libusb/msvc/stress_2013.vcxproj.filters +32 -0
- package/libusb/msvc/stress_2015.vcxproj +4 -2
- package/libusb/msvc/stress_2015.vcxproj.filters +32 -0
- package/libusb/msvc/stress_2017.vcxproj +4 -6
- package/libusb/msvc/stress_2017.vcxproj.filters +32 -0
- package/libusb/msvc/{stress_2010.vcxproj → stress_2019.vcxproj} +26 -4
- package/libusb/msvc/stress_2019.vcxproj.filters +32 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +6 -3
- package/libusb/msvc/testlibusb_2013.vcxproj.filters +23 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +6 -3
- package/libusb/msvc/testlibusb_2015.vcxproj.filters +23 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +6 -7
- package/libusb/msvc/testlibusb_2017.vcxproj.filters +23 -0
- package/libusb/msvc/{testlibusb_2010.vcxproj → testlibusb_2019.vcxproj} +28 -5
- package/libusb/msvc/testlibusb_2019.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2013.vcxproj +6 -3
- package/libusb/msvc/xusb_2013.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2015.vcxproj +6 -3
- package/libusb/msvc/xusb_2015.vcxproj.filters +23 -0
- package/libusb/msvc/xusb_2017.vcxproj +6 -7
- package/libusb/msvc/xusb_2017.vcxproj.filters +23 -0
- package/libusb/msvc/{xusb_2010.vcxproj → xusb_2019.vcxproj} +28 -5
- package/libusb/msvc/xusb_2019.vcxproj.filters +23 -0
- package/libusb/tests/Makefile.am +13 -1
- package/libusb/tests/libusb_testlib.h +12 -43
- package/libusb/tests/stress.c +59 -50
- package/libusb/tests/testlib.c +78 -171
- package/libusb/tests/umockdev.c +1175 -0
- package/libusb.gypi +10 -11
- package/package.json +1 -1
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +12 -7
- package/src/node_usb.cc +10 -0
- package/test/usb.coffee +6 -0
- package/tsc/index.ts +2 -0
- package/tsc/usb/bindings.ts +5 -0
- package/tsc/usb/device.ts +6 -0
- package/tsc/usb/index.ts +5 -8
- package/tsc/webusb/webusb-device.ts +67 -124
- package/dist/webusb/mutex.d.ts +0 -22
- package/dist/webusb/mutex.js +0 -89
- package/dist/webusb/mutex.js.map +0 -1
- package/libusb/.private/bd.cmd +0 -89
- package/libusb/.private/bwince.cmd +0 -57
- package/libusb/.private/wbs_wince.txt +0 -42
- package/libusb/Brewfile +0 -4
- package/libusb/appveyor_cygwin.bat +0 -11
- package/libusb/appveyor_minGW.bat +0 -19
- package/libusb/doc/Makefile.am +0 -9
- package/libusb/examples/dpfp_threaded.c +0 -557
- package/libusb/libusb/hotplug.h +0 -99
- package/libusb/libusb/os/poll_posix.c +0 -84
- package/libusb/libusb/os/poll_posix.h +0 -14
- package/libusb/libusb/os/poll_windows.c +0 -447
- package/libusb/libusb/os/poll_windows.h +0 -98
- package/libusb/libusb/os/wince_usb.c +0 -888
- package/libusb/libusb/os/wince_usb.h +0 -126
- package/libusb/libusb/os/windows_nt_common.c +0 -1010
- package/libusb/libusb/os/windows_nt_common.h +0 -110
- package/libusb/libusb/os/windows_nt_shared_types.h +0 -147
- package/libusb/msvc/appveyor.bat +0 -27
- package/libusb/msvc/ddk_build.cmd +0 -219
- package/libusb/msvc/errno.h +0 -102
- package/libusb/msvc/fxload_sources +0 -23
- package/libusb/msvc/getopt_2005.vcproj +0 -288
- package/libusb/msvc/getopt_2012.vcxproj +0 -73
- package/libusb/msvc/getopt_sources +0 -24
- package/libusb/msvc/hotplugtest_sources +0 -20
- package/libusb/msvc/inttypes.h +0 -295
- package/libusb/msvc/libusb.dsw +0 -71
- package/libusb/msvc/libusb_2005.sln +0 -95
- package/libusb/msvc/libusb_2010.sln +0 -105
- package/libusb/msvc/libusb_2012.sln +0 -105
- package/libusb/msvc/libusb_dll.dsp +0 -194
- package/libusb/msvc/libusb_dll_2005.vcproj +0 -464
- package/libusb/msvc/libusb_dll_2012.vcxproj +0 -107
- package/libusb/msvc/libusb_dll_wince.vcproj +0 -1251
- package/libusb/msvc/libusb_sources +0 -43
- package/libusb/msvc/libusb_static.dsp +0 -174
- package/libusb/msvc/libusb_static_2005.vcproj +0 -390
- package/libusb/msvc/libusb_static_2012.vcxproj +0 -98
- package/libusb/msvc/libusb_static_wince.vcproj +0 -1179
- package/libusb/msvc/libusb_wince.sln +0 -246
- package/libusb/msvc/listdevs.dsp +0 -103
- package/libusb/msvc/listdevs_2005.vcproj +0 -360
- package/libusb/msvc/listdevs_sources +0 -20
- package/libusb/msvc/listdevs_wince.vcproj +0 -1120
- package/libusb/msvc/missing.c +0 -80
- package/libusb/msvc/stdint.h +0 -256
- package/libusb/msvc/stress_2005.vcproj +0 -390
- package/libusb/msvc/stress_2012.vcxproj +0 -87
- package/libusb/msvc/stress_sources +0 -21
- package/libusb/msvc/stress_wince.vcproj +0 -1128
- package/libusb/msvc/testlibusb_2012.vcxproj +0 -83
- package/libusb/msvc/testlibusb_sources +0 -20
- package/libusb/msvc/xusb.dsp +0 -102
- package/libusb/msvc/xusb_2005.vcproj +0 -344
- package/libusb/msvc/xusb_2012.vcxproj +0 -83
- package/libusb/msvc/xusb_sources +0 -20
- package/libusb/msvc/xusb_wince.vcproj +0 -1120
- package/libusb/travis-autogen.sh +0 -39
- package/tsc/webusb/mutex.ts +0 -38
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
|
6
6
|
* Copyright © 2013 Nathan Hjelm <hjelmn@mac.com>
|
|
7
7
|
* Copyright © 2012-2013 Hans de Goede <hdegoede@redhat.com>
|
|
8
|
+
* Copyright © 2020 Chris Dickens <christopher.a.dickens@gmail.com>
|
|
8
9
|
*
|
|
9
10
|
* This library is free software; you can redistribute it and/or
|
|
10
11
|
* modify it under the terms of the GNU Lesser General Public
|
|
@@ -21,26 +22,21 @@
|
|
|
21
22
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
|
-
#include "
|
|
25
|
+
#include "libusbi.h"
|
|
26
|
+
#include "linux_usbfs.h"
|
|
25
27
|
|
|
26
|
-
#include <
|
|
28
|
+
#include <alloca.h>
|
|
27
29
|
#include <ctype.h>
|
|
28
30
|
#include <dirent.h>
|
|
29
31
|
#include <errno.h>
|
|
30
32
|
#include <fcntl.h>
|
|
31
|
-
#include <poll.h>
|
|
32
33
|
#include <stdio.h>
|
|
33
|
-
#include <stdlib.h>
|
|
34
34
|
#include <string.h>
|
|
35
35
|
#include <sys/ioctl.h>
|
|
36
36
|
#include <sys/mman.h>
|
|
37
|
-
#include <sys/stat.h>
|
|
38
|
-
#include <sys/types.h>
|
|
39
37
|
#include <sys/utsname.h>
|
|
40
|
-
#include <
|
|
41
|
-
|
|
42
|
-
#include "libusbi.h"
|
|
43
|
-
#include "linux_usbfs.h"
|
|
38
|
+
#include <sys/vfs.h>
|
|
39
|
+
#include <unistd.h>
|
|
44
40
|
|
|
45
41
|
/* sysfs vs usbfs:
|
|
46
42
|
* opening a usbfs node causes the device to be resumed, so we attempt to
|
|
@@ -76,7 +72,8 @@
|
|
|
76
72
|
* In sysfs all descriptors are bus-endian.
|
|
77
73
|
*/
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
#define USBDEV_PATH "/dev"
|
|
76
|
+
#define USB_DEVTMPFS_PATH "/dev/bus/usb"
|
|
80
77
|
|
|
81
78
|
/* use usbdev*.* device names in /dev instead of the usbfs bus directories */
|
|
82
79
|
static int usbdev_names = 0;
|
|
@@ -86,67 +83,29 @@ static int usbdev_names = 0;
|
|
|
86
83
|
* (commit 3612242e527eb47ee4756b5350f8bdf791aa5ede) increased this value to
|
|
87
84
|
* 8,192 bytes to support higher bandwidth devices. Linux 3.10
|
|
88
85
|
* (commit e2e2f0ea1c935edcf53feb4c4c8fdb4f86d57dd9) further increased this
|
|
89
|
-
* value to 49,152 bytes to support super speed devices.
|
|
86
|
+
* value to 49,152 bytes to support super speed devices. Linux 5.2
|
|
87
|
+
* (commit 8a1dbc8d91d3d1602282c7e6b4222c7759c916fa) even further increased
|
|
88
|
+
* this value to 98,304 bytes to support super speed plus devices.
|
|
90
89
|
*/
|
|
91
90
|
static unsigned int max_iso_packet_len = 0;
|
|
92
91
|
|
|
93
|
-
/*
|
|
94
|
-
|
|
95
|
-
static int supports_flag_cloexec = -1;
|
|
96
|
-
|
|
97
|
-
/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically
|
|
98
|
-
* allows us to mark URBs as being part of a specific logical transfer when
|
|
99
|
-
* we submit them to the kernel. then, on any error except a cancellation, all
|
|
100
|
-
* URBs within that transfer will be cancelled and no more URBs will be
|
|
101
|
-
* accepted for the transfer, meaning that no more data can creep in.
|
|
102
|
-
*
|
|
103
|
-
* The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer
|
|
104
|
-
* (in either direction) except the first.
|
|
105
|
-
* For IN transfers, we must also set SHORT_NOT_OK on all URBs except the
|
|
106
|
-
* last; it means that the kernel should treat a short reply as an error.
|
|
107
|
-
* For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT
|
|
108
|
-
* transfers can't be short unless there's already some sort of error), and
|
|
109
|
-
* setting this flag is disallowed (a kernel with USB debugging enabled will
|
|
110
|
-
* reject such URBs).
|
|
111
|
-
*/
|
|
112
|
-
static int supports_flag_bulk_continuation = -1;
|
|
113
|
-
|
|
114
|
-
/* Linux 2.6.31 fixes support for the zero length packet URB flag. This
|
|
115
|
-
* allows us to mark URBs that should be followed by a zero length data
|
|
116
|
-
* packet, which can be required by device- or class-specific protocols.
|
|
117
|
-
*/
|
|
118
|
-
static int supports_flag_zero_packet = -1;
|
|
119
|
-
|
|
120
|
-
/* clock ID for monotonic clock, as not all clock sources are available on all
|
|
121
|
-
* systems. appropriate choice made at initialization time. */
|
|
122
|
-
static clockid_t monotonic_clkid = -1;
|
|
123
|
-
|
|
124
|
-
/* Linux 2.6.22 (commit 83f7d958eab2fbc6b159ee92bf1493924e1d0f72) adds a busnum
|
|
125
|
-
* to sysfs, so we can relate devices. This also implies that we can read
|
|
126
|
-
* the active configuration through bConfigurationValue */
|
|
127
|
-
static int sysfs_can_relate_devices = -1;
|
|
128
|
-
|
|
129
|
-
/* Linux 2.6.26 (commit 217a9081d8e69026186067711131b77f0ce219ed) adds all
|
|
130
|
-
* config descriptors (rather then just the active config) to the sysfs
|
|
131
|
-
* descriptors file, so from then on we can use them. */
|
|
132
|
-
static int sysfs_has_descriptors = -1;
|
|
92
|
+
/* is sysfs available (mounted) ? */
|
|
93
|
+
static int sysfs_available = -1;
|
|
133
94
|
|
|
134
95
|
/* how many times have we initted (and not exited) ? */
|
|
135
96
|
static int init_count = 0;
|
|
136
97
|
|
|
137
|
-
/*
|
|
138
|
-
static
|
|
98
|
+
/* have no authority to operate usb device directly */
|
|
99
|
+
static int no_enumeration = 0;
|
|
100
|
+
|
|
139
101
|
/* Serialize scan-devices, event-thread, and poll */
|
|
140
102
|
usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER;
|
|
141
103
|
|
|
142
|
-
static int linux_start_event_monitor(void);
|
|
143
|
-
static int linux_stop_event_monitor(void);
|
|
144
104
|
static int linux_scan_devices(struct libusb_context *ctx);
|
|
145
|
-
static int
|
|
146
|
-
static int detach_kernel_driver_and_claim(struct libusb_device_handle *, int);
|
|
105
|
+
static int detach_kernel_driver_and_claim(struct libusb_device_handle *, uint8_t);
|
|
147
106
|
|
|
148
|
-
#if !defined(
|
|
149
|
-
static int linux_default_scan_devices
|
|
107
|
+
#if !defined(HAVE_LIBUDEV)
|
|
108
|
+
static int linux_default_scan_devices(struct libusb_context *ctx);
|
|
150
109
|
#endif
|
|
151
110
|
|
|
152
111
|
struct kernel_version {
|
|
@@ -155,11 +114,17 @@ struct kernel_version {
|
|
|
155
114
|
int sublevel;
|
|
156
115
|
};
|
|
157
116
|
|
|
117
|
+
struct config_descriptor {
|
|
118
|
+
struct usbi_configuration_descriptor *desc;
|
|
119
|
+
size_t actual_len;
|
|
120
|
+
};
|
|
121
|
+
|
|
158
122
|
struct linux_device_priv {
|
|
159
123
|
char *sysfs_dir;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
124
|
+
void *descriptors;
|
|
125
|
+
size_t descriptors_len;
|
|
126
|
+
struct config_descriptor *config_descriptors;
|
|
127
|
+
int active_config; /* cache val for !sysfs_available */
|
|
163
128
|
};
|
|
164
129
|
|
|
165
130
|
struct linux_device_handle_priv {
|
|
@@ -200,52 +165,57 @@ struct linux_transfer_priv {
|
|
|
200
165
|
int iso_packet_offset;
|
|
201
166
|
};
|
|
202
167
|
|
|
203
|
-
static int
|
|
168
|
+
static int dev_has_config0(struct libusb_device *dev)
|
|
204
169
|
{
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
170
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
171
|
+
struct config_descriptor *config;
|
|
172
|
+
uint8_t idx;
|
|
173
|
+
|
|
174
|
+
for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
|
|
175
|
+
config = &priv->config_descriptors[idx];
|
|
176
|
+
if (config->desc->bConfigurationValue == 0)
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return 0;
|
|
211
181
|
}
|
|
212
182
|
|
|
213
|
-
static int
|
|
183
|
+
static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
214
184
|
{
|
|
215
185
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
216
|
-
char path[
|
|
186
|
+
char path[24];
|
|
217
187
|
int fd;
|
|
218
|
-
int delay = 10000;
|
|
219
188
|
|
|
220
189
|
if (usbdev_names)
|
|
221
|
-
|
|
222
|
-
|
|
190
|
+
sprintf(path, USBDEV_PATH "/usbdev%u.%u",
|
|
191
|
+
dev->bus_number, dev->device_address);
|
|
223
192
|
else
|
|
224
|
-
|
|
225
|
-
|
|
193
|
+
sprintf(path, USB_DEVTMPFS_PATH "/%03u/%03u",
|
|
194
|
+
dev->bus_number, dev->device_address);
|
|
226
195
|
|
|
227
|
-
fd =
|
|
196
|
+
fd = open(path, mode | O_CLOEXEC);
|
|
228
197
|
if (fd != -1)
|
|
229
198
|
return fd; /* Success */
|
|
230
199
|
|
|
231
200
|
if (errno == ENOENT) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
201
|
+
const long delay_ms = 10L;
|
|
202
|
+
const struct timespec delay_ts = { 0L, delay_ms * 1000L * 1000L };
|
|
203
|
+
|
|
204
|
+
if (!silent)
|
|
205
|
+
usbi_err(ctx, "File doesn't exist, wait %ld ms and try again", delay_ms);
|
|
206
|
+
|
|
235
207
|
/* Wait 10ms for USB device path creation.*/
|
|
236
|
-
nanosleep(&
|
|
208
|
+
nanosleep(&delay_ts, NULL);
|
|
237
209
|
|
|
238
|
-
fd =
|
|
210
|
+
fd = open(path, mode | O_CLOEXEC);
|
|
239
211
|
if (fd != -1)
|
|
240
212
|
return fd; /* Success */
|
|
241
213
|
}
|
|
242
|
-
|
|
214
|
+
|
|
243
215
|
if (!silent) {
|
|
244
|
-
usbi_err(ctx, "libusb couldn't open USB device %s
|
|
245
|
-
path, strerror(errno));
|
|
216
|
+
usbi_err(ctx, "libusb couldn't open USB device %s, errno=%d", path, errno);
|
|
246
217
|
if (errno == EACCES && mode == O_RDWR)
|
|
247
|
-
usbi_err(ctx, "libusb requires write access to USB "
|
|
248
|
-
"device nodes.");
|
|
218
|
+
usbi_err(ctx, "libusb requires write access to USB device nodes");
|
|
249
219
|
}
|
|
250
220
|
|
|
251
221
|
if (errno == EACCES)
|
|
@@ -255,87 +225,69 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
|
255
225
|
return LIBUSB_ERROR_IO;
|
|
256
226
|
}
|
|
257
227
|
|
|
258
|
-
static struct linux_device_priv *_device_priv(struct libusb_device *dev)
|
|
259
|
-
{
|
|
260
|
-
return (struct linux_device_priv *) dev->os_priv;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
static struct linux_device_handle_priv *_device_handle_priv(
|
|
264
|
-
struct libusb_device_handle *handle)
|
|
265
|
-
{
|
|
266
|
-
return (struct linux_device_handle_priv *) handle->os_priv;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
228
|
/* check dirent for a /dev/usbdev%d.%d name
|
|
270
229
|
* optionally return bus/device on success */
|
|
271
|
-
static int
|
|
230
|
+
static int is_usbdev_entry(const char *name, uint8_t *bus_p, uint8_t *dev_p)
|
|
272
231
|
{
|
|
273
232
|
int busnum, devnum;
|
|
274
233
|
|
|
275
|
-
if (sscanf(
|
|
234
|
+
if (sscanf(name, "usbdev%d.%d", &busnum, &devnum) != 2)
|
|
235
|
+
return 0;
|
|
236
|
+
if (busnum < 0 || busnum > UINT8_MAX || devnum < 0 || devnum > UINT8_MAX) {
|
|
237
|
+
usbi_dbg(NULL, "invalid usbdev format '%s'", name);
|
|
276
238
|
return 0;
|
|
239
|
+
}
|
|
277
240
|
|
|
278
|
-
usbi_dbg("found: %s",
|
|
279
|
-
if (bus_p
|
|
280
|
-
*bus_p = busnum;
|
|
281
|
-
if (dev_p
|
|
282
|
-
*dev_p = devnum;
|
|
241
|
+
usbi_dbg(NULL, "found: %s", name);
|
|
242
|
+
if (bus_p)
|
|
243
|
+
*bus_p = (uint8_t)busnum;
|
|
244
|
+
if (dev_p)
|
|
245
|
+
*dev_p = (uint8_t)devnum;
|
|
283
246
|
return 1;
|
|
284
247
|
}
|
|
285
248
|
|
|
286
|
-
static
|
|
249
|
+
static const char *find_usbfs_path(void)
|
|
287
250
|
{
|
|
251
|
+
const char *path;
|
|
288
252
|
DIR *dir;
|
|
289
253
|
struct dirent *entry;
|
|
290
|
-
int found = 0;
|
|
291
254
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
255
|
+
path = USB_DEVTMPFS_PATH;
|
|
256
|
+
dir = opendir(path);
|
|
257
|
+
if (dir) {
|
|
258
|
+
while ((entry = readdir(dir))) {
|
|
259
|
+
if (entry->d_name[0] == '.')
|
|
260
|
+
continue;
|
|
295
261
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
262
|
+
/* We assume if we find any files that it must be the right place */
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
299
265
|
|
|
300
|
-
|
|
301
|
-
found = 1;
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
266
|
+
closedir(dir);
|
|
304
267
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
268
|
+
if (entry)
|
|
269
|
+
return path;
|
|
270
|
+
}
|
|
308
271
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
272
|
+
/* look for /dev/usbdev*.* if the normal place fails */
|
|
273
|
+
path = USBDEV_PATH;
|
|
274
|
+
dir = opendir(path);
|
|
275
|
+
if (dir) {
|
|
276
|
+
while ((entry = readdir(dir))) {
|
|
277
|
+
if (entry->d_name[0] == '.')
|
|
278
|
+
continue;
|
|
313
279
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
path = "/proc/bus/usb";
|
|
318
|
-
if (check_usb_vfs(path))
|
|
319
|
-
ret = path;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/* look for /dev/usbdev*.* if the normal places fail */
|
|
323
|
-
if (ret == NULL) {
|
|
324
|
-
struct dirent *entry;
|
|
325
|
-
DIR *dir;
|
|
326
|
-
|
|
327
|
-
path = "/dev";
|
|
328
|
-
dir = opendir(path);
|
|
329
|
-
if (dir != NULL) {
|
|
330
|
-
while ((entry = readdir(dir)) != NULL) {
|
|
331
|
-
if (_is_usbdev_entry(entry, NULL, NULL)) {
|
|
332
|
-
/* found one; that's enough */
|
|
333
|
-
ret = path;
|
|
334
|
-
usbdev_names = 1;
|
|
335
|
-
break;
|
|
336
|
-
}
|
|
280
|
+
if (is_usbdev_entry(entry->d_name, NULL, NULL)) {
|
|
281
|
+
/* found one; that's enough */
|
|
282
|
+
break;
|
|
337
283
|
}
|
|
338
|
-
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
closedir(dir);
|
|
287
|
+
|
|
288
|
+
if (entry) {
|
|
289
|
+
usbdev_names = 1;
|
|
290
|
+
return path;
|
|
339
291
|
}
|
|
340
292
|
}
|
|
341
293
|
|
|
@@ -344,34 +296,11 @@ static const char *find_usbfs_path(void)
|
|
|
344
296
|
* simply assume /dev/bus/usb rather then making libusb_init fail.
|
|
345
297
|
* Make the same assumption for Android where SELinux policies might block us
|
|
346
298
|
* from reading /dev on newer devices. */
|
|
347
|
-
#if defined(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (ret != NULL)
|
|
353
|
-
usbi_dbg("found usbfs at %s", ret);
|
|
354
|
-
|
|
355
|
-
return ret;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/* the monotonic clock is not usable on all systems (e.g. embedded ones often
|
|
359
|
-
* seem to lack it). fall back to REALTIME if we have to. */
|
|
360
|
-
static clockid_t find_monotonic_clock(void)
|
|
361
|
-
{
|
|
362
|
-
#ifdef CLOCK_MONOTONIC
|
|
363
|
-
struct timespec ts;
|
|
364
|
-
int r;
|
|
365
|
-
|
|
366
|
-
/* Linux 2.6.28 adds CLOCK_MONOTONIC_RAW but we don't use it
|
|
367
|
-
* because it's not available through timerfd */
|
|
368
|
-
r = clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
369
|
-
if (r == 0)
|
|
370
|
-
return CLOCK_MONOTONIC;
|
|
371
|
-
usbi_dbg("monotonic clock doesn't work, errno %d", errno);
|
|
299
|
+
#if defined(HAVE_LIBUDEV) || defined(__ANDROID__)
|
|
300
|
+
return USB_DEVTMPFS_PATH;
|
|
301
|
+
#else
|
|
302
|
+
return NULL;
|
|
372
303
|
#endif
|
|
373
|
-
|
|
374
|
-
return CLOCK_REALTIME;
|
|
375
304
|
}
|
|
376
305
|
|
|
377
306
|
static int get_kernel_version(struct libusb_context *ctx,
|
|
@@ -381,22 +310,20 @@ static int get_kernel_version(struct libusb_context *ctx,
|
|
|
381
310
|
int atoms;
|
|
382
311
|
|
|
383
312
|
if (uname(&uts) < 0) {
|
|
384
|
-
usbi_err(ctx, "uname failed, errno
|
|
313
|
+
usbi_err(ctx, "uname failed, errno=%d", errno);
|
|
385
314
|
return -1;
|
|
386
315
|
}
|
|
387
316
|
|
|
388
317
|
atoms = sscanf(uts.release, "%d.%d.%d", &ver->major, &ver->minor, &ver->sublevel);
|
|
389
|
-
if (atoms <
|
|
318
|
+
if (atoms < 2) {
|
|
390
319
|
usbi_err(ctx, "failed to parse uname release '%s'", uts.release);
|
|
391
320
|
return -1;
|
|
392
321
|
}
|
|
393
322
|
|
|
394
|
-
if (atoms < 2)
|
|
395
|
-
ver->minor = -1;
|
|
396
323
|
if (atoms < 3)
|
|
397
324
|
ver->sublevel = -1;
|
|
398
325
|
|
|
399
|
-
usbi_dbg("reported kernel version is %s", uts.release);
|
|
326
|
+
usbi_dbg(ctx, "reported kernel version is %s", uts.release);
|
|
400
327
|
|
|
401
328
|
return 0;
|
|
402
329
|
}
|
|
@@ -410,16 +337,14 @@ static int kernel_version_ge(const struct kernel_version *ver,
|
|
|
410
337
|
return 0;
|
|
411
338
|
|
|
412
339
|
/* kmajor == major */
|
|
413
|
-
if (ver->minor
|
|
414
|
-
return 0 == minor && 0 == sublevel;
|
|
415
|
-
else if (ver->minor > minor)
|
|
340
|
+
if (ver->minor > minor)
|
|
416
341
|
return 1;
|
|
417
342
|
else if (ver->minor < minor)
|
|
418
343
|
return 0;
|
|
419
344
|
|
|
420
345
|
/* kminor == minor */
|
|
421
346
|
if (ver->sublevel == -1)
|
|
422
|
-
return
|
|
347
|
+
return sublevel == 0;
|
|
423
348
|
|
|
424
349
|
return ver->sublevel >= sublevel;
|
|
425
350
|
}
|
|
@@ -427,79 +352,55 @@ static int kernel_version_ge(const struct kernel_version *ver,
|
|
|
427
352
|
static int op_init(struct libusb_context *ctx)
|
|
428
353
|
{
|
|
429
354
|
struct kernel_version kversion;
|
|
430
|
-
|
|
355
|
+
const char *usbfs_path;
|
|
431
356
|
int r;
|
|
432
357
|
|
|
433
|
-
usbfs_path = find_usbfs_path();
|
|
434
|
-
if (!usbfs_path) {
|
|
435
|
-
usbi_err(ctx, "could not find usbfs");
|
|
436
|
-
return LIBUSB_ERROR_OTHER;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (monotonic_clkid == -1)
|
|
440
|
-
monotonic_clkid = find_monotonic_clock();
|
|
441
|
-
|
|
442
358
|
if (get_kernel_version(ctx, &kversion) < 0)
|
|
443
359
|
return LIBUSB_ERROR_OTHER;
|
|
444
360
|
|
|
445
|
-
if (
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (supports_flag_bulk_continuation == -1) {
|
|
451
|
-
/* bulk continuation URB flag available from Linux 2.6.32 */
|
|
452
|
-
supports_flag_bulk_continuation = kernel_version_ge(&kversion,2,6,32);
|
|
361
|
+
if (!kernel_version_ge(&kversion, 2, 6, 32)) {
|
|
362
|
+
usbi_err(ctx, "kernel version is too old (reported as %d.%d.%d)",
|
|
363
|
+
kversion.major, kversion.minor,
|
|
364
|
+
kversion.sublevel != -1 ? kversion.sublevel : 0);
|
|
365
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
453
366
|
}
|
|
454
367
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
/* zero length packet URB flag fixed since Linux 2.6.31 */
|
|
460
|
-
supports_flag_zero_packet = kernel_version_ge(&kversion,2,6,31);
|
|
368
|
+
usbfs_path = find_usbfs_path();
|
|
369
|
+
if (!usbfs_path) {
|
|
370
|
+
usbi_err(ctx, "could not find usbfs");
|
|
371
|
+
return LIBUSB_ERROR_OTHER;
|
|
461
372
|
}
|
|
462
373
|
|
|
463
|
-
|
|
464
|
-
usbi_dbg("zero length packet flag supported");
|
|
374
|
+
usbi_dbg(ctx, "found usbfs at %s", usbfs_path);
|
|
465
375
|
|
|
466
376
|
if (!max_iso_packet_len) {
|
|
467
|
-
if (kernel_version_ge(&kversion,
|
|
377
|
+
if (kernel_version_ge(&kversion, 5, 2, 0))
|
|
378
|
+
max_iso_packet_len = 98304;
|
|
379
|
+
else if (kernel_version_ge(&kversion, 3, 10, 0))
|
|
468
380
|
max_iso_packet_len = 49152;
|
|
469
|
-
else if (kernel_version_ge(&kversion,2,6,18))
|
|
470
|
-
max_iso_packet_len = 8192;
|
|
471
381
|
else
|
|
472
|
-
max_iso_packet_len =
|
|
382
|
+
max_iso_packet_len = 8192;
|
|
473
383
|
}
|
|
474
384
|
|
|
475
|
-
usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len);
|
|
385
|
+
usbi_dbg(ctx, "max iso packet length is (likely) %u bytes", max_iso_packet_len);
|
|
476
386
|
|
|
477
|
-
if (
|
|
478
|
-
|
|
479
|
-
sysfs_has_descriptors = kernel_version_ge(&kversion,2,6,26);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
if (-1 == sysfs_can_relate_devices) {
|
|
483
|
-
/* sysfs has busnum since Linux 2.6.22 */
|
|
484
|
-
sysfs_can_relate_devices = kernel_version_ge(&kversion,2,6,22);
|
|
485
|
-
}
|
|
387
|
+
if (sysfs_available == -1) {
|
|
388
|
+
struct statfs statfsbuf;
|
|
486
389
|
|
|
487
|
-
|
|
488
|
-
r
|
|
489
|
-
|
|
390
|
+
r = statfs(SYSFS_MOUNT_PATH, &statfsbuf);
|
|
391
|
+
if (r == 0 && statfsbuf.f_type == SYSFS_MAGIC) {
|
|
392
|
+
usbi_dbg(ctx, "sysfs is available");
|
|
393
|
+
sysfs_available = 1;
|
|
394
|
+
} else {
|
|
490
395
|
usbi_warn(ctx, "sysfs not mounted");
|
|
491
|
-
|
|
492
|
-
sysfs_has_descriptors = 0;
|
|
396
|
+
sysfs_available = 0;
|
|
493
397
|
}
|
|
494
398
|
}
|
|
495
399
|
|
|
496
|
-
if (
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if (sysfs_has_descriptors)
|
|
500
|
-
usbi_dbg("sysfs has complete descriptors");
|
|
400
|
+
if (no_enumeration) {
|
|
401
|
+
return LIBUSB_SUCCESS;
|
|
402
|
+
}
|
|
501
403
|
|
|
502
|
-
usbi_mutex_static_lock(&linux_hotplug_startstop_lock);
|
|
503
404
|
r = LIBUSB_SUCCESS;
|
|
504
405
|
if (init_count == 0) {
|
|
505
406
|
/* start up hotplug event handler */
|
|
@@ -511,9 +412,9 @@ static int op_init(struct libusb_context *ctx)
|
|
|
511
412
|
init_count++;
|
|
512
413
|
else if (init_count == 0)
|
|
513
414
|
linux_stop_event_monitor();
|
|
514
|
-
} else
|
|
415
|
+
} else {
|
|
515
416
|
usbi_err(ctx, "error starting hotplug event monitor");
|
|
516
|
-
|
|
417
|
+
}
|
|
517
418
|
|
|
518
419
|
return r;
|
|
519
420
|
}
|
|
@@ -521,46 +422,41 @@ static int op_init(struct libusb_context *ctx)
|
|
|
521
422
|
static void op_exit(struct libusb_context *ctx)
|
|
522
423
|
{
|
|
523
424
|
UNUSED(ctx);
|
|
524
|
-
|
|
425
|
+
|
|
426
|
+
if (no_enumeration) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
525
430
|
assert(init_count != 0);
|
|
526
431
|
if (!--init_count) {
|
|
527
432
|
/* tear down event handler */
|
|
528
|
-
|
|
433
|
+
linux_stop_event_monitor();
|
|
529
434
|
}
|
|
530
|
-
usbi_mutex_static_unlock(&linux_hotplug_startstop_lock);
|
|
531
435
|
}
|
|
532
436
|
|
|
533
|
-
static int
|
|
437
|
+
static int op_set_option(struct libusb_context *ctx, enum libusb_option option, va_list ap)
|
|
534
438
|
{
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
#elif !defined(__ANDROID__)
|
|
538
|
-
return linux_netlink_start_event_monitor();
|
|
539
|
-
#else
|
|
540
|
-
return LIBUSB_SUCCESS;
|
|
541
|
-
#endif
|
|
542
|
-
}
|
|
439
|
+
UNUSED(ctx);
|
|
440
|
+
UNUSED(ap);
|
|
543
441
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
return LIBUSB_SUCCESS;
|
|
552
|
-
#endif
|
|
442
|
+
if (option == LIBUSB_OPTION_NO_DEVICE_DISCOVERY) {
|
|
443
|
+
usbi_dbg(ctx, "no enumeration will be performed");
|
|
444
|
+
no_enumeration = 1;
|
|
445
|
+
return LIBUSB_SUCCESS;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
553
449
|
}
|
|
554
450
|
|
|
555
451
|
static int linux_scan_devices(struct libusb_context *ctx)
|
|
556
452
|
{
|
|
557
|
-
int ret
|
|
453
|
+
int ret;
|
|
558
454
|
|
|
559
455
|
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
560
456
|
|
|
561
|
-
#if defined(
|
|
457
|
+
#if defined(HAVE_LIBUDEV)
|
|
562
458
|
ret = linux_udev_scan_devices(ctx);
|
|
563
|
-
#
|
|
459
|
+
#else
|
|
564
460
|
ret = linux_default_scan_devices(ctx);
|
|
565
461
|
#endif
|
|
566
462
|
|
|
@@ -571,25 +467,24 @@ static int linux_scan_devices(struct libusb_context *ctx)
|
|
|
571
467
|
|
|
572
468
|
static void op_hotplug_poll(void)
|
|
573
469
|
{
|
|
574
|
-
|
|
575
|
-
linux_udev_hotplug_poll();
|
|
576
|
-
#elif !defined(__ANDROID__)
|
|
577
|
-
linux_netlink_hotplug_poll();
|
|
578
|
-
#endif
|
|
470
|
+
linux_hotplug_poll();
|
|
579
471
|
}
|
|
580
472
|
|
|
581
|
-
static int
|
|
473
|
+
static int open_sysfs_attr(struct libusb_context *ctx,
|
|
474
|
+
const char *sysfs_dir, const char *attr)
|
|
582
475
|
{
|
|
583
|
-
|
|
584
|
-
char filename[PATH_MAX];
|
|
476
|
+
char filename[256];
|
|
585
477
|
int fd;
|
|
586
478
|
|
|
587
|
-
snprintf(filename,
|
|
588
|
-
|
|
589
|
-
fd = _open(filename, O_RDONLY);
|
|
479
|
+
snprintf(filename, sizeof(filename), SYSFS_DEVICE_PATH "/%s/%s", sysfs_dir, attr);
|
|
480
|
+
fd = open(filename, O_RDONLY | O_CLOEXEC);
|
|
590
481
|
if (fd < 0) {
|
|
591
|
-
|
|
592
|
-
|
|
482
|
+
if (errno == ENOENT) {
|
|
483
|
+
/* File doesn't exist. Assume the device has been
|
|
484
|
+
disconnected (see trac ticket #70). */
|
|
485
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
|
486
|
+
}
|
|
487
|
+
usbi_err(ctx, "open %s failed, errno=%d", filename, errno);
|
|
593
488
|
return LIBUSB_ERROR_IO;
|
|
594
489
|
}
|
|
595
490
|
|
|
@@ -597,291 +492,322 @@ static int _open_sysfs_attr(struct libusb_device *dev, const char *attr)
|
|
|
597
492
|
}
|
|
598
493
|
|
|
599
494
|
/* Note only suitable for attributes which always read >= 0, < 0 is error */
|
|
600
|
-
static int
|
|
601
|
-
const char *
|
|
495
|
+
static int read_sysfs_attr(struct libusb_context *ctx,
|
|
496
|
+
const char *sysfs_dir, const char *attr, int max_value, int *value_p)
|
|
602
497
|
{
|
|
603
|
-
char
|
|
604
|
-
|
|
605
|
-
|
|
498
|
+
char buf[20], *endptr;
|
|
499
|
+
long value;
|
|
500
|
+
ssize_t r;
|
|
501
|
+
int fd;
|
|
606
502
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
503
|
+
fd = open_sysfs_attr(ctx, sysfs_dir, attr);
|
|
504
|
+
if (fd < 0)
|
|
505
|
+
return fd;
|
|
506
|
+
|
|
507
|
+
r = read(fd, buf, sizeof(buf) - 1);
|
|
508
|
+
if (r < 0) {
|
|
509
|
+
r = errno;
|
|
510
|
+
close(fd);
|
|
511
|
+
if (r == ENODEV)
|
|
614
512
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
615
|
-
|
|
616
|
-
usbi_err(ctx, "open %s failed errno=%d", filename, errno);
|
|
513
|
+
usbi_err(ctx, "attribute %s read failed, errno=%zd", attr, r);
|
|
617
514
|
return LIBUSB_ERROR_IO;
|
|
618
515
|
}
|
|
516
|
+
close(fd);
|
|
619
517
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return
|
|
518
|
+
if (r == 0) {
|
|
519
|
+
/* Certain attributes (e.g. bConfigurationValue) are not
|
|
520
|
+
* populated if the device is not configured. */
|
|
521
|
+
*value_p = -1;
|
|
522
|
+
return 0;
|
|
625
523
|
}
|
|
626
524
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (
|
|
630
|
-
usbi_err(ctx, "
|
|
631
|
-
return LIBUSB_ERROR_NO_DEVICE; /* For unplug race (trac #70) */
|
|
632
|
-
}
|
|
633
|
-
if (value < 0) {
|
|
634
|
-
usbi_err(ctx, "%s contains a negative value", filename);
|
|
525
|
+
/* The kernel does *not* NUL-terminate the string, but every attribute
|
|
526
|
+
* should be terminated with a newline character. */
|
|
527
|
+
if (!isdigit(buf[0])) {
|
|
528
|
+
usbi_err(ctx, "attribute %s doesn't have numeric value?", attr);
|
|
635
529
|
return LIBUSB_ERROR_IO;
|
|
530
|
+
} else if (buf[r - 1] != '\n') {
|
|
531
|
+
usbi_warn(ctx, "attribute %s doesn't end with newline?", attr);
|
|
532
|
+
} else {
|
|
533
|
+
/* Remove the terminating newline character */
|
|
534
|
+
r--;
|
|
636
535
|
}
|
|
536
|
+
buf[r] = '\0';
|
|
637
537
|
|
|
638
|
-
|
|
538
|
+
errno = 0;
|
|
539
|
+
value = strtol(buf, &endptr, 10);
|
|
540
|
+
if (value < 0 || value > (long)max_value || errno) {
|
|
541
|
+
usbi_err(ctx, "attribute %s contains an invalid value: '%s'", attr, buf);
|
|
542
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
543
|
+
} else if (*endptr != '\0') {
|
|
544
|
+
/* Consider the value to be valid if the remainder is a '.'
|
|
545
|
+
* character followed by numbers. This occurs, for example,
|
|
546
|
+
* when reading the "speed" attribute for a low-speed device
|
|
547
|
+
* (e.g. "1.5") */
|
|
548
|
+
if (*endptr == '.' && isdigit(*(endptr + 1))) {
|
|
549
|
+
endptr++;
|
|
550
|
+
while (isdigit(*endptr))
|
|
551
|
+
endptr++;
|
|
552
|
+
}
|
|
553
|
+
if (*endptr != '\0') {
|
|
554
|
+
usbi_err(ctx, "attribute %s contains an invalid value: '%s'", attr, buf);
|
|
555
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
*value_p = (int)value;
|
|
560
|
+
return 0;
|
|
639
561
|
}
|
|
640
562
|
|
|
641
|
-
static int
|
|
642
|
-
unsigned char *buffer, int *host_endian)
|
|
563
|
+
static int sysfs_scan_device(struct libusb_context *ctx, const char *devname)
|
|
643
564
|
{
|
|
644
|
-
|
|
565
|
+
uint8_t busnum, devaddr;
|
|
566
|
+
int ret;
|
|
645
567
|
|
|
646
|
-
|
|
647
|
-
|
|
568
|
+
ret = linux_get_device_address(ctx, 0, &busnum, &devaddr, NULL, devname, -1);
|
|
569
|
+
if (ret != LIBUSB_SUCCESS)
|
|
570
|
+
return ret;
|
|
648
571
|
|
|
649
|
-
return
|
|
572
|
+
return linux_enumerate_device(ctx, busnum, devaddr, devname);
|
|
650
573
|
}
|
|
651
574
|
|
|
652
575
|
/* read the bConfigurationValue for a device */
|
|
653
576
|
static int sysfs_get_active_config(struct libusb_device *dev, int *config)
|
|
654
577
|
{
|
|
655
|
-
|
|
656
|
-
char tmp[5] = {0, 0, 0, 0, 0};
|
|
657
|
-
long num;
|
|
658
|
-
int fd;
|
|
659
|
-
ssize_t r;
|
|
578
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
660
579
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
return fd;
|
|
664
|
-
|
|
665
|
-
r = read(fd, tmp, sizeof(tmp));
|
|
666
|
-
close(fd);
|
|
667
|
-
if (r < 0) {
|
|
668
|
-
usbi_err(DEVICE_CTX(dev),
|
|
669
|
-
"read bConfigurationValue failed ret=%zd errno=%d", r, errno);
|
|
670
|
-
return LIBUSB_ERROR_IO;
|
|
671
|
-
} else if (r == 0) {
|
|
672
|
-
usbi_dbg("device unconfigured");
|
|
673
|
-
*config = -1;
|
|
674
|
-
return 0;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (tmp[sizeof(tmp) - 1] != 0) {
|
|
678
|
-
usbi_err(DEVICE_CTX(dev), "not null-terminated?");
|
|
679
|
-
return LIBUSB_ERROR_IO;
|
|
680
|
-
} else if (tmp[0] == 0) {
|
|
681
|
-
usbi_err(DEVICE_CTX(dev), "no configuration value?");
|
|
682
|
-
return LIBUSB_ERROR_IO;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
num = strtol(tmp, &endptr, 10);
|
|
686
|
-
if (endptr == tmp) {
|
|
687
|
-
usbi_err(DEVICE_CTX(dev), "error converting '%s' to integer", tmp);
|
|
688
|
-
return LIBUSB_ERROR_IO;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
*config = (int) num;
|
|
692
|
-
return 0;
|
|
580
|
+
return read_sysfs_attr(DEVICE_CTX(dev), priv->sysfs_dir, "bConfigurationValue",
|
|
581
|
+
UINT8_MAX, config);
|
|
693
582
|
}
|
|
694
583
|
|
|
695
|
-
int linux_get_device_address
|
|
696
|
-
uint8_t *busnum, uint8_t *devaddr,const char *dev_node,
|
|
584
|
+
int linux_get_device_address(struct libusb_context *ctx, int detached,
|
|
585
|
+
uint8_t *busnum, uint8_t *devaddr, const char *dev_node,
|
|
697
586
|
const char *sys_name, int fd)
|
|
698
587
|
{
|
|
699
|
-
|
|
700
|
-
int
|
|
701
|
-
ssize_t r;
|
|
588
|
+
int sysfs_val;
|
|
589
|
+
int r;
|
|
702
590
|
|
|
703
|
-
usbi_dbg("getting address for device: %s detached: %d", sys_name, detached);
|
|
591
|
+
usbi_dbg(ctx, "getting address for device: %s detached: %d", sys_name, detached);
|
|
704
592
|
/* can't use sysfs to read the bus and device number if the
|
|
705
593
|
* device has been detached */
|
|
706
|
-
if (!
|
|
707
|
-
if (
|
|
594
|
+
if (!sysfs_available || detached || !sys_name) {
|
|
595
|
+
if (!dev_node && fd >= 0) {
|
|
596
|
+
char *fd_path = alloca(PATH_MAX);
|
|
597
|
+
char proc_path[32];
|
|
598
|
+
|
|
708
599
|
/* try to retrieve the device node from fd */
|
|
709
|
-
|
|
710
|
-
r = readlink(proc_path, fd_path, PATH_MAX);
|
|
711
|
-
if (r > 0)
|
|
600
|
+
sprintf(proc_path, "/proc/self/fd/%d", fd);
|
|
601
|
+
r = readlink(proc_path, fd_path, PATH_MAX - 1);
|
|
602
|
+
if (r > 0) {
|
|
603
|
+
fd_path[r] = '\0';
|
|
712
604
|
dev_node = fd_path;
|
|
605
|
+
}
|
|
713
606
|
}
|
|
714
|
-
|
|
607
|
+
|
|
608
|
+
if (!dev_node)
|
|
715
609
|
return LIBUSB_ERROR_OTHER;
|
|
716
|
-
}
|
|
717
610
|
|
|
718
611
|
/* will this work with all supported kernel versions? */
|
|
719
|
-
if (!strncmp(dev_node, "/dev/bus/usb", 12))
|
|
720
|
-
sscanf
|
|
721
|
-
|
|
722
|
-
sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr);
|
|
723
|
-
} else {
|
|
612
|
+
if (!strncmp(dev_node, "/dev/bus/usb", 12))
|
|
613
|
+
sscanf(dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr);
|
|
614
|
+
else
|
|
724
615
|
return LIBUSB_ERROR_OTHER;
|
|
725
|
-
}
|
|
726
616
|
|
|
727
617
|
return LIBUSB_SUCCESS;
|
|
728
618
|
}
|
|
729
619
|
|
|
730
|
-
usbi_dbg("scan %s", sys_name);
|
|
620
|
+
usbi_dbg(ctx, "scan %s", sys_name);
|
|
731
621
|
|
|
732
|
-
|
|
733
|
-
if (
|
|
734
|
-
return
|
|
735
|
-
|
|
736
|
-
return LIBUSB_ERROR_INVALID_PARAM;
|
|
737
|
-
*busnum = (uint8_t) sysfs_attr;
|
|
738
|
-
|
|
739
|
-
sysfs_attr = __read_sysfs_attr(ctx, sys_name, "devnum");
|
|
740
|
-
if (0 > sysfs_attr)
|
|
741
|
-
return sysfs_attr;
|
|
742
|
-
if (sysfs_attr > 255)
|
|
743
|
-
return LIBUSB_ERROR_INVALID_PARAM;
|
|
622
|
+
r = read_sysfs_attr(ctx, sys_name, "busnum", UINT8_MAX, &sysfs_val);
|
|
623
|
+
if (r < 0)
|
|
624
|
+
return r;
|
|
625
|
+
*busnum = (uint8_t)sysfs_val;
|
|
744
626
|
|
|
745
|
-
|
|
627
|
+
r = read_sysfs_attr(ctx, sys_name, "devnum", UINT8_MAX, &sysfs_val);
|
|
628
|
+
if (r < 0)
|
|
629
|
+
return r;
|
|
630
|
+
*devaddr = (uint8_t)sysfs_val;
|
|
746
631
|
|
|
747
|
-
usbi_dbg("bus=%
|
|
632
|
+
usbi_dbg(ctx, "bus=%u dev=%u", *busnum, *devaddr);
|
|
748
633
|
|
|
749
634
|
return LIBUSB_SUCCESS;
|
|
750
635
|
}
|
|
751
636
|
|
|
752
|
-
/* Return offset of the next descriptor
|
|
753
|
-
static int
|
|
754
|
-
uint8_t
|
|
637
|
+
/* Return offset of the next config descriptor */
|
|
638
|
+
static int seek_to_next_config(struct libusb_context *ctx,
|
|
639
|
+
uint8_t *buffer, size_t len)
|
|
755
640
|
{
|
|
756
|
-
struct
|
|
757
|
-
int
|
|
641
|
+
struct usbi_descriptor_header *header;
|
|
642
|
+
int offset;
|
|
758
643
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
644
|
+
/* Start seeking past the config descriptor */
|
|
645
|
+
offset = LIBUSB_DT_CONFIG_SIZE;
|
|
646
|
+
buffer += LIBUSB_DT_CONFIG_SIZE;
|
|
647
|
+
len -= LIBUSB_DT_CONFIG_SIZE;
|
|
762
648
|
|
|
763
|
-
|
|
764
|
-
|
|
649
|
+
while (len > 0) {
|
|
650
|
+
if (len < 2) {
|
|
651
|
+
usbi_err(ctx, "short descriptor read %zu/2", len);
|
|
765
652
|
return LIBUSB_ERROR_IO;
|
|
766
653
|
}
|
|
767
|
-
usbi_parse_descriptor(buffer + i, "bb", &header, 0);
|
|
768
654
|
|
|
769
|
-
|
|
770
|
-
|
|
655
|
+
header = (struct usbi_descriptor_header *)buffer;
|
|
656
|
+
if (header->bDescriptorType == LIBUSB_DT_CONFIG)
|
|
657
|
+
return offset;
|
|
658
|
+
|
|
659
|
+
if (len < header->bLength) {
|
|
660
|
+
usbi_err(ctx, "bLength overflow by %zu bytes",
|
|
661
|
+
(size_t)header->bLength - len);
|
|
662
|
+
return LIBUSB_ERROR_IO;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
offset += header->bLength;
|
|
666
|
+
buffer += header->bLength;
|
|
667
|
+
len -= header->bLength;
|
|
771
668
|
}
|
|
772
|
-
|
|
669
|
+
|
|
670
|
+
usbi_err(ctx, "config descriptor not found");
|
|
773
671
|
return LIBUSB_ERROR_IO;
|
|
774
672
|
}
|
|
775
673
|
|
|
776
|
-
|
|
777
|
-
static int seek_to_next_config(struct libusb_device *dev,
|
|
778
|
-
unsigned char *buffer, int size)
|
|
674
|
+
static int parse_config_descriptors(struct libusb_device *dev)
|
|
779
675
|
{
|
|
780
676
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
781
|
-
struct linux_device_priv *priv =
|
|
782
|
-
struct
|
|
677
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
678
|
+
struct usbi_device_descriptor *device_desc;
|
|
679
|
+
uint8_t idx, num_configs;
|
|
680
|
+
uint8_t *buffer;
|
|
681
|
+
size_t remaining;
|
|
783
682
|
|
|
784
|
-
|
|
785
|
-
|
|
683
|
+
device_desc = priv->descriptors;
|
|
684
|
+
num_configs = device_desc->bNumConfigurations;
|
|
786
685
|
|
|
787
|
-
if (
|
|
788
|
-
|
|
789
|
-
size, LIBUSB_DT_CONFIG_SIZE);
|
|
790
|
-
return LIBUSB_ERROR_IO;
|
|
791
|
-
}
|
|
686
|
+
if (num_configs == 0)
|
|
687
|
+
return 0; /* no configurations? */
|
|
792
688
|
|
|
793
|
-
|
|
794
|
-
if (
|
|
795
|
-
|
|
796
|
-
config.bDescriptorType);
|
|
797
|
-
return LIBUSB_ERROR_IO;
|
|
798
|
-
}
|
|
689
|
+
priv->config_descriptors = malloc(num_configs * sizeof(priv->config_descriptors[0]));
|
|
690
|
+
if (!priv->config_descriptors)
|
|
691
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
799
692
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
buffer, size);
|
|
811
|
-
if (next == LIBUSB_ERROR_NOT_FOUND)
|
|
812
|
-
next = size;
|
|
813
|
-
if (next < 0)
|
|
814
|
-
return next;
|
|
815
|
-
|
|
816
|
-
if (next != config.wTotalLength)
|
|
817
|
-
usbi_warn(ctx, "config length mismatch wTotalLength "
|
|
818
|
-
"%d real %d", config.wTotalLength, next);
|
|
819
|
-
return next;
|
|
820
|
-
} else {
|
|
821
|
-
if (config.wTotalLength < LIBUSB_DT_CONFIG_SIZE) {
|
|
822
|
-
usbi_err(ctx, "invalid wTotalLength %d",
|
|
823
|
-
config.wTotalLength);
|
|
693
|
+
buffer = (uint8_t *)priv->descriptors + LIBUSB_DT_DEVICE_SIZE;
|
|
694
|
+
remaining = priv->descriptors_len - LIBUSB_DT_DEVICE_SIZE;
|
|
695
|
+
|
|
696
|
+
for (idx = 0; idx < num_configs; idx++) {
|
|
697
|
+
struct usbi_configuration_descriptor *config_desc;
|
|
698
|
+
uint16_t config_len;
|
|
699
|
+
|
|
700
|
+
if (remaining < LIBUSB_DT_CONFIG_SIZE) {
|
|
701
|
+
usbi_err(ctx, "short descriptor read %zu/%d",
|
|
702
|
+
remaining, LIBUSB_DT_CONFIG_SIZE);
|
|
824
703
|
return LIBUSB_ERROR_IO;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
config_desc = (struct usbi_configuration_descriptor *)buffer;
|
|
707
|
+
if (config_desc->bDescriptorType != LIBUSB_DT_CONFIG) {
|
|
708
|
+
usbi_err(ctx, "descriptor is not a config desc (type 0x%02x)",
|
|
709
|
+
config_desc->bDescriptorType);
|
|
710
|
+
return LIBUSB_ERROR_IO;
|
|
711
|
+
} else if (config_desc->bLength < LIBUSB_DT_CONFIG_SIZE) {
|
|
712
|
+
usbi_err(ctx, "invalid descriptor bLength %u",
|
|
713
|
+
config_desc->bLength);
|
|
714
|
+
return LIBUSB_ERROR_IO;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
config_len = libusb_le16_to_cpu(config_desc->wTotalLength);
|
|
718
|
+
if (config_len < LIBUSB_DT_CONFIG_SIZE) {
|
|
719
|
+
usbi_err(ctx, "invalid wTotalLength %u", config_len);
|
|
720
|
+
return LIBUSB_ERROR_IO;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (priv->sysfs_dir) {
|
|
724
|
+
/*
|
|
725
|
+
* In sysfs wTotalLength is ignored, instead the kernel returns a
|
|
726
|
+
* config descriptor with verified bLength fields, with descriptors
|
|
727
|
+
* with an invalid bLength removed.
|
|
728
|
+
*/
|
|
729
|
+
uint16_t sysfs_config_len;
|
|
730
|
+
int offset;
|
|
731
|
+
|
|
732
|
+
if (num_configs > 1 && idx < num_configs - 1) {
|
|
733
|
+
offset = seek_to_next_config(ctx, buffer, remaining);
|
|
734
|
+
if (offset < 0)
|
|
735
|
+
return offset;
|
|
736
|
+
sysfs_config_len = (uint16_t)offset;
|
|
737
|
+
} else {
|
|
738
|
+
sysfs_config_len = (uint16_t)remaining;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
if (config_len != sysfs_config_len) {
|
|
742
|
+
usbi_warn(ctx, "config length mismatch wTotalLength %u real %u",
|
|
743
|
+
config_len, sysfs_config_len);
|
|
744
|
+
config_len = sysfs_config_len;
|
|
745
|
+
}
|
|
746
|
+
} else {
|
|
747
|
+
/*
|
|
748
|
+
* In usbfs the config descriptors are wTotalLength bytes apart,
|
|
749
|
+
* with any short reads from the device appearing as holes in the file.
|
|
750
|
+
*/
|
|
751
|
+
if (config_len > remaining) {
|
|
752
|
+
usbi_warn(ctx, "short descriptor read %zu/%u", remaining, config_len);
|
|
753
|
+
config_len = (uint16_t)remaining;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (config_desc->bConfigurationValue == 0)
|
|
758
|
+
usbi_warn(ctx, "device has configuration 0");
|
|
759
|
+
|
|
760
|
+
priv->config_descriptors[idx].desc = config_desc;
|
|
761
|
+
priv->config_descriptors[idx].actual_len = config_len;
|
|
762
|
+
|
|
763
|
+
buffer += config_len;
|
|
764
|
+
remaining -= config_len;
|
|
831
765
|
}
|
|
766
|
+
|
|
767
|
+
return LIBUSB_SUCCESS;
|
|
832
768
|
}
|
|
833
769
|
|
|
834
770
|
static int op_get_config_descriptor_by_value(struct libusb_device *dev,
|
|
835
|
-
uint8_t value,
|
|
836
|
-
{
|
|
837
|
-
struct linux_device_priv *priv =
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
/* Skip device header */
|
|
847
|
-
descriptors += DEVICE_DESC_LENGTH;
|
|
848
|
-
size -= DEVICE_DESC_LENGTH;
|
|
849
|
-
|
|
850
|
-
/* Seek till the config is found, or till "EOF" */
|
|
851
|
-
while (1) {
|
|
852
|
-
int next = seek_to_next_config(dev, descriptors, size);
|
|
853
|
-
if (next < 0)
|
|
854
|
-
return next;
|
|
855
|
-
config = (struct libusb_config_descriptor *)descriptors;
|
|
856
|
-
if (config->bConfigurationValue == value) {
|
|
857
|
-
*buffer = descriptors;
|
|
858
|
-
return next;
|
|
771
|
+
uint8_t value, void **buffer)
|
|
772
|
+
{
|
|
773
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
774
|
+
struct config_descriptor *config;
|
|
775
|
+
uint8_t idx;
|
|
776
|
+
|
|
777
|
+
for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
|
|
778
|
+
config = &priv->config_descriptors[idx];
|
|
779
|
+
if (config->desc->bConfigurationValue == value) {
|
|
780
|
+
*buffer = config->desc;
|
|
781
|
+
return (int)config->actual_len;
|
|
859
782
|
}
|
|
860
|
-
size -= next;
|
|
861
|
-
descriptors += next;
|
|
862
783
|
}
|
|
784
|
+
|
|
785
|
+
return LIBUSB_ERROR_NOT_FOUND;
|
|
863
786
|
}
|
|
864
787
|
|
|
865
788
|
static int op_get_active_config_descriptor(struct libusb_device *dev,
|
|
866
|
-
|
|
789
|
+
void *buffer, size_t len)
|
|
867
790
|
{
|
|
868
|
-
struct linux_device_priv *priv =
|
|
869
|
-
|
|
870
|
-
|
|
791
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
792
|
+
void *config_desc;
|
|
793
|
+
int active_config;
|
|
794
|
+
int r;
|
|
871
795
|
|
|
872
|
-
if (priv->sysfs_dir
|
|
873
|
-
r = sysfs_get_active_config(dev, &
|
|
796
|
+
if (priv->sysfs_dir) {
|
|
797
|
+
r = sysfs_get_active_config(dev, &active_config);
|
|
874
798
|
if (r < 0)
|
|
875
799
|
return r;
|
|
876
800
|
} else {
|
|
877
801
|
/* Use cached bConfigurationValue */
|
|
878
|
-
|
|
802
|
+
active_config = priv->active_config;
|
|
879
803
|
}
|
|
880
|
-
|
|
804
|
+
|
|
805
|
+
if (active_config == -1) {
|
|
806
|
+
usbi_err(DEVICE_CTX(dev), "device unconfigured");
|
|
881
807
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
808
|
+
}
|
|
882
809
|
|
|
883
|
-
r = op_get_config_descriptor_by_value(dev,
|
|
884
|
-
host_endian);
|
|
810
|
+
r = op_get_config_descriptor_by_value(dev, (uint8_t)active_config, &config_desc);
|
|
885
811
|
if (r < 0)
|
|
886
812
|
return r;
|
|
887
813
|
|
|
@@ -891,40 +817,25 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
|
|
|
891
817
|
}
|
|
892
818
|
|
|
893
819
|
static int op_get_config_descriptor(struct libusb_device *dev,
|
|
894
|
-
uint8_t config_index,
|
|
820
|
+
uint8_t config_index, void *buffer, size_t len)
|
|
895
821
|
{
|
|
896
|
-
struct linux_device_priv *priv =
|
|
897
|
-
|
|
898
|
-
int i, r, size = priv->descriptors_len;
|
|
822
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
823
|
+
struct config_descriptor *config;
|
|
899
824
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
/* Skip device header */
|
|
904
|
-
descriptors += DEVICE_DESC_LENGTH;
|
|
905
|
-
size -= DEVICE_DESC_LENGTH;
|
|
906
|
-
|
|
907
|
-
/* Seek till the config is found, or till "EOF" */
|
|
908
|
-
for (i = 0; ; i++) {
|
|
909
|
-
r = seek_to_next_config(dev, descriptors, size);
|
|
910
|
-
if (r < 0)
|
|
911
|
-
return r;
|
|
912
|
-
if (i == config_index)
|
|
913
|
-
break;
|
|
914
|
-
size -= r;
|
|
915
|
-
descriptors += r;
|
|
916
|
-
}
|
|
825
|
+
if (config_index >= dev->device_descriptor.bNumConfigurations)
|
|
826
|
+
return LIBUSB_ERROR_NOT_FOUND;
|
|
917
827
|
|
|
918
|
-
|
|
919
|
-
|
|
828
|
+
config = &priv->config_descriptors[config_index];
|
|
829
|
+
len = MIN(len, config->actual_len);
|
|
830
|
+
memcpy(buffer, config->desc, len);
|
|
920
831
|
return len;
|
|
921
832
|
}
|
|
922
833
|
|
|
923
834
|
/* send a control message to retrieve active configuration */
|
|
924
835
|
static int usbfs_get_active_config(struct libusb_device *dev, int fd)
|
|
925
836
|
{
|
|
926
|
-
struct linux_device_priv *priv =
|
|
927
|
-
|
|
837
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
838
|
+
uint8_t active_config = 0;
|
|
928
839
|
int r;
|
|
929
840
|
|
|
930
841
|
struct usbfs_ctrltransfer ctrl = {
|
|
@@ -943,35 +854,58 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
|
|
|
943
854
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
944
855
|
|
|
945
856
|
/* we hit this error path frequently with buggy devices :( */
|
|
946
|
-
usbi_warn(DEVICE_CTX(dev),
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
857
|
+
usbi_warn(DEVICE_CTX(dev), "get configuration failed, errno=%d", errno);
|
|
858
|
+
|
|
859
|
+
/* assume the current configuration is the first one if we have
|
|
860
|
+
* the configuration descriptors, otherwise treat the device
|
|
861
|
+
* as unconfigured. */
|
|
862
|
+
if (priv->config_descriptors)
|
|
863
|
+
priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue;
|
|
864
|
+
else
|
|
865
|
+
priv->active_config = -1;
|
|
866
|
+
} else if (active_config == 0) {
|
|
867
|
+
if (dev_has_config0(dev)) {
|
|
953
868
|
/* some buggy devices have a configuration 0, but we're
|
|
954
|
-
* reaching into the corner of a corner case here
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
* unconfigured. */
|
|
958
|
-
usbi_warn(DEVICE_CTX(dev),
|
|
959
|
-
"active cfg 0? assuming unconfigured device");
|
|
869
|
+
* reaching into the corner of a corner case here. */
|
|
870
|
+
priv->active_config = 0;
|
|
871
|
+
} else {
|
|
960
872
|
priv->active_config = -1;
|
|
961
873
|
}
|
|
874
|
+
} else {
|
|
875
|
+
priv->active_config = (int)active_config;
|
|
962
876
|
}
|
|
963
877
|
|
|
964
878
|
return LIBUSB_SUCCESS;
|
|
965
879
|
}
|
|
966
880
|
|
|
881
|
+
static enum libusb_speed usbfs_get_speed(struct libusb_context *ctx, int fd)
|
|
882
|
+
{
|
|
883
|
+
int r;
|
|
884
|
+
|
|
885
|
+
r = ioctl(fd, IOCTL_USBFS_GET_SPEED, NULL);
|
|
886
|
+
switch (r) {
|
|
887
|
+
case USBFS_SPEED_UNKNOWN: return LIBUSB_SPEED_UNKNOWN;
|
|
888
|
+
case USBFS_SPEED_LOW: return LIBUSB_SPEED_LOW;
|
|
889
|
+
case USBFS_SPEED_FULL: return LIBUSB_SPEED_FULL;
|
|
890
|
+
case USBFS_SPEED_HIGH: return LIBUSB_SPEED_HIGH;
|
|
891
|
+
case USBFS_SPEED_WIRELESS: return LIBUSB_SPEED_HIGH;
|
|
892
|
+
case USBFS_SPEED_SUPER: return LIBUSB_SPEED_SUPER;
|
|
893
|
+
case USBFS_SPEED_SUPER_PLUS: return LIBUSB_SPEED_SUPER_PLUS;
|
|
894
|
+
default:
|
|
895
|
+
usbi_warn(ctx, "Error getting device speed: %d", r);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
return LIBUSB_SPEED_UNKNOWN;
|
|
899
|
+
}
|
|
900
|
+
|
|
967
901
|
static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
968
902
|
uint8_t devaddr, const char *sysfs_dir, int wrapped_fd)
|
|
969
903
|
{
|
|
970
|
-
struct linux_device_priv *priv =
|
|
904
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
971
905
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
972
|
-
|
|
973
|
-
int fd, speed;
|
|
974
|
-
ssize_t
|
|
906
|
+
size_t alloc_len;
|
|
907
|
+
int fd, speed, r;
|
|
908
|
+
ssize_t nb;
|
|
975
909
|
|
|
976
910
|
dev->bus_number = busnum;
|
|
977
911
|
dev->device_address = devaddr;
|
|
@@ -981,10 +915,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
981
915
|
if (!priv->sysfs_dir)
|
|
982
916
|
return LIBUSB_ERROR_NO_MEM;
|
|
983
917
|
|
|
984
|
-
/* Note speed can contain 1.5, in this case
|
|
918
|
+
/* Note speed can contain 1.5, in this case read_sysfs_attr()
|
|
985
919
|
will stop parsing at the '.' and return 1 */
|
|
986
|
-
|
|
987
|
-
if (speed >= 0) {
|
|
920
|
+
if (read_sysfs_attr(ctx, sysfs_dir, "speed", INT_MAX, &speed) == 0) {
|
|
988
921
|
switch (speed) {
|
|
989
922
|
case 1: dev->speed = LIBUSB_SPEED_LOW; break;
|
|
990
923
|
case 12: dev->speed = LIBUSB_SPEED_FULL; break;
|
|
@@ -992,68 +925,78 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
992
925
|
case 5000: dev->speed = LIBUSB_SPEED_SUPER; break;
|
|
993
926
|
case 10000: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
|
|
994
927
|
default:
|
|
995
|
-
usbi_warn(
|
|
928
|
+
usbi_warn(ctx, "unknown device speed: %d Mbps", speed);
|
|
996
929
|
}
|
|
997
930
|
}
|
|
931
|
+
} else if (wrapped_fd >= 0) {
|
|
932
|
+
dev->speed = usbfs_get_speed(ctx, wrapped_fd);
|
|
998
933
|
}
|
|
999
934
|
|
|
1000
935
|
/* cache descriptors in memory */
|
|
1001
|
-
if (sysfs_dir
|
|
1002
|
-
fd =
|
|
936
|
+
if (sysfs_dir) {
|
|
937
|
+
fd = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
|
|
1003
938
|
} else if (wrapped_fd < 0) {
|
|
1004
|
-
fd =
|
|
939
|
+
fd = get_usbfs_fd(dev, O_RDONLY, 0);
|
|
1005
940
|
} else {
|
|
1006
941
|
fd = wrapped_fd;
|
|
1007
942
|
r = lseek(fd, 0, SEEK_SET);
|
|
1008
943
|
if (r < 0) {
|
|
1009
|
-
usbi_err(ctx, "
|
|
944
|
+
usbi_err(ctx, "lseek failed, errno=%d", errno);
|
|
1010
945
|
return LIBUSB_ERROR_IO;
|
|
1011
946
|
}
|
|
1012
947
|
}
|
|
1013
948
|
if (fd < 0)
|
|
1014
949
|
return fd;
|
|
1015
950
|
|
|
951
|
+
alloc_len = 0;
|
|
1016
952
|
do {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
953
|
+
const size_t desc_read_length = 256;
|
|
954
|
+
uint8_t *read_ptr;
|
|
955
|
+
|
|
956
|
+
alloc_len += desc_read_length;
|
|
957
|
+
priv->descriptors = usbi_reallocf(priv->descriptors, alloc_len);
|
|
1020
958
|
if (!priv->descriptors) {
|
|
1021
959
|
if (fd != wrapped_fd)
|
|
1022
960
|
close(fd);
|
|
1023
961
|
return LIBUSB_ERROR_NO_MEM;
|
|
1024
962
|
}
|
|
963
|
+
read_ptr = (uint8_t *)priv->descriptors + priv->descriptors_len;
|
|
1025
964
|
/* usbfs has holes in the file */
|
|
1026
|
-
if (!
|
|
1027
|
-
memset(
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
descriptors_size - priv->descriptors_len);
|
|
1032
|
-
if (r < 0) {
|
|
1033
|
-
usbi_err(ctx, "read descriptor failed ret=%d errno=%d",
|
|
1034
|
-
fd, errno);
|
|
965
|
+
if (!sysfs_dir)
|
|
966
|
+
memset(read_ptr, 0, desc_read_length);
|
|
967
|
+
nb = read(fd, read_ptr, desc_read_length);
|
|
968
|
+
if (nb < 0) {
|
|
969
|
+
usbi_err(ctx, "read descriptor failed, errno=%d", errno);
|
|
1035
970
|
if (fd != wrapped_fd)
|
|
1036
971
|
close(fd);
|
|
1037
972
|
return LIBUSB_ERROR_IO;
|
|
1038
973
|
}
|
|
1039
|
-
priv->descriptors_len +=
|
|
1040
|
-
} while (priv->descriptors_len ==
|
|
974
|
+
priv->descriptors_len += (size_t)nb;
|
|
975
|
+
} while (priv->descriptors_len == alloc_len);
|
|
1041
976
|
|
|
1042
977
|
if (fd != wrapped_fd)
|
|
1043
978
|
close(fd);
|
|
1044
979
|
|
|
1045
|
-
if (priv->descriptors_len <
|
|
1046
|
-
usbi_err(ctx, "short descriptor read (%
|
|
1047
|
-
priv->descriptors_len);
|
|
980
|
+
if (priv->descriptors_len < LIBUSB_DT_DEVICE_SIZE) {
|
|
981
|
+
usbi_err(ctx, "short descriptor read (%zu)", priv->descriptors_len);
|
|
1048
982
|
return LIBUSB_ERROR_IO;
|
|
1049
983
|
}
|
|
1050
984
|
|
|
1051
|
-
|
|
985
|
+
r = parse_config_descriptors(dev);
|
|
986
|
+
if (r < 0)
|
|
987
|
+
return r;
|
|
988
|
+
|
|
989
|
+
memcpy(&dev->device_descriptor, priv->descriptors, LIBUSB_DT_DEVICE_SIZE);
|
|
990
|
+
|
|
991
|
+
if (sysfs_dir) {
|
|
992
|
+
/* sysfs descriptors are in bus-endian format */
|
|
993
|
+
usbi_localize_device_descriptor(&dev->device_descriptor);
|
|
1052
994
|
return LIBUSB_SUCCESS;
|
|
995
|
+
}
|
|
1053
996
|
|
|
1054
997
|
/* cache active config */
|
|
1055
998
|
if (wrapped_fd < 0)
|
|
1056
|
-
fd =
|
|
999
|
+
fd = get_usbfs_fd(dev, O_RDWR, 1);
|
|
1057
1000
|
else
|
|
1058
1001
|
fd = wrapped_fd;
|
|
1059
1002
|
if (fd < 0) {
|
|
@@ -1061,21 +1004,16 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
|
|
|
1061
1004
|
* config. just assume the first one is active. */
|
|
1062
1005
|
usbi_warn(ctx, "Missing rw usbfs access; cannot determine "
|
|
1063
1006
|
"active configuration descriptor");
|
|
1064
|
-
if (priv->
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
usbi_parse_descriptor(
|
|
1068
|
-
priv->descriptors + DEVICE_DESC_LENGTH,
|
|
1069
|
-
"bbwbbbbb", &config, 0);
|
|
1070
|
-
priv->active_config = config.bConfigurationValue;
|
|
1071
|
-
} else
|
|
1007
|
+
if (priv->config_descriptors)
|
|
1008
|
+
priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue;
|
|
1009
|
+
else
|
|
1072
1010
|
priv->active_config = -1; /* No config dt */
|
|
1073
1011
|
|
|
1074
1012
|
return LIBUSB_SUCCESS;
|
|
1075
1013
|
}
|
|
1076
1014
|
|
|
1077
1015
|
r = usbfs_get_active_config(dev, fd);
|
|
1078
|
-
if (
|
|
1016
|
+
if (fd != wrapped_fd)
|
|
1079
1017
|
close(fd);
|
|
1080
1018
|
|
|
1081
1019
|
return r;
|
|
@@ -1089,43 +1027,43 @@ static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_di
|
|
|
1089
1027
|
int ret, add_parent = 1;
|
|
1090
1028
|
|
|
1091
1029
|
/* XXX -- can we figure out the topology when using usbfs? */
|
|
1092
|
-
if (
|
|
1030
|
+
if (!sysfs_dir || !strncmp(sysfs_dir, "usb", 3)) {
|
|
1093
1031
|
/* either using usbfs or finding the parent of a root hub */
|
|
1094
1032
|
return LIBUSB_SUCCESS;
|
|
1095
1033
|
}
|
|
1096
1034
|
|
|
1097
1035
|
parent_sysfs_dir = strdup(sysfs_dir);
|
|
1098
|
-
if (
|
|
1036
|
+
if (!parent_sysfs_dir)
|
|
1099
1037
|
return LIBUSB_ERROR_NO_MEM;
|
|
1100
|
-
|
|
1101
|
-
if (
|
|
1102
|
-
|
|
1038
|
+
|
|
1039
|
+
if ((tmp = strrchr(parent_sysfs_dir, '.')) ||
|
|
1040
|
+
(tmp = strrchr(parent_sysfs_dir, '-'))) {
|
|
1103
1041
|
dev->port_number = atoi(tmp + 1);
|
|
1104
1042
|
*tmp = '\0';
|
|
1105
1043
|
} else {
|
|
1106
1044
|
usbi_warn(ctx, "Can not parse sysfs_dir: %s, no parent info",
|
|
1107
1045
|
parent_sysfs_dir);
|
|
1108
|
-
free
|
|
1046
|
+
free(parent_sysfs_dir);
|
|
1109
1047
|
return LIBUSB_SUCCESS;
|
|
1110
1048
|
}
|
|
1111
1049
|
|
|
1112
1050
|
/* is the parent a root hub? */
|
|
1113
|
-
if (
|
|
1051
|
+
if (!strchr(parent_sysfs_dir, '-')) {
|
|
1114
1052
|
tmp = parent_sysfs_dir;
|
|
1115
|
-
ret = asprintf
|
|
1116
|
-
free
|
|
1117
|
-
if (
|
|
1053
|
+
ret = asprintf(&parent_sysfs_dir, "usb%s", tmp);
|
|
1054
|
+
free(tmp);
|
|
1055
|
+
if (ret < 0)
|
|
1118
1056
|
return LIBUSB_ERROR_NO_MEM;
|
|
1119
|
-
}
|
|
1120
1057
|
}
|
|
1121
1058
|
|
|
1122
1059
|
retry:
|
|
1123
1060
|
/* find the parent in the context */
|
|
1124
1061
|
usbi_mutex_lock(&ctx->usb_devs_lock);
|
|
1125
|
-
|
|
1126
|
-
struct linux_device_priv *priv =
|
|
1062
|
+
for_each_device(ctx, it) {
|
|
1063
|
+
struct linux_device_priv *priv = usbi_get_device_priv(it);
|
|
1064
|
+
|
|
1127
1065
|
if (priv->sysfs_dir) {
|
|
1128
|
-
if (
|
|
1066
|
+
if (!strcmp(priv->sysfs_dir, parent_sysfs_dir)) {
|
|
1129
1067
|
dev->parent_dev = libusb_ref_device(it);
|
|
1130
1068
|
break;
|
|
1131
1069
|
}
|
|
@@ -1134,17 +1072,17 @@ retry:
|
|
|
1134
1072
|
usbi_mutex_unlock(&ctx->usb_devs_lock);
|
|
1135
1073
|
|
|
1136
1074
|
if (!dev->parent_dev && add_parent) {
|
|
1137
|
-
usbi_dbg("parent_dev %s not enumerated yet, enumerating now",
|
|
1075
|
+
usbi_dbg(ctx, "parent_dev %s not enumerated yet, enumerating now",
|
|
1138
1076
|
parent_sysfs_dir);
|
|
1139
1077
|
sysfs_scan_device(ctx, parent_sysfs_dir);
|
|
1140
1078
|
add_parent = 0;
|
|
1141
1079
|
goto retry;
|
|
1142
1080
|
}
|
|
1143
1081
|
|
|
1144
|
-
usbi_dbg("
|
|
1082
|
+
usbi_dbg(ctx, "dev %p (%s) has parent %p (%s) port %u", dev, sysfs_dir,
|
|
1145
1083
|
dev->parent_dev, parent_sysfs_dir, dev->port_number);
|
|
1146
1084
|
|
|
1147
|
-
free
|
|
1085
|
+
free(parent_sysfs_dir);
|
|
1148
1086
|
|
|
1149
1087
|
return LIBUSB_SUCCESS;
|
|
1150
1088
|
}
|
|
@@ -1154,24 +1092,23 @@ int linux_enumerate_device(struct libusb_context *ctx,
|
|
|
1154
1092
|
{
|
|
1155
1093
|
unsigned long session_id;
|
|
1156
1094
|
struct libusb_device *dev;
|
|
1157
|
-
int r
|
|
1095
|
+
int r;
|
|
1158
1096
|
|
|
1159
1097
|
/* FIXME: session ID is not guaranteed unique as addresses can wrap and
|
|
1160
1098
|
* will be reused. instead we should add a simple sysfs attribute with
|
|
1161
1099
|
* a session ID. */
|
|
1162
1100
|
session_id = busnum << 8 | devaddr;
|
|
1163
|
-
usbi_dbg("busnum %
|
|
1164
|
-
session_id);
|
|
1101
|
+
usbi_dbg(ctx, "busnum %u devaddr %u session_id %lu", busnum, devaddr, session_id);
|
|
1165
1102
|
|
|
1166
1103
|
dev = usbi_get_device_by_session_id(ctx, session_id);
|
|
1167
1104
|
if (dev) {
|
|
1168
1105
|
/* device already exists in the context */
|
|
1169
|
-
usbi_dbg("session_id %
|
|
1106
|
+
usbi_dbg(ctx, "session_id %lu already exists", session_id);
|
|
1170
1107
|
libusb_unref_device(dev);
|
|
1171
1108
|
return LIBUSB_SUCCESS;
|
|
1172
1109
|
}
|
|
1173
1110
|
|
|
1174
|
-
usbi_dbg("allocating new device for %
|
|
1111
|
+
usbi_dbg(ctx, "allocating new device for %u/%u (session %lu)",
|
|
1175
1112
|
busnum, devaddr, session_id);
|
|
1176
1113
|
dev = usbi_alloc_device(ctx, session_id);
|
|
1177
1114
|
if (!dev)
|
|
@@ -1201,7 +1138,7 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na
|
|
|
1201
1138
|
struct libusb_context *ctx;
|
|
1202
1139
|
|
|
1203
1140
|
usbi_mutex_static_lock(&active_contexts_lock);
|
|
1204
|
-
|
|
1141
|
+
for_each_context(ctx) {
|
|
1205
1142
|
linux_enumerate_device(ctx, busnum, devaddr, sys_name);
|
|
1206
1143
|
}
|
|
1207
1144
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
@@ -1214,29 +1151,45 @@ void linux_device_disconnected(uint8_t busnum, uint8_t devaddr)
|
|
|
1214
1151
|
unsigned long session_id = busnum << 8 | devaddr;
|
|
1215
1152
|
|
|
1216
1153
|
usbi_mutex_static_lock(&active_contexts_lock);
|
|
1217
|
-
|
|
1218
|
-
dev = usbi_get_device_by_session_id
|
|
1219
|
-
if (
|
|
1220
|
-
usbi_disconnect_device
|
|
1154
|
+
for_each_context(ctx) {
|
|
1155
|
+
dev = usbi_get_device_by_session_id(ctx, session_id);
|
|
1156
|
+
if (dev) {
|
|
1157
|
+
usbi_disconnect_device(dev);
|
|
1221
1158
|
libusb_unref_device(dev);
|
|
1222
1159
|
} else {
|
|
1223
|
-
usbi_dbg("device not found for session %lx", session_id);
|
|
1160
|
+
usbi_dbg(ctx, "device not found for session %lx", session_id);
|
|
1224
1161
|
}
|
|
1225
1162
|
}
|
|
1226
1163
|
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
1227
1164
|
}
|
|
1228
1165
|
|
|
1229
|
-
#if !defined(
|
|
1166
|
+
#if !defined(HAVE_LIBUDEV)
|
|
1167
|
+
static int parse_u8(const char *str, uint8_t *val_p)
|
|
1168
|
+
{
|
|
1169
|
+
char *endptr;
|
|
1170
|
+
long num;
|
|
1171
|
+
|
|
1172
|
+
errno = 0;
|
|
1173
|
+
num = strtol(str, &endptr, 10);
|
|
1174
|
+
if (num < 0 || num > UINT8_MAX || errno)
|
|
1175
|
+
return 0;
|
|
1176
|
+
if (endptr == str || *endptr != '\0')
|
|
1177
|
+
return 0;
|
|
1178
|
+
|
|
1179
|
+
*val_p = (uint8_t)num;
|
|
1180
|
+
return 1;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1230
1183
|
/* open a bus directory and adds all discovered devices to the context */
|
|
1231
1184
|
static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum)
|
|
1232
1185
|
{
|
|
1233
1186
|
DIR *dir;
|
|
1234
|
-
char dirpath[
|
|
1187
|
+
char dirpath[20];
|
|
1235
1188
|
struct dirent *entry;
|
|
1236
1189
|
int r = LIBUSB_ERROR_IO;
|
|
1237
1190
|
|
|
1238
|
-
|
|
1239
|
-
usbi_dbg("%s", dirpath);
|
|
1191
|
+
sprintf(dirpath, USB_DEVTMPFS_PATH "/%03u", busnum);
|
|
1192
|
+
usbi_dbg(ctx, "%s", dirpath);
|
|
1240
1193
|
dir = opendir(dirpath);
|
|
1241
1194
|
if (!dir) {
|
|
1242
1195
|
usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno);
|
|
@@ -1246,19 +1199,18 @@ static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum)
|
|
|
1246
1199
|
}
|
|
1247
1200
|
|
|
1248
1201
|
while ((entry = readdir(dir))) {
|
|
1249
|
-
|
|
1202
|
+
uint8_t devaddr;
|
|
1250
1203
|
|
|
1251
1204
|
if (entry->d_name[0] == '.')
|
|
1252
1205
|
continue;
|
|
1253
1206
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
usbi_dbg("unknown dir entry %s", entry->d_name);
|
|
1207
|
+
if (!parse_u8(entry->d_name, &devaddr)) {
|
|
1208
|
+
usbi_dbg(ctx, "unknown dir entry %s", entry->d_name);
|
|
1257
1209
|
continue;
|
|
1258
1210
|
}
|
|
1259
1211
|
|
|
1260
|
-
if (linux_enumerate_device(ctx, busnum,
|
|
1261
|
-
usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
|
|
1212
|
+
if (linux_enumerate_device(ctx, busnum, devaddr, NULL)) {
|
|
1213
|
+
usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
|
|
1262
1214
|
continue;
|
|
1263
1215
|
}
|
|
1264
1216
|
|
|
@@ -1272,34 +1224,36 @@ static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum)
|
|
|
1272
1224
|
static int usbfs_get_device_list(struct libusb_context *ctx)
|
|
1273
1225
|
{
|
|
1274
1226
|
struct dirent *entry;
|
|
1275
|
-
DIR *buses
|
|
1227
|
+
DIR *buses;
|
|
1228
|
+
uint8_t busnum, devaddr;
|
|
1276
1229
|
int r = 0;
|
|
1277
1230
|
|
|
1231
|
+
if (usbdev_names)
|
|
1232
|
+
buses = opendir(USBDEV_PATH);
|
|
1233
|
+
else
|
|
1234
|
+
buses = opendir(USB_DEVTMPFS_PATH);
|
|
1235
|
+
|
|
1278
1236
|
if (!buses) {
|
|
1279
|
-
usbi_err(ctx, "opendir buses failed errno=%d", errno);
|
|
1237
|
+
usbi_err(ctx, "opendir buses failed, errno=%d", errno);
|
|
1280
1238
|
return LIBUSB_ERROR_IO;
|
|
1281
1239
|
}
|
|
1282
1240
|
|
|
1283
1241
|
while ((entry = readdir(buses))) {
|
|
1284
|
-
int busnum;
|
|
1285
|
-
|
|
1286
1242
|
if (entry->d_name[0] == '.')
|
|
1287
1243
|
continue;
|
|
1288
1244
|
|
|
1289
1245
|
if (usbdev_names) {
|
|
1290
|
-
|
|
1291
|
-
if (!_is_usbdev_entry(entry, &busnum, &devaddr))
|
|
1246
|
+
if (!is_usbdev_entry(entry->d_name, &busnum, &devaddr))
|
|
1292
1247
|
continue;
|
|
1293
1248
|
|
|
1294
|
-
r = linux_enumerate_device(ctx, busnum,
|
|
1249
|
+
r = linux_enumerate_device(ctx, busnum, devaddr, NULL);
|
|
1295
1250
|
if (r < 0) {
|
|
1296
|
-
usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
|
|
1251
|
+
usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
|
|
1297
1252
|
continue;
|
|
1298
1253
|
}
|
|
1299
1254
|
} else {
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
usbi_dbg("unknown dir entry %s", entry->d_name);
|
|
1255
|
+
if (!parse_u8(entry->d_name, &busnum)) {
|
|
1256
|
+
usbi_dbg(ctx, "unknown dir entry %s", entry->d_name);
|
|
1303
1257
|
continue;
|
|
1304
1258
|
}
|
|
1305
1259
|
|
|
@@ -1313,23 +1267,7 @@ static int usbfs_get_device_list(struct libusb_context *ctx)
|
|
|
1313
1267
|
return r;
|
|
1314
1268
|
|
|
1315
1269
|
}
|
|
1316
|
-
#endif
|
|
1317
1270
|
|
|
1318
|
-
static int sysfs_scan_device(struct libusb_context *ctx, const char *devname)
|
|
1319
|
-
{
|
|
1320
|
-
uint8_t busnum, devaddr;
|
|
1321
|
-
int ret;
|
|
1322
|
-
|
|
1323
|
-
ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname, -1);
|
|
1324
|
-
if (LIBUSB_SUCCESS != ret) {
|
|
1325
|
-
return ret;
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
return linux_enumerate_device(ctx, busnum & 0xff, devaddr & 0xff,
|
|
1329
|
-
devname);
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
#if !defined(USE_UDEV)
|
|
1333
1271
|
static int sysfs_get_device_list(struct libusb_context *ctx)
|
|
1334
1272
|
{
|
|
1335
1273
|
DIR *devices = opendir(SYSFS_DEVICE_PATH);
|
|
@@ -1338,19 +1276,19 @@ static int sysfs_get_device_list(struct libusb_context *ctx)
|
|
|
1338
1276
|
int num_enumerated = 0;
|
|
1339
1277
|
|
|
1340
1278
|
if (!devices) {
|
|
1341
|
-
usbi_err(ctx, "opendir devices failed errno=%d", errno);
|
|
1279
|
+
usbi_err(ctx, "opendir devices failed, errno=%d", errno);
|
|
1342
1280
|
return LIBUSB_ERROR_IO;
|
|
1343
1281
|
}
|
|
1344
1282
|
|
|
1345
1283
|
while ((entry = readdir(devices))) {
|
|
1346
1284
|
if ((!isdigit(entry->d_name[0]) && strncmp(entry->d_name, "usb", 3))
|
|
1347
|
-
|
|
1285
|
+
|| strchr(entry->d_name, ':'))
|
|
1348
1286
|
continue;
|
|
1349
1287
|
|
|
1350
1288
|
num_devices++;
|
|
1351
1289
|
|
|
1352
1290
|
if (sysfs_scan_device(ctx, entry->d_name)) {
|
|
1353
|
-
usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
|
|
1291
|
+
usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
|
|
1354
1292
|
continue;
|
|
1355
1293
|
}
|
|
1356
1294
|
|
|
@@ -1366,19 +1304,14 @@ static int sysfs_get_device_list(struct libusb_context *ctx)
|
|
|
1366
1304
|
return LIBUSB_ERROR_IO;
|
|
1367
1305
|
}
|
|
1368
1306
|
|
|
1369
|
-
static int linux_default_scan_devices
|
|
1307
|
+
static int linux_default_scan_devices(struct libusb_context *ctx)
|
|
1370
1308
|
{
|
|
1371
1309
|
/* we can retrieve device list and descriptors from sysfs or usbfs.
|
|
1372
1310
|
* sysfs is preferable, because if we use usbfs we end up resuming
|
|
1373
1311
|
* any autosuspended USB devices. however, sysfs is not available
|
|
1374
1312
|
* everywhere, so we need a usbfs fallback too.
|
|
1375
|
-
*
|
|
1376
|
-
* as described in the "sysfs vs usbfs" comment at the top of this
|
|
1377
|
-
* file, sometimes we have sysfs but not enough information to
|
|
1378
|
-
* relate sysfs devices to usbfs nodes. op_init() determines the
|
|
1379
|
-
* adequacy of sysfs and sets sysfs_can_relate_devices.
|
|
1380
1313
|
*/
|
|
1381
|
-
if (
|
|
1314
|
+
if (sysfs_available)
|
|
1382
1315
|
return sysfs_get_device_list(ctx);
|
|
1383
1316
|
else
|
|
1384
1317
|
return usbfs_get_device_list(ctx);
|
|
@@ -1387,7 +1320,7 @@ static int linux_default_scan_devices (struct libusb_context *ctx)
|
|
|
1387
1320
|
|
|
1388
1321
|
static int initialize_handle(struct libusb_device_handle *handle, int fd)
|
|
1389
1322
|
{
|
|
1390
|
-
struct linux_device_handle_priv *hpriv =
|
|
1323
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1391
1324
|
int r;
|
|
1392
1325
|
|
|
1393
1326
|
hpriv->fd = fd;
|
|
@@ -1395,23 +1328,19 @@ static int initialize_handle(struct libusb_device_handle *handle, int fd)
|
|
|
1395
1328
|
r = ioctl(fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
|
|
1396
1329
|
if (r < 0) {
|
|
1397
1330
|
if (errno == ENOTTY)
|
|
1398
|
-
usbi_dbg("getcap not available");
|
|
1331
|
+
usbi_dbg(HANDLE_CTX(handle), "getcap not available");
|
|
1399
1332
|
else
|
|
1400
|
-
usbi_err(HANDLE_CTX(handle), "getcap failed
|
|
1401
|
-
hpriv->caps =
|
|
1402
|
-
if (supports_flag_zero_packet)
|
|
1403
|
-
hpriv->caps |= USBFS_CAP_ZERO_PACKET;
|
|
1404
|
-
if (supports_flag_bulk_continuation)
|
|
1405
|
-
hpriv->caps |= USBFS_CAP_BULK_CONTINUATION;
|
|
1333
|
+
usbi_err(HANDLE_CTX(handle), "getcap failed, errno=%d", errno);
|
|
1334
|
+
hpriv->caps = USBFS_CAP_BULK_CONTINUATION;
|
|
1406
1335
|
}
|
|
1407
1336
|
|
|
1408
|
-
return
|
|
1337
|
+
return usbi_add_event_source(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
|
|
1409
1338
|
}
|
|
1410
1339
|
|
|
1411
1340
|
static int op_wrap_sys_device(struct libusb_context *ctx,
|
|
1412
1341
|
struct libusb_device_handle *handle, intptr_t sys_dev)
|
|
1413
1342
|
{
|
|
1414
|
-
struct linux_device_handle_priv *hpriv =
|
|
1343
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1415
1344
|
int fd = (int)sys_dev;
|
|
1416
1345
|
uint8_t busnum, devaddr;
|
|
1417
1346
|
struct usbfs_connectinfo ci;
|
|
@@ -1422,7 +1351,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx,
|
|
|
1422
1351
|
if (r < 0) {
|
|
1423
1352
|
r = ioctl(fd, IOCTL_USBFS_CONNECTINFO, &ci);
|
|
1424
1353
|
if (r < 0) {
|
|
1425
|
-
usbi_err(ctx, "connectinfo failed
|
|
1354
|
+
usbi_err(ctx, "connectinfo failed, errno=%d", errno);
|
|
1426
1355
|
return LIBUSB_ERROR_IO;
|
|
1427
1356
|
}
|
|
1428
1357
|
/* There is no ioctl to get the bus number. We choose 0 here
|
|
@@ -1433,7 +1362,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx,
|
|
|
1433
1362
|
|
|
1434
1363
|
/* Session id is unused as we do not add the device to the list of
|
|
1435
1364
|
* connected devices. */
|
|
1436
|
-
usbi_dbg("allocating new device for fd %d", fd);
|
|
1365
|
+
usbi_dbg(ctx, "allocating new device for fd %d", fd);
|
|
1437
1366
|
dev = usbi_alloc_device(ctx, 0);
|
|
1438
1367
|
if (!dev)
|
|
1439
1368
|
return LIBUSB_ERROR_NO_MEM;
|
|
@@ -1446,7 +1375,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx,
|
|
|
1446
1375
|
goto out;
|
|
1447
1376
|
/* Consider the device as connected, but do not add it to the managed
|
|
1448
1377
|
* device list. */
|
|
1449
|
-
dev->attached
|
|
1378
|
+
usbi_atomic_store(&dev->attached, 1);
|
|
1450
1379
|
handle->dev = dev;
|
|
1451
1380
|
|
|
1452
1381
|
r = initialize_handle(handle, fd);
|
|
@@ -1462,16 +1391,16 @@ static int op_open(struct libusb_device_handle *handle)
|
|
|
1462
1391
|
{
|
|
1463
1392
|
int fd, r;
|
|
1464
1393
|
|
|
1465
|
-
fd =
|
|
1394
|
+
fd = get_usbfs_fd(handle->dev, O_RDWR, 0);
|
|
1466
1395
|
if (fd < 0) {
|
|
1467
1396
|
if (fd == LIBUSB_ERROR_NO_DEVICE) {
|
|
1468
1397
|
/* device will still be marked as attached if hotplug monitor thread
|
|
1469
1398
|
* hasn't processed remove event yet */
|
|
1470
1399
|
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
1471
|
-
if (handle->dev->attached) {
|
|
1472
|
-
usbi_dbg("open failed with no device, but device still attached");
|
|
1400
|
+
if (usbi_atomic_load(&handle->dev->attached)) {
|
|
1401
|
+
usbi_dbg(HANDLE_CTX(handle), "open failed with no device, but device still attached");
|
|
1473
1402
|
linux_device_disconnected(handle->dev->bus_number,
|
|
1474
|
-
|
|
1403
|
+
handle->dev->device_address);
|
|
1475
1404
|
}
|
|
1476
1405
|
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
1477
1406
|
}
|
|
@@ -1487,45 +1416,52 @@ static int op_open(struct libusb_device_handle *handle)
|
|
|
1487
1416
|
|
|
1488
1417
|
static void op_close(struct libusb_device_handle *dev_handle)
|
|
1489
1418
|
{
|
|
1490
|
-
struct linux_device_handle_priv *hpriv =
|
|
1419
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(dev_handle);
|
|
1420
|
+
|
|
1491
1421
|
/* fd may have already been removed by POLLERR condition in op_handle_events() */
|
|
1492
1422
|
if (!hpriv->fd_removed)
|
|
1493
|
-
|
|
1423
|
+
usbi_remove_event_source(HANDLE_CTX(dev_handle), hpriv->fd);
|
|
1494
1424
|
if (!hpriv->fd_keep)
|
|
1495
1425
|
close(hpriv->fd);
|
|
1496
1426
|
}
|
|
1497
1427
|
|
|
1498
1428
|
static int op_get_configuration(struct libusb_device_handle *handle,
|
|
1499
|
-
|
|
1429
|
+
uint8_t *config)
|
|
1500
1430
|
{
|
|
1501
|
-
struct linux_device_priv *priv =
|
|
1431
|
+
struct linux_device_priv *priv = usbi_get_device_priv(handle->dev);
|
|
1432
|
+
int active_config = -1; /* to please compiler */
|
|
1502
1433
|
int r;
|
|
1503
1434
|
|
|
1504
|
-
if (priv->sysfs_dir
|
|
1505
|
-
r = sysfs_get_active_config(handle->dev,
|
|
1435
|
+
if (priv->sysfs_dir) {
|
|
1436
|
+
r = sysfs_get_active_config(handle->dev, &active_config);
|
|
1506
1437
|
} else {
|
|
1507
|
-
|
|
1508
|
-
|
|
1438
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1439
|
+
|
|
1440
|
+
r = usbfs_get_active_config(handle->dev, hpriv->fd);
|
|
1509
1441
|
if (r == LIBUSB_SUCCESS)
|
|
1510
|
-
|
|
1442
|
+
active_config = priv->active_config;
|
|
1511
1443
|
}
|
|
1512
1444
|
if (r < 0)
|
|
1513
1445
|
return r;
|
|
1514
1446
|
|
|
1515
|
-
if (
|
|
1516
|
-
|
|
1517
|
-
|
|
1447
|
+
if (active_config == -1) {
|
|
1448
|
+
usbi_warn(HANDLE_CTX(handle), "device unconfigured");
|
|
1449
|
+
active_config = 0;
|
|
1518
1450
|
}
|
|
1519
1451
|
|
|
1452
|
+
*config = (uint8_t)active_config;
|
|
1453
|
+
|
|
1520
1454
|
return 0;
|
|
1521
1455
|
}
|
|
1522
1456
|
|
|
1523
1457
|
static int op_set_configuration(struct libusb_device_handle *handle, int config)
|
|
1524
1458
|
{
|
|
1525
|
-
struct linux_device_priv *priv =
|
|
1526
|
-
|
|
1527
|
-
int
|
|
1528
|
-
|
|
1459
|
+
struct linux_device_priv *priv = usbi_get_device_priv(handle->dev);
|
|
1460
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1461
|
+
int fd = hpriv->fd;
|
|
1462
|
+
int r = ioctl(fd, IOCTL_USBFS_SETCONFIGURATION, &config);
|
|
1463
|
+
|
|
1464
|
+
if (r < 0) {
|
|
1529
1465
|
if (errno == EINVAL)
|
|
1530
1466
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1531
1467
|
else if (errno == EBUSY)
|
|
@@ -1533,21 +1469,28 @@ static int op_set_configuration(struct libusb_device_handle *handle, int config)
|
|
|
1533
1469
|
else if (errno == ENODEV)
|
|
1534
1470
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1535
1471
|
|
|
1536
|
-
usbi_err(HANDLE_CTX(handle), "failed,
|
|
1472
|
+
usbi_err(HANDLE_CTX(handle), "set configuration failed, errno=%d", errno);
|
|
1537
1473
|
return LIBUSB_ERROR_OTHER;
|
|
1538
1474
|
}
|
|
1539
1475
|
|
|
1540
|
-
/* update our cached active config descriptor */
|
|
1541
|
-
priv->
|
|
1476
|
+
/* if necessary, update our cached active config descriptor */
|
|
1477
|
+
if (!priv->sysfs_dir) {
|
|
1478
|
+
if (config == 0 && !dev_has_config0(handle->dev))
|
|
1479
|
+
config = -1;
|
|
1480
|
+
|
|
1481
|
+
priv->active_config = config;
|
|
1482
|
+
}
|
|
1542
1483
|
|
|
1543
1484
|
return LIBUSB_SUCCESS;
|
|
1544
1485
|
}
|
|
1545
1486
|
|
|
1546
|
-
static int claim_interface(struct libusb_device_handle *handle, int iface)
|
|
1487
|
+
static int claim_interface(struct libusb_device_handle *handle, unsigned int iface)
|
|
1547
1488
|
{
|
|
1548
|
-
|
|
1549
|
-
int
|
|
1550
|
-
|
|
1489
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1490
|
+
int fd = hpriv->fd;
|
|
1491
|
+
int r = ioctl(fd, IOCTL_USBFS_CLAIMINTERFACE, &iface);
|
|
1492
|
+
|
|
1493
|
+
if (r < 0) {
|
|
1551
1494
|
if (errno == ENOENT)
|
|
1552
1495
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1553
1496
|
else if (errno == EBUSY)
|
|
@@ -1555,46 +1498,46 @@ static int claim_interface(struct libusb_device_handle *handle, int iface)
|
|
|
1555
1498
|
else if (errno == ENODEV)
|
|
1556
1499
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1557
1500
|
|
|
1558
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1559
|
-
"claim interface failed, error %d errno %d", r, errno);
|
|
1501
|
+
usbi_err(HANDLE_CTX(handle), "claim interface failed, errno=%d", errno);
|
|
1560
1502
|
return LIBUSB_ERROR_OTHER;
|
|
1561
1503
|
}
|
|
1562
1504
|
return 0;
|
|
1563
1505
|
}
|
|
1564
1506
|
|
|
1565
|
-
static int release_interface(struct libusb_device_handle *handle, int iface)
|
|
1507
|
+
static int release_interface(struct libusb_device_handle *handle, unsigned int iface)
|
|
1566
1508
|
{
|
|
1567
|
-
|
|
1568
|
-
int
|
|
1569
|
-
|
|
1509
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1510
|
+
int fd = hpriv->fd;
|
|
1511
|
+
int r = ioctl(fd, IOCTL_USBFS_RELEASEINTERFACE, &iface);
|
|
1512
|
+
|
|
1513
|
+
if (r < 0) {
|
|
1570
1514
|
if (errno == ENODEV)
|
|
1571
1515
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1572
1516
|
|
|
1573
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1574
|
-
"release interface failed, error %d errno %d", r, errno);
|
|
1517
|
+
usbi_err(HANDLE_CTX(handle), "release interface failed, errno=%d", errno);
|
|
1575
1518
|
return LIBUSB_ERROR_OTHER;
|
|
1576
1519
|
}
|
|
1577
1520
|
return 0;
|
|
1578
1521
|
}
|
|
1579
1522
|
|
|
1580
|
-
static int op_set_interface(struct libusb_device_handle *handle,
|
|
1581
|
-
|
|
1523
|
+
static int op_set_interface(struct libusb_device_handle *handle, uint8_t interface,
|
|
1524
|
+
uint8_t altsetting)
|
|
1582
1525
|
{
|
|
1583
|
-
|
|
1526
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1527
|
+
int fd = hpriv->fd;
|
|
1584
1528
|
struct usbfs_setinterface setintf;
|
|
1585
1529
|
int r;
|
|
1586
1530
|
|
|
1587
|
-
setintf.interface =
|
|
1531
|
+
setintf.interface = interface;
|
|
1588
1532
|
setintf.altsetting = altsetting;
|
|
1589
|
-
r = ioctl(fd,
|
|
1590
|
-
if (r) {
|
|
1533
|
+
r = ioctl(fd, IOCTL_USBFS_SETINTERFACE, &setintf);
|
|
1534
|
+
if (r < 0) {
|
|
1591
1535
|
if (errno == EINVAL)
|
|
1592
1536
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1593
1537
|
else if (errno == ENODEV)
|
|
1594
1538
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1595
1539
|
|
|
1596
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1597
|
-
"setintf failed error %d errno %d", r, errno);
|
|
1540
|
+
usbi_err(HANDLE_CTX(handle), "set interface failed, errno=%d", errno);
|
|
1598
1541
|
return LIBUSB_ERROR_OTHER;
|
|
1599
1542
|
}
|
|
1600
1543
|
|
|
@@ -1604,17 +1547,18 @@ static int op_set_interface(struct libusb_device_handle *handle, int iface,
|
|
|
1604
1547
|
static int op_clear_halt(struct libusb_device_handle *handle,
|
|
1605
1548
|
unsigned char endpoint)
|
|
1606
1549
|
{
|
|
1607
|
-
|
|
1550
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1551
|
+
int fd = hpriv->fd;
|
|
1608
1552
|
unsigned int _endpoint = endpoint;
|
|
1609
1553
|
int r = ioctl(fd, IOCTL_USBFS_CLEAR_HALT, &_endpoint);
|
|
1610
|
-
|
|
1554
|
+
|
|
1555
|
+
if (r < 0) {
|
|
1611
1556
|
if (errno == ENOENT)
|
|
1612
1557
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1613
1558
|
else if (errno == ENODEV)
|
|
1614
1559
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1615
1560
|
|
|
1616
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1617
|
-
"clear_halt failed error %d errno %d", r, errno);
|
|
1561
|
+
usbi_err(HANDLE_CTX(handle), "clear halt failed, errno=%d", errno);
|
|
1618
1562
|
return LIBUSB_ERROR_OTHER;
|
|
1619
1563
|
}
|
|
1620
1564
|
|
|
@@ -1623,50 +1567,49 @@ static int op_clear_halt(struct libusb_device_handle *handle,
|
|
|
1623
1567
|
|
|
1624
1568
|
static int op_reset_device(struct libusb_device_handle *handle)
|
|
1625
1569
|
{
|
|
1626
|
-
|
|
1627
|
-
int
|
|
1570
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1571
|
+
int fd = hpriv->fd;
|
|
1572
|
+
int r, ret = 0;
|
|
1573
|
+
uint8_t i;
|
|
1628
1574
|
|
|
1629
1575
|
/* Doing a device reset will cause the usbfs driver to get unbound
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1576
|
+
* from any interfaces it is bound to. By voluntarily unbinding
|
|
1577
|
+
* the usbfs driver ourself, we stop the kernel from rebinding
|
|
1578
|
+
* the interface after reset (which would end up with the interface
|
|
1579
|
+
* getting bound to the in kernel driver if any). */
|
|
1634
1580
|
for (i = 0; i < USB_MAXINTERFACES; i++) {
|
|
1635
|
-
if (handle->claimed_interfaces & (
|
|
1581
|
+
if (handle->claimed_interfaces & (1UL << i))
|
|
1636
1582
|
release_interface(handle, i);
|
|
1637
|
-
}
|
|
1638
1583
|
}
|
|
1639
1584
|
|
|
1640
1585
|
usbi_mutex_lock(&handle->lock);
|
|
1641
1586
|
r = ioctl(fd, IOCTL_USBFS_RESET, NULL);
|
|
1642
|
-
if (r) {
|
|
1587
|
+
if (r < 0) {
|
|
1643
1588
|
if (errno == ENODEV) {
|
|
1644
1589
|
ret = LIBUSB_ERROR_NOT_FOUND;
|
|
1645
1590
|
goto out;
|
|
1646
1591
|
}
|
|
1647
1592
|
|
|
1648
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1649
|
-
"reset failed error %d errno %d", r, errno);
|
|
1593
|
+
usbi_err(HANDLE_CTX(handle), "reset failed, errno=%d", errno);
|
|
1650
1594
|
ret = LIBUSB_ERROR_OTHER;
|
|
1651
1595
|
goto out;
|
|
1652
1596
|
}
|
|
1653
1597
|
|
|
1654
1598
|
/* And re-claim any interfaces which were claimed before the reset */
|
|
1655
1599
|
for (i = 0; i < USB_MAXINTERFACES; i++) {
|
|
1656
|
-
if (handle->claimed_interfaces & (
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
}
|
|
1600
|
+
if (!(handle->claimed_interfaces & (1UL << i)))
|
|
1601
|
+
continue;
|
|
1602
|
+
/*
|
|
1603
|
+
* A driver may have completed modprobing during
|
|
1604
|
+
* IOCTL_USBFS_RESET, and bound itself as soon as
|
|
1605
|
+
* IOCTL_USBFS_RESET released the device lock
|
|
1606
|
+
*/
|
|
1607
|
+
r = detach_kernel_driver_and_claim(handle, i);
|
|
1608
|
+
if (r) {
|
|
1609
|
+
usbi_warn(HANDLE_CTX(handle), "failed to re-claim interface %u after reset: %s",
|
|
1610
|
+
i, libusb_error_name(r));
|
|
1611
|
+
handle->claimed_interfaces &= ~(1UL << i);
|
|
1612
|
+
ret = LIBUSB_ERROR_NOT_FOUND;
|
|
1670
1613
|
}
|
|
1671
1614
|
}
|
|
1672
1615
|
out:
|
|
@@ -1677,13 +1620,14 @@ out:
|
|
|
1677
1620
|
static int do_streams_ioctl(struct libusb_device_handle *handle, long req,
|
|
1678
1621
|
uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
|
|
1679
1622
|
{
|
|
1680
|
-
|
|
1623
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1624
|
+
int r, fd = hpriv->fd;
|
|
1681
1625
|
struct usbfs_streams *streams;
|
|
1682
1626
|
|
|
1683
1627
|
if (num_endpoints > 30) /* Max 15 in + 15 out eps */
|
|
1684
1628
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1685
1629
|
|
|
1686
|
-
streams = malloc(sizeof(
|
|
1630
|
+
streams = malloc(sizeof(*streams) + num_endpoints);
|
|
1687
1631
|
if (!streams)
|
|
1688
1632
|
return LIBUSB_ERROR_NO_MEM;
|
|
1689
1633
|
|
|
@@ -1703,8 +1647,7 @@ static int do_streams_ioctl(struct libusb_device_handle *handle, long req,
|
|
|
1703
1647
|
else if (errno == ENODEV)
|
|
1704
1648
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1705
1649
|
|
|
1706
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1707
|
-
"streams-ioctl failed error %d errno %d", r, errno);
|
|
1650
|
+
usbi_err(HANDLE_CTX(handle), "streams-ioctl failed, errno=%d", errno);
|
|
1708
1651
|
return LIBUSB_ERROR_OTHER;
|
|
1709
1652
|
}
|
|
1710
1653
|
return r;
|
|
@@ -1724,26 +1667,24 @@ static int op_free_streams(struct libusb_device_handle *handle,
|
|
|
1724
1667
|
endpoints, num_endpoints);
|
|
1725
1668
|
}
|
|
1726
1669
|
|
|
1727
|
-
static
|
|
1728
|
-
size_t len)
|
|
1670
|
+
static void *op_dev_mem_alloc(struct libusb_device_handle *handle, size_t len)
|
|
1729
1671
|
{
|
|
1730
|
-
struct linux_device_handle_priv *hpriv =
|
|
1731
|
-
|
|
1732
|
-
|
|
1672
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1673
|
+
void *buffer;
|
|
1674
|
+
|
|
1675
|
+
buffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, hpriv->fd, 0);
|
|
1733
1676
|
if (buffer == MAP_FAILED) {
|
|
1734
|
-
usbi_err(HANDLE_CTX(handle), "alloc dev mem failed errno
|
|
1735
|
-
errno);
|
|
1677
|
+
usbi_err(HANDLE_CTX(handle), "alloc dev mem failed, errno=%d", errno);
|
|
1736
1678
|
return NULL;
|
|
1737
1679
|
}
|
|
1738
1680
|
return buffer;
|
|
1739
1681
|
}
|
|
1740
1682
|
|
|
1741
|
-
static int op_dev_mem_free(struct libusb_device_handle *handle,
|
|
1742
|
-
|
|
1683
|
+
static int op_dev_mem_free(struct libusb_device_handle *handle, void *buffer,
|
|
1684
|
+
size_t len)
|
|
1743
1685
|
{
|
|
1744
1686
|
if (munmap(buffer, len) != 0) {
|
|
1745
|
-
usbi_err(HANDLE_CTX(handle), "free dev mem failed errno
|
|
1746
|
-
errno);
|
|
1687
|
+
usbi_err(HANDLE_CTX(handle), "free dev mem failed, errno=%d", errno);
|
|
1747
1688
|
return LIBUSB_ERROR_OTHER;
|
|
1748
1689
|
} else {
|
|
1749
1690
|
return LIBUSB_SUCCESS;
|
|
@@ -1751,32 +1692,33 @@ static int op_dev_mem_free(struct libusb_device_handle *handle,
|
|
|
1751
1692
|
}
|
|
1752
1693
|
|
|
1753
1694
|
static int op_kernel_driver_active(struct libusb_device_handle *handle,
|
|
1754
|
-
|
|
1695
|
+
uint8_t interface)
|
|
1755
1696
|
{
|
|
1756
|
-
|
|
1697
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1698
|
+
int fd = hpriv->fd;
|
|
1757
1699
|
struct usbfs_getdriver getdrv;
|
|
1758
1700
|
int r;
|
|
1759
1701
|
|
|
1760
1702
|
getdrv.interface = interface;
|
|
1761
1703
|
r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv);
|
|
1762
|
-
if (r) {
|
|
1704
|
+
if (r < 0) {
|
|
1763
1705
|
if (errno == ENODATA)
|
|
1764
1706
|
return 0;
|
|
1765
1707
|
else if (errno == ENODEV)
|
|
1766
1708
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1767
1709
|
|
|
1768
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1769
|
-
"get driver failed error %d errno %d", r, errno);
|
|
1710
|
+
usbi_err(HANDLE_CTX(handle), "get driver failed, errno=%d", errno);
|
|
1770
1711
|
return LIBUSB_ERROR_OTHER;
|
|
1771
1712
|
}
|
|
1772
1713
|
|
|
1773
|
-
return
|
|
1714
|
+
return strcmp(getdrv.driver, "usbfs") != 0;
|
|
1774
1715
|
}
|
|
1775
1716
|
|
|
1776
1717
|
static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
|
1777
|
-
|
|
1718
|
+
uint8_t interface)
|
|
1778
1719
|
{
|
|
1779
|
-
|
|
1720
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1721
|
+
int fd = hpriv->fd;
|
|
1780
1722
|
struct usbfs_ioctl command;
|
|
1781
1723
|
struct usbfs_getdriver getdrv;
|
|
1782
1724
|
int r;
|
|
@@ -1787,11 +1729,11 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
|
|
1787
1729
|
|
|
1788
1730
|
getdrv.interface = interface;
|
|
1789
1731
|
r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv);
|
|
1790
|
-
if (r == 0 && strcmp(getdrv.driver, "usbfs")
|
|
1732
|
+
if (r == 0 && !strcmp(getdrv.driver, "usbfs"))
|
|
1791
1733
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1792
1734
|
|
|
1793
1735
|
r = ioctl(fd, IOCTL_USBFS_IOCTL, &command);
|
|
1794
|
-
if (r) {
|
|
1736
|
+
if (r < 0) {
|
|
1795
1737
|
if (errno == ENODATA)
|
|
1796
1738
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1797
1739
|
else if (errno == EINVAL)
|
|
@@ -1799,8 +1741,7 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
|
|
1799
1741
|
else if (errno == ENODEV)
|
|
1800
1742
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
1801
1743
|
|
|
1802
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1803
|
-
"detach failed error %d errno %d", r, errno);
|
|
1744
|
+
usbi_err(HANDLE_CTX(handle), "detach failed, errno=%d", errno);
|
|
1804
1745
|
return LIBUSB_ERROR_OTHER;
|
|
1805
1746
|
}
|
|
1806
1747
|
|
|
@@ -1808,9 +1749,10 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
|
|
1808
1749
|
}
|
|
1809
1750
|
|
|
1810
1751
|
static int op_attach_kernel_driver(struct libusb_device_handle *handle,
|
|
1811
|
-
|
|
1752
|
+
uint8_t interface)
|
|
1812
1753
|
{
|
|
1813
|
-
|
|
1754
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1755
|
+
int fd = hpriv->fd;
|
|
1814
1756
|
struct usbfs_ioctl command;
|
|
1815
1757
|
int r;
|
|
1816
1758
|
|
|
@@ -1829,8 +1771,7 @@ static int op_attach_kernel_driver(struct libusb_device_handle *handle,
|
|
|
1829
1771
|
else if (errno == EBUSY)
|
|
1830
1772
|
return LIBUSB_ERROR_BUSY;
|
|
1831
1773
|
|
|
1832
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1833
|
-
"attach failed error %d errno %d", r, errno);
|
|
1774
|
+
usbi_err(HANDLE_CTX(handle), "attach failed, errno=%d", errno);
|
|
1834
1775
|
return LIBUSB_ERROR_OTHER;
|
|
1835
1776
|
} else if (r == 0) {
|
|
1836
1777
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
@@ -1840,29 +1781,31 @@ static int op_attach_kernel_driver(struct libusb_device_handle *handle,
|
|
|
1840
1781
|
}
|
|
1841
1782
|
|
|
1842
1783
|
static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle,
|
|
1843
|
-
|
|
1784
|
+
uint8_t interface)
|
|
1844
1785
|
{
|
|
1786
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
1845
1787
|
struct usbfs_disconnect_claim dc;
|
|
1846
|
-
int r, fd =
|
|
1788
|
+
int r, fd = hpriv->fd;
|
|
1847
1789
|
|
|
1848
1790
|
dc.interface = interface;
|
|
1849
1791
|
strcpy(dc.driver, "usbfs");
|
|
1850
1792
|
dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER;
|
|
1851
1793
|
r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc);
|
|
1852
|
-
if (r
|
|
1853
|
-
switch (errno) {
|
|
1854
|
-
case EBUSY:
|
|
1855
|
-
return LIBUSB_ERROR_BUSY;
|
|
1856
|
-
case EINVAL:
|
|
1857
|
-
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1858
|
-
case ENODEV:
|
|
1859
|
-
return LIBUSB_ERROR_NO_DEVICE;
|
|
1860
|
-
}
|
|
1861
|
-
usbi_err(HANDLE_CTX(handle),
|
|
1862
|
-
"disconnect-and-claim failed errno %d", errno);
|
|
1863
|
-
return LIBUSB_ERROR_OTHER;
|
|
1864
|
-
} else if (r == 0)
|
|
1794
|
+
if (r == 0)
|
|
1865
1795
|
return 0;
|
|
1796
|
+
switch (errno) {
|
|
1797
|
+
case ENOTTY:
|
|
1798
|
+
break;
|
|
1799
|
+
case EBUSY:
|
|
1800
|
+
return LIBUSB_ERROR_BUSY;
|
|
1801
|
+
case EINVAL:
|
|
1802
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1803
|
+
case ENODEV:
|
|
1804
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
|
1805
|
+
default:
|
|
1806
|
+
usbi_err(HANDLE_CTX(handle), "disconnect-and-claim failed, errno=%d", errno);
|
|
1807
|
+
return LIBUSB_ERROR_OTHER;
|
|
1808
|
+
}
|
|
1866
1809
|
|
|
1867
1810
|
/* Fallback code for kernels which don't support the
|
|
1868
1811
|
disconnect-and-claim ioctl */
|
|
@@ -1873,35 +1816,35 @@ static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle,
|
|
|
1873
1816
|
return claim_interface(handle, interface);
|
|
1874
1817
|
}
|
|
1875
1818
|
|
|
1876
|
-
static int op_claim_interface(struct libusb_device_handle *handle,
|
|
1819
|
+
static int op_claim_interface(struct libusb_device_handle *handle, uint8_t interface)
|
|
1877
1820
|
{
|
|
1878
1821
|
if (handle->auto_detach_kernel_driver)
|
|
1879
|
-
return detach_kernel_driver_and_claim(handle,
|
|
1822
|
+
return detach_kernel_driver_and_claim(handle, interface);
|
|
1880
1823
|
else
|
|
1881
|
-
return claim_interface(handle,
|
|
1824
|
+
return claim_interface(handle, interface);
|
|
1882
1825
|
}
|
|
1883
1826
|
|
|
1884
|
-
static int op_release_interface(struct libusb_device_handle *handle,
|
|
1827
|
+
static int op_release_interface(struct libusb_device_handle *handle, uint8_t interface)
|
|
1885
1828
|
{
|
|
1886
1829
|
int r;
|
|
1887
1830
|
|
|
1888
|
-
r = release_interface(handle,
|
|
1831
|
+
r = release_interface(handle, interface);
|
|
1889
1832
|
if (r)
|
|
1890
1833
|
return r;
|
|
1891
1834
|
|
|
1892
1835
|
if (handle->auto_detach_kernel_driver)
|
|
1893
|
-
op_attach_kernel_driver(handle,
|
|
1836
|
+
op_attach_kernel_driver(handle, interface);
|
|
1894
1837
|
|
|
1895
1838
|
return 0;
|
|
1896
1839
|
}
|
|
1897
1840
|
|
|
1898
1841
|
static void op_destroy_device(struct libusb_device *dev)
|
|
1899
1842
|
{
|
|
1900
|
-
struct linux_device_priv *priv =
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1843
|
+
struct linux_device_priv *priv = usbi_get_device_priv(dev);
|
|
1844
|
+
|
|
1845
|
+
free(priv->config_descriptors);
|
|
1846
|
+
free(priv->descriptors);
|
|
1847
|
+
free(priv->sysfs_dir);
|
|
1905
1848
|
}
|
|
1906
1849
|
|
|
1907
1850
|
/* URBs are discarded in reverse order of submission to avoid races. */
|
|
@@ -1909,32 +1852,30 @@ static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plu
|
|
|
1909
1852
|
{
|
|
1910
1853
|
struct libusb_transfer *transfer =
|
|
1911
1854
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1912
|
-
struct linux_transfer_priv *tpriv =
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
_device_handle_priv(transfer->dev_handle);
|
|
1855
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
1856
|
+
struct linux_device_handle_priv *hpriv =
|
|
1857
|
+
usbi_get_device_handle_priv(transfer->dev_handle);
|
|
1916
1858
|
int i, ret = 0;
|
|
1917
1859
|
struct usbfs_urb *urb;
|
|
1918
1860
|
|
|
1919
1861
|
for (i = last_plus_one - 1; i >= first; i--) {
|
|
1920
|
-
if (
|
|
1862
|
+
if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
|
|
1921
1863
|
urb = tpriv->iso_urbs[i];
|
|
1922
1864
|
else
|
|
1923
1865
|
urb = &tpriv->urbs[i];
|
|
1924
1866
|
|
|
1925
|
-
if (
|
|
1867
|
+
if (ioctl(hpriv->fd, IOCTL_USBFS_DISCARDURB, urb) == 0)
|
|
1926
1868
|
continue;
|
|
1927
1869
|
|
|
1928
|
-
if (
|
|
1929
|
-
usbi_dbg("URB not found --> assuming ready to be reaped");
|
|
1870
|
+
if (errno == EINVAL) {
|
|
1871
|
+
usbi_dbg(TRANSFER_CTX(transfer), "URB not found --> assuming ready to be reaped");
|
|
1930
1872
|
if (i == (last_plus_one - 1))
|
|
1931
1873
|
ret = LIBUSB_ERROR_NOT_FOUND;
|
|
1932
|
-
} else if (
|
|
1933
|
-
usbi_dbg("Device not found for URB --> assuming ready to be reaped");
|
|
1874
|
+
} else if (errno == ENODEV) {
|
|
1875
|
+
usbi_dbg(TRANSFER_CTX(transfer), "Device not found for URB --> assuming ready to be reaped");
|
|
1934
1876
|
ret = LIBUSB_ERROR_NO_DEVICE;
|
|
1935
1877
|
} else {
|
|
1936
|
-
usbi_warn(TRANSFER_CTX(transfer),
|
|
1937
|
-
"unrecognised discard errno %d", errno);
|
|
1878
|
+
usbi_warn(TRANSFER_CTX(transfer), "unrecognised discard errno %d", errno);
|
|
1938
1879
|
ret = LIBUSB_ERROR_OTHER;
|
|
1939
1880
|
}
|
|
1940
1881
|
}
|
|
@@ -1944,8 +1885,10 @@ static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plu
|
|
|
1944
1885
|
static void free_iso_urbs(struct linux_transfer_priv *tpriv)
|
|
1945
1886
|
{
|
|
1946
1887
|
int i;
|
|
1888
|
+
|
|
1947
1889
|
for (i = 0; i < tpriv->num_urbs; i++) {
|
|
1948
1890
|
struct usbfs_urb *urb = tpriv->iso_urbs[i];
|
|
1891
|
+
|
|
1949
1892
|
if (!urb)
|
|
1950
1893
|
break;
|
|
1951
1894
|
free(urb);
|
|
@@ -1959,20 +1902,17 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
1959
1902
|
{
|
|
1960
1903
|
struct libusb_transfer *transfer =
|
|
1961
1904
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1962
|
-
struct linux_transfer_priv *tpriv =
|
|
1963
|
-
struct linux_device_handle_priv *
|
|
1964
|
-
|
|
1905
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
1906
|
+
struct linux_device_handle_priv *hpriv =
|
|
1907
|
+
usbi_get_device_handle_priv(transfer->dev_handle);
|
|
1965
1908
|
struct usbfs_urb *urbs;
|
|
1966
|
-
int is_out = (transfer
|
|
1967
|
-
== LIBUSB_ENDPOINT_OUT;
|
|
1909
|
+
int is_out = IS_XFEROUT(transfer);
|
|
1968
1910
|
int bulk_buffer_len, use_bulk_continuation;
|
|
1911
|
+
int num_urbs;
|
|
1912
|
+
int last_urb_partial = 0;
|
|
1969
1913
|
int r;
|
|
1970
1914
|
int i;
|
|
1971
1915
|
|
|
1972
|
-
if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) &&
|
|
1973
|
-
!(dpriv->caps & USBFS_CAP_ZERO_PACKET))
|
|
1974
|
-
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
1975
|
-
|
|
1976
1916
|
/*
|
|
1977
1917
|
* Older versions of usbfs place a 16kb limit on bulk URBs. We work
|
|
1978
1918
|
* around this by splitting large transfers into 16k blocks, and then
|
|
@@ -1980,7 +1920,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
1980
1920
|
* a time, but there is a big performance gain doing it this way.
|
|
1981
1921
|
*
|
|
1982
1922
|
* Newer versions lift the 16k limit (USBFS_CAP_NO_PACKET_SIZE_LIM),
|
|
1983
|
-
* using
|
|
1923
|
+
* using arbitrary large transfers can still be a bad idea though, as
|
|
1984
1924
|
* the kernel needs to allocate physical contiguous memory for this,
|
|
1985
1925
|
* which may fail for large buffers.
|
|
1986
1926
|
*
|
|
@@ -1992,16 +1932,16 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
1992
1932
|
* short split-transfers to work reliable USBFS_CAP_BULK_CONTINUATION
|
|
1993
1933
|
* is needed, but this is not always available.
|
|
1994
1934
|
*/
|
|
1995
|
-
if (
|
|
1935
|
+
if (hpriv->caps & USBFS_CAP_BULK_SCATTER_GATHER) {
|
|
1996
1936
|
/* Good! Just submit everything in one go */
|
|
1997
1937
|
bulk_buffer_len = transfer->length ? transfer->length : 1;
|
|
1998
1938
|
use_bulk_continuation = 0;
|
|
1999
|
-
} else if (
|
|
1939
|
+
} else if (hpriv->caps & USBFS_CAP_BULK_CONTINUATION) {
|
|
2000
1940
|
/* Split the transfers and use bulk-continuation to
|
|
2001
1941
|
avoid issues with short-transfers */
|
|
2002
1942
|
bulk_buffer_len = MAX_BULK_BUFFER_LENGTH;
|
|
2003
1943
|
use_bulk_continuation = 1;
|
|
2004
|
-
} else if (
|
|
1944
|
+
} else if (hpriv->caps & USBFS_CAP_NO_PACKET_SIZE_LIM) {
|
|
2005
1945
|
/* Don't split, assume the kernel can alloc the buffer
|
|
2006
1946
|
(otherwise the submit will fail with -ENOMEM) */
|
|
2007
1947
|
bulk_buffer_len = transfer->length ? transfer->length : 1;
|
|
@@ -2015,8 +1955,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
2015
1955
|
use_bulk_continuation = 0;
|
|
2016
1956
|
}
|
|
2017
1957
|
|
|
2018
|
-
|
|
2019
|
-
int last_urb_partial = 0;
|
|
1958
|
+
num_urbs = transfer->length / bulk_buffer_len;
|
|
2020
1959
|
|
|
2021
1960
|
if (transfer->length == 0) {
|
|
2022
1961
|
num_urbs = 1;
|
|
@@ -2024,9 +1963,8 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
2024
1963
|
last_urb_partial = 1;
|
|
2025
1964
|
num_urbs++;
|
|
2026
1965
|
}
|
|
2027
|
-
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
|
2028
|
-
|
|
2029
|
-
urbs = calloc(num_urbs, sizeof(struct usbfs_urb));
|
|
1966
|
+
usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length);
|
|
1967
|
+
urbs = calloc(num_urbs, sizeof(*urbs));
|
|
2030
1968
|
if (!urbs)
|
|
2031
1969
|
return LIBUSB_ERROR_NO_MEM;
|
|
2032
1970
|
tpriv->urbs = urbs;
|
|
@@ -2037,6 +1975,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
2037
1975
|
|
|
2038
1976
|
for (i = 0; i < num_urbs; i++) {
|
|
2039
1977
|
struct usbfs_urb *urb = &urbs[i];
|
|
1978
|
+
|
|
2040
1979
|
urb->usercontext = itransfer;
|
|
2041
1980
|
switch (transfer->type) {
|
|
2042
1981
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
@@ -2053,9 +1992,11 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
2053
1992
|
}
|
|
2054
1993
|
urb->endpoint = transfer->endpoint;
|
|
2055
1994
|
urb->buffer = transfer->buffer + (i * bulk_buffer_len);
|
|
1995
|
+
|
|
2056
1996
|
/* don't set the short not ok flag for the last URB */
|
|
2057
1997
|
if (use_bulk_continuation && !is_out && (i < num_urbs - 1))
|
|
2058
1998
|
urb->flags = USBFS_URB_SHORT_NOT_OK;
|
|
1999
|
+
|
|
2059
2000
|
if (i == num_urbs - 1 && last_urb_partial)
|
|
2060
2001
|
urb->buffer_length = transfer->length % bulk_buffer_len;
|
|
2061
2002
|
else if (transfer->length == 0)
|
|
@@ -2068,60 +2009,62 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
|
2068
2009
|
|
|
2069
2010
|
/* we have already checked that the flag is supported */
|
|
2070
2011
|
if (is_out && i == num_urbs - 1 &&
|
|
2071
|
-
transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
|
|
2012
|
+
(transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
|
|
2072
2013
|
urb->flags |= USBFS_URB_ZERO_PACKET;
|
|
2073
2014
|
|
|
2074
|
-
r = ioctl(
|
|
2075
|
-
if (r
|
|
2076
|
-
|
|
2077
|
-
r = LIBUSB_ERROR_NO_DEVICE;
|
|
2078
|
-
} else {
|
|
2079
|
-
usbi_err(TRANSFER_CTX(transfer),
|
|
2080
|
-
"submiturb failed error %d errno=%d", r, errno);
|
|
2081
|
-
r = LIBUSB_ERROR_IO;
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
/* if the first URB submission fails, we can simply free up and
|
|
2085
|
-
* return failure immediately. */
|
|
2086
|
-
if (i == 0) {
|
|
2087
|
-
usbi_dbg("first URB failed, easy peasy");
|
|
2088
|
-
free(urbs);
|
|
2089
|
-
tpriv->urbs = NULL;
|
|
2090
|
-
return r;
|
|
2091
|
-
}
|
|
2015
|
+
r = ioctl(hpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
|
|
2016
|
+
if (r == 0)
|
|
2017
|
+
continue;
|
|
2092
2018
|
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
* not want to throw away any data.
|
|
2102
|
-
* - this URB failing may be no error; EREMOTEIO means that
|
|
2103
|
-
* this transfer simply didn't need all the URBs we submitted
|
|
2104
|
-
* so, we report that the transfer was submitted successfully and
|
|
2105
|
-
* in case of error we discard all previous URBs. later when
|
|
2106
|
-
* the final reap completes we can report error to the user,
|
|
2107
|
-
* or success if an earlier URB was completed successfully.
|
|
2108
|
-
*/
|
|
2109
|
-
tpriv->reap_action = EREMOTEIO == errno ? COMPLETED_EARLY : SUBMIT_FAILED;
|
|
2019
|
+
if (errno == ENODEV) {
|
|
2020
|
+
r = LIBUSB_ERROR_NO_DEVICE;
|
|
2021
|
+
} else if (errno == ENOMEM) {
|
|
2022
|
+
r = LIBUSB_ERROR_NO_MEM;
|
|
2023
|
+
} else {
|
|
2024
|
+
usbi_err(TRANSFER_CTX(transfer), "submiturb failed, errno=%d", errno);
|
|
2025
|
+
r = LIBUSB_ERROR_IO;
|
|
2026
|
+
}
|
|
2110
2027
|
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2028
|
+
/* if the first URB submission fails, we can simply free up and
|
|
2029
|
+
* return failure immediately. */
|
|
2030
|
+
if (i == 0) {
|
|
2031
|
+
usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy");
|
|
2032
|
+
free(urbs);
|
|
2033
|
+
tpriv->urbs = NULL;
|
|
2034
|
+
return r;
|
|
2035
|
+
}
|
|
2114
2036
|
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2037
|
+
/* if it's not the first URB that failed, the situation is a bit
|
|
2038
|
+
* tricky. we may need to discard all previous URBs. there are
|
|
2039
|
+
* complications:
|
|
2040
|
+
* - discarding is asynchronous - discarded urbs will be reaped
|
|
2041
|
+
* later. the user must not have freed the transfer when the
|
|
2042
|
+
* discarded URBs are reaped, otherwise libusb will be using
|
|
2043
|
+
* freed memory.
|
|
2044
|
+
* - the earlier URBs may have completed successfully and we do
|
|
2045
|
+
* not want to throw away any data.
|
|
2046
|
+
* - this URB failing may be no error; EREMOTEIO means that
|
|
2047
|
+
* this transfer simply didn't need all the URBs we submitted
|
|
2048
|
+
* so, we report that the transfer was submitted successfully and
|
|
2049
|
+
* in case of error we discard all previous URBs. later when
|
|
2050
|
+
* the final reap completes we can report error to the user,
|
|
2051
|
+
* or success if an earlier URB was completed successfully.
|
|
2052
|
+
*/
|
|
2053
|
+
tpriv->reap_action = errno == EREMOTEIO ? COMPLETED_EARLY : SUBMIT_FAILED;
|
|
2118
2054
|
|
|
2119
|
-
|
|
2055
|
+
/* The URBs we haven't submitted yet we count as already
|
|
2056
|
+
* retired. */
|
|
2057
|
+
tpriv->num_retired += num_urbs - i;
|
|
2120
2058
|
|
|
2121
|
-
|
|
2122
|
-
|
|
2059
|
+
/* If we completed short then don't try to discard. */
|
|
2060
|
+
if (tpriv->reap_action == COMPLETED_EARLY)
|
|
2123
2061
|
return 0;
|
|
2124
|
-
|
|
2062
|
+
|
|
2063
|
+
discard_urbs(itransfer, 0, i);
|
|
2064
|
+
|
|
2065
|
+
usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d "
|
|
2066
|
+
"discards before reporting error", i);
|
|
2067
|
+
return 0;
|
|
2125
2068
|
}
|
|
2126
2069
|
|
|
2127
2070
|
return 0;
|
|
@@ -2131,9 +2074,9 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2131
2074
|
{
|
|
2132
2075
|
struct libusb_transfer *transfer =
|
|
2133
2076
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2134
|
-
struct linux_transfer_priv *tpriv =
|
|
2135
|
-
struct linux_device_handle_priv *
|
|
2136
|
-
|
|
2077
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2078
|
+
struct linux_device_handle_priv *hpriv =
|
|
2079
|
+
usbi_get_device_handle_priv(transfer->dev_handle);
|
|
2137
2080
|
struct usbfs_urb **urbs;
|
|
2138
2081
|
int num_packets = transfer->num_iso_packets;
|
|
2139
2082
|
int num_packets_remaining;
|
|
@@ -2156,8 +2099,8 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2156
2099
|
|
|
2157
2100
|
if (packet_len > max_iso_packet_len) {
|
|
2158
2101
|
usbi_warn(TRANSFER_CTX(transfer),
|
|
2159
|
-
|
|
2160
|
-
|
|
2102
|
+
"iso packet length of %u bytes exceeds maximum of %u bytes",
|
|
2103
|
+
packet_len, max_iso_packet_len);
|
|
2161
2104
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2162
2105
|
}
|
|
2163
2106
|
|
|
@@ -2170,8 +2113,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2170
2113
|
/* usbfs limits the number of iso packets per URB */
|
|
2171
2114
|
num_urbs = (num_packets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB;
|
|
2172
2115
|
|
|
2173
|
-
usbi_dbg("need %d urbs for new transfer with length %d", num_urbs,
|
|
2174
|
-
transfer->length);
|
|
2116
|
+
usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length);
|
|
2175
2117
|
|
|
2176
2118
|
urbs = calloc(num_urbs, sizeof(*urbs));
|
|
2177
2119
|
if (!urbs)
|
|
@@ -2221,56 +2163,55 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2221
2163
|
|
|
2222
2164
|
/* submit URBs */
|
|
2223
2165
|
for (i = 0; i < num_urbs; i++) {
|
|
2224
|
-
int r = ioctl(
|
|
2225
|
-
if (r < 0) {
|
|
2226
|
-
if (errno == ENODEV) {
|
|
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;
|
|
2236
|
-
} else {
|
|
2237
|
-
usbi_err(TRANSFER_CTX(transfer),
|
|
2238
|
-
"submiturb failed error %d errno=%d", r, errno);
|
|
2239
|
-
r = LIBUSB_ERROR_IO;
|
|
2240
|
-
}
|
|
2166
|
+
int r = ioctl(hpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]);
|
|
2241
2167
|
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
if (i == 0) {
|
|
2245
|
-
usbi_dbg("first URB failed, easy peasy");
|
|
2246
|
-
free_iso_urbs(tpriv);
|
|
2247
|
-
return r;
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
/* if it's not the first URB that failed, the situation is a bit
|
|
2251
|
-
* tricky. we must discard all previous URBs. there are
|
|
2252
|
-
* complications:
|
|
2253
|
-
* - discarding is asynchronous - discarded urbs will be reaped
|
|
2254
|
-
* later. the user must not have freed the transfer when the
|
|
2255
|
-
* discarded URBs are reaped, otherwise libusb will be using
|
|
2256
|
-
* freed memory.
|
|
2257
|
-
* - the earlier URBs may have completed successfully and we do
|
|
2258
|
-
* not want to throw away any data.
|
|
2259
|
-
* so, in this case we discard all the previous URBs BUT we report
|
|
2260
|
-
* that the transfer was submitted successfully. then later when
|
|
2261
|
-
* the final discard completes we can report error to the user.
|
|
2262
|
-
*/
|
|
2263
|
-
tpriv->reap_action = SUBMIT_FAILED;
|
|
2168
|
+
if (r == 0)
|
|
2169
|
+
continue;
|
|
2264
2170
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2171
|
+
if (errno == ENODEV) {
|
|
2172
|
+
r = LIBUSB_ERROR_NO_DEVICE;
|
|
2173
|
+
} else if (errno == EINVAL) {
|
|
2174
|
+
usbi_warn(TRANSFER_CTX(transfer), "submiturb failed, transfer too large");
|
|
2175
|
+
r = LIBUSB_ERROR_INVALID_PARAM;
|
|
2176
|
+
} else if (errno == EMSGSIZE) {
|
|
2177
|
+
usbi_warn(TRANSFER_CTX(transfer), "submiturb failed, iso packet length too large");
|
|
2178
|
+
r = LIBUSB_ERROR_INVALID_PARAM;
|
|
2179
|
+
} else {
|
|
2180
|
+
usbi_err(TRANSFER_CTX(transfer), "submiturb failed, errno=%d", errno);
|
|
2181
|
+
r = LIBUSB_ERROR_IO;
|
|
2182
|
+
}
|
|
2269
2183
|
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2184
|
+
/* if the first URB submission fails, we can simply free up and
|
|
2185
|
+
* return failure immediately. */
|
|
2186
|
+
if (i == 0) {
|
|
2187
|
+
usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy");
|
|
2188
|
+
free_iso_urbs(tpriv);
|
|
2189
|
+
return r;
|
|
2273
2190
|
}
|
|
2191
|
+
|
|
2192
|
+
/* if it's not the first URB that failed, the situation is a bit
|
|
2193
|
+
* tricky. we must discard all previous URBs. there are
|
|
2194
|
+
* complications:
|
|
2195
|
+
* - discarding is asynchronous - discarded urbs will be reaped
|
|
2196
|
+
* later. the user must not have freed the transfer when the
|
|
2197
|
+
* discarded URBs are reaped, otherwise libusb will be using
|
|
2198
|
+
* freed memory.
|
|
2199
|
+
* - the earlier URBs may have completed successfully and we do
|
|
2200
|
+
* not want to throw away any data.
|
|
2201
|
+
* so, in this case we discard all the previous URBs BUT we report
|
|
2202
|
+
* that the transfer was submitted successfully. then later when
|
|
2203
|
+
* the final discard completes we can report error to the user.
|
|
2204
|
+
*/
|
|
2205
|
+
tpriv->reap_action = SUBMIT_FAILED;
|
|
2206
|
+
|
|
2207
|
+
/* The URBs we haven't submitted yet we count as already
|
|
2208
|
+
* retired. */
|
|
2209
|
+
tpriv->num_retired = num_urbs - i;
|
|
2210
|
+
discard_urbs(itransfer, 0, i);
|
|
2211
|
+
|
|
2212
|
+
usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d "
|
|
2213
|
+
"discards before reporting error", i);
|
|
2214
|
+
return 0;
|
|
2274
2215
|
}
|
|
2275
2216
|
|
|
2276
2217
|
return 0;
|
|
@@ -2278,18 +2219,18 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
|
|
|
2278
2219
|
|
|
2279
2220
|
static int submit_control_transfer(struct usbi_transfer *itransfer)
|
|
2280
2221
|
{
|
|
2281
|
-
struct linux_transfer_priv *tpriv =
|
|
2222
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2282
2223
|
struct libusb_transfer *transfer =
|
|
2283
2224
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2284
|
-
struct linux_device_handle_priv *
|
|
2285
|
-
|
|
2225
|
+
struct linux_device_handle_priv *hpriv =
|
|
2226
|
+
usbi_get_device_handle_priv(transfer->dev_handle);
|
|
2286
2227
|
struct usbfs_urb *urb;
|
|
2287
2228
|
int r;
|
|
2288
2229
|
|
|
2289
2230
|
if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH)
|
|
2290
2231
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2291
2232
|
|
|
2292
|
-
urb = calloc(1, sizeof(
|
|
2233
|
+
urb = calloc(1, sizeof(*urb));
|
|
2293
2234
|
if (!urb)
|
|
2294
2235
|
return LIBUSB_ERROR_NO_MEM;
|
|
2295
2236
|
tpriv->urbs = urb;
|
|
@@ -2302,15 +2243,14 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
|
|
|
2302
2243
|
urb->buffer = transfer->buffer;
|
|
2303
2244
|
urb->buffer_length = transfer->length;
|
|
2304
2245
|
|
|
2305
|
-
r = ioctl(
|
|
2246
|
+
r = ioctl(hpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
|
|
2306
2247
|
if (r < 0) {
|
|
2307
2248
|
free(urb);
|
|
2308
2249
|
tpriv->urbs = NULL;
|
|
2309
2250
|
if (errno == ENODEV)
|
|
2310
2251
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
2311
2252
|
|
|
2312
|
-
usbi_err(TRANSFER_CTX(transfer),
|
|
2313
|
-
"submiturb failed error %d errno=%d", r, errno);
|
|
2253
|
+
usbi_err(TRANSFER_CTX(transfer), "submiturb failed, errno=%d", errno);
|
|
2314
2254
|
return LIBUSB_ERROR_IO;
|
|
2315
2255
|
}
|
|
2316
2256
|
return 0;
|
|
@@ -2332,15 +2272,14 @@ static int op_submit_transfer(struct usbi_transfer *itransfer)
|
|
|
2332
2272
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2333
2273
|
return submit_iso_transfer(itransfer);
|
|
2334
2274
|
default:
|
|
2335
|
-
usbi_err(TRANSFER_CTX(transfer),
|
|
2336
|
-
"unknown endpoint type %d", transfer->type);
|
|
2275
|
+
usbi_err(TRANSFER_CTX(transfer), "unknown transfer type %u", transfer->type);
|
|
2337
2276
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2338
2277
|
}
|
|
2339
2278
|
}
|
|
2340
2279
|
|
|
2341
2280
|
static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
|
2342
2281
|
{
|
|
2343
|
-
struct linux_transfer_priv *tpriv =
|
|
2282
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2344
2283
|
struct libusb_transfer *transfer =
|
|
2345
2284
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2346
2285
|
int r;
|
|
@@ -2369,7 +2308,7 @@ static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
|
2369
2308
|
{
|
|
2370
2309
|
struct libusb_transfer *transfer =
|
|
2371
2310
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2372
|
-
struct linux_transfer_priv *tpriv =
|
|
2311
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2373
2312
|
|
|
2374
2313
|
switch (transfer->type) {
|
|
2375
2314
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
@@ -2388,27 +2327,26 @@ static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
|
2388
2327
|
}
|
|
2389
2328
|
break;
|
|
2390
2329
|
default:
|
|
2391
|
-
usbi_err(TRANSFER_CTX(transfer),
|
|
2392
|
-
"unknown endpoint type %d", transfer->type);
|
|
2330
|
+
usbi_err(TRANSFER_CTX(transfer), "unknown transfer type %u", transfer->type);
|
|
2393
2331
|
}
|
|
2394
2332
|
}
|
|
2395
2333
|
|
|
2396
2334
|
static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
|
2397
2335
|
struct usbfs_urb *urb)
|
|
2398
2336
|
{
|
|
2399
|
-
struct linux_transfer_priv *tpriv =
|
|
2337
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2400
2338
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2401
2339
|
int urb_idx = urb - tpriv->urbs;
|
|
2402
2340
|
|
|
2403
2341
|
usbi_mutex_lock(&itransfer->lock);
|
|
2404
|
-
usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status,
|
|
2405
|
-
|
|
2342
|
+
usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of bulk urb %d/%d", urb->status,
|
|
2343
|
+
urb_idx + 1, tpriv->num_urbs);
|
|
2406
2344
|
|
|
2407
2345
|
tpriv->num_retired++;
|
|
2408
2346
|
|
|
2409
2347
|
if (tpriv->reap_action != NORMAL) {
|
|
2410
2348
|
/* cancelled, submit_fail, or completed early */
|
|
2411
|
-
usbi_dbg("abnormal reap: urb status %d", urb->status);
|
|
2349
|
+
usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: urb status %d", urb->status);
|
|
2412
2350
|
|
|
2413
2351
|
/* even though we're in the process of cancelling, it's possible that
|
|
2414
2352
|
* we may receive some data in these URBs that we don't want to lose.
|
|
@@ -2428,18 +2366,19 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
|
|
2428
2366
|
*/
|
|
2429
2367
|
if (urb->actual_length > 0) {
|
|
2430
2368
|
unsigned char *target = transfer->buffer + itransfer->transferred;
|
|
2431
|
-
|
|
2369
|
+
|
|
2370
|
+
usbi_dbg(TRANSFER_CTX(transfer), "received %d bytes of surplus data", urb->actual_length);
|
|
2432
2371
|
if (urb->buffer != target) {
|
|
2433
|
-
usbi_dbg("moving surplus data from offset %
|
|
2434
|
-
|
|
2435
|
-
|
|
2372
|
+
usbi_dbg(TRANSFER_CTX(transfer), "moving surplus data from offset %zu to offset %zu",
|
|
2373
|
+
(unsigned char *)urb->buffer - transfer->buffer,
|
|
2374
|
+
target - transfer->buffer);
|
|
2436
2375
|
memmove(target, urb->buffer, urb->actual_length);
|
|
2437
2376
|
}
|
|
2438
2377
|
itransfer->transferred += urb->actual_length;
|
|
2439
2378
|
}
|
|
2440
2379
|
|
|
2441
2380
|
if (tpriv->num_retired == tpriv->num_urbs) {
|
|
2442
|
-
usbi_dbg("abnormal reap: last URB handled, reporting");
|
|
2381
|
+
usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: last URB handled, reporting");
|
|
2443
2382
|
if (tpriv->reap_action != COMPLETED_EARLY &&
|
|
2444
2383
|
tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
|
|
2445
2384
|
tpriv->reap_status = LIBUSB_TRANSFER_ERROR;
|
|
@@ -2463,17 +2402,17 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
|
|
2463
2402
|
break;
|
|
2464
2403
|
case -ENODEV:
|
|
2465
2404
|
case -ESHUTDOWN:
|
|
2466
|
-
usbi_dbg("device removed");
|
|
2405
|
+
usbi_dbg(TRANSFER_CTX(transfer), "device removed");
|
|
2467
2406
|
tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE;
|
|
2468
2407
|
goto cancel_remaining;
|
|
2469
2408
|
case -EPIPE:
|
|
2470
|
-
usbi_dbg("detected endpoint stall");
|
|
2409
|
+
usbi_dbg(TRANSFER_CTX(transfer), "detected endpoint stall");
|
|
2471
2410
|
if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
|
|
2472
2411
|
tpriv->reap_status = LIBUSB_TRANSFER_STALL;
|
|
2473
2412
|
goto cancel_remaining;
|
|
2474
2413
|
case -EOVERFLOW:
|
|
2475
2414
|
/* overflow can only ever occur in the last urb */
|
|
2476
|
-
usbi_dbg("overflow, actual_length=%d", urb->actual_length);
|
|
2415
|
+
usbi_dbg(TRANSFER_CTX(transfer), "overflow, actual_length=%d", urb->actual_length);
|
|
2477
2416
|
if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
|
|
2478
2417
|
tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW;
|
|
2479
2418
|
goto completed;
|
|
@@ -2482,31 +2421,31 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
|
|
2482
2421
|
case -EILSEQ:
|
|
2483
2422
|
case -ECOMM:
|
|
2484
2423
|
case -ENOSR:
|
|
2485
|
-
usbi_dbg("low
|
|
2424
|
+
usbi_dbg(TRANSFER_CTX(transfer), "low-level bus error %d", urb->status);
|
|
2486
2425
|
tpriv->reap_action = ERROR;
|
|
2487
2426
|
goto cancel_remaining;
|
|
2488
2427
|
default:
|
|
2489
|
-
usbi_warn(ITRANSFER_CTX(itransfer),
|
|
2490
|
-
"unrecognised urb status %d", urb->status);
|
|
2428
|
+
usbi_warn(ITRANSFER_CTX(itransfer), "unrecognised urb status %d", urb->status);
|
|
2491
2429
|
tpriv->reap_action = ERROR;
|
|
2492
2430
|
goto cancel_remaining;
|
|
2493
2431
|
}
|
|
2494
2432
|
|
|
2495
|
-
/* if we'
|
|
2433
|
+
/* if we've reaped all urbs or we got less data than requested then we're
|
|
2496
2434
|
* done */
|
|
2497
|
-
if (
|
|
2498
|
-
usbi_dbg("
|
|
2435
|
+
if (tpriv->num_retired == tpriv->num_urbs) {
|
|
2436
|
+
usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!");
|
|
2499
2437
|
goto completed;
|
|
2500
2438
|
} else if (urb->actual_length < urb->buffer_length) {
|
|
2501
|
-
usbi_dbg("short transfer %d/%d --> complete!",
|
|
2502
|
-
|
|
2439
|
+
usbi_dbg(TRANSFER_CTX(transfer), "short transfer %d/%d --> complete!",
|
|
2440
|
+
urb->actual_length, urb->buffer_length);
|
|
2503
2441
|
if (tpriv->reap_action == NORMAL)
|
|
2504
2442
|
tpriv->reap_action = COMPLETED_EARLY;
|
|
2505
|
-
} else
|
|
2443
|
+
} else {
|
|
2506
2444
|
goto out_unlock;
|
|
2445
|
+
}
|
|
2507
2446
|
|
|
2508
2447
|
cancel_remaining:
|
|
2509
|
-
if (
|
|
2448
|
+
if (tpriv->reap_action == ERROR && tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
|
|
2510
2449
|
tpriv->reap_status = LIBUSB_TRANSFER_ERROR;
|
|
2511
2450
|
|
|
2512
2451
|
if (tpriv->num_retired == tpriv->num_urbs) /* nothing to cancel */
|
|
@@ -2524,7 +2463,7 @@ completed:
|
|
|
2524
2463
|
free(tpriv->urbs);
|
|
2525
2464
|
tpriv->urbs = NULL;
|
|
2526
2465
|
usbi_mutex_unlock(&itransfer->lock);
|
|
2527
|
-
return
|
|
2466
|
+
return tpriv->reap_action == CANCELLED ?
|
|
2528
2467
|
usbi_handle_transfer_cancellation(itransfer) :
|
|
2529
2468
|
usbi_handle_transfer_completion(itransfer, tpriv->reap_status);
|
|
2530
2469
|
}
|
|
@@ -2534,7 +2473,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2534
2473
|
{
|
|
2535
2474
|
struct libusb_transfer *transfer =
|
|
2536
2475
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2537
|
-
struct linux_transfer_priv *tpriv =
|
|
2476
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2538
2477
|
int num_urbs = tpriv->num_urbs;
|
|
2539
2478
|
int urb_idx = 0;
|
|
2540
2479
|
int i;
|
|
@@ -2553,8 +2492,8 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2553
2492
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
2554
2493
|
}
|
|
2555
2494
|
|
|
2556
|
-
usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status,
|
|
2557
|
-
|
|
2495
|
+
usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of iso urb %d/%d", urb->status,
|
|
2496
|
+
urb_idx, num_urbs);
|
|
2558
2497
|
|
|
2559
2498
|
/* copy isochronous results back in */
|
|
2560
2499
|
|
|
@@ -2562,6 +2501,7 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2562
2501
|
struct usbfs_iso_packet_desc *urb_desc = &urb->iso_frame_desc[i];
|
|
2563
2502
|
struct libusb_iso_packet_descriptor *lib_desc =
|
|
2564
2503
|
&transfer->iso_packet_desc[tpriv->iso_packet_offset++];
|
|
2504
|
+
|
|
2565
2505
|
lib_desc->status = LIBUSB_TRANSFER_COMPLETED;
|
|
2566
2506
|
switch (urb_desc->status) {
|
|
2567
2507
|
case 0:
|
|
@@ -2571,15 +2511,15 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2571
2511
|
break;
|
|
2572
2512
|
case -ENODEV:
|
|
2573
2513
|
case -ESHUTDOWN:
|
|
2574
|
-
usbi_dbg("device removed");
|
|
2514
|
+
usbi_dbg(TRANSFER_CTX(transfer), "packet %d - device removed", i);
|
|
2575
2515
|
lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE;
|
|
2576
2516
|
break;
|
|
2577
2517
|
case -EPIPE:
|
|
2578
|
-
usbi_dbg("detected endpoint stall");
|
|
2518
|
+
usbi_dbg(TRANSFER_CTX(transfer), "packet %d - detected endpoint stall", i);
|
|
2579
2519
|
lib_desc->status = LIBUSB_TRANSFER_STALL;
|
|
2580
2520
|
break;
|
|
2581
2521
|
case -EOVERFLOW:
|
|
2582
|
-
usbi_dbg("overflow error");
|
|
2522
|
+
usbi_dbg(TRANSFER_CTX(transfer), "packet %d - overflow error", i);
|
|
2583
2523
|
lib_desc->status = LIBUSB_TRANSFER_OVERFLOW;
|
|
2584
2524
|
break;
|
|
2585
2525
|
case -ETIME:
|
|
@@ -2588,12 +2528,12 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2588
2528
|
case -ECOMM:
|
|
2589
2529
|
case -ENOSR:
|
|
2590
2530
|
case -EXDEV:
|
|
2591
|
-
usbi_dbg("low-level USB error %d", urb_desc->status);
|
|
2531
|
+
usbi_dbg(TRANSFER_CTX(transfer), "packet %d - low-level USB error %d", i, urb_desc->status);
|
|
2592
2532
|
lib_desc->status = LIBUSB_TRANSFER_ERROR;
|
|
2593
2533
|
break;
|
|
2594
2534
|
default:
|
|
2595
|
-
usbi_warn(TRANSFER_CTX(transfer),
|
|
2596
|
-
|
|
2535
|
+
usbi_warn(TRANSFER_CTX(transfer), "packet %d - unrecognised urb status %d",
|
|
2536
|
+
i, urb_desc->status);
|
|
2597
2537
|
lib_desc->status = LIBUSB_TRANSFER_ERROR;
|
|
2598
2538
|
break;
|
|
2599
2539
|
}
|
|
@@ -2603,18 +2543,17 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2603
2543
|
tpriv->num_retired++;
|
|
2604
2544
|
|
|
2605
2545
|
if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */
|
|
2606
|
-
usbi_dbg("CANCEL: urb status %d", urb->status);
|
|
2546
|
+
usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: urb status %d", urb->status);
|
|
2607
2547
|
|
|
2608
2548
|
if (tpriv->num_retired == num_urbs) {
|
|
2609
|
-
usbi_dbg("CANCEL: last URB handled, reporting");
|
|
2549
|
+
usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: last URB handled, reporting");
|
|
2610
2550
|
free_iso_urbs(tpriv);
|
|
2611
2551
|
if (tpriv->reap_action == CANCELLED) {
|
|
2612
2552
|
usbi_mutex_unlock(&itransfer->lock);
|
|
2613
2553
|
return usbi_handle_transfer_cancellation(itransfer);
|
|
2614
2554
|
} else {
|
|
2615
2555
|
usbi_mutex_unlock(&itransfer->lock);
|
|
2616
|
-
return usbi_handle_transfer_completion(itransfer,
|
|
2617
|
-
LIBUSB_TRANSFER_ERROR);
|
|
2556
|
+
return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_ERROR);
|
|
2618
2557
|
}
|
|
2619
2558
|
}
|
|
2620
2559
|
goto out;
|
|
@@ -2627,19 +2566,18 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
|
|
2627
2566
|
case -ECONNRESET:
|
|
2628
2567
|
break;
|
|
2629
2568
|
case -ESHUTDOWN:
|
|
2630
|
-
usbi_dbg("device removed");
|
|
2569
|
+
usbi_dbg(TRANSFER_CTX(transfer), "device removed");
|
|
2631
2570
|
status = LIBUSB_TRANSFER_NO_DEVICE;
|
|
2632
2571
|
break;
|
|
2633
2572
|
default:
|
|
2634
|
-
usbi_warn(TRANSFER_CTX(transfer),
|
|
2635
|
-
"unrecognised urb status %d", urb->status);
|
|
2573
|
+
usbi_warn(TRANSFER_CTX(transfer), "unrecognised urb status %d", urb->status);
|
|
2636
2574
|
status = LIBUSB_TRANSFER_ERROR;
|
|
2637
2575
|
break;
|
|
2638
2576
|
}
|
|
2639
2577
|
|
|
2640
|
-
/* if we'
|
|
2641
|
-
if (
|
|
2642
|
-
usbi_dbg("
|
|
2578
|
+
/* if we've reaped all urbs then we're done */
|
|
2579
|
+
if (tpriv->num_retired == num_urbs) {
|
|
2580
|
+
usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!");
|
|
2643
2581
|
free_iso_urbs(tpriv);
|
|
2644
2582
|
usbi_mutex_unlock(&itransfer->lock);
|
|
2645
2583
|
return usbi_handle_transfer_completion(itransfer, status);
|
|
@@ -2653,18 +2591,18 @@ out:
|
|
|
2653
2591
|
static int handle_control_completion(struct usbi_transfer *itransfer,
|
|
2654
2592
|
struct usbfs_urb *urb)
|
|
2655
2593
|
{
|
|
2656
|
-
struct linux_transfer_priv *tpriv =
|
|
2594
|
+
struct linux_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
|
|
2657
2595
|
int status;
|
|
2658
2596
|
|
|
2659
2597
|
usbi_mutex_lock(&itransfer->lock);
|
|
2660
|
-
usbi_dbg("handling completion status %d", urb->status);
|
|
2598
|
+
usbi_dbg(ITRANSFER_CTX(itransfer), "handling completion status %d", urb->status);
|
|
2661
2599
|
|
|
2662
2600
|
itransfer->transferred += urb->actual_length;
|
|
2663
2601
|
|
|
2664
2602
|
if (tpriv->reap_action == CANCELLED) {
|
|
2665
|
-
if (urb->status
|
|
2666
|
-
usbi_warn(ITRANSFER_CTX(itransfer),
|
|
2667
|
-
|
|
2603
|
+
if (urb->status && urb->status != -ENOENT)
|
|
2604
|
+
usbi_warn(ITRANSFER_CTX(itransfer), "cancel: unrecognised urb status %d",
|
|
2605
|
+
urb->status);
|
|
2668
2606
|
free(tpriv->urbs);
|
|
2669
2607
|
tpriv->urbs = NULL;
|
|
2670
2608
|
usbi_mutex_unlock(&itransfer->lock);
|
|
@@ -2680,15 +2618,15 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
|
|
|
2680
2618
|
break;
|
|
2681
2619
|
case -ENODEV:
|
|
2682
2620
|
case -ESHUTDOWN:
|
|
2683
|
-
usbi_dbg("device removed");
|
|
2621
|
+
usbi_dbg(ITRANSFER_CTX(itransfer), "device removed");
|
|
2684
2622
|
status = LIBUSB_TRANSFER_NO_DEVICE;
|
|
2685
2623
|
break;
|
|
2686
2624
|
case -EPIPE:
|
|
2687
|
-
usbi_dbg("unsupported control request");
|
|
2625
|
+
usbi_dbg(ITRANSFER_CTX(itransfer), "unsupported control request");
|
|
2688
2626
|
status = LIBUSB_TRANSFER_STALL;
|
|
2689
2627
|
break;
|
|
2690
2628
|
case -EOVERFLOW:
|
|
2691
|
-
usbi_dbg("
|
|
2629
|
+
usbi_dbg(ITRANSFER_CTX(itransfer), "overflow, actual_length=%d", urb->actual_length);
|
|
2692
2630
|
status = LIBUSB_TRANSFER_OVERFLOW;
|
|
2693
2631
|
break;
|
|
2694
2632
|
case -ETIME:
|
|
@@ -2696,12 +2634,11 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
|
|
|
2696
2634
|
case -EILSEQ:
|
|
2697
2635
|
case -ECOMM:
|
|
2698
2636
|
case -ENOSR:
|
|
2699
|
-
usbi_dbg("low-level bus error
|
|
2637
|
+
usbi_dbg(ITRANSFER_CTX(itransfer), "low-level bus error %d", urb->status);
|
|
2700
2638
|
status = LIBUSB_TRANSFER_ERROR;
|
|
2701
2639
|
break;
|
|
2702
2640
|
default:
|
|
2703
|
-
usbi_warn(ITRANSFER_CTX(itransfer),
|
|
2704
|
-
"unrecognised urb status %d", urb->status);
|
|
2641
|
+
usbi_warn(ITRANSFER_CTX(itransfer), "unrecognised urb status %d", urb->status);
|
|
2705
2642
|
status = LIBUSB_TRANSFER_ERROR;
|
|
2706
2643
|
break;
|
|
2707
2644
|
}
|
|
@@ -2714,29 +2651,27 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
|
|
|
2714
2651
|
|
|
2715
2652
|
static int reap_for_handle(struct libusb_device_handle *handle)
|
|
2716
2653
|
{
|
|
2717
|
-
struct linux_device_handle_priv *hpriv =
|
|
2654
|
+
struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
|
|
2718
2655
|
int r;
|
|
2719
2656
|
struct usbfs_urb *urb = NULL;
|
|
2720
2657
|
struct usbi_transfer *itransfer;
|
|
2721
2658
|
struct libusb_transfer *transfer;
|
|
2722
2659
|
|
|
2723
2660
|
r = ioctl(hpriv->fd, IOCTL_USBFS_REAPURBNDELAY, &urb);
|
|
2724
|
-
if (r == -1 && errno == EAGAIN)
|
|
2725
|
-
return 1;
|
|
2726
2661
|
if (r < 0) {
|
|
2662
|
+
if (errno == EAGAIN)
|
|
2663
|
+
return 1;
|
|
2727
2664
|
if (errno == ENODEV)
|
|
2728
2665
|
return LIBUSB_ERROR_NO_DEVICE;
|
|
2729
2666
|
|
|
2730
|
-
usbi_err(HANDLE_CTX(handle), "reap failed
|
|
2731
|
-
r, errno);
|
|
2667
|
+
usbi_err(HANDLE_CTX(handle), "reap failed, errno=%d", errno);
|
|
2732
2668
|
return LIBUSB_ERROR_IO;
|
|
2733
2669
|
}
|
|
2734
2670
|
|
|
2735
2671
|
itransfer = urb->usercontext;
|
|
2736
2672
|
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
2737
2673
|
|
|
2738
|
-
usbi_dbg("urb type=%
|
|
2739
|
-
urb->actual_length);
|
|
2674
|
+
usbi_dbg(HANDLE_CTX(handle), "urb type=%u status=%d transferred=%d", urb->type, urb->status, urb->actual_length);
|
|
2740
2675
|
|
|
2741
2676
|
switch (transfer->type) {
|
|
2742
2677
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
@@ -2748,30 +2683,31 @@ static int reap_for_handle(struct libusb_device_handle *handle)
|
|
|
2748
2683
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
2749
2684
|
return handle_control_completion(itransfer, urb);
|
|
2750
2685
|
default:
|
|
2751
|
-
usbi_err(HANDLE_CTX(handle), "unrecognised
|
|
2752
|
-
transfer->type);
|
|
2686
|
+
usbi_err(HANDLE_CTX(handle), "unrecognised transfer type %u", transfer->type);
|
|
2753
2687
|
return LIBUSB_ERROR_OTHER;
|
|
2754
2688
|
}
|
|
2755
2689
|
}
|
|
2756
2690
|
|
|
2757
2691
|
static int op_handle_events(struct libusb_context *ctx,
|
|
2758
|
-
|
|
2692
|
+
void *event_data, unsigned int count, unsigned int num_ready)
|
|
2759
2693
|
{
|
|
2694
|
+
struct pollfd *fds = event_data;
|
|
2695
|
+
unsigned int n;
|
|
2760
2696
|
int r;
|
|
2761
|
-
unsigned int i = 0;
|
|
2762
2697
|
|
|
2763
2698
|
usbi_mutex_lock(&ctx->open_devs_lock);
|
|
2764
|
-
for (
|
|
2765
|
-
struct pollfd *pollfd = &fds[
|
|
2699
|
+
for (n = 0; n < count && num_ready > 0; n++) {
|
|
2700
|
+
struct pollfd *pollfd = &fds[n];
|
|
2766
2701
|
struct libusb_device_handle *handle;
|
|
2767
2702
|
struct linux_device_handle_priv *hpriv = NULL;
|
|
2703
|
+
int reap_count;
|
|
2768
2704
|
|
|
2769
2705
|
if (!pollfd->revents)
|
|
2770
2706
|
continue;
|
|
2771
2707
|
|
|
2772
2708
|
num_ready--;
|
|
2773
|
-
|
|
2774
|
-
hpriv =
|
|
2709
|
+
for_each_open_device(ctx, handle) {
|
|
2710
|
+
hpriv = usbi_get_device_handle_priv(handle);
|
|
2775
2711
|
if (hpriv->fd == pollfd->fd)
|
|
2776
2712
|
break;
|
|
2777
2713
|
}
|
|
@@ -2786,15 +2722,15 @@ static int op_handle_events(struct libusb_context *ctx,
|
|
|
2786
2722
|
/* remove the fd from the pollfd set so that it doesn't continuously
|
|
2787
2723
|
* trigger an event, and flag that it has been removed so op_close()
|
|
2788
2724
|
* doesn't try to remove it a second time */
|
|
2789
|
-
|
|
2725
|
+
usbi_remove_event_source(HANDLE_CTX(handle), hpriv->fd);
|
|
2790
2726
|
hpriv->fd_removed = 1;
|
|
2791
2727
|
|
|
2792
2728
|
/* device will still be marked as attached if hotplug monitor thread
|
|
2793
2729
|
* hasn't processed remove event yet */
|
|
2794
2730
|
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
2795
|
-
if (handle->dev->attached)
|
|
2731
|
+
if (usbi_atomic_load(&handle->dev->attached))
|
|
2796
2732
|
linux_device_disconnected(handle->dev->bus_number,
|
|
2797
|
-
|
|
2733
|
+
handle->dev->device_address);
|
|
2798
2734
|
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
2799
2735
|
|
|
2800
2736
|
if (hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT) {
|
|
@@ -2807,9 +2743,11 @@ static int op_handle_events(struct libusb_context *ctx,
|
|
|
2807
2743
|
continue;
|
|
2808
2744
|
}
|
|
2809
2745
|
|
|
2746
|
+
reap_count = 0;
|
|
2810
2747
|
do {
|
|
2811
2748
|
r = reap_for_handle(handle);
|
|
2812
|
-
} while (r == 0);
|
|
2749
|
+
} while (r == 0 && ++reap_count <= 25);
|
|
2750
|
+
|
|
2813
2751
|
if (r == 1 || r == LIBUSB_ERROR_NO_DEVICE)
|
|
2814
2752
|
continue;
|
|
2815
2753
|
else if (r < 0)
|
|
@@ -2822,34 +2760,13 @@ out:
|
|
|
2822
2760
|
return r;
|
|
2823
2761
|
}
|
|
2824
2762
|
|
|
2825
|
-
static int op_clock_gettime(int clk_id, struct timespec *tp)
|
|
2826
|
-
{
|
|
2827
|
-
switch (clk_id) {
|
|
2828
|
-
case USBI_CLOCK_MONOTONIC:
|
|
2829
|
-
return clock_gettime(monotonic_clkid, tp);
|
|
2830
|
-
case USBI_CLOCK_REALTIME:
|
|
2831
|
-
return clock_gettime(CLOCK_REALTIME, tp);
|
|
2832
|
-
default:
|
|
2833
|
-
return LIBUSB_ERROR_INVALID_PARAM;
|
|
2834
|
-
}
|
|
2835
|
-
}
|
|
2836
|
-
|
|
2837
|
-
#ifdef USBI_TIMERFD_AVAILABLE
|
|
2838
|
-
static clockid_t op_get_timerfd_clockid(void)
|
|
2839
|
-
{
|
|
2840
|
-
return monotonic_clkid;
|
|
2841
|
-
|
|
2842
|
-
}
|
|
2843
|
-
#endif
|
|
2844
|
-
|
|
2845
2763
|
const struct usbi_os_backend usbi_backend = {
|
|
2846
2764
|
.name = "Linux usbfs",
|
|
2847
2765
|
.caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
|
|
2848
2766
|
.init = op_init,
|
|
2849
2767
|
.exit = op_exit,
|
|
2850
|
-
.
|
|
2768
|
+
.set_option = op_set_option,
|
|
2851
2769
|
.hotplug_poll = op_hotplug_poll,
|
|
2852
|
-
.get_device_descriptor = op_get_device_descriptor,
|
|
2853
2770
|
.get_active_config_descriptor = op_get_active_config_descriptor,
|
|
2854
2771
|
.get_config_descriptor = op_get_config_descriptor,
|
|
2855
2772
|
.get_config_descriptor_by_value = op_get_config_descriptor_by_value,
|
|
@@ -2884,12 +2801,6 @@ const struct usbi_os_backend usbi_backend = {
|
|
|
2884
2801
|
|
|
2885
2802
|
.handle_events = op_handle_events,
|
|
2886
2803
|
|
|
2887
|
-
.clock_gettime = op_clock_gettime,
|
|
2888
|
-
|
|
2889
|
-
#ifdef USBI_TIMERFD_AVAILABLE
|
|
2890
|
-
.get_timerfd_clockid = op_get_timerfd_clockid,
|
|
2891
|
-
#endif
|
|
2892
|
-
|
|
2893
2804
|
.device_priv_size = sizeof(struct linux_device_priv),
|
|
2894
2805
|
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
|
|
2895
2806
|
.transfer_priv_size = sizeof(struct linux_transfer_priv),
|