libusb 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -2
  3. data/Gemfile +2 -0
  4. data/History.md +12 -0
  5. data/README.md +25 -14
  6. data/Rakefile +64 -109
  7. data/appveyor.yml +23 -0
  8. data/ext/extconf.rb +10 -12
  9. data/ext/libusb_recipe.rb +29 -0
  10. data/lib/libusb/call.rb +14 -11
  11. data/lib/libusb/compat.rb +9 -9
  12. data/lib/libusb/context.rb +16 -1
  13. data/lib/libusb/dependencies.rb +7 -0
  14. data/lib/libusb/dev_handle.rb +13 -3
  15. data/lib/libusb/eventmachine.rb +4 -4
  16. data/lib/libusb/transfer.rb +71 -10
  17. data/lib/libusb/version_gem.rb +1 -1
  18. data/libusb.gemspec +7 -5
  19. data/ports/archives/libusb-1.0.21.tar.bz2 +0 -0
  20. data/test/test_libusb_bulk_stream_transfer.rb +1 -1
  21. data/test/test_libusb_descriptors.rb +4 -4
  22. data/test/test_libusb_event_machine.rb +7 -7
  23. data/test/test_libusb_hotplug.rb +15 -3
  24. data/test/test_libusb_iso_transfer.rb +1 -1
  25. data/test/test_libusb_mass_storage.rb +19 -19
  26. data/test/test_libusb_mass_storage2.rb +1 -1
  27. data/test/test_libusb_structs.rb +13 -0
  28. data/test/test_libusb_threads.rb +2 -2
  29. data/wireshark-usb-sniffer.png +0 -0
  30. metadata +32 -156
  31. checksums.yaml.gz.sig +0 -0
  32. data.tar.gz.sig +0 -0
  33. data/ext/libusb-1.0.20/AUTHORS +0 -89
  34. data/ext/libusb-1.0.20/COPYING +0 -504
  35. data/ext/libusb-1.0.20/ChangeLog +0 -227
  36. data/ext/libusb-1.0.20/INSTALL +0 -234
  37. data/ext/libusb-1.0.20/Makefile.am +0 -28
  38. data/ext/libusb-1.0.20/Makefile.in +0 -897
  39. data/ext/libusb-1.0.20/NEWS +0 -2
  40. data/ext/libusb-1.0.20/PORTING +0 -94
  41. data/ext/libusb-1.0.20/README +0 -29
  42. data/ext/libusb-1.0.20/TODO +0 -2
  43. data/ext/libusb-1.0.20/Xcode/common.xcconfig +0 -49
  44. data/ext/libusb-1.0.20/Xcode/config.h +0 -28
  45. data/ext/libusb-1.0.20/Xcode/debug.xcconfig +0 -29
  46. data/ext/libusb-1.0.20/Xcode/libusb.xcconfig +0 -21
  47. data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +0 -865
  48. data/ext/libusb-1.0.20/Xcode/libusb_debug.xcconfig +0 -21
  49. data/ext/libusb-1.0.20/Xcode/libusb_release.xcconfig +0 -21
  50. data/ext/libusb-1.0.20/Xcode/release.xcconfig +0 -30
  51. data/ext/libusb-1.0.20/aclocal.m4 +0 -1193
  52. data/ext/libusb-1.0.20/android/README +0 -114
  53. data/ext/libusb-1.0.20/android/config.h +0 -81
  54. data/ext/libusb-1.0.20/android/jni/Android.mk +0 -23
  55. data/ext/libusb-1.0.20/android/jni/Application.mk +0 -24
  56. data/ext/libusb-1.0.20/android/jni/examples.mk +0 -134
  57. data/ext/libusb-1.0.20/android/jni/libusb.mk +0 -54
  58. data/ext/libusb-1.0.20/android/jni/tests.mk +0 -56
  59. data/ext/libusb-1.0.20/compile +0 -347
  60. data/ext/libusb-1.0.20/config.guess +0 -1421
  61. data/ext/libusb-1.0.20/config.h.in +0 -155
  62. data/ext/libusb-1.0.20/config.sub +0 -1807
  63. data/ext/libusb-1.0.20/configure +0 -15466
  64. data/ext/libusb-1.0.20/configure.ac +0 -326
  65. data/ext/libusb-1.0.20/depcomp +0 -791
  66. data/ext/libusb-1.0.20/doc/Makefile.am +0 -9
  67. data/ext/libusb-1.0.20/doc/Makefile.in +0 -456
  68. data/ext/libusb-1.0.20/doc/doxygen.cfg.in +0 -2334
  69. data/ext/libusb-1.0.20/examples/Makefile.am +0 -19
  70. data/ext/libusb-1.0.20/examples/Makefile.in +0 -713
  71. data/ext/libusb-1.0.20/examples/dpfp.c +0 -506
  72. data/ext/libusb-1.0.20/examples/dpfp_threaded.c +0 -549
  73. data/ext/libusb-1.0.20/examples/ezusb.c +0 -831
  74. data/ext/libusb-1.0.20/examples/ezusb.h +0 -120
  75. data/ext/libusb-1.0.20/examples/fxload.c +0 -308
  76. data/ext/libusb-1.0.20/examples/getopt/getopt.c +0 -1060
  77. data/ext/libusb-1.0.20/examples/getopt/getopt.h +0 -180
  78. data/ext/libusb-1.0.20/examples/getopt/getopt1.c +0 -188
  79. data/ext/libusb-1.0.20/examples/hotplugtest.c +0 -122
  80. data/ext/libusb-1.0.20/examples/listdevs.c +0 -71
  81. data/ext/libusb-1.0.20/examples/sam3u_benchmark.c +0 -193
  82. data/ext/libusb-1.0.20/examples/xusb.c +0 -1130
  83. data/ext/libusb-1.0.20/install-sh +0 -501
  84. data/ext/libusb-1.0.20/libusb-1.0.pc.in +0 -11
  85. data/ext/libusb-1.0.20/libusb/Makefile.am +0 -90
  86. data/ext/libusb-1.0.20/libusb/Makefile.in +0 -1053
  87. data/ext/libusb-1.0.20/libusb/core.c +0 -2452
  88. data/ext/libusb-1.0.20/libusb/descriptor.c +0 -1201
  89. data/ext/libusb-1.0.20/libusb/hotplug.c +0 -344
  90. data/ext/libusb-1.0.20/libusb/hotplug.h +0 -90
  91. data/ext/libusb-1.0.20/libusb/io.c +0 -2760
  92. data/ext/libusb-1.0.20/libusb/libusb-1.0.def +0 -168
  93. data/ext/libusb-1.0.20/libusb/libusb-1.0.rc +0 -61
  94. data/ext/libusb-1.0.20/libusb/libusb.h +0 -1999
  95. data/ext/libusb-1.0.20/libusb/libusbi.h +0 -1102
  96. data/ext/libusb-1.0.20/libusb/os/darwin_usb.c +0 -1969
  97. data/ext/libusb-1.0.20/libusb/os/darwin_usb.h +0 -158
  98. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +0 -5
  99. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +0 -810
  100. data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +0 -1193
  101. data/ext/libusb-1.0.20/libusb/os/haiku/compile +0 -347
  102. data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +0 -1421
  103. data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +0 -1807
  104. data/ext/libusb-1.0.20/libusb/os/haiku/configure +0 -17579
  105. data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +0 -8
  106. data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +0 -791
  107. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +0 -378
  108. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +0 -112
  109. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +0 -550
  110. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +0 -255
  111. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +0 -180
  112. data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +0 -501
  113. data/ext/libusb-1.0.20/libusb/os/haiku/ltmain.sh +0 -9655
  114. data/ext/libusb-1.0.20/libusb/os/haiku/m4/libtool.m4 +0 -7992
  115. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltoptions.m4 +0 -384
  116. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltsugar.m4 +0 -123
  117. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltversion.m4 +0 -23
  118. data/ext/libusb-1.0.20/libusb/os/haiku/m4/lt~obsolete.m4 +0 -98
  119. data/ext/libusb-1.0.20/libusb/os/haiku/missing +0 -215
  120. data/ext/libusb-1.0.20/libusb/os/linux_netlink.c +0 -369
  121. data/ext/libusb-1.0.20/libusb/os/linux_udev.c +0 -306
  122. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.c +0 -2692
  123. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.h +0 -192
  124. data/ext/libusb-1.0.20/libusb/os/netbsd_usb.c +0 -674
  125. data/ext/libusb-1.0.20/libusb/os/openbsd_usb.c +0 -768
  126. data/ext/libusb-1.0.20/libusb/os/poll_posix.c +0 -53
  127. data/ext/libusb-1.0.20/libusb/os/poll_posix.h +0 -11
  128. data/ext/libusb-1.0.20/libusb/os/poll_windows.c +0 -728
  129. data/ext/libusb-1.0.20/libusb/os/poll_windows.h +0 -131
  130. data/ext/libusb-1.0.20/libusb/os/threads_posix.c +0 -82
  131. data/ext/libusb-1.0.20/libusb/os/threads_posix.h +0 -50
  132. data/ext/libusb-1.0.20/libusb/os/threads_windows.c +0 -214
  133. data/ext/libusb-1.0.20/libusb/os/threads_windows.h +0 -87
  134. data/ext/libusb-1.0.20/libusb/os/wince_usb.c +0 -869
  135. data/ext/libusb-1.0.20/libusb/os/wince_usb.h +0 -131
  136. data/ext/libusb-1.0.20/libusb/os/windows_common.h +0 -108
  137. data/ext/libusb-1.0.20/libusb/os/windows_usb.c +0 -4643
  138. data/ext/libusb-1.0.20/libusb/os/windows_usb.h +0 -973
  139. data/ext/libusb-1.0.20/libusb/strerror.c +0 -202
  140. data/ext/libusb-1.0.20/libusb/sync.c +0 -308
  141. data/ext/libusb-1.0.20/libusb/version.h +0 -18
  142. data/ext/libusb-1.0.20/libusb/version_nano.h +0 -1
  143. data/ext/libusb-1.0.20/ltmain.sh +0 -9655
  144. data/ext/libusb-1.0.20/m4/libtool.m4 +0 -7992
  145. data/ext/libusb-1.0.20/m4/ltoptions.m4 +0 -384
  146. data/ext/libusb-1.0.20/m4/ltsugar.m4 +0 -123
  147. data/ext/libusb-1.0.20/m4/ltversion.m4 +0 -23
  148. data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +0 -98
  149. data/ext/libusb-1.0.20/missing +0 -215
  150. data/ext/libusb-1.0.20/tests/Makefile.am +0 -6
  151. data/ext/libusb-1.0.20/tests/Makefile.in +0 -596
  152. data/ext/libusb-1.0.20/tests/libusb_testlib.h +0 -107
  153. data/ext/libusb-1.0.20/tests/stress.c +0 -160
  154. data/ext/libusb-1.0.20/tests/testlib.c +0 -277
  155. metadata.gz.sig +0 -0
@@ -1,87 +0,0 @@
1
- /*
2
- * libusb synchronization on Microsoft Windows
3
- *
4
- * Copyright © 2010 Michael Plante <michael.plante@gmail.com>
5
- *
6
- * This library is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU Lesser General Public
8
- * License as published by the Free Software Foundation; either
9
- * version 2.1 of the License, or (at your option) any later version.
10
- *
11
- * This library is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * Lesser General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Lesser General Public
17
- * License along with this library; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
- */
20
-
21
- #ifndef LIBUSB_THREADS_WINDOWS_H
22
- #define LIBUSB_THREADS_WINDOWS_H
23
-
24
- #define usbi_mutex_static_t volatile LONG
25
- #define USBI_MUTEX_INITIALIZER 0
26
-
27
- #define usbi_mutex_t HANDLE
28
-
29
- struct usbi_cond_perthread {
30
- struct list_head list;
31
- DWORD tid;
32
- HANDLE event;
33
- };
34
- struct usbi_cond_t_ {
35
- // Every time a thread touches the CV, it winds up in one of these lists.
36
- // It stays there until the CV is destroyed, even if the thread
37
- // terminates.
38
- struct list_head waiters;
39
- struct list_head not_waiting;
40
- };
41
- typedef struct usbi_cond_t_ usbi_cond_t;
42
-
43
- // We *were* getting timespec from pthread.h:
44
- #if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
45
- #define HAVE_STRUCT_TIMESPEC 1
46
- #define _TIMESPEC_DEFINED 1
47
- struct timespec {
48
- long tv_sec;
49
- long tv_nsec;
50
- };
51
- #endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
52
-
53
- // We *were* getting ETIMEDOUT from pthread.h:
54
- #ifndef ETIMEDOUT
55
- # define ETIMEDOUT 10060 /* This is the value in winsock.h. */
56
- #endif
57
-
58
- #define usbi_mutexattr_t void
59
- #define usbi_condattr_t void
60
-
61
- // all Windows mutexes are recursive
62
- #define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
63
-
64
- int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
65
- int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
66
-
67
-
68
- int usbi_mutex_init(usbi_mutex_t *mutex,
69
- const usbi_mutexattr_t *attr);
70
- int usbi_mutex_lock(usbi_mutex_t *mutex);
71
- int usbi_mutex_unlock(usbi_mutex_t *mutex);
72
- int usbi_mutex_trylock(usbi_mutex_t *mutex);
73
- int usbi_mutex_destroy(usbi_mutex_t *mutex);
74
-
75
- int usbi_cond_init(usbi_cond_t *cond,
76
- const usbi_condattr_t *attr);
77
- int usbi_cond_destroy(usbi_cond_t *cond);
78
- int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
79
- int usbi_cond_timedwait(usbi_cond_t *cond,
80
- usbi_mutex_t *mutex,
81
- const struct timespec *abstime);
82
- int usbi_cond_broadcast(usbi_cond_t *cond);
83
- int usbi_cond_signal(usbi_cond_t *cond);
84
-
85
- int usbi_get_tid(void);
86
-
87
- #endif /* LIBUSB_THREADS_WINDOWS_H */
@@ -1,869 +0,0 @@
1
- /*
2
- * Windows CE backend for libusb 1.0
3
- * Copyright © 2011-2013 RealVNC Ltd.
4
- * Large portions taken from Windows backend, which is
5
- * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
6
- * With contributions from Michael Plante, Orin Eman et al.
7
- * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
8
- * Major code testing contribution by Xiaofan Chen
9
- *
10
- * This library is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU Lesser General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2.1 of the License, or (at your option) any later version.
14
- *
15
- * This library is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * Lesser General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU Lesser General Public
21
- * License along with this library; if not, write to the Free Software
22
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
- */
24
-
25
- #include <config.h>
26
-
27
- #include <stdint.h>
28
- #include <inttypes.h>
29
-
30
- #include "libusbi.h"
31
- #include "wince_usb.h"
32
-
33
- // Global variables
34
- uint64_t hires_frequency, hires_ticks_to_ps;
35
- const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
36
- int windows_version = WINDOWS_CE;
37
- static int concurrent_usage = -1;
38
- HANDLE driver_handle = INVALID_HANDLE_VALUE;
39
-
40
- /*
41
- * Converts a windows error to human readable string
42
- * uses retval as errorcode, or, if 0, use GetLastError()
43
- */
44
- #if defined(ENABLE_LOGGING)
45
- static char* windows_error_str(uint32_t retval)
46
- {
47
- static TCHAR wErr_string[ERR_BUFFER_SIZE];
48
- static char err_string[ERR_BUFFER_SIZE];
49
-
50
- DWORD size;
51
- size_t i;
52
- uint32_t error_code, format_error;
53
-
54
- error_code = retval?retval:GetLastError();
55
-
56
- safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%d] "), error_code);
57
-
58
- size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
59
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)],
60
- ERR_BUFFER_SIZE - (DWORD)safe_tcslen(wErr_string), NULL);
61
- if (size == 0) {
62
- format_error = GetLastError();
63
- if (format_error)
64
- safe_stprintf(wErr_string, ERR_BUFFER_SIZE,
65
- _T("Windows error code %u (FormatMessage error code %u)"), error_code, format_error);
66
- else
67
- safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), error_code);
68
- } else {
69
- // Remove CR/LF terminators
70
- for (i=safe_tcslen(wErr_string)-1; ((wErr_string[i]==0x0A) || (wErr_string[i]==0x0D)); i--) {
71
- wErr_string[i] = 0;
72
- }
73
- }
74
- if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0)
75
- {
76
- strcpy(err_string, "Unable to convert error string");
77
- }
78
- return err_string;
79
- }
80
- #endif
81
-
82
- static struct wince_device_priv *_device_priv(struct libusb_device *dev)
83
- {
84
- return (struct wince_device_priv *) dev->os_priv;
85
- }
86
-
87
- // ceusbkwrapper to libusb error code mapping
88
- static int translate_driver_error(int error)
89
- {
90
- switch (error) {
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 equivilant.
105
- case ERROR_CANCELLED:
106
- case ERROR_INTERNAL_ERROR:
107
- default:
108
- return LIBUSB_ERROR_OTHER;
109
- }
110
- }
111
-
112
- static int init_dllimports()
113
- {
114
- DLL_LOAD(ceusbkwrapper.dll, UkwOpenDriver, TRUE);
115
- DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceList, TRUE);
116
- DLL_LOAD(ceusbkwrapper.dll, UkwReleaseDeviceList, TRUE);
117
- DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceAddress, TRUE);
118
- DLL_LOAD(ceusbkwrapper.dll, UkwGetDeviceDescriptor, TRUE);
119
- DLL_LOAD(ceusbkwrapper.dll, UkwGetConfigDescriptor, TRUE);
120
- DLL_LOAD(ceusbkwrapper.dll, UkwCloseDriver, TRUE);
121
- DLL_LOAD(ceusbkwrapper.dll, UkwCancelTransfer, TRUE);
122
- DLL_LOAD(ceusbkwrapper.dll, UkwIssueControlTransfer, TRUE);
123
- DLL_LOAD(ceusbkwrapper.dll, UkwClaimInterface, TRUE);
124
- DLL_LOAD(ceusbkwrapper.dll, UkwReleaseInterface, TRUE);
125
- DLL_LOAD(ceusbkwrapper.dll, UkwSetInterfaceAlternateSetting, TRUE);
126
- DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltHost, TRUE);
127
- DLL_LOAD(ceusbkwrapper.dll, UkwClearHaltDevice, TRUE);
128
- DLL_LOAD(ceusbkwrapper.dll, UkwGetConfig, TRUE);
129
- DLL_LOAD(ceusbkwrapper.dll, UkwSetConfig, TRUE);
130
- DLL_LOAD(ceusbkwrapper.dll, UkwResetDevice, TRUE);
131
- DLL_LOAD(ceusbkwrapper.dll, UkwKernelDriverActive, TRUE);
132
- DLL_LOAD(ceusbkwrapper.dll, UkwAttachKernelDriver, TRUE);
133
- DLL_LOAD(ceusbkwrapper.dll, UkwDetachKernelDriver, TRUE);
134
- DLL_LOAD(ceusbkwrapper.dll, UkwIssueBulkTransfer, TRUE);
135
- DLL_LOAD(ceusbkwrapper.dll, UkwIsPipeHalted, TRUE);
136
- return LIBUSB_SUCCESS;
137
- }
138
-
139
- static int init_device(
140
- struct libusb_device *dev, UKW_DEVICE drv_dev,
141
- unsigned char bus_addr, unsigned char dev_addr)
142
- {
143
- struct wince_device_priv *priv = _device_priv(dev);
144
- int r = LIBUSB_SUCCESS;
145
-
146
- dev->bus_number = bus_addr;
147
- dev->device_address = dev_addr;
148
- priv->dev = drv_dev;
149
-
150
- if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc))) {
151
- r = translate_driver_error(GetLastError());
152
- }
153
- return r;
154
- }
155
-
156
- // Internal API functions
157
- static int wince_init(struct libusb_context *ctx)
158
- {
159
- int r = LIBUSB_ERROR_OTHER;
160
- HANDLE semaphore;
161
- LARGE_INTEGER li_frequency;
162
- TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
163
-
164
- _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
165
- semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
166
- if (semaphore == NULL) {
167
- usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
168
- return LIBUSB_ERROR_NO_MEM;
169
- }
170
-
171
- // A successful wait brings our semaphore count to 0 (unsignaled)
172
- // => any concurent wait stalls until the semaphore's release
173
- if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
174
- usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
175
- CloseHandle(semaphore);
176
- return LIBUSB_ERROR_NO_MEM;
177
- }
178
-
179
- // NB: concurrent usage supposes that init calls are equally balanced with
180
- // exit calls. If init is called more than exit, we will not exit properly
181
- if ( ++concurrent_usage == 0 ) { // First init?
182
- // Initialize pollable file descriptors
183
- init_polling();
184
-
185
- // Load DLL imports
186
- if (init_dllimports() != LIBUSB_SUCCESS) {
187
- usbi_err(ctx, "could not resolve DLL functions");
188
- r = LIBUSB_ERROR_NOT_SUPPORTED;
189
- goto init_exit;
190
- }
191
-
192
- // try to open a handle to the driver
193
- driver_handle = UkwOpenDriver();
194
- if (driver_handle == INVALID_HANDLE_VALUE) {
195
- usbi_err(ctx, "could not connect to driver");
196
- r = LIBUSB_ERROR_NOT_SUPPORTED;
197
- goto init_exit;
198
- }
199
-
200
- // find out if we have access to a monotonic (hires) timer
201
- if (QueryPerformanceFrequency(&li_frequency)) {
202
- hires_frequency = li_frequency.QuadPart;
203
- // The hires frequency can go as high as 4 GHz, so we'll use a conversion
204
- // to picoseconds to compute the tv_nsecs part in clock_gettime
205
- hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
206
- usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
207
- } else {
208
- usbi_dbg("no hires timer available on this platform");
209
- hires_frequency = 0;
210
- hires_ticks_to_ps = UINT64_C(0);
211
- }
212
- }
213
- // At this stage, either we went through full init successfully, or didn't need to
214
- r = LIBUSB_SUCCESS;
215
-
216
- init_exit: // Holds semaphore here.
217
- if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
218
- if (driver_handle != INVALID_HANDLE_VALUE) {
219
- UkwCloseDriver(driver_handle);
220
- driver_handle = INVALID_HANDLE_VALUE;
221
- }
222
- }
223
-
224
- if (r != LIBUSB_SUCCESS)
225
- --concurrent_usage; // Not expected to call libusb_exit if we failed.
226
-
227
- ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
228
- CloseHandle(semaphore);
229
- return r;
230
- }
231
-
232
- static void wince_exit(void)
233
- {
234
- HANDLE semaphore;
235
- TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
236
-
237
- _stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)GetCurrentProcessId()&0xFFFFFFFF);
238
- semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
239
- if (semaphore == NULL) {
240
- return;
241
- }
242
-
243
- // A successful wait brings our semaphore count to 0 (unsignaled)
244
- // => any concurent wait stalls until the semaphore release
245
- if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
246
- CloseHandle(semaphore);
247
- return;
248
- }
249
-
250
- // Only works if exits and inits are balanced exactly
251
- if (--concurrent_usage < 0) { // Last exit
252
- exit_polling();
253
-
254
- if (driver_handle != INVALID_HANDLE_VALUE) {
255
- UkwCloseDriver(driver_handle);
256
- driver_handle = INVALID_HANDLE_VALUE;
257
- }
258
- }
259
-
260
- ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
261
- CloseHandle(semaphore);
262
- }
263
-
264
- static int wince_get_device_list(
265
- struct libusb_context *ctx,
266
- struct discovered_devs **discdevs)
267
- {
268
- UKW_DEVICE devices[MAX_DEVICE_COUNT];
269
- struct discovered_devs * new_devices = *discdevs;
270
- DWORD count = 0, i;
271
- struct libusb_device *dev = NULL;
272
- unsigned char bus_addr, dev_addr;
273
- unsigned long session_id;
274
- BOOL success;
275
- DWORD release_list_offset = 0;
276
- int r = LIBUSB_SUCCESS;
277
-
278
- success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count);
279
- if (!success) {
280
- int libusbErr = translate_driver_error(GetLastError());
281
- usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
282
- return libusbErr;
283
- }
284
- for(i = 0; i < count; ++i) {
285
- release_list_offset = i;
286
- success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
287
- if (!success) {
288
- r = translate_driver_error(GetLastError());
289
- usbi_err(ctx, "could not get device address for %d: %s", i, windows_error_str(0));
290
- goto err_out;
291
- }
292
- dev = usbi_get_device_by_session_id(ctx, session_id);
293
- if (dev) {
294
- usbi_dbg("using existing device for %d/%d (session %ld)",
295
- bus_addr, dev_addr, session_id);
296
- // Release just this element in the device list (as we already hold a
297
- // reference to it).
298
- UkwReleaseDeviceList(driver_handle, &devices[i], 1);
299
- release_list_offset++;
300
- } else {
301
- usbi_dbg("allocating new device for %d/%d (session %ld)",
302
- bus_addr, dev_addr, session_id);
303
- dev = usbi_alloc_device(ctx, session_id);
304
- if (!dev) {
305
- r = LIBUSB_ERROR_NO_MEM;
306
- goto err_out;
307
- }
308
- r = init_device(dev, devices[i], bus_addr, dev_addr);
309
- if (r < 0)
310
- goto err_out;
311
- r = usbi_sanitize_device(dev);
312
- if (r < 0)
313
- goto err_out;
314
- }
315
- new_devices = discovered_devs_append(new_devices, dev);
316
- if (!discdevs) {
317
- r = LIBUSB_ERROR_NO_MEM;
318
- goto err_out;
319
- }
320
- safe_unref_device(dev);
321
- }
322
- *discdevs = new_devices;
323
- return r;
324
- err_out:
325
- *discdevs = new_devices;
326
- safe_unref_device(dev);
327
- // Release the remainder of the unprocessed device list.
328
- // The devices added to new_devices already will still be passed up to libusb,
329
- // which can dispose of them at its leisure.
330
- UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
331
- return r;
332
- }
333
-
334
- static int wince_open(struct libusb_device_handle *handle)
335
- {
336
- // Nothing to do to open devices as a handle to it has
337
- // been retrieved by wince_get_device_list
338
- return LIBUSB_SUCCESS;
339
- }
340
-
341
- static void wince_close(struct libusb_device_handle *handle)
342
- {
343
- // Nothing to do as wince_open does nothing.
344
- }
345
-
346
- static int wince_get_device_descriptor(
347
- struct libusb_device *device,
348
- unsigned char *buffer, int *host_endian)
349
- {
350
- struct wince_device_priv *priv = _device_priv(device);
351
-
352
- *host_endian = 1;
353
- memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH);
354
- return LIBUSB_SUCCESS;
355
- }
356
-
357
- static int wince_get_active_config_descriptor(
358
- struct libusb_device *device,
359
- unsigned char *buffer, size_t len, int *host_endian)
360
- {
361
- struct wince_device_priv *priv = _device_priv(device);
362
- DWORD actualSize = len;
363
- *host_endian = 0;
364
- if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize)) {
365
- return translate_driver_error(GetLastError());
366
- }
367
- return actualSize;
368
- }
369
-
370
- static int wince_get_config_descriptor(
371
- struct libusb_device *device,
372
- uint8_t config_index,
373
- unsigned char *buffer, size_t len, int *host_endian)
374
- {
375
- struct wince_device_priv *priv = _device_priv(device);
376
- DWORD actualSize = len;
377
- *host_endian = 0;
378
- if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize)) {
379
- return translate_driver_error(GetLastError());
380
- }
381
- return actualSize;
382
- }
383
-
384
- static int wince_get_configuration(
385
- struct libusb_device_handle *handle,
386
- int *config)
387
- {
388
- struct wince_device_priv *priv = _device_priv(handle->dev);
389
- UCHAR cv = 0;
390
- if (!UkwGetConfig(priv->dev, &cv)) {
391
- return translate_driver_error(GetLastError());
392
- }
393
- (*config) = cv;
394
- return LIBUSB_SUCCESS;
395
- }
396
-
397
- static int wince_set_configuration(
398
- struct libusb_device_handle *handle,
399
- int config)
400
- {
401
- struct wince_device_priv *priv = _device_priv(handle->dev);
402
- // Setting configuration 0 places the device in Address state.
403
- // This should correspond to the "unconfigured state" required by
404
- // libusb when the specified configuration is -1.
405
- UCHAR cv = (config < 0) ? 0 : config;
406
- if (!UkwSetConfig(priv->dev, cv)) {
407
- return translate_driver_error(GetLastError());
408
- }
409
- return LIBUSB_SUCCESS;
410
- }
411
-
412
- static int wince_claim_interface(
413
- struct libusb_device_handle *handle,
414
- int interface_number)
415
- {
416
- struct wince_device_priv *priv = _device_priv(handle->dev);
417
- if (!UkwClaimInterface(priv->dev, interface_number)) {
418
- return translate_driver_error(GetLastError());
419
- }
420
- return LIBUSB_SUCCESS;
421
- }
422
-
423
- static int wince_release_interface(
424
- struct libusb_device_handle *handle,
425
- int interface_number)
426
- {
427
- struct wince_device_priv *priv = _device_priv(handle->dev);
428
- if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0)) {
429
- return translate_driver_error(GetLastError());
430
- }
431
- if (!UkwReleaseInterface(priv->dev, interface_number)) {
432
- return translate_driver_error(GetLastError());
433
- }
434
- return LIBUSB_SUCCESS;
435
- }
436
-
437
- static int wince_set_interface_altsetting(
438
- struct libusb_device_handle *handle,
439
- int interface_number, int altsetting)
440
- {
441
- struct wince_device_priv *priv = _device_priv(handle->dev);
442
- if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting)) {
443
- return translate_driver_error(GetLastError());
444
- }
445
- return LIBUSB_SUCCESS;
446
- }
447
-
448
- static int wince_clear_halt(
449
- struct libusb_device_handle *handle,
450
- unsigned char endpoint)
451
- {
452
- struct wince_device_priv *priv = _device_priv(handle->dev);
453
- if (!UkwClearHaltHost(priv->dev, endpoint)) {
454
- return translate_driver_error(GetLastError());
455
- }
456
- if (!UkwClearHaltDevice(priv->dev, endpoint)) {
457
- return translate_driver_error(GetLastError());
458
- }
459
- return LIBUSB_SUCCESS;
460
- }
461
-
462
- static int wince_reset_device(
463
- struct libusb_device_handle *handle)
464
- {
465
- struct wince_device_priv *priv = _device_priv(handle->dev);
466
- if (!UkwResetDevice(priv->dev)) {
467
- return translate_driver_error(GetLastError());
468
- }
469
- return LIBUSB_SUCCESS;
470
- }
471
-
472
- static int wince_kernel_driver_active(
473
- struct libusb_device_handle *handle,
474
- int interface_number)
475
- {
476
- struct wince_device_priv *priv = _device_priv(handle->dev);
477
- BOOL result = FALSE;
478
- if (!UkwKernelDriverActive(priv->dev, interface_number, &result)) {
479
- return translate_driver_error(GetLastError());
480
- }
481
- return result ? 1 : 0;
482
- }
483
-
484
- static int wince_detach_kernel_driver(
485
- struct libusb_device_handle *handle,
486
- int interface_number)
487
- {
488
- struct wince_device_priv *priv = _device_priv(handle->dev);
489
- if (!UkwDetachKernelDriver(priv->dev, interface_number)) {
490
- return translate_driver_error(GetLastError());
491
- }
492
- return LIBUSB_SUCCESS;
493
- }
494
-
495
- static int wince_attach_kernel_driver(
496
- struct libusb_device_handle *handle,
497
- int interface_number)
498
- {
499
- struct wince_device_priv *priv = _device_priv(handle->dev);
500
- if (!UkwAttachKernelDriver(priv->dev, interface_number)) {
501
- return translate_driver_error(GetLastError());
502
- }
503
- return LIBUSB_SUCCESS;
504
- }
505
-
506
- static void wince_destroy_device(struct libusb_device *dev)
507
- {
508
- struct wince_device_priv *priv = _device_priv(dev);
509
- UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
510
- }
511
-
512
- static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
513
- {
514
- struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
515
- struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
516
- // No need to cancel transfer as it is either complete or abandoned
517
- wfd.itransfer = NULL;
518
- CloseHandle(wfd.handle);
519
- usbi_free_fd(&transfer_priv->pollable_fd);
520
- }
521
-
522
- static int wince_cancel_transfer(struct usbi_transfer *itransfer)
523
- {
524
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
525
- struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
526
- struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
527
-
528
- if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT)) {
529
- return translate_driver_error(GetLastError());
530
- }
531
- return LIBUSB_SUCCESS;
532
- }
533
-
534
- static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
535
- {
536
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
537
- struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
538
- struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
539
- struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
540
- BOOL direction_in, ret;
541
- struct winfd wfd;
542
- DWORD flags;
543
- HANDLE eventHandle;
544
- PUKW_CONTROL_HEADER setup = NULL;
545
- const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
546
-
547
- transfer_priv->pollable_fd = INVALID_WINFD;
548
- if (control_transfer) {
549
- setup = (PUKW_CONTROL_HEADER) transfer->buffer;
550
- direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
551
- } else {
552
- direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
553
- }
554
- flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
555
- flags |= UKW_TF_SHORT_TRANSFER_OK;
556
-
557
- eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
558
- if (eventHandle == NULL) {
559
- usbi_err(ctx, "Failed to create event for async transfer");
560
- return LIBUSB_ERROR_NO_MEM;
561
- }
562
-
563
- wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
564
- if (wfd.fd < 0) {
565
- CloseHandle(eventHandle);
566
- return LIBUSB_ERROR_NO_MEM;
567
- }
568
-
569
- transfer_priv->pollable_fd = wfd;
570
- if (control_transfer) {
571
- // Split out control setup header and data buffer
572
- DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
573
- PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];
574
-
575
- ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
576
- } else {
577
- ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
578
- transfer->length, &transfer->actual_length, wfd.overlapped);
579
- }
580
- if (!ret) {
581
- int libusbErr = translate_driver_error(GetLastError());
582
- usbi_err(ctx, "UkwIssue%sTransfer failed: error %d",
583
- control_transfer ? "Control" : "Bulk", GetLastError());
584
- wince_clear_transfer_priv(itransfer);
585
- return libusbErr;
586
- }
587
- usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
588
-
589
- return LIBUSB_SUCCESS;
590
- }
591
-
592
- static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
593
- {
594
- return LIBUSB_ERROR_NOT_SUPPORTED;
595
- }
596
-
597
- static int wince_submit_transfer(struct usbi_transfer *itransfer)
598
- {
599
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
600
-
601
- switch (transfer->type) {
602
- case LIBUSB_TRANSFER_TYPE_CONTROL:
603
- case LIBUSB_TRANSFER_TYPE_BULK:
604
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
605
- return wince_submit_control_or_bulk_transfer(itransfer);
606
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
607
- return wince_submit_iso_transfer(itransfer);
608
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
609
- return LIBUSB_ERROR_NOT_SUPPORTED;
610
- default:
611
- usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
612
- return LIBUSB_ERROR_INVALID_PARAM;
613
- }
614
- }
615
-
616
- static void wince_transfer_callback(
617
- struct usbi_transfer *itransfer,
618
- uint32_t io_result, uint32_t io_size)
619
- {
620
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
621
- struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
622
- struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
623
- int status;
624
-
625
- usbi_dbg("handling I/O completion with errcode %d", io_result);
626
-
627
- if (io_result == ERROR_NOT_SUPPORTED &&
628
- transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
629
- /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
630
- * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
631
- * endpoint isn't actually stalled.
632
- *
633
- * One example of this is that some devices will occasionally fail to reply to an IN
634
- * token. The WinCE USB layer carries on with the transaction until it is completed
635
- * (or cancelled) but then completes it with USB_ERROR_STALL.
636
- *
637
- * This code therefore needs to confirm that there really is a stall error, by both
638
- * checking the pipe status and requesting the endpoint status from the device.
639
- */
640
- BOOL halted = FALSE;
641
- usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
642
- if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
643
- /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
644
- * control request to the device. This is done synchronously, which is a bit
645
- * naughty, but this is a special corner case.
646
- */
647
- WORD wStatus = 0;
648
- DWORD written = 0;
649
- UKW_CONTROL_HEADER ctrlHeader;
650
- ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD |
651
- LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT;
652
- ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS;
653
- ctrlHeader.wValue = 0;
654
- ctrlHeader.wIndex = transfer->endpoint;
655
- ctrlHeader.wLength = sizeof(wStatus);
656
- if (UkwIssueControlTransfer(priv->dev,
657
- UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT,
658
- &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) {
659
- if (written == sizeof(wStatus) &&
660
- (wStatus & STATUS_HALT_FLAG) == 0) {
661
- if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) {
662
- usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
663
- io_result = ERROR_SUCCESS;
664
- } else {
665
- usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
666
- io_result = ERROR_IO_DEVICE;
667
- }
668
- }
669
- }
670
- }
671
- }
672
-
673
- switch(io_result) {
674
- case ERROR_SUCCESS:
675
- itransfer->transferred += io_size;
676
- status = LIBUSB_TRANSFER_COMPLETED;
677
- break;
678
- case ERROR_CANCELLED:
679
- usbi_dbg("detected transfer cancel");
680
- status = LIBUSB_TRANSFER_CANCELLED;
681
- break;
682
- case ERROR_NOT_SUPPORTED:
683
- case ERROR_GEN_FAILURE:
684
- usbi_dbg("detected endpoint stall");
685
- status = LIBUSB_TRANSFER_STALL;
686
- break;
687
- case ERROR_SEM_TIMEOUT:
688
- usbi_dbg("detected semaphore timeout");
689
- status = LIBUSB_TRANSFER_TIMED_OUT;
690
- break;
691
- case ERROR_OPERATION_ABORTED:
692
- if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
693
- usbi_dbg("detected timeout");
694
- status = LIBUSB_TRANSFER_TIMED_OUT;
695
- } else {
696
- usbi_dbg("detected operation aborted");
697
- status = LIBUSB_TRANSFER_CANCELLED;
698
- }
699
- break;
700
- default:
701
- usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
702
- status = LIBUSB_TRANSFER_ERROR;
703
- break;
704
- }
705
- wince_clear_transfer_priv(itransfer);
706
- if (status == LIBUSB_TRANSFER_CANCELLED) {
707
- usbi_handle_transfer_cancellation(itransfer);
708
- } else {
709
- usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
710
- }
711
- }
712
-
713
- static void wince_handle_callback(
714
- struct usbi_transfer *itransfer,
715
- uint32_t io_result, uint32_t io_size)
716
- {
717
- struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
718
-
719
- switch (transfer->type) {
720
- case LIBUSB_TRANSFER_TYPE_CONTROL:
721
- case LIBUSB_TRANSFER_TYPE_BULK:
722
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
723
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
724
- wince_transfer_callback (itransfer, io_result, io_size);
725
- break;
726
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
727
- break;
728
- default:
729
- usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
730
- }
731
- }
732
-
733
- static int wince_handle_events(
734
- struct libusb_context *ctx,
735
- struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
736
- {
737
- struct wince_transfer_priv* transfer_priv = NULL;
738
- POLL_NFDS_TYPE i = 0;
739
- BOOL found = FALSE;
740
- struct usbi_transfer *transfer;
741
- DWORD io_size, io_result;
742
-
743
- usbi_mutex_lock(&ctx->open_devs_lock);
744
- for (i = 0; i < nfds && num_ready > 0; i++) {
745
-
746
- usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
747
-
748
- if (!fds[i].revents) {
749
- continue;
750
- }
751
-
752
- num_ready--;
753
-
754
- // Because a Windows OVERLAPPED is used for poll emulation,
755
- // a pollable fd is created and stored with each transfer
756
- usbi_mutex_lock(&ctx->flying_transfers_lock);
757
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
758
- transfer_priv = usbi_transfer_get_os_priv(transfer);
759
- if (transfer_priv->pollable_fd.fd == fds[i].fd) {
760
- found = TRUE;
761
- break;
762
- }
763
- }
764
- usbi_mutex_unlock(&ctx->flying_transfers_lock);
765
-
766
- if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
767
- io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
768
- io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
769
- usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
770
- // let handle_callback free the event using the transfer wfd
771
- // If you don't use the transfer wfd, you run a risk of trying to free a
772
- // newly allocated wfd that took the place of the one from the transfer.
773
- wince_handle_callback(transfer, io_result, io_size);
774
- } else if (found) {
775
- usbi_err(ctx, "matching transfer for fd %x has not completed", fds[i]);
776
- usbi_mutex_unlock(&ctx->open_devs_lock);
777
- return LIBUSB_ERROR_OTHER;
778
- } else {
779
- usbi_err(ctx, "could not find a matching transfer for fd %x", fds[i]);
780
- usbi_mutex_unlock(&ctx->open_devs_lock);
781
- return LIBUSB_ERROR_NOT_FOUND;
782
- }
783
- }
784
-
785
- usbi_mutex_unlock(&ctx->open_devs_lock);
786
- return LIBUSB_SUCCESS;
787
- }
788
-
789
- /*
790
- * Monotonic and real time functions
791
- */
792
- static int wince_clock_gettime(int clk_id, struct timespec *tp)
793
- {
794
- LARGE_INTEGER hires_counter;
795
- ULARGE_INTEGER rtime;
796
- FILETIME filetime;
797
- SYSTEMTIME st;
798
- switch(clk_id) {
799
- case USBI_CLOCK_MONOTONIC:
800
- if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
801
- tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
802
- tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
803
- return LIBUSB_SUCCESS;
804
- }
805
- // Fall through and return real-time if monotonic read failed or was not detected @ init
806
- case USBI_CLOCK_REALTIME:
807
- // We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
808
- // with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
809
- // Note however that our resolution is bounded by the Windows system time
810
- // functions and is at best of the order of 1 ms (or, usually, worse)
811
- GetSystemTime(&st);
812
- SystemTimeToFileTime(&st, &filetime);
813
- rtime.LowPart = filetime.dwLowDateTime;
814
- rtime.HighPart = filetime.dwHighDateTime;
815
- rtime.QuadPart -= epoch_time;
816
- tp->tv_sec = (long)(rtime.QuadPart / 10000000);
817
- tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
818
- return LIBUSB_SUCCESS;
819
- default:
820
- return LIBUSB_ERROR_INVALID_PARAM;
821
- }
822
- }
823
-
824
- const struct usbi_os_backend wince_backend = {
825
- "Windows CE",
826
- 0,
827
- wince_init,
828
- wince_exit,
829
-
830
- wince_get_device_list,
831
- NULL, /* hotplug_poll */
832
- wince_open,
833
- wince_close,
834
-
835
- wince_get_device_descriptor,
836
- wince_get_active_config_descriptor,
837
- wince_get_config_descriptor,
838
- NULL, /* get_config_descriptor_by_value() */
839
-
840
- wince_get_configuration,
841
- wince_set_configuration,
842
- wince_claim_interface,
843
- wince_release_interface,
844
-
845
- wince_set_interface_altsetting,
846
- wince_clear_halt,
847
- wince_reset_device,
848
-
849
- NULL, /* alloc_streams */
850
- NULL, /* free_streams */
851
-
852
- wince_kernel_driver_active,
853
- wince_detach_kernel_driver,
854
- wince_attach_kernel_driver,
855
-
856
- wince_destroy_device,
857
-
858
- wince_submit_transfer,
859
- wince_cancel_transfer,
860
- wince_clear_transfer_priv,
861
-
862
- wince_handle_events,
863
- NULL, /* handle_transfer_completion() */
864
-
865
- wince_clock_gettime,
866
- sizeof(struct wince_device_priv),
867
- sizeof(struct wince_device_handle_priv),
868
- sizeof(struct wince_transfer_priv),
869
- };