usb 1.7.2 → 1.8.1-libusb.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +1 -1
- package/Readme.md +2 -2
- package/binding.gyp +2 -2
- package/libusb/.private/pre-commit.sh +7 -1
- package/libusb/.travis.yml +49 -0
- package/libusb/AUTHORS +44 -3
- package/libusb/Brewfile +4 -0
- package/libusb/ChangeLog +74 -2
- package/libusb/README.md +32 -0
- package/libusb/TODO +1 -1
- package/libusb/Xcode/common.xcconfig +12 -0
- package/libusb/Xcode/config.h +25 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +75 -0
- package/libusb/appveyor.yml +41 -0
- package/libusb/appveyor_cygwin.bat +11 -0
- package/libusb/appveyor_minGW.bat +19 -0
- package/libusb/autogen.sh +1 -1
- package/libusb/bootstrap.sh +3 -16
- package/libusb/configure.ac +108 -80
- package/libusb/doc/doxygen.cfg.in +1785 -739
- package/libusb/examples/Makefile.am +1 -1
- package/libusb/examples/dpfp.c +3 -1
- package/libusb/examples/dpfp_threaded.c +23 -10
- package/libusb/examples/ezusb.c +3 -3
- package/libusb/examples/ezusb.h +2 -2
- package/libusb/examples/fxload.c +31 -9
- package/libusb/examples/hotplugtest.c +35 -7
- package/libusb/examples/listdevs.c +3 -1
- package/libusb/examples/sam3u_benchmark.c +3 -3
- package/libusb/examples/testlibusb.c +277 -0
- package/libusb/examples/xusb.c +40 -34
- package/libusb/libusb/Makefile.am +49 -23
- package/libusb/libusb/core.c +855 -457
- package/libusb/libusb/descriptor.c +72 -78
- package/libusb/libusb/hotplug.c +122 -76
- package/libusb/libusb/hotplug.h +42 -25
- package/libusb/libusb/io.c +625 -390
- package/libusb/libusb/libusb-1.0.def +12 -0
- package/libusb/libusb/libusb.h +218 -150
- package/libusb/libusb/libusbi.h +346 -176
- package/libusb/libusb/os/darwin_usb.c +604 -319
- package/libusb/libusb/os/darwin_usb.h +61 -20
- package/libusb/libusb/os/haiku_pollfs.cpp +367 -0
- package/libusb/libusb/os/haiku_usb.h +113 -0
- package/libusb/libusb/os/haiku_usb_backend.cpp +533 -0
- package/libusb/libusb/os/haiku_usb_raw.cpp +267 -0
- package/libusb/libusb/os/haiku_usb_raw.h +188 -0
- package/libusb/libusb/os/linux_netlink.c +186 -146
- package/libusb/libusb/os/linux_udev.c +36 -14
- package/libusb/libusb/os/linux_usbfs.c +426 -225
- package/libusb/libusb/os/linux_usbfs.h +5 -3
- package/libusb/libusb/os/netbsd_usb.c +21 -77
- package/libusb/libusb/os/openbsd_usb.c +32 -115
- package/libusb/libusb/os/poll_posix.c +38 -5
- package/libusb/libusb/os/poll_posix.h +3 -0
- package/libusb/libusb/os/poll_windows.c +277 -626
- package/libusb/libusb/os/poll_windows.h +11 -44
- package/libusb/libusb/os/sunos_usb.c +1695 -0
- package/libusb/libusb/os/sunos_usb.h +80 -0
- package/libusb/libusb/os/threads_posix.c +24 -26
- package/libusb/libusb/os/threads_posix.h +73 -21
- package/libusb/libusb/os/threads_windows.c +71 -157
- package/libusb/libusb/os/threads_windows.h +68 -44
- package/libusb/libusb/os/wince_usb.c +276 -420
- package/libusb/libusb/os/wince_usb.h +23 -28
- package/libusb/libusb/os/windows_common.h +78 -58
- package/libusb/libusb/os/windows_nt_common.c +1010 -0
- package/libusb/libusb/os/windows_nt_common.h +110 -0
- package/libusb/libusb/os/windows_nt_shared_types.h +147 -0
- package/libusb/libusb/os/windows_usbdk.c +830 -0
- package/libusb/libusb/os/windows_usbdk.h +103 -0
- package/libusb/libusb/os/windows_winusb.c +4391 -0
- package/libusb/libusb/os/windows_winusb.h +783 -0
- package/libusb/libusb/strerror.c +41 -7
- package/libusb/libusb/sync.c +41 -13
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/libusb-1.0.pc.in +1 -1
- package/libusb/msvc/appveyor.bat +27 -0
- package/libusb/msvc/config.h +5 -4
- package/libusb/msvc/ddk_build.cmd +87 -43
- package/libusb/msvc/fxload_2010.vcxproj +24 -104
- package/libusb/msvc/fxload_2012.vcxproj +24 -107
- package/libusb/msvc/fxload_2013.vcxproj +24 -107
- package/libusb/msvc/fxload_2015.vcxproj +91 -0
- package/libusb/msvc/fxload_2017.vcxproj +114 -0
- package/libusb/msvc/fxload_sources +1 -1
- package/libusb/msvc/getopt_2010.vcxproj +16 -75
- package/libusb/msvc/getopt_2012.vcxproj +16 -79
- package/libusb/msvc/getopt_2013.vcxproj +16 -79
- package/libusb/msvc/getopt_2015.vcxproj +73 -0
- package/libusb/msvc/getopt_2017.vcxproj +98 -0
- package/libusb/msvc/getopt_sources +6 -2
- package/libusb/msvc/hotplugtest_2010.vcxproj +18 -99
- package/libusb/msvc/hotplugtest_2012.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2013.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2015.vcxproj +83 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +106 -0
- package/libusb/msvc/hotplugtest_sources +1 -1
- package/libusb/msvc/libusb_2005.sln +20 -20
- package/libusb/msvc/libusb_2010.sln +57 -46
- package/libusb/msvc/libusb_2012.sln +57 -46
- package/libusb/msvc/libusb_2013.sln +57 -50
- package/libusb/msvc/libusb_2015.sln +59 -52
- package/libusb/msvc/libusb_2017.sln +186 -0
- package/libusb/msvc/libusb_dll.dsp +2 -2
- package/libusb/msvc/libusb_dll_2005.vcproj +30 -2
- package/libusb/msvc/libusb_dll_2010.vcxproj +26 -90
- package/libusb/msvc/libusb_dll_2012.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2013.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2015.vcxproj +107 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +134 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +9 -1
- package/libusb/msvc/libusb_sources +10 -5
- package/libusb/msvc/libusb_static.dsp +2 -2
- package/libusb/msvc/libusb_static_2005.vcproj +32 -4
- package/libusb/msvc/libusb_static_2010.vcxproj +24 -83
- package/libusb/msvc/libusb_static_2012.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2013.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2015.vcxproj +98 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +117 -0
- package/libusb/msvc/libusb_static_wince.vcproj +20 -26
- package/libusb/msvc/libusb_wince.sln +88 -88
- package/libusb/msvc/listdevs_2010.vcxproj +16 -99
- package/libusb/msvc/listdevs_2012.vcxproj +16 -102
- package/libusb/msvc/listdevs_2013.vcxproj +16 -102
- package/libusb/msvc/listdevs_2015.vcxproj +83 -0
- package/libusb/msvc/listdevs_2017.vcxproj +106 -0
- package/libusb/msvc/listdevs_sources +2 -1
- package/libusb/msvc/stress_2010.vcxproj +20 -101
- package/libusb/msvc/stress_2012.vcxproj +20 -104
- package/libusb/msvc/stress_2013.vcxproj +20 -104
- package/libusb/msvc/stress_2015.vcxproj +87 -0
- package/libusb/msvc/stress_2017.vcxproj +110 -0
- package/libusb/msvc/stress_sources +21 -0
- package/libusb/msvc/testlibusb_2010.vcxproj +82 -0
- package/libusb/msvc/testlibusb_2012.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +106 -0
- package/libusb/msvc/testlibusb_sources +20 -0
- package/libusb/msvc/xusb_2010.vcxproj +17 -98
- package/libusb/msvc/xusb_2012.vcxproj +17 -101
- package/libusb/msvc/xusb_2013.vcxproj +17 -101
- package/libusb/msvc/xusb_2015.vcxproj +83 -0
- package/libusb/msvc/xusb_2017.vcxproj +106 -0
- package/libusb/msvc/xusb_sources +1 -1
- package/libusb/tests/stress.c +2 -2
- package/libusb/tests/testlib.c +0 -4
- package/libusb/travis-autogen.sh +39 -0
- package/libusb.gypi +13 -2
- package/package.json +20 -11
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +1 -1
- package/usb.js +51 -5
- package/.github/workflows/prebuild.yml +0 -49
- package/libusb/INSTALL +0 -234
- package/libusb/README +0 -28
- package/libusb/libusb/os/windows_usb.c +0 -5347
- package/libusb/libusb/os/windows_usb.h +0 -971
- package/libusb/msvc/fxload_2010.vcxproj.filters +0 -25
- package/libusb/msvc/fxload_2012.vcxproj.filters +0 -25
- package/libusb/msvc/getopt_2010.vcxproj.filters +0 -26
- package/libusb/msvc/getopt_2012.vcxproj.filters +0 -26
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +0 -14
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +0 -14
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +0 -81
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +0 -84
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +0 -74
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +0 -74
- package/libusb/msvc/listdevs_2010.vcxproj.filters +0 -14
- package/libusb/msvc/listdevs_2012.vcxproj.filters +0 -14
- package/libusb/msvc/stress_2010.vcxproj.filters +0 -25
- package/libusb/msvc/stress_2012.vcxproj.filters +0 -25
- package/libusb/msvc/xusb_2010.vcxproj.filters +0 -14
- package/libusb/msvc/xusb_2012.vcxproj.filters +0 -14
|
@@ -22,135 +22,130 @@
|
|
|
22
22
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
#include <
|
|
25
|
+
#include <config.h>
|
|
26
26
|
|
|
27
27
|
#include <stdint.h>
|
|
28
|
-
#include <errno.h>
|
|
29
28
|
#include <inttypes.h>
|
|
30
29
|
|
|
30
|
+
#include "libusbi.h"
|
|
31
31
|
#include "wince_usb.h"
|
|
32
32
|
|
|
33
|
-
// Forward declares
|
|
34
|
-
static int wince_clock_gettime(int clk_id, struct timespec *tp);
|
|
35
|
-
unsigned __stdcall wince_clock_gettime_threaded(void* param);
|
|
36
|
-
|
|
37
33
|
// Global variables
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
int windows_version = WINDOWS_CE;
|
|
34
|
+
int errno = 0;
|
|
35
|
+
static uint64_t hires_frequency, hires_ticks_to_ps;
|
|
36
|
+
static HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
|
42
37
|
static int concurrent_usage = -1;
|
|
43
|
-
// Timer thread
|
|
44
|
-
// NB: index 0 is for monotonic and 1 is for the thread exit event
|
|
45
|
-
HANDLE timer_thread = NULL;
|
|
46
|
-
HANDLE timer_mutex = NULL;
|
|
47
|
-
struct timespec timer_tp;
|
|
48
|
-
volatile LONG request_count[2] = {0, 1}; // last one must be > 0
|
|
49
|
-
HANDLE timer_request[2] = { NULL, NULL };
|
|
50
|
-
HANDLE timer_response = NULL;
|
|
51
|
-
HANDLE driver_handle = INVALID_HANDLE_VALUE;
|
|
52
38
|
|
|
53
39
|
/*
|
|
54
40
|
* Converts a windows error to human readable string
|
|
55
41
|
* uses retval as errorcode, or, if 0, use GetLastError()
|
|
56
42
|
*/
|
|
57
43
|
#if defined(ENABLE_LOGGING)
|
|
58
|
-
static char*
|
|
44
|
+
static const char *windows_error_str(DWORD error_code)
|
|
59
45
|
{
|
|
60
46
|
static TCHAR wErr_string[ERR_BUFFER_SIZE];
|
|
61
47
|
static char err_string[ERR_BUFFER_SIZE];
|
|
62
48
|
|
|
63
49
|
DWORD size;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
72
|
-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
73
|
-
|
|
50
|
+
int len;
|
|
51
|
+
|
|
52
|
+
if (error_code == 0)
|
|
53
|
+
error_code = GetLastError();
|
|
54
|
+
|
|
55
|
+
len = sprintf(err_string, "[%u] ", (unsigned int)error_code);
|
|
56
|
+
|
|
57
|
+
size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
58
|
+
NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
59
|
+
wErr_string, ERR_BUFFER_SIZE, NULL);
|
|
74
60
|
if (size == 0) {
|
|
75
|
-
format_error = GetLastError();
|
|
61
|
+
DWORD format_error = GetLastError();
|
|
76
62
|
if (format_error)
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
snprintf(err_string, ERR_BUFFER_SIZE,
|
|
64
|
+
"Windows error code %u (FormatMessage error code %u)",
|
|
65
|
+
(unsigned int)error_code, (unsigned int)format_error);
|
|
79
66
|
else
|
|
80
|
-
|
|
67
|
+
snprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", (unsigned int)error_code);
|
|
81
68
|
} else {
|
|
82
|
-
// Remove CR/LF terminators
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
strcpy(err_string, "Unable to convert error string");
|
|
69
|
+
// Remove CR/LF terminators, if present
|
|
70
|
+
size_t pos = size - 2;
|
|
71
|
+
if (wErr_string[pos] == 0x0D)
|
|
72
|
+
wErr_string[pos] = 0;
|
|
73
|
+
|
|
74
|
+
if (!WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, &err_string[len], ERR_BUFFER_SIZE - len, NULL, NULL))
|
|
75
|
+
strcpy(err_string, "Unable to convert error string");
|
|
90
76
|
}
|
|
77
|
+
|
|
91
78
|
return err_string;
|
|
92
79
|
}
|
|
93
80
|
#endif
|
|
94
81
|
|
|
95
82
|
static struct wince_device_priv *_device_priv(struct libusb_device *dev)
|
|
96
83
|
{
|
|
97
|
-
|
|
84
|
+
return (struct wince_device_priv *)dev->os_priv;
|
|
98
85
|
}
|
|
99
86
|
|
|
100
87
|
// ceusbkwrapper to libusb error code mapping
|
|
101
|
-
static int translate_driver_error(
|
|
88
|
+
static int translate_driver_error(DWORD error)
|
|
102
89
|
{
|
|
103
90
|
switch (error) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
91
|
+
case ERROR_INVALID_PARAMETER:
|
|
92
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
93
|
+
case ERROR_CALL_NOT_IMPLEMENTED:
|
|
94
|
+
case ERROR_NOT_SUPPORTED:
|
|
95
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
96
|
+
case ERROR_NOT_ENOUGH_MEMORY:
|
|
97
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
98
|
+
case ERROR_INVALID_HANDLE:
|
|
99
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
|
100
|
+
case ERROR_BUSY:
|
|
101
|
+
return LIBUSB_ERROR_BUSY;
|
|
102
|
+
|
|
103
|
+
// Error codes that are either unexpected, or have
|
|
104
|
+
// no suitable LIBUSB_ERROR equivalent.
|
|
105
|
+
case ERROR_CANCELLED:
|
|
106
|
+
case ERROR_INTERNAL_ERROR:
|
|
107
|
+
default:
|
|
108
|
+
return LIBUSB_ERROR_OTHER;
|
|
122
109
|
}
|
|
123
110
|
}
|
|
124
111
|
|
|
125
|
-
static
|
|
112
|
+
static BOOL init_dllimports(void)
|
|
126
113
|
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
114
|
+
DLL_GET_HANDLE(ceusbkwrapper);
|
|
115
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
|
|
116
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
|
|
117
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
|
|
118
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
|
|
119
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
|
|
120
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
|
|
121
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
|
|
122
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
|
|
123
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
|
|
124
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
|
|
125
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
|
|
126
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
|
|
127
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
|
|
128
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
|
|
129
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
|
|
130
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
|
|
131
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
|
|
132
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
|
|
133
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
|
|
134
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
|
|
135
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
|
|
136
|
+
DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
|
|
137
|
+
|
|
138
|
+
return TRUE;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static void exit_dllimports(void)
|
|
142
|
+
{
|
|
143
|
+
DLL_FREE_HANDLE(ceusbkwrapper);
|
|
150
144
|
}
|
|
151
145
|
|
|
152
|
-
static int init_device(
|
|
153
|
-
|
|
146
|
+
static int init_device(
|
|
147
|
+
struct libusb_device *dev, UKW_DEVICE drv_dev,
|
|
148
|
+
unsigned char bus_addr, unsigned char dev_addr)
|
|
154
149
|
{
|
|
155
150
|
struct wince_device_priv *priv = _device_priv(dev);
|
|
156
151
|
int r = LIBUSB_SUCCESS;
|
|
@@ -159,20 +154,21 @@ static int init_device(struct libusb_device *dev, UKW_DEVICE drv_dev,
|
|
|
159
154
|
dev->device_address = dev_addr;
|
|
160
155
|
priv->dev = drv_dev;
|
|
161
156
|
|
|
162
|
-
if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
|
|
157
|
+
if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
|
|
163
158
|
r = translate_driver_error(GetLastError());
|
|
164
|
-
|
|
159
|
+
|
|
165
160
|
return r;
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
// Internal API functions
|
|
169
164
|
static int wince_init(struct libusb_context *ctx)
|
|
170
165
|
{
|
|
171
|
-
int
|
|
166
|
+
int r = LIBUSB_ERROR_OTHER;
|
|
172
167
|
HANDLE semaphore;
|
|
173
|
-
|
|
168
|
+
LARGE_INTEGER li_frequency;
|
|
169
|
+
TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
|
174
170
|
|
|
175
|
-
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
|
171
|
+
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
|
176
172
|
semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
|
|
177
173
|
if (semaphore == NULL) {
|
|
178
174
|
usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
|
|
@@ -190,11 +186,8 @@ static int wince_init(struct libusb_context *ctx)
|
|
|
190
186
|
// NB: concurrent usage supposes that init calls are equally balanced with
|
|
191
187
|
// exit calls. If init is called more than exit, we will not exit properly
|
|
192
188
|
if ( ++concurrent_usage == 0 ) { // First init?
|
|
193
|
-
// Initialize pollable file descriptors
|
|
194
|
-
init_polling();
|
|
195
|
-
|
|
196
189
|
// Load DLL imports
|
|
197
|
-
if (init_dllimports()
|
|
190
|
+
if (!init_dllimports()) {
|
|
198
191
|
usbi_err(ctx, "could not resolve DLL functions");
|
|
199
192
|
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
|
200
193
|
goto init_exit;
|
|
@@ -208,37 +201,17 @@ static int wince_init(struct libusb_context *ctx)
|
|
|
208
201
|
goto init_exit;
|
|
209
202
|
}
|
|
210
203
|
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
timer_response = CreateSemaphore(NULL, 0, MAX_TIMER_SEMAPHORES, NULL);
|
|
223
|
-
if (timer_response == NULL) {
|
|
224
|
-
usbi_err(ctx, "could not create timer response semaphore - aborting");
|
|
225
|
-
goto init_exit;
|
|
226
|
-
}
|
|
227
|
-
timer_mutex = CreateMutex(NULL, FALSE, NULL);
|
|
228
|
-
if (timer_mutex == NULL) {
|
|
229
|
-
usbi_err(ctx, "could not create timer mutex - aborting");
|
|
230
|
-
goto init_exit;
|
|
231
|
-
}
|
|
232
|
-
timer_thread = CreateThread(NULL, 0, wince_clock_gettime_threaded, NULL, 0, NULL);
|
|
233
|
-
if (timer_thread == NULL) {
|
|
234
|
-
usbi_err(ctx, "Unable to create timer thread - aborting");
|
|
235
|
-
goto init_exit;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Wait for timer thread to init before continuing.
|
|
239
|
-
if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
|
|
240
|
-
usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
|
|
241
|
-
goto init_exit;
|
|
204
|
+
// find out if we have access to a monotonic (hires) timer
|
|
205
|
+
if (QueryPerformanceFrequency(&li_frequency)) {
|
|
206
|
+
hires_frequency = li_frequency.QuadPart;
|
|
207
|
+
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
|
208
|
+
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
|
209
|
+
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
|
|
210
|
+
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
|
211
|
+
} else {
|
|
212
|
+
usbi_dbg("no hires timer available on this platform");
|
|
213
|
+
hires_frequency = 0;
|
|
214
|
+
hires_ticks_to_ps = UINT64_C(0);
|
|
242
215
|
}
|
|
243
216
|
}
|
|
244
217
|
// At this stage, either we went through full init successfully, or didn't need to
|
|
@@ -246,34 +219,12 @@ static int wince_init(struct libusb_context *ctx)
|
|
|
246
219
|
|
|
247
220
|
init_exit: // Holds semaphore here.
|
|
248
221
|
if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
|
|
222
|
+
exit_dllimports();
|
|
223
|
+
|
|
249
224
|
if (driver_handle != INVALID_HANDLE_VALUE) {
|
|
250
225
|
UkwCloseDriver(driver_handle);
|
|
251
226
|
driver_handle = INVALID_HANDLE_VALUE;
|
|
252
227
|
}
|
|
253
|
-
if (timer_thread) {
|
|
254
|
-
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
|
255
|
-
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
|
256
|
-
usbi_warn(ctx, "could not wait for timer thread to quit");
|
|
257
|
-
TerminateThread(timer_thread, 1); // shouldn't happen, but we're destroying
|
|
258
|
-
// all objects it might have held anyway.
|
|
259
|
-
}
|
|
260
|
-
CloseHandle(timer_thread);
|
|
261
|
-
timer_thread = NULL;
|
|
262
|
-
}
|
|
263
|
-
for (i = 0; i < 2; i++) {
|
|
264
|
-
if (timer_request[i]) {
|
|
265
|
-
CloseHandle(timer_request[i]);
|
|
266
|
-
timer_request[i] = NULL;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (timer_response) {
|
|
270
|
-
CloseHandle(timer_response);
|
|
271
|
-
timer_response = NULL;
|
|
272
|
-
}
|
|
273
|
-
if (timer_mutex) {
|
|
274
|
-
CloseHandle(timer_mutex);
|
|
275
|
-
timer_mutex = NULL;
|
|
276
|
-
}
|
|
277
228
|
}
|
|
278
229
|
|
|
279
230
|
if (r != LIBUSB_SUCCESS)
|
|
@@ -284,17 +235,16 @@ init_exit: // Holds semaphore here.
|
|
|
284
235
|
return r;
|
|
285
236
|
}
|
|
286
237
|
|
|
287
|
-
static void wince_exit(
|
|
238
|
+
static void wince_exit(struct libusb_context *ctx)
|
|
288
239
|
{
|
|
289
|
-
int i;
|
|
290
240
|
HANDLE semaphore;
|
|
291
|
-
TCHAR sem_name[11+1
|
|
241
|
+
TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
|
|
242
|
+
UNUSED(ctx);
|
|
292
243
|
|
|
293
|
-
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
|
|
244
|
+
_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
|
|
294
245
|
semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
|
|
295
|
-
if (semaphore == NULL)
|
|
246
|
+
if (semaphore == NULL)
|
|
296
247
|
return;
|
|
297
|
-
}
|
|
298
248
|
|
|
299
249
|
// A successful wait brings our semaphore count to 0 (unsignaled)
|
|
300
250
|
// => any concurent wait stalls until the semaphore release
|
|
@@ -305,31 +255,8 @@ static void wince_exit(void)
|
|
|
305
255
|
|
|
306
256
|
// Only works if exits and inits are balanced exactly
|
|
307
257
|
if (--concurrent_usage < 0) { // Last exit
|
|
308
|
-
|
|
258
|
+
exit_dllimports();
|
|
309
259
|
|
|
310
|
-
if (timer_thread) {
|
|
311
|
-
SetEvent(timer_request[1]); // actually the signal to quit the thread.
|
|
312
|
-
if (WAIT_OBJECT_0 != WaitForSingleObject(timer_thread, INFINITE)) {
|
|
313
|
-
usbi_dbg("could not wait for timer thread to quit");
|
|
314
|
-
TerminateThread(timer_thread, 1);
|
|
315
|
-
}
|
|
316
|
-
CloseHandle(timer_thread);
|
|
317
|
-
timer_thread = NULL;
|
|
318
|
-
}
|
|
319
|
-
for (i = 0; i < 2; i++) {
|
|
320
|
-
if (timer_request[i]) {
|
|
321
|
-
CloseHandle(timer_request[i]);
|
|
322
|
-
timer_request[i] = NULL;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (timer_response) {
|
|
326
|
-
CloseHandle(timer_response);
|
|
327
|
-
timer_response = NULL;
|
|
328
|
-
}
|
|
329
|
-
if (timer_mutex) {
|
|
330
|
-
CloseHandle(timer_mutex);
|
|
331
|
-
timer_mutex = NULL;
|
|
332
|
-
}
|
|
333
260
|
if (driver_handle != INVALID_HANDLE_VALUE) {
|
|
334
261
|
UkwCloseDriver(driver_handle);
|
|
335
262
|
driver_handle = INVALID_HANDLE_VALUE;
|
|
@@ -345,7 +272,7 @@ static int wince_get_device_list(
|
|
|
345
272
|
struct discovered_devs **discdevs)
|
|
346
273
|
{
|
|
347
274
|
UKW_DEVICE devices[MAX_DEVICE_COUNT];
|
|
348
|
-
struct discovered_devs *
|
|
275
|
+
struct discovered_devs *new_devices = *discdevs;
|
|
349
276
|
DWORD count = 0, i;
|
|
350
277
|
struct libusb_device *dev = NULL;
|
|
351
278
|
unsigned char bus_addr, dev_addr;
|
|
@@ -360,51 +287,58 @@ static int wince_get_device_list(
|
|
|
360
287
|
usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
|
|
361
288
|
return libusbErr;
|
|
362
289
|
}
|
|
363
|
-
|
|
290
|
+
|
|
291
|
+
for (i = 0; i < count; ++i) {
|
|
364
292
|
release_list_offset = i;
|
|
365
293
|
success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
|
|
366
294
|
if (!success) {
|
|
367
295
|
r = translate_driver_error(GetLastError());
|
|
368
|
-
usbi_err(ctx, "could not get device address for %
|
|
296
|
+
usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0));
|
|
369
297
|
goto err_out;
|
|
370
298
|
}
|
|
299
|
+
|
|
371
300
|
dev = usbi_get_device_by_session_id(ctx, session_id);
|
|
372
301
|
if (dev) {
|
|
373
|
-
usbi_dbg("using existing device for %
|
|
302
|
+
usbi_dbg("using existing device for %u/%u (session %lu)",
|
|
374
303
|
bus_addr, dev_addr, session_id);
|
|
375
|
-
// Release just this element in the device list (as we already hold a
|
|
304
|
+
// Release just this element in the device list (as we already hold a
|
|
376
305
|
// reference to it).
|
|
377
306
|
UkwReleaseDeviceList(driver_handle, &devices[i], 1);
|
|
378
307
|
release_list_offset++;
|
|
379
308
|
} else {
|
|
380
|
-
usbi_dbg("allocating new device for %
|
|
309
|
+
usbi_dbg("allocating new device for %u/%u (session %lu)",
|
|
381
310
|
bus_addr, dev_addr, session_id);
|
|
382
311
|
dev = usbi_alloc_device(ctx, session_id);
|
|
383
312
|
if (!dev) {
|
|
384
313
|
r = LIBUSB_ERROR_NO_MEM;
|
|
385
314
|
goto err_out;
|
|
386
315
|
}
|
|
316
|
+
|
|
387
317
|
r = init_device(dev, devices[i], bus_addr, dev_addr);
|
|
388
318
|
if (r < 0)
|
|
389
319
|
goto err_out;
|
|
320
|
+
|
|
390
321
|
r = usbi_sanitize_device(dev);
|
|
391
322
|
if (r < 0)
|
|
392
323
|
goto err_out;
|
|
393
324
|
}
|
|
325
|
+
|
|
394
326
|
new_devices = discovered_devs_append(new_devices, dev);
|
|
395
|
-
if (!
|
|
327
|
+
if (!new_devices) {
|
|
396
328
|
r = LIBUSB_ERROR_NO_MEM;
|
|
397
329
|
goto err_out;
|
|
398
330
|
}
|
|
399
|
-
|
|
331
|
+
|
|
332
|
+
libusb_unref_device(dev);
|
|
400
333
|
}
|
|
334
|
+
|
|
401
335
|
*discdevs = new_devices;
|
|
402
336
|
return r;
|
|
403
337
|
err_out:
|
|
404
338
|
*discdevs = new_devices;
|
|
405
|
-
|
|
339
|
+
libusb_unref_device(dev);
|
|
406
340
|
// Release the remainder of the unprocessed device list.
|
|
407
|
-
// The devices added to new_devices already will still be passed up to libusb,
|
|
341
|
+
// The devices added to new_devices already will still be passed up to libusb,
|
|
408
342
|
// which can dispose of them at its leisure.
|
|
409
343
|
UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
|
|
410
344
|
return r;
|
|
@@ -423,8 +357,8 @@ static void wince_close(struct libusb_device_handle *handle)
|
|
|
423
357
|
}
|
|
424
358
|
|
|
425
359
|
static int wince_get_device_descriptor(
|
|
426
|
-
|
|
427
|
-
|
|
360
|
+
struct libusb_device *device,
|
|
361
|
+
unsigned char *buffer, int *host_endian)
|
|
428
362
|
{
|
|
429
363
|
struct wince_device_priv *priv = _device_priv(device);
|
|
430
364
|
|
|
@@ -439,10 +373,11 @@ static int wince_get_active_config_descriptor(
|
|
|
439
373
|
{
|
|
440
374
|
struct wince_device_priv *priv = _device_priv(device);
|
|
441
375
|
DWORD actualSize = len;
|
|
376
|
+
|
|
442
377
|
*host_endian = 0;
|
|
443
|
-
if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
|
|
378
|
+
if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
|
|
444
379
|
return translate_driver_error(GetLastError());
|
|
445
|
-
|
|
380
|
+
|
|
446
381
|
return actualSize;
|
|
447
382
|
}
|
|
448
383
|
|
|
@@ -453,22 +388,24 @@ static int wince_get_config_descriptor(
|
|
|
453
388
|
{
|
|
454
389
|
struct wince_device_priv *priv = _device_priv(device);
|
|
455
390
|
DWORD actualSize = len;
|
|
391
|
+
|
|
456
392
|
*host_endian = 0;
|
|
457
|
-
if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
|
|
393
|
+
if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
|
|
458
394
|
return translate_driver_error(GetLastError());
|
|
459
|
-
|
|
395
|
+
|
|
460
396
|
return actualSize;
|
|
461
397
|
}
|
|
462
398
|
|
|
463
399
|
static int wince_get_configuration(
|
|
464
|
-
|
|
465
|
-
|
|
400
|
+
struct libusb_device_handle *handle,
|
|
401
|
+
int *config)
|
|
466
402
|
{
|
|
467
403
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
468
404
|
UCHAR cv = 0;
|
|
469
|
-
|
|
405
|
+
|
|
406
|
+
if (!UkwGetConfig(priv->dev, &cv))
|
|
470
407
|
return translate_driver_error(GetLastError());
|
|
471
|
-
|
|
408
|
+
|
|
472
409
|
(*config) = cv;
|
|
473
410
|
return LIBUSB_SUCCESS;
|
|
474
411
|
}
|
|
@@ -482,9 +419,9 @@ static int wince_set_configuration(
|
|
|
482
419
|
// This should correspond to the "unconfigured state" required by
|
|
483
420
|
// libusb when the specified configuration is -1.
|
|
484
421
|
UCHAR cv = (config < 0) ? 0 : config;
|
|
485
|
-
if (!UkwSetConfig(priv->dev, cv))
|
|
422
|
+
if (!UkwSetConfig(priv->dev, cv))
|
|
486
423
|
return translate_driver_error(GetLastError());
|
|
487
|
-
|
|
424
|
+
|
|
488
425
|
return LIBUSB_SUCCESS;
|
|
489
426
|
}
|
|
490
427
|
|
|
@@ -493,9 +430,10 @@ static int wince_claim_interface(
|
|
|
493
430
|
int interface_number)
|
|
494
431
|
{
|
|
495
432
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
496
|
-
|
|
433
|
+
|
|
434
|
+
if (!UkwClaimInterface(priv->dev, interface_number))
|
|
497
435
|
return translate_driver_error(GetLastError());
|
|
498
|
-
|
|
436
|
+
|
|
499
437
|
return LIBUSB_SUCCESS;
|
|
500
438
|
}
|
|
501
439
|
|
|
@@ -504,12 +442,13 @@ static int wince_release_interface(
|
|
|
504
442
|
int interface_number)
|
|
505
443
|
{
|
|
506
444
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
507
|
-
|
|
445
|
+
|
|
446
|
+
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0))
|
|
508
447
|
return translate_driver_error(GetLastError());
|
|
509
|
-
|
|
510
|
-
if (!UkwReleaseInterface(priv->dev, interface_number))
|
|
448
|
+
|
|
449
|
+
if (!UkwReleaseInterface(priv->dev, interface_number))
|
|
511
450
|
return translate_driver_error(GetLastError());
|
|
512
|
-
|
|
451
|
+
|
|
513
452
|
return LIBUSB_SUCCESS;
|
|
514
453
|
}
|
|
515
454
|
|
|
@@ -518,9 +457,10 @@ static int wince_set_interface_altsetting(
|
|
|
518
457
|
int interface_number, int altsetting)
|
|
519
458
|
{
|
|
520
459
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
521
|
-
|
|
460
|
+
|
|
461
|
+
if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting))
|
|
522
462
|
return translate_driver_error(GetLastError());
|
|
523
|
-
|
|
463
|
+
|
|
524
464
|
return LIBUSB_SUCCESS;
|
|
525
465
|
}
|
|
526
466
|
|
|
@@ -529,12 +469,13 @@ static int wince_clear_halt(
|
|
|
529
469
|
unsigned char endpoint)
|
|
530
470
|
{
|
|
531
471
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
532
|
-
|
|
472
|
+
|
|
473
|
+
if (!UkwClearHaltHost(priv->dev, endpoint))
|
|
533
474
|
return translate_driver_error(GetLastError());
|
|
534
|
-
|
|
535
|
-
if (!UkwClearHaltDevice(priv->dev, endpoint))
|
|
475
|
+
|
|
476
|
+
if (!UkwClearHaltDevice(priv->dev, endpoint))
|
|
536
477
|
return translate_driver_error(GetLastError());
|
|
537
|
-
|
|
478
|
+
|
|
538
479
|
return LIBUSB_SUCCESS;
|
|
539
480
|
}
|
|
540
481
|
|
|
@@ -542,9 +483,10 @@ static int wince_reset_device(
|
|
|
542
483
|
struct libusb_device_handle *handle)
|
|
543
484
|
{
|
|
544
485
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
545
|
-
|
|
486
|
+
|
|
487
|
+
if (!UkwResetDevice(priv->dev))
|
|
546
488
|
return translate_driver_error(GetLastError());
|
|
547
|
-
|
|
489
|
+
|
|
548
490
|
return LIBUSB_SUCCESS;
|
|
549
491
|
}
|
|
550
492
|
|
|
@@ -554,9 +496,10 @@ static int wince_kernel_driver_active(
|
|
|
554
496
|
{
|
|
555
497
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
556
498
|
BOOL result = FALSE;
|
|
557
|
-
|
|
499
|
+
|
|
500
|
+
if (!UkwKernelDriverActive(priv->dev, interface_number, &result))
|
|
558
501
|
return translate_driver_error(GetLastError());
|
|
559
|
-
|
|
502
|
+
|
|
560
503
|
return result ? 1 : 0;
|
|
561
504
|
}
|
|
562
505
|
|
|
@@ -565,9 +508,10 @@ static int wince_detach_kernel_driver(
|
|
|
565
508
|
int interface_number)
|
|
566
509
|
{
|
|
567
510
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
568
|
-
|
|
511
|
+
|
|
512
|
+
if (!UkwDetachKernelDriver(priv->dev, interface_number))
|
|
569
513
|
return translate_driver_error(GetLastError());
|
|
570
|
-
|
|
514
|
+
|
|
571
515
|
return LIBUSB_SUCCESS;
|
|
572
516
|
}
|
|
573
517
|
|
|
@@ -576,40 +520,37 @@ static int wince_attach_kernel_driver(
|
|
|
576
520
|
int interface_number)
|
|
577
521
|
{
|
|
578
522
|
struct wince_device_priv *priv = _device_priv(handle->dev);
|
|
579
|
-
|
|
523
|
+
|
|
524
|
+
if (!UkwAttachKernelDriver(priv->dev, interface_number))
|
|
580
525
|
return translate_driver_error(GetLastError());
|
|
581
|
-
|
|
526
|
+
|
|
582
527
|
return LIBUSB_SUCCESS;
|
|
583
528
|
}
|
|
584
529
|
|
|
585
|
-
static void wince_destroy_device(
|
|
586
|
-
struct libusb_device *dev)
|
|
530
|
+
static void wince_destroy_device(struct libusb_device *dev)
|
|
587
531
|
{
|
|
588
532
|
struct wince_device_priv *priv = _device_priv(dev);
|
|
533
|
+
|
|
589
534
|
UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
|
|
590
535
|
}
|
|
591
536
|
|
|
592
|
-
static void wince_clear_transfer_priv(
|
|
593
|
-
struct usbi_transfer *itransfer)
|
|
537
|
+
static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
594
538
|
{
|
|
595
|
-
struct wince_transfer_priv *transfer_priv =
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
CloseHandle(wfd.handle);
|
|
600
|
-
usbi_free_fd(&transfer_priv->pollable_fd);
|
|
539
|
+
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
|
540
|
+
|
|
541
|
+
usbi_close(transfer_priv->pollable_fd.fd);
|
|
542
|
+
transfer_priv->pollable_fd = INVALID_WINFD;
|
|
601
543
|
}
|
|
602
544
|
|
|
603
|
-
static int wince_cancel_transfer(
|
|
604
|
-
struct usbi_transfer *itransfer)
|
|
545
|
+
static int wince_cancel_transfer(struct usbi_transfer *itransfer)
|
|
605
546
|
{
|
|
606
547
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
607
548
|
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
|
608
|
-
struct wince_transfer_priv *transfer_priv =
|
|
609
|
-
|
|
610
|
-
if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
|
|
549
|
+
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
|
550
|
+
|
|
551
|
+
if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
|
|
611
552
|
return translate_driver_error(GetLastError());
|
|
612
|
-
|
|
553
|
+
|
|
613
554
|
return LIBUSB_SUCCESS;
|
|
614
555
|
}
|
|
615
556
|
|
|
@@ -617,16 +558,15 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
|
|
|
617
558
|
{
|
|
618
559
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
619
560
|
struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
|
|
620
|
-
struct wince_transfer_priv *transfer_priv =
|
|
561
|
+
struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
|
621
562
|
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
|
622
563
|
BOOL direction_in, ret;
|
|
623
564
|
struct winfd wfd;
|
|
624
565
|
DWORD flags;
|
|
625
|
-
HANDLE eventHandle;
|
|
626
566
|
PUKW_CONTROL_HEADER setup = NULL;
|
|
627
567
|
const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
|
|
568
|
+
int r;
|
|
628
569
|
|
|
629
|
-
transfer_priv->pollable_fd = INVALID_WINFD;
|
|
630
570
|
if (control_transfer) {
|
|
631
571
|
setup = (PUKW_CONTROL_HEADER) transfer->buffer;
|
|
632
572
|
direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
|
|
@@ -636,19 +576,18 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
|
|
|
636
576
|
flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
|
|
637
577
|
flags |= UKW_TF_SHORT_TRANSFER_OK;
|
|
638
578
|
|
|
639
|
-
|
|
640
|
-
if (
|
|
641
|
-
usbi_err(ctx, "Failed to create event for async transfer");
|
|
579
|
+
wfd = usbi_create_fd();
|
|
580
|
+
if (wfd.fd < 0)
|
|
642
581
|
return LIBUSB_ERROR_NO_MEM;
|
|
643
|
-
}
|
|
644
582
|
|
|
645
|
-
|
|
646
|
-
if (
|
|
647
|
-
|
|
648
|
-
return
|
|
583
|
+
r = usbi_add_pollfd(ctx, wfd.fd, direction_in ? POLLIN : POLLOUT);
|
|
584
|
+
if (r) {
|
|
585
|
+
usbi_close(wfd.fd);
|
|
586
|
+
return r;
|
|
649
587
|
}
|
|
650
588
|
|
|
651
589
|
transfer_priv->pollable_fd = wfd;
|
|
590
|
+
|
|
652
591
|
if (control_transfer) {
|
|
653
592
|
// Split out control setup header and data buffer
|
|
654
593
|
DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
|
|
@@ -656,29 +595,25 @@ static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer
|
|
|
656
595
|
|
|
657
596
|
ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
|
|
658
597
|
} else {
|
|
659
|
-
ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
|
|
598
|
+
ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
|
|
660
599
|
transfer->length, &transfer->actual_length, wfd.overlapped);
|
|
661
600
|
}
|
|
601
|
+
|
|
662
602
|
if (!ret) {
|
|
663
603
|
int libusbErr = translate_driver_error(GetLastError());
|
|
664
|
-
usbi_err(ctx, "UkwIssue%sTransfer failed: error %
|
|
665
|
-
control_transfer ? "Control" : "Bulk", GetLastError());
|
|
666
|
-
|
|
604
|
+
usbi_err(ctx, "UkwIssue%sTransfer failed: error %u",
|
|
605
|
+
control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError());
|
|
606
|
+
usbi_remove_pollfd(ctx, wfd.fd);
|
|
607
|
+
usbi_close(wfd.fd);
|
|
608
|
+
transfer_priv->pollable_fd = INVALID_WINFD;
|
|
667
609
|
return libusbErr;
|
|
668
610
|
}
|
|
669
|
-
usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
|
|
670
|
-
itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;
|
|
671
611
|
|
|
672
|
-
return LIBUSB_SUCCESS;
|
|
673
|
-
}
|
|
674
612
|
|
|
675
|
-
|
|
676
|
-
{
|
|
677
|
-
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
613
|
+
return LIBUSB_SUCCESS;
|
|
678
614
|
}
|
|
679
615
|
|
|
680
|
-
static int wince_submit_transfer(
|
|
681
|
-
struct usbi_transfer *itransfer)
|
|
616
|
+
static int wince_submit_transfer(struct usbi_transfer *itransfer)
|
|
682
617
|
{
|
|
683
618
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
684
619
|
|
|
@@ -688,7 +623,6 @@ static int wince_submit_transfer(
|
|
|
688
623
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
689
624
|
return wince_submit_control_or_bulk_transfer(itransfer);
|
|
690
625
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
691
|
-
return wince_submit_iso_transfer(itransfer);
|
|
692
626
|
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
693
627
|
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
694
628
|
default:
|
|
@@ -697,19 +631,21 @@ static int wince_submit_transfer(
|
|
|
697
631
|
}
|
|
698
632
|
}
|
|
699
633
|
|
|
700
|
-
static void wince_transfer_callback(
|
|
634
|
+
static void wince_transfer_callback(
|
|
635
|
+
struct usbi_transfer *itransfer,
|
|
636
|
+
uint32_t io_result, uint32_t io_size)
|
|
701
637
|
{
|
|
702
638
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
703
639
|
struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
|
704
640
|
struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
|
705
641
|
int status;
|
|
706
642
|
|
|
707
|
-
usbi_dbg("handling I/O completion with errcode %
|
|
643
|
+
usbi_dbg("handling I/O completion with errcode %u", io_result);
|
|
708
644
|
|
|
709
|
-
if (io_result == ERROR_NOT_SUPPORTED &&
|
|
645
|
+
if (io_result == ERROR_NOT_SUPPORTED &&
|
|
710
646
|
transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
|
|
711
|
-
/* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
|
|
712
|
-
* Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
|
|
647
|
+
/* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
|
|
648
|
+
* Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
|
|
713
649
|
* endpoint isn't actually stalled.
|
|
714
650
|
*
|
|
715
651
|
* One example of this is that some devices will occasionally fail to reply to an IN
|
|
@@ -723,7 +659,7 @@ static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io
|
|
|
723
659
|
usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
|
|
724
660
|
if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
|
|
725
661
|
/* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
|
|
726
|
-
* control request to the device. This is done synchronously, which is a bit
|
|
662
|
+
* control request to the device. This is done synchronously, which is a bit
|
|
727
663
|
* naughty, but this is a special corner case.
|
|
728
664
|
*/
|
|
729
665
|
WORD wStatus = 0;
|
|
@@ -771,28 +707,25 @@ static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io
|
|
|
771
707
|
status = LIBUSB_TRANSFER_TIMED_OUT;
|
|
772
708
|
break;
|
|
773
709
|
case ERROR_OPERATION_ABORTED:
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
status = LIBUSB_TRANSFER_TIMED_OUT;
|
|
777
|
-
} else {
|
|
778
|
-
usbi_dbg("detected operation aborted");
|
|
779
|
-
status = LIBUSB_TRANSFER_CANCELLED;
|
|
780
|
-
}
|
|
710
|
+
usbi_dbg("detected operation aborted");
|
|
711
|
+
status = LIBUSB_TRANSFER_CANCELLED;
|
|
781
712
|
break;
|
|
782
713
|
default:
|
|
783
714
|
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
|
|
784
715
|
status = LIBUSB_TRANSFER_ERROR;
|
|
785
716
|
break;
|
|
786
717
|
}
|
|
718
|
+
|
|
787
719
|
wince_clear_transfer_priv(itransfer);
|
|
788
|
-
if (status == LIBUSB_TRANSFER_CANCELLED)
|
|
720
|
+
if (status == LIBUSB_TRANSFER_CANCELLED)
|
|
789
721
|
usbi_handle_transfer_cancellation(itransfer);
|
|
790
|
-
|
|
722
|
+
else
|
|
791
723
|
usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
|
|
792
|
-
}
|
|
793
724
|
}
|
|
794
725
|
|
|
795
|
-
static void wince_handle_callback
|
|
726
|
+
static void wince_handle_callback(
|
|
727
|
+
struct usbi_transfer *itransfer,
|
|
728
|
+
uint32_t io_result, uint32_t io_size)
|
|
796
729
|
{
|
|
797
730
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
798
731
|
|
|
@@ -804,7 +737,7 @@ static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_
|
|
|
804
737
|
wince_transfer_callback (itransfer, io_result, io_size);
|
|
805
738
|
break;
|
|
806
739
|
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
807
|
-
|
|
740
|
+
break;
|
|
808
741
|
default:
|
|
809
742
|
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
|
810
743
|
}
|
|
@@ -817,25 +750,25 @@ static int wince_handle_events(
|
|
|
817
750
|
struct wince_transfer_priv* transfer_priv = NULL;
|
|
818
751
|
POLL_NFDS_TYPE i = 0;
|
|
819
752
|
BOOL found = FALSE;
|
|
820
|
-
struct usbi_transfer *
|
|
753
|
+
struct usbi_transfer *itransfer;
|
|
821
754
|
DWORD io_size, io_result;
|
|
755
|
+
int r = LIBUSB_SUCCESS;
|
|
822
756
|
|
|
823
757
|
usbi_mutex_lock(&ctx->open_devs_lock);
|
|
824
758
|
for (i = 0; i < nfds && num_ready > 0; i++) {
|
|
825
759
|
|
|
826
760
|
usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
|
|
827
761
|
|
|
828
|
-
if (!fds[i].revents)
|
|
762
|
+
if (!fds[i].revents)
|
|
829
763
|
continue;
|
|
830
|
-
}
|
|
831
764
|
|
|
832
765
|
num_ready--;
|
|
833
766
|
|
|
834
767
|
// Because a Windows OVERLAPPED is used for poll emulation,
|
|
835
768
|
// a pollable fd is created and stored with each transfer
|
|
836
769
|
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
|
837
|
-
list_for_each_entry(
|
|
838
|
-
transfer_priv = usbi_transfer_get_os_priv(
|
|
770
|
+
list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
|
771
|
+
transfer_priv = usbi_transfer_get_os_priv(itransfer);
|
|
839
772
|
if (transfer_priv->pollable_fd.fd == fds[i].fd) {
|
|
840
773
|
found = TRUE;
|
|
841
774
|
break;
|
|
@@ -850,132 +783,50 @@ static int wince_handle_events(
|
|
|
850
783
|
// let handle_callback free the event using the transfer wfd
|
|
851
784
|
// If you don't use the transfer wfd, you run a risk of trying to free a
|
|
852
785
|
// newly allocated wfd that took the place of the one from the transfer.
|
|
853
|
-
wince_handle_callback(
|
|
786
|
+
wince_handle_callback(itransfer, io_result, io_size);
|
|
854
787
|
} else if (found) {
|
|
855
|
-
usbi_err(ctx, "matching transfer for fd %
|
|
856
|
-
|
|
788
|
+
usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
|
|
789
|
+
r = LIBUSB_ERROR_OTHER;
|
|
790
|
+
break;
|
|
857
791
|
} else {
|
|
858
|
-
usbi_err(ctx, "could not find a matching transfer for fd %
|
|
859
|
-
|
|
792
|
+
usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
|
|
793
|
+
r = LIBUSB_ERROR_NOT_FOUND;
|
|
794
|
+
break;
|
|
860
795
|
}
|
|
861
796
|
}
|
|
862
|
-
|
|
863
797
|
usbi_mutex_unlock(&ctx->open_devs_lock);
|
|
864
|
-
|
|
798
|
+
|
|
799
|
+
return r;
|
|
865
800
|
}
|
|
866
801
|
|
|
867
802
|
/*
|
|
868
803
|
* Monotonic and real time functions
|
|
869
804
|
*/
|
|
870
|
-
unsigned __stdcall wince_clock_gettime_threaded(void* param)
|
|
871
|
-
{
|
|
872
|
-
LARGE_INTEGER hires_counter, li_frequency;
|
|
873
|
-
LONG nb_responses;
|
|
874
|
-
int timer_index;
|
|
875
|
-
|
|
876
|
-
// Init - find out if we have access to a monotonic (hires) timer
|
|
877
|
-
if (!QueryPerformanceFrequency(&li_frequency)) {
|
|
878
|
-
usbi_dbg("no hires timer available on this platform");
|
|
879
|
-
hires_frequency = 0;
|
|
880
|
-
hires_ticks_to_ps = UINT64_C(0);
|
|
881
|
-
} else {
|
|
882
|
-
hires_frequency = li_frequency.QuadPart;
|
|
883
|
-
// The hires frequency can go as high as 4 GHz, so we'll use a conversion
|
|
884
|
-
// to picoseconds to compute the tv_nsecs part in clock_gettime
|
|
885
|
-
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
|
|
886
|
-
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
// Signal wince_init() that we're ready to service requests
|
|
890
|
-
if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
|
|
891
|
-
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
// Main loop - wait for requests
|
|
895
|
-
while (1) {
|
|
896
|
-
timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
|
|
897
|
-
if ( (timer_index != 0) && (timer_index != 1) ) {
|
|
898
|
-
usbi_dbg("failure to wait on requests: %s", windows_error_str(0));
|
|
899
|
-
continue;
|
|
900
|
-
}
|
|
901
|
-
if (request_count[timer_index] == 0) {
|
|
902
|
-
// Request already handled
|
|
903
|
-
ResetEvent(timer_request[timer_index]);
|
|
904
|
-
// There's still a possiblity that a thread sends a request between the
|
|
905
|
-
// time we test request_count[] == 0 and we reset the event, in which case
|
|
906
|
-
// the request would be ignored. The simple solution to that is to test
|
|
907
|
-
// request_count again and process requests if non zero.
|
|
908
|
-
if (request_count[timer_index] == 0)
|
|
909
|
-
continue;
|
|
910
|
-
}
|
|
911
|
-
switch (timer_index) {
|
|
912
|
-
case 0:
|
|
913
|
-
WaitForSingleObject(timer_mutex, INFINITE);
|
|
914
|
-
// Requests to this thread are for hires always
|
|
915
|
-
if (QueryPerformanceCounter(&hires_counter) != 0) {
|
|
916
|
-
timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
|
917
|
-
timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
|
|
918
|
-
} else {
|
|
919
|
-
// Fallback to real-time if we can't get monotonic value
|
|
920
|
-
// Note that real-time clock does not wait on the mutex or this thread.
|
|
921
|
-
wince_clock_gettime(USBI_CLOCK_REALTIME, &timer_tp);
|
|
922
|
-
}
|
|
923
|
-
ReleaseMutex(timer_mutex);
|
|
924
|
-
|
|
925
|
-
nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
|
|
926
|
-
if ( (nb_responses)
|
|
927
|
-
&& (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
|
|
928
|
-
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
|
929
|
-
}
|
|
930
|
-
continue;
|
|
931
|
-
case 1: // time to quit
|
|
932
|
-
usbi_dbg("timer thread quitting");
|
|
933
|
-
return 0;
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
usbi_dbg("ERROR: broken timer thread");
|
|
937
|
-
return 1;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
805
|
static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
|
941
806
|
{
|
|
942
|
-
|
|
807
|
+
LARGE_INTEGER hires_counter;
|
|
943
808
|
ULARGE_INTEGER rtime;
|
|
944
|
-
|
|
809
|
+
FILETIME filetime;
|
|
945
810
|
SYSTEMTIME st;
|
|
811
|
+
|
|
946
812
|
switch(clk_id) {
|
|
947
813
|
case USBI_CLOCK_MONOTONIC:
|
|
948
|
-
if (hires_frequency != 0) {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
r = WaitForSingleObject(timer_response, TIMER_REQUEST_RETRY_MS);
|
|
953
|
-
switch(r) {
|
|
954
|
-
case WAIT_OBJECT_0:
|
|
955
|
-
WaitForSingleObject(timer_mutex, INFINITE);
|
|
956
|
-
*tp = timer_tp;
|
|
957
|
-
ReleaseMutex(timer_mutex);
|
|
958
|
-
return LIBUSB_SUCCESS;
|
|
959
|
-
case WAIT_TIMEOUT:
|
|
960
|
-
usbi_dbg("could not obtain a timer value within reasonable timeframe - too much load?");
|
|
961
|
-
break; // Retry until successful
|
|
962
|
-
default:
|
|
963
|
-
usbi_dbg("WaitForSingleObject failed: %s", windows_error_str(0));
|
|
964
|
-
return LIBUSB_ERROR_OTHER;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
814
|
+
if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
|
|
815
|
+
tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
|
816
|
+
tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
|
|
817
|
+
return LIBUSB_SUCCESS;
|
|
967
818
|
}
|
|
968
|
-
// Fall through and return real-time if monotonic was not detected @
|
|
819
|
+
// Fall through and return real-time if monotonic read failed or was not detected @ init
|
|
969
820
|
case USBI_CLOCK_REALTIME:
|
|
970
821
|
// We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
|
|
971
|
-
// with a predef
|
|
822
|
+
// with a predef epoch time to have an epoch that starts at 1970.01.01 00:00
|
|
972
823
|
// Note however that our resolution is bounded by the Windows system time
|
|
973
824
|
// functions and is at best of the order of 1 ms (or, usually, worse)
|
|
974
825
|
GetSystemTime(&st);
|
|
975
826
|
SystemTimeToFileTime(&st, &filetime);
|
|
976
827
|
rtime.LowPart = filetime.dwLowDateTime;
|
|
977
828
|
rtime.HighPart = filetime.dwHighDateTime;
|
|
978
|
-
rtime.QuadPart -=
|
|
829
|
+
rtime.QuadPart -= EPOCH_TIME;
|
|
979
830
|
tp->tv_sec = (long)(rtime.QuadPart / 10000000);
|
|
980
831
|
tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
|
|
981
832
|
return LIBUSB_SUCCESS;
|
|
@@ -984,49 +835,54 @@ static int wince_clock_gettime(int clk_id, struct timespec *tp)
|
|
|
984
835
|
}
|
|
985
836
|
}
|
|
986
837
|
|
|
987
|
-
const struct usbi_os_backend
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
838
|
+
const struct usbi_os_backend usbi_backend = {
|
|
839
|
+
"Windows CE",
|
|
840
|
+
0,
|
|
841
|
+
wince_init,
|
|
842
|
+
wince_exit,
|
|
843
|
+
NULL, /* set_option() */
|
|
992
844
|
|
|
993
|
-
|
|
845
|
+
wince_get_device_list,
|
|
994
846
|
NULL, /* hotplug_poll */
|
|
995
|
-
|
|
996
|
-
|
|
847
|
+
wince_open,
|
|
848
|
+
wince_close,
|
|
997
849
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
850
|
+
wince_get_device_descriptor,
|
|
851
|
+
wince_get_active_config_descriptor,
|
|
852
|
+
wince_get_config_descriptor,
|
|
1001
853
|
NULL, /* get_config_descriptor_by_value() */
|
|
1002
854
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
855
|
+
wince_get_configuration,
|
|
856
|
+
wince_set_configuration,
|
|
857
|
+
wince_claim_interface,
|
|
858
|
+
wince_release_interface,
|
|
1007
859
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
860
|
+
wince_set_interface_altsetting,
|
|
861
|
+
wince_clear_halt,
|
|
862
|
+
wince_reset_device,
|
|
1011
863
|
|
|
1012
864
|
NULL, /* alloc_streams */
|
|
1013
865
|
NULL, /* free_streams */
|
|
1014
866
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
867
|
+
NULL, /* dev_mem_alloc() */
|
|
868
|
+
NULL, /* dev_mem_free() */
|
|
869
|
+
|
|
870
|
+
wince_kernel_driver_active,
|
|
871
|
+
wince_detach_kernel_driver,
|
|
872
|
+
wince_attach_kernel_driver,
|
|
1018
873
|
|
|
1019
|
-
|
|
874
|
+
wince_destroy_device,
|
|
1020
875
|
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
876
|
+
wince_submit_transfer,
|
|
877
|
+
wince_cancel_transfer,
|
|
878
|
+
wince_clear_transfer_priv,
|
|
1024
879
|
|
|
1025
|
-
|
|
880
|
+
wince_handle_events,
|
|
881
|
+
NULL, /* handle_transfer_completion() */
|
|
1026
882
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
883
|
+
wince_clock_gettime,
|
|
884
|
+
0,
|
|
885
|
+
sizeof(struct wince_device_priv),
|
|
886
|
+
0,
|
|
887
|
+
sizeof(struct wince_transfer_priv),
|
|
1032
888
|
};
|