usb 2.17.0 → 3.0.0-alpha.2

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.
Files changed (207) hide show
  1. package/LICENSE +18 -4
  2. package/README.md +25 -516
  3. package/dist/index.d.ts +67 -13
  4. package/dist/index.js +333 -64
  5. package/index.d.ts +89 -0
  6. package/index.js +583 -0
  7. package/package.json +53 -33
  8. package/CHANGELOG.md +0 -294
  9. package/binding.gyp +0 -128
  10. package/dist/index.js.map +0 -1
  11. package/dist/usb/bindings.d.ts +0 -266
  12. package/dist/usb/bindings.js +0 -10
  13. package/dist/usb/bindings.js.map +0 -1
  14. package/dist/usb/capability.d.ts +0 -13
  15. package/dist/usb/capability.js +0 -17
  16. package/dist/usb/capability.js.map +0 -1
  17. package/dist/usb/descriptors.d.ts +0 -128
  18. package/dist/usb/descriptors.js +0 -3
  19. package/dist/usb/descriptors.js.map +0 -1
  20. package/dist/usb/device.d.ts +0 -100
  21. package/dist/usb/device.js +0 -297
  22. package/dist/usb/device.js.map +0 -1
  23. package/dist/usb/endpoint.d.ts +0 -94
  24. package/dist/usb/endpoint.js +0 -219
  25. package/dist/usb/endpoint.js.map +0 -1
  26. package/dist/usb/index.d.ts +0 -31
  27. package/dist/usb/index.js +0 -116
  28. package/dist/usb/index.js.map +0 -1
  29. package/dist/usb/interface.d.ts +0 -80
  30. package/dist/usb/interface.js +0 -133
  31. package/dist/usb/interface.js.map +0 -1
  32. package/dist/webusb/index.d.ts +0 -64
  33. package/dist/webusb/index.js +0 -295
  34. package/dist/webusb/index.js.map +0 -1
  35. package/dist/webusb/webusb-device.d.ts +0 -54
  36. package/dist/webusb/webusb-device.js +0 -434
  37. package/dist/webusb/webusb-device.js.map +0 -1
  38. package/libusb/.clang-tidy +0 -34
  39. package/libusb/.codespellrc +0 -3
  40. package/libusb/.private/README.txt +0 -5
  41. package/libusb/.private/appveyor_build.sh +0 -26
  42. package/libusb/.private/bm.sh +0 -54
  43. package/libusb/.private/ci-build.sh +0 -92
  44. package/libusb/.private/ci-container-build.sh +0 -67
  45. package/libusb/.private/post-rewrite.sh +0 -32
  46. package/libusb/.private/pre-commit.sh +0 -52
  47. package/libusb/.private/wbs.txt +0 -43
  48. package/libusb/.travis.yml +0 -58
  49. package/libusb/AUTHORS +0 -231
  50. package/libusb/COPYING +0 -504
  51. package/libusb/ChangeLog +0 -365
  52. package/libusb/HACKING +0 -25
  53. package/libusb/INSTALL_WIN.txt +0 -52
  54. package/libusb/KEYS +0 -123
  55. package/libusb/Makefile.am +0 -50
  56. package/libusb/NEWS +0 -2
  57. package/libusb/PORTING +0 -94
  58. package/libusb/README +0 -29
  59. package/libusb/README.git +0 -41
  60. package/libusb/TODO +0 -2
  61. package/libusb/Xcode/common.xcconfig +0 -92
  62. package/libusb/Xcode/config.h +0 -31
  63. package/libusb/Xcode/debug.xcconfig +0 -32
  64. package/libusb/Xcode/libusb.xcconfig +0 -21
  65. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +0 -1391
  66. package/libusb/Xcode/libusb_debug.xcconfig +0 -21
  67. package/libusb/Xcode/libusb_release.xcconfig +0 -21
  68. package/libusb/Xcode/release.xcconfig +0 -30
  69. package/libusb/android/README +0 -152
  70. package/libusb/android/config.h +0 -55
  71. package/libusb/android/examples/unrooted_android.c +0 -301
  72. package/libusb/android/examples/unrooted_android.h +0 -36
  73. package/libusb/android/jni/Android.mk +0 -23
  74. package/libusb/android/jni/Application.mk +0 -40
  75. package/libusb/android/jni/examples.mk +0 -168
  76. package/libusb/android/jni/libusb.mk +0 -60
  77. package/libusb/android/jni/tests.mk +0 -45
  78. package/libusb/appveyor.yml +0 -108
  79. package/libusb/autogen.sh +0 -10
  80. package/libusb/bootstrap.sh +0 -10
  81. package/libusb/configure.ac +0 -450
  82. package/libusb/doc/Makefile.in +0 -22
  83. package/libusb/doc/doxygen.cfg.in +0 -2571
  84. package/libusb/doc/libusb.png +0 -0
  85. package/libusb/examples/Makefile.am +0 -12
  86. package/libusb/examples/dpfp.c +0 -711
  87. package/libusb/examples/ezusb.c +0 -846
  88. package/libusb/examples/ezusb.h +0 -109
  89. package/libusb/examples/fxload.c +0 -310
  90. package/libusb/examples/hotplugtest.c +0 -147
  91. package/libusb/examples/listdevs.c +0 -73
  92. package/libusb/examples/sam3u_benchmark.c +0 -228
  93. package/libusb/examples/testlibusb.c +0 -312
  94. package/libusb/examples/xusb.c +0 -1254
  95. package/libusb/libusb/Makefile.am +0 -98
  96. package/libusb/libusb/Makefile.am.extra +0 -26
  97. package/libusb/libusb/core.c +0 -2925
  98. package/libusb/libusb/descriptor.c +0 -1558
  99. package/libusb/libusb/hotplug.c +0 -489
  100. package/libusb/libusb/io.c +0 -2865
  101. package/libusb/libusb/libusb-1.0.def +0 -199
  102. package/libusb/libusb/libusb-1.0.rc +0 -53
  103. package/libusb/libusb/libusb.h +0 -2421
  104. package/libusb/libusb/libusbi.h +0 -1535
  105. package/libusb/libusb/os/darwin_usb.c +0 -2977
  106. package/libusb/libusb/os/darwin_usb.h +0 -156
  107. package/libusb/libusb/os/emscripten_webusb.cpp +0 -875
  108. package/libusb/libusb/os/events_posix.c +0 -340
  109. package/libusb/libusb/os/events_posix.h +0 -62
  110. package/libusb/libusb/os/events_windows.c +0 -214
  111. package/libusb/libusb/os/events_windows.h +0 -46
  112. package/libusb/libusb/os/haiku_pollfs.cpp +0 -372
  113. package/libusb/libusb/os/haiku_usb.h +0 -113
  114. package/libusb/libusb/os/haiku_usb_backend.cpp +0 -532
  115. package/libusb/libusb/os/haiku_usb_raw.cpp +0 -231
  116. package/libusb/libusb/os/haiku_usb_raw.h +0 -188
  117. package/libusb/libusb/os/linux_netlink.c +0 -401
  118. package/libusb/libusb/os/linux_udev.c +0 -321
  119. package/libusb/libusb/os/linux_usbfs.c +0 -2829
  120. package/libusb/libusb/os/linux_usbfs.h +0 -221
  121. package/libusb/libusb/os/netbsd_usb.c +0 -617
  122. package/libusb/libusb/os/null_usb.c +0 -111
  123. package/libusb/libusb/os/openbsd_usb.c +0 -700
  124. package/libusb/libusb/os/sunos_usb.c +0 -1619
  125. package/libusb/libusb/os/sunos_usb.h +0 -79
  126. package/libusb/libusb/os/threads_posix.c +0 -126
  127. package/libusb/libusb/os/threads_posix.h +0 -98
  128. package/libusb/libusb/os/threads_windows.c +0 -40
  129. package/libusb/libusb/os/threads_windows.h +0 -113
  130. package/libusb/libusb/os/windows_common.c +0 -923
  131. package/libusb/libusb/os/windows_common.h +0 -424
  132. package/libusb/libusb/os/windows_usbdk.c +0 -724
  133. package/libusb/libusb/os/windows_usbdk.h +0 -106
  134. package/libusb/libusb/os/windows_winusb.c +0 -4766
  135. package/libusb/libusb/os/windows_winusb.h +0 -787
  136. package/libusb/libusb/strerror.c +0 -223
  137. package/libusb/libusb/sync.c +0 -342
  138. package/libusb/libusb/version.h +0 -18
  139. package/libusb/libusb/version_nano.h +0 -1
  140. package/libusb/libusb-1.0.pc.in +0 -11
  141. package/libusb/msvc/Base.props +0 -60
  142. package/libusb/msvc/Configuration.Application.props +0 -7
  143. package/libusb/msvc/Configuration.Base.props +0 -47
  144. package/libusb/msvc/Configuration.DynamicLibrary.props +0 -21
  145. package/libusb/msvc/Configuration.StaticLibrary.props +0 -7
  146. package/libusb/msvc/ProjectConfigurations.Base.props +0 -69
  147. package/libusb/msvc/build_all.ps1 +0 -17
  148. package/libusb/msvc/config.h +0 -58
  149. package/libusb/msvc/dpfp.vcxproj +0 -33
  150. package/libusb/msvc/dpfp_threaded.vcxproj +0 -38
  151. package/libusb/msvc/fxload.vcxproj +0 -46
  152. package/libusb/msvc/getopt/getopt.c +0 -1060
  153. package/libusb/msvc/getopt/getopt.h +0 -180
  154. package/libusb/msvc/getopt/getopt1.c +0 -188
  155. package/libusb/msvc/getopt.vcxproj +0 -33
  156. package/libusb/msvc/hotplugtest.vcxproj +0 -32
  157. package/libusb/msvc/init_context.vcxproj +0 -35
  158. package/libusb/msvc/libusb.sln +0 -542
  159. package/libusb/msvc/libusb_dll.vcxproj +0 -61
  160. package/libusb/msvc/libusb_static.vcxproj +0 -49
  161. package/libusb/msvc/listdevs.vcxproj +0 -32
  162. package/libusb/msvc/sam3u_benchmark.vcxproj +0 -33
  163. package/libusb/msvc/set_option.vcxproj +0 -35
  164. package/libusb/msvc/stress.vcxproj +0 -35
  165. package/libusb/msvc/stress_mt.vcxproj +0 -33
  166. package/libusb/msvc/testlibusb.vcxproj +0 -32
  167. package/libusb/msvc/xusb.vcxproj +0 -38
  168. package/libusb/tests/Makefile.am +0 -40
  169. package/libusb/tests/init_context.c +0 -153
  170. package/libusb/tests/libusb_testlib.h +0 -76
  171. package/libusb/tests/macos.c +0 -130
  172. package/libusb/tests/set_option.c +0 -253
  173. package/libusb/tests/stress.c +0 -172
  174. package/libusb/tests/stress_mt.c +0 -267
  175. package/libusb/tests/testlib.c +0 -184
  176. package/libusb/tests/umockdev.c +0 -1175
  177. package/libusb/tests/webusb-test-shim/index.js +0 -12
  178. package/libusb/tests/webusb-test-shim/package-lock.json +0 -50
  179. package/libusb/tests/webusb-test-shim/package.json +0 -10
  180. package/libusb.gypi +0 -154
  181. package/libusb_config/config.h +0 -1
  182. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  183. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  184. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  185. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  186. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  187. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  188. package/prebuilds/linux-ia32/node.napi.node +0 -0
  189. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  190. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  191. package/prebuilds/win32-arm64/node.napi.node +0 -0
  192. package/prebuilds/win32-ia32/node.napi.node +0 -0
  193. package/prebuilds/win32-x64/node.napi.node +0 -0
  194. package/src/device.cc +0 -439
  195. package/src/helpers.h +0 -64
  196. package/src/hotplug/hotplug.h +0 -22
  197. package/src/hotplug/libusb.cc +0 -90
  198. package/src/hotplug/windows.cc +0 -168
  199. package/src/node_usb.cc +0 -314
  200. package/src/node_usb.h +0 -131
  201. package/src/thread_name.cc +0 -79
  202. package/src/thread_name.h +0 -11
  203. package/src/transfer.cc +0 -143
  204. package/src/uv_async_queue.h +0 -41
  205. package/test/usb.coffee +0 -250
  206. package/test/webusb.coffee +0 -227
  207. package/test/worker.cjs +0 -13
@@ -1,1619 +0,0 @@
1
- /*
2
- * Copyright (c) 2016, Oracle and/or its affiliates.
3
- * Copyright 2023 Oxide Computer Company
4
- *
5
- * This library is free software; you can redistribute it and/or
6
- * modify it under the terms of the GNU Lesser General Public
7
- * License as published by the Free Software Foundation; either
8
- * version 2.1 of the License, or (at your option) any later version.
9
- *
10
- * This library is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * Lesser General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU Lesser General Public
16
- * License along with this library; if not, write to the Free Software
17
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- */
19
-
20
- #include <config.h>
21
-
22
- #include <sys/time.h>
23
- #include <sys/types.h>
24
- #include <sys/stat.h>
25
- #include <strings.h>
26
- #include <errno.h>
27
- #include <fcntl.h>
28
- #include <stdio.h>
29
- #include <stdlib.h>
30
- #include <string.h>
31
- #include <wait.h>
32
- #include <unistd.h>
33
- #include <aio.h>
34
- #include <libdevinfo.h>
35
- #include <sys/nvpair.h>
36
- #include <sys/devctl.h>
37
- #include <sys/usb/clients/ugen/usb_ugen.h>
38
- #include <sys/usb/usba.h>
39
- #include <sys/pci.h>
40
-
41
- #include "libusbi.h"
42
- #include "sunos_usb.h"
43
-
44
- #define UPDATEDRV_PATH "/usr/sbin/update_drv"
45
- #define UPDATEDRV "update_drv"
46
-
47
- #define DEFAULT_LISTSIZE 6
48
-
49
- typedef struct {
50
- int nargs;
51
- int listsize;
52
- char **string;
53
- } string_list_t;
54
-
55
- /*
56
- * Backend functions
57
- */
58
- static int sunos_get_device_list(struct libusb_context *,
59
- struct discovered_devs **);
60
- static int sunos_open(struct libusb_device_handle *);
61
- static void sunos_close(struct libusb_device_handle *);
62
- static int sunos_get_active_config_descriptor(struct libusb_device *,
63
- void *, size_t);
64
- static int sunos_get_config_descriptor(struct libusb_device *, uint8_t,
65
- void *, size_t);
66
- static int sunos_get_configuration(struct libusb_device_handle *, uint8_t *);
67
- static int sunos_set_configuration(struct libusb_device_handle *, int);
68
- static int sunos_claim_interface(struct libusb_device_handle *, uint8_t);
69
- static int sunos_release_interface(struct libusb_device_handle *, uint8_t);
70
- static int sunos_set_interface_altsetting(struct libusb_device_handle *,
71
- uint8_t, uint8_t);
72
- static int sunos_clear_halt(struct libusb_device_handle *, unsigned char);
73
- static void sunos_destroy_device(struct libusb_device *);
74
- static int sunos_submit_transfer(struct usbi_transfer *);
75
- static int sunos_cancel_transfer(struct usbi_transfer *);
76
- static int sunos_handle_transfer_completion(struct usbi_transfer *);
77
- static int sunos_kernel_driver_active(struct libusb_device_handle *, uint8_t);
78
- static int sunos_detach_kernel_driver(struct libusb_device_handle *, uint8_t);
79
- static int sunos_attach_kernel_driver(struct libusb_device_handle *, uint8_t);
80
- static int sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv);
81
- static int sunos_usb_ioctl(struct libusb_device *dev, int cmd);
82
-
83
- static int sunos_get_link(di_devlink_t devlink, void *arg)
84
- {
85
- walk_link_t *link_arg = (walk_link_t *)arg;
86
- const char *p;
87
- const char *q;
88
-
89
- if (link_arg->path) {
90
- char *content = (char *)di_devlink_content(devlink);
91
- char *start = strstr(content, "/devices/");
92
- start += strlen("/devices");
93
- usbi_dbg(NULL, "%s", start);
94
-
95
- /* line content must have minor node */
96
- if (start == NULL ||
97
- strncmp(start, link_arg->path, link_arg->len) != 0 ||
98
- start[link_arg->len] != ':')
99
- return (DI_WALK_CONTINUE);
100
- }
101
-
102
- p = di_devlink_path(devlink);
103
- q = strrchr(p, '/');
104
- usbi_dbg(NULL, "%s", q);
105
-
106
- *(link_arg->linkpp) = strndup(p, strlen(p) - strlen(q));
107
-
108
- return (DI_WALK_TERMINATE);
109
- }
110
-
111
-
112
- static int sunos_physpath_to_devlink(
113
- const char *node_path, const char *match, char **link_path)
114
- {
115
- walk_link_t link_arg;
116
- di_devlink_handle_t hdl;
117
-
118
- *link_path = NULL;
119
- link_arg.linkpp = link_path;
120
- if ((hdl = di_devlink_init(NULL, 0)) == NULL) {
121
- usbi_dbg(NULL, "di_devlink_init failure");
122
- return (-1);
123
- }
124
-
125
- link_arg.len = strlen(node_path);
126
- link_arg.path = (char *)node_path;
127
-
128
- (void) di_devlink_walk(hdl, match, NULL, DI_PRIMARY_LINK,
129
- (void *)&link_arg, sunos_get_link);
130
-
131
- (void) di_devlink_fini(&hdl);
132
-
133
- if (*link_path == NULL) {
134
- usbi_dbg(NULL, "there is no devlink for this path");
135
- return (-1);
136
- }
137
-
138
- return 0;
139
- }
140
-
141
- static int
142
- sunos_usb_ioctl(struct libusb_device *dev, int cmd)
143
- {
144
- int fd;
145
- nvlist_t *nvlist;
146
- char *end;
147
- char *phypath;
148
- char *hubpath;
149
- char path_arg[PATH_MAX];
150
- sunos_dev_priv_t *dpriv;
151
- devctl_ap_state_t devctl_ap_state;
152
- struct devctl_iocdata iocdata;
153
-
154
- dpriv = usbi_get_device_priv(dev);
155
- phypath = dpriv->phypath;
156
-
157
- end = strrchr(phypath, '/');
158
- if (end == NULL)
159
- return (-1);
160
- hubpath = strndup(phypath, end - phypath);
161
- if (hubpath == NULL)
162
- return (-1);
163
-
164
- end = strrchr(hubpath, '@');
165
- if (end == NULL) {
166
- free(hubpath);
167
- return (-1);
168
- }
169
- end++;
170
- usbi_dbg(DEVICE_CTX(dev), "unitaddr: %s", end);
171
-
172
- nvlist_alloc(&nvlist, NV_UNIQUE_NAME_TYPE, KM_NOSLEEP);
173
- nvlist_add_int32(nvlist, "port", dev->port_number);
174
- /* find the hub path */
175
- snprintf(path_arg, sizeof(path_arg), "/devices%s:hubd", hubpath);
176
- usbi_dbg(DEVICE_CTX(dev), "ioctl hub path: %s", path_arg);
177
-
178
- fd = open(path_arg, O_RDONLY);
179
- if (fd < 0) {
180
- usbi_err(DEVICE_CTX(dev), "open failed: errno %d (%s)", errno, strerror(errno));
181
- nvlist_free(nvlist);
182
- free(hubpath);
183
- return (-1);
184
- }
185
-
186
- memset(&iocdata, 0, sizeof(iocdata));
187
- memset(&devctl_ap_state, 0, sizeof(devctl_ap_state));
188
-
189
- nvlist_pack(nvlist, (char **)&iocdata.nvl_user, &iocdata.nvl_usersz, NV_ENCODE_NATIVE, 0);
190
-
191
- iocdata.cmd = DEVCTL_AP_GETSTATE;
192
- iocdata.flags = 0;
193
- iocdata.c_nodename = (char *)"hub";
194
- iocdata.c_unitaddr = end;
195
- iocdata.cpyout_buf = &devctl_ap_state;
196
- usbi_dbg(DEVICE_CTX(dev), "%p, %" PRIuPTR, iocdata.nvl_user, iocdata.nvl_usersz);
197
-
198
- errno = 0;
199
- if (ioctl(fd, DEVCTL_AP_GETSTATE, &iocdata) == -1) {
200
- usbi_err(DEVICE_CTX(dev), "ioctl failed: fd %d, cmd %x, errno %d (%s)",
201
- fd, DEVCTL_AP_GETSTATE, errno, strerror(errno));
202
- } else {
203
- usbi_dbg(DEVICE_CTX(dev), "dev rstate: %d", devctl_ap_state.ap_rstate);
204
- usbi_dbg(DEVICE_CTX(dev), "dev ostate: %d", devctl_ap_state.ap_ostate);
205
- }
206
-
207
- errno = 0;
208
- iocdata.cmd = cmd;
209
- if (ioctl(fd, (int)cmd, &iocdata) != 0) {
210
- usbi_err(DEVICE_CTX(dev), "ioctl failed: fd %d, cmd %x, errno %d (%s)",
211
- fd, cmd, errno, strerror(errno));
212
- sleep(2);
213
- }
214
-
215
- close(fd);
216
- free(iocdata.nvl_user);
217
- nvlist_free(nvlist);
218
- free(hubpath);
219
-
220
- return (-errno);
221
- }
222
-
223
- static int
224
- sunos_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface)
225
- {
226
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(dev_handle->dev);
227
-
228
- UNUSED(interface);
229
-
230
- usbi_dbg(HANDLE_CTX(dev_handle), "%s", dpriv->ugenpath);
231
-
232
- return (dpriv->ugenpath == NULL);
233
- }
234
-
235
- /*
236
- * Private functions
237
- */
238
- static int _errno_to_libusb(int);
239
- static int sunos_usb_get_status(struct libusb_context *ctx, int fd);
240
-
241
- static string_list_t *
242
- sunos_new_string_list(void)
243
- {
244
- string_list_t *list;
245
-
246
- list = calloc(1, sizeof(string_list_t));
247
- if (list == NULL)
248
- return (NULL);
249
- list->string = calloc(DEFAULT_LISTSIZE, sizeof(char *));
250
- if (list->string == NULL) {
251
- free(list);
252
- return (NULL);
253
- }
254
- list->nargs = 0;
255
- list->listsize = DEFAULT_LISTSIZE;
256
-
257
- return (list);
258
- }
259
-
260
- static int
261
- sunos_append_to_string_list(string_list_t *list, const char *arg)
262
- {
263
- char *str = strdup(arg);
264
-
265
- if (str == NULL)
266
- return (-1);
267
-
268
- if ((list->nargs + 1) == list->listsize) { /* +1 is for NULL */
269
- char **tmp = realloc(list->string,
270
- sizeof(char *) * (list->listsize + 1));
271
- if (tmp == NULL) {
272
- free(str);
273
- return (-1);
274
- }
275
- list->string = tmp;
276
- list->string[list->listsize++] = NULL;
277
- }
278
- list->string[list->nargs++] = str;
279
-
280
- return (0);
281
- }
282
-
283
- static void
284
- sunos_free_string_list(string_list_t *list)
285
- {
286
- int i;
287
-
288
- for (i = 0; i < list->nargs; i++) {
289
- free(list->string[i]);
290
- }
291
-
292
- free(list->string);
293
- free(list);
294
- }
295
-
296
- static char **
297
- sunos_build_argv_list(string_list_t *list)
298
- {
299
- return (list->string);
300
- }
301
-
302
-
303
- static int
304
- sunos_exec_command(struct libusb_context *ctx, const char *path,
305
- string_list_t *list)
306
- {
307
- pid_t pid;
308
- int status;
309
- int waitstat;
310
- int exit_status;
311
- char **argv_list;
312
-
313
- argv_list = sunos_build_argv_list(list);
314
- if (argv_list == NULL)
315
- return (-1);
316
-
317
- pid = fork();
318
- if (pid == 0) {
319
- /* child */
320
- execv(path, argv_list);
321
- _exit(127);
322
- } else if (pid > 0) {
323
- /* parent */
324
- do {
325
- waitstat = waitpid(pid, &status, 0);
326
- } while ((waitstat == -1 && errno == EINTR) ||
327
- (waitstat == 0 && !WIFEXITED(status) && !WIFSIGNALED(status)));
328
-
329
- if (waitstat == 0) {
330
- if (WIFEXITED(status))
331
- exit_status = WEXITSTATUS(status);
332
- else
333
- exit_status = WTERMSIG(status);
334
- } else {
335
- usbi_err(ctx, "waitpid failed: errno %d (%s)", errno, strerror(errno));
336
- exit_status = -1;
337
- }
338
- } else {
339
- /* fork failed */
340
- usbi_err(ctx, "fork failed: errno %d (%s)", errno, strerror(errno));
341
- exit_status = -1;
342
- }
343
-
344
- return (exit_status);
345
- }
346
-
347
- static int
348
- sunos_detach_kernel_driver(struct libusb_device_handle *dev_handle,
349
- uint8_t interface_number)
350
- {
351
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
352
- string_list_t *list;
353
- char path_arg[PATH_MAX];
354
- sunos_dev_priv_t *dpriv;
355
- int r;
356
-
357
- UNUSED(interface_number);
358
-
359
- dpriv = usbi_get_device_priv(dev_handle->dev);
360
- snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath);
361
- usbi_dbg(HANDLE_CTX(dev_handle), "%s", path_arg);
362
-
363
- list = sunos_new_string_list();
364
- if (list == NULL)
365
- return (LIBUSB_ERROR_NO_MEM);
366
-
367
- /* attach ugen driver */
368
- r = 0;
369
- r |= sunos_append_to_string_list(list, UPDATEDRV);
370
- r |= sunos_append_to_string_list(list, "-a"); /* add rule */
371
- r |= sunos_append_to_string_list(list, "-i"); /* specific device */
372
- r |= sunos_append_to_string_list(list, path_arg); /* physical path */
373
- r |= sunos_append_to_string_list(list, "ugen");
374
- if (r) {
375
- sunos_free_string_list(list);
376
- return (LIBUSB_ERROR_NO_MEM);
377
- }
378
-
379
- r = sunos_exec_command(ctx, UPDATEDRV_PATH, list);
380
- sunos_free_string_list(list);
381
- if (r < 0)
382
- return (LIBUSB_ERROR_OTHER);
383
-
384
- /* reconfigure the driver node */
385
- r = 0;
386
- r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_DISCONNECT);
387
- r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE);
388
- if (r)
389
- usbi_warn(HANDLE_CTX(dev_handle), "one or more ioctls failed");
390
-
391
- snprintf(path_arg, sizeof(path_arg), "^usb/%x.%x",
392
- dev_handle->dev->device_descriptor.idVendor,
393
- dev_handle->dev->device_descriptor.idProduct);
394
- sunos_physpath_to_devlink(dpriv->phypath, path_arg, &dpriv->ugenpath);
395
-
396
- if (access(dpriv->ugenpath, F_OK) == -1) {
397
- usbi_err(HANDLE_CTX(dev_handle), "fail to detach kernel driver");
398
- return (LIBUSB_ERROR_IO);
399
- }
400
-
401
- return sunos_usb_open_ep0(usbi_get_device_handle_priv(dev_handle), dpriv);
402
- }
403
-
404
- static int
405
- sunos_attach_kernel_driver(struct libusb_device_handle *dev_handle,
406
- uint8_t interface_number)
407
- {
408
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
409
- string_list_t *list;
410
- char path_arg[PATH_MAX];
411
- sunos_dev_priv_t *dpriv;
412
- int r;
413
-
414
- UNUSED(interface_number);
415
-
416
- /* we open the dev in detach driver, so we need close it first. */
417
- sunos_close(dev_handle);
418
-
419
- dpriv = usbi_get_device_priv(dev_handle->dev);
420
- snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath);
421
- usbi_dbg(HANDLE_CTX(dev_handle), "%s", path_arg);
422
-
423
- list = sunos_new_string_list();
424
- if (list == NULL)
425
- return (LIBUSB_ERROR_NO_MEM);
426
-
427
- /* detach ugen driver */
428
- r = 0;
429
- r |= sunos_append_to_string_list(list, UPDATEDRV);
430
- r |= sunos_append_to_string_list(list, "-d"); /* add rule */
431
- r |= sunos_append_to_string_list(list, "-i"); /* specific device */
432
- r |= sunos_append_to_string_list(list, path_arg); /* physical path */
433
- r |= sunos_append_to_string_list(list, "ugen");
434
- if (r) {
435
- sunos_free_string_list(list);
436
- return (LIBUSB_ERROR_NO_MEM);
437
- }
438
-
439
- r = sunos_exec_command(ctx, UPDATEDRV_PATH, list);
440
- sunos_free_string_list(list);
441
- if (r < 0)
442
- return (LIBUSB_ERROR_OTHER);
443
-
444
- /* reconfigure the driver node */
445
- r = 0;
446
- r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE);
447
- r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_DISCONNECT);
448
- r |= sunos_usb_ioctl(dev_handle->dev, DEVCTL_AP_CONFIGURE);
449
- if (r)
450
- usbi_warn(HANDLE_CTX(dev_handle), "one or more ioctls failed");
451
-
452
- return 0;
453
- }
454
-
455
- static int
456
- sunos_fill_in_dev_info(di_node_t node, struct libusb_device *dev)
457
- {
458
- int proplen;
459
- int *i, n, *addr, *port_prop;
460
- char *phypath;
461
- uint8_t *rdata;
462
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(dev);
463
- char match_str[PATH_MAX];
464
-
465
- /* Device descriptors */
466
- proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
467
- "usb-dev-descriptor", &rdata);
468
- if (proplen <= 0) {
469
- return (LIBUSB_ERROR_IO);
470
- }
471
- bcopy(rdata, &dev->device_descriptor, LIBUSB_DT_DEVICE_SIZE);
472
-
473
- /* Raw configuration descriptors */
474
- proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
475
- "usb-raw-cfg-descriptors", &rdata);
476
- if (proplen <= 0) {
477
- usbi_dbg(DEVICE_CTX(dev), "can't find raw config descriptors");
478
-
479
- return (LIBUSB_ERROR_IO);
480
- }
481
- dpriv->raw_cfgdescr = calloc(1, proplen);
482
- if (dpriv->raw_cfgdescr == NULL) {
483
- return (LIBUSB_ERROR_NO_MEM);
484
- } else {
485
- bcopy(rdata, dpriv->raw_cfgdescr, proplen);
486
- dpriv->cfgvalue = ((struct libusb_config_descriptor *)
487
- rdata)->bConfigurationValue;
488
- }
489
-
490
- n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &port_prop);
491
-
492
- if ((n != 1) || (*port_prop <= 0)) {
493
- return (LIBUSB_ERROR_IO);
494
- }
495
- dev->port_number = *port_prop;
496
-
497
- /* device physical path */
498
- phypath = di_devfs_path(node);
499
- if (phypath) {
500
- dpriv->phypath = strdup(phypath);
501
- snprintf(match_str, sizeof(match_str), "^usb/%x.%x",
502
- dev->device_descriptor.idVendor,
503
- dev->device_descriptor.idProduct);
504
- usbi_dbg(DEVICE_CTX(dev), "match is %s", match_str);
505
- sunos_physpath_to_devlink(dpriv->phypath, match_str, &dpriv->ugenpath);
506
- di_devfs_path_free(phypath);
507
-
508
- } else {
509
- free(dpriv->raw_cfgdescr);
510
-
511
- return (LIBUSB_ERROR_IO);
512
- }
513
-
514
- /* address */
515
- n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "assigned-address", &addr);
516
- if (n != 1 || *addr == 0) {
517
- usbi_dbg(DEVICE_CTX(dev), "can't get address");
518
- } else {
519
- dev->device_address = *addr;
520
- }
521
-
522
- /* speed */
523
- if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "low-speed", &i) >= 0) {
524
- dev->speed = LIBUSB_SPEED_LOW;
525
- } else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "high-speed", &i) >= 0) {
526
- dev->speed = LIBUSB_SPEED_HIGH;
527
- } else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "full-speed", &i) >= 0) {
528
- dev->speed = LIBUSB_SPEED_FULL;
529
- } else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "super-speed", &i) >= 0) {
530
- dev->speed = LIBUSB_SPEED_SUPER;
531
- }
532
-
533
- usbi_dbg(DEVICE_CTX(dev), "vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, speed=%d",
534
- dev->device_descriptor.idVendor, dev->device_descriptor.idProduct,
535
- dpriv->phypath, dev->bus_number, dev->port_number, dev->speed);
536
-
537
- return (LIBUSB_SUCCESS);
538
- }
539
-
540
- static int
541
- sunos_add_devices(di_devlink_t link, void *arg)
542
- {
543
- struct devlink_cbarg *largs = (struct devlink_cbarg *)arg;
544
- struct node_args *nargs;
545
- di_node_t myself, dn;
546
- uint64_t session_id = 0;
547
- uint64_t sid = 0;
548
- uint64_t bdf = 0;
549
- struct libusb_device *dev;
550
- sunos_dev_priv_t *devpriv;
551
- int n, *j;
552
- int i = 0;
553
- int *addr_prop;
554
- uint8_t bus_number = 0;
555
- uint32_t * regbuf = NULL;
556
- uint32_t reg;
557
-
558
- UNUSED(link);
559
-
560
- nargs = (struct node_args *)largs->nargs;
561
- myself = largs->myself;
562
-
563
- /*
564
- * Construct session ID.
565
- * session ID = dev_addr | hub addr |parent hub addr|...|root hub bdf
566
- * 8 bits 8bits 8 bits 16bits
567
- */
568
- if (myself == DI_NODE_NIL)
569
- return (DI_WALK_CONTINUE);
570
-
571
- dn = myself;
572
- /* find the root hub */
573
- while (di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "root-hub", &j) != 0) {
574
- usbi_dbg(NULL, "find_root_hub:%s", di_devfs_path(dn));
575
- n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn,
576
- "assigned-address", &addr_prop);
577
- session_id |= ((addr_prop[0] & 0xff) << i++ * 8);
578
- dn = di_parent_node(dn);
579
- }
580
-
581
- /* dn is the root hub node */
582
- n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "reg", (int **)&regbuf);
583
- reg = regbuf[0];
584
- bdf = (PCI_REG_BUS_G(reg) << 8) | (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg);
585
- /* bdf must larger than i*8 bits */
586
- session_id |= (bdf << i * 8);
587
- bus_number = (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg);
588
-
589
- usbi_dbg(NULL, "device bus address=%s:%x, name:%s",
590
- di_bus_addr(myself), bus_number, di_node_name(dn));
591
- usbi_dbg(NULL, "session id org:%" PRIx64, session_id);
592
-
593
- /* dn is the usb device */
594
- for (dn = di_child_node(myself); dn != DI_NODE_NIL; dn = di_sibling_node(dn)) {
595
- usbi_dbg(NULL, "device path:%s", di_devfs_path(dn));
596
- /* skip hub devices, because its driver can not been unload */
597
- if (di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "usb-port-count", &addr_prop) != -1)
598
- continue;
599
- /* usb_addr */
600
- n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn,
601
- "assigned-address", &addr_prop);
602
- if ((n != 1) || (addr_prop[0] == 0)) {
603
- usbi_dbg(NULL, "cannot get valid usb_addr");
604
- continue;
605
- }
606
-
607
- sid = (session_id << 8) | (addr_prop[0] & 0xff) ;
608
- usbi_dbg(NULL, "session id %" PRIX64, sid);
609
-
610
- dev = usbi_get_device_by_session_id(nargs->ctx, sid);
611
- if (dev == NULL) {
612
- dev = usbi_alloc_device(nargs->ctx, sid);
613
- if (dev == NULL) {
614
- usbi_dbg(NULL, "can't alloc device");
615
- continue;
616
- }
617
- devpriv = usbi_get_device_priv(dev);
618
- dev->bus_number = bus_number;
619
-
620
- if (sunos_fill_in_dev_info(dn, dev) != LIBUSB_SUCCESS) {
621
- libusb_unref_device(dev);
622
- usbi_dbg(NULL, "get information fail");
623
- continue;
624
- }
625
- if (usbi_sanitize_device(dev) < 0) {
626
- libusb_unref_device(dev);
627
- usbi_dbg(NULL, "sanitize failed: ");
628
- return (DI_WALK_TERMINATE);
629
- }
630
- } else {
631
- devpriv = usbi_get_device_priv(dev);
632
- usbi_dbg(NULL, "Dev %s exists", devpriv->ugenpath);
633
- }
634
-
635
- if (discovered_devs_append(*(nargs->discdevs), dev) == NULL) {
636
- usbi_dbg(NULL, "cannot append device");
637
- }
638
-
639
- /*
640
- * we alloc and hence ref this dev. We don't need to ref it
641
- * hereafter. Front end or app should take care of their ref.
642
- */
643
- libusb_unref_device(dev);
644
-
645
- usbi_dbg(NULL, "Device %s %s id=0x%" PRIx64 ", devcount:%" PRIuPTR
646
- ", bdf=%" PRIx64,
647
- devpriv->ugenpath, di_devfs_path(dn), (uint64_t)sid,
648
- (*nargs->discdevs)->len, bdf);
649
- }
650
-
651
- return (DI_WALK_CONTINUE);
652
- }
653
-
654
- static int
655
- sunos_walk_minor_node_link(di_node_t node, void *args)
656
- {
657
- di_minor_t minor = DI_MINOR_NIL;
658
- char *minor_path;
659
- struct devlink_cbarg arg;
660
- struct node_args *nargs = (struct node_args *)args;
661
- di_devlink_handle_t devlink_hdl = nargs->dlink_hdl;
662
-
663
- /* walk each minor to find usb devices */
664
- while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) {
665
- minor_path = di_devfs_minor_path(minor);
666
- arg.nargs = args;
667
- arg.myself = node;
668
- arg.minor = minor;
669
- (void) di_devlink_walk(devlink_hdl,
670
- "^usb/hub[0-9]+", minor_path,
671
- DI_PRIMARY_LINK, (void *)&arg, sunos_add_devices);
672
- di_devfs_path_free(minor_path);
673
- }
674
-
675
- /* switch to a different node */
676
- nargs->last_ugenpath = NULL;
677
-
678
- return (DI_WALK_CONTINUE);
679
- }
680
-
681
- int
682
- sunos_get_device_list(struct libusb_context * ctx,
683
- struct discovered_devs **discdevs)
684
- {
685
- di_node_t root_node;
686
- struct node_args args;
687
- di_devlink_handle_t devlink_hdl;
688
-
689
- args.ctx = ctx;
690
- args.discdevs = discdevs;
691
- args.last_ugenpath = NULL;
692
- if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
693
- usbi_dbg(ctx, "di_int() failed: errno %d (%s)", errno, strerror(errno));
694
- return (LIBUSB_ERROR_IO);
695
- }
696
-
697
- if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
698
- di_fini(root_node);
699
- usbi_dbg(ctx, "di_devlink_init() failed: errno %d (%s)", errno, strerror(errno));
700
-
701
- return (LIBUSB_ERROR_IO);
702
- }
703
- args.dlink_hdl = devlink_hdl;
704
-
705
- /* walk each node to find USB devices */
706
- if (di_walk_node(root_node, DI_WALK_SIBFIRST, &args,
707
- sunos_walk_minor_node_link) == -1) {
708
- usbi_dbg(ctx, "di_walk_node() failed: errno %d (%s)", errno, strerror(errno));
709
- di_fini(root_node);
710
-
711
- return (LIBUSB_ERROR_IO);
712
- }
713
-
714
- di_fini(root_node);
715
- di_devlink_fini(&devlink_hdl);
716
-
717
- usbi_dbg(ctx, "%zu devices", (*discdevs)->len);
718
-
719
- return ((*discdevs)->len);
720
- }
721
-
722
- static int
723
- sunos_usb_open_ep0(sunos_dev_handle_priv_t *hpriv, sunos_dev_priv_t *dpriv)
724
- {
725
- char filename[PATH_MAX + 1];
726
-
727
- if (hpriv->eps[0].datafd > 0) {
728
- return (LIBUSB_SUCCESS);
729
- }
730
- snprintf(filename, PATH_MAX, "%s/cntrl0", dpriv->ugenpath);
731
-
732
- usbi_dbg(NULL, "opening %s", filename);
733
- hpriv->eps[0].datafd = open(filename, O_RDWR);
734
- if (hpriv->eps[0].datafd < 0) {
735
- return(_errno_to_libusb(errno));
736
- }
737
-
738
- snprintf(filename, PATH_MAX, "%s/cntrl0stat", dpriv->ugenpath);
739
- hpriv->eps[0].statfd = open(filename, O_RDONLY);
740
- if (hpriv->eps[0].statfd < 0) {
741
- close(hpriv->eps[0].datafd);
742
- hpriv->eps[0].datafd = -1;
743
-
744
- return(_errno_to_libusb(errno));
745
- }
746
-
747
- return (LIBUSB_SUCCESS);
748
- }
749
-
750
- static void
751
- sunos_usb_close_all_eps(sunos_dev_handle_priv_t *hdev)
752
- {
753
- int i;
754
-
755
- /* not close ep0 */
756
- for (i = 1; i < USB_MAXENDPOINTS; i++) {
757
- if (hdev->eps[i].datafd != -1) {
758
- (void) close(hdev->eps[i].datafd);
759
- hdev->eps[i].datafd = -1;
760
- }
761
- if (hdev->eps[i].statfd != -1) {
762
- (void) close(hdev->eps[i].statfd);
763
- hdev->eps[i].statfd = -1;
764
- }
765
- }
766
- }
767
-
768
- static void
769
- sunos_usb_close_ep0(sunos_dev_handle_priv_t *hdev)
770
- {
771
- if (hdev->eps[0].datafd >= 0) {
772
- close(hdev->eps[0].datafd);
773
- close(hdev->eps[0].statfd);
774
- hdev->eps[0].datafd = -1;
775
- hdev->eps[0].statfd = -1;
776
- }
777
- }
778
-
779
- static uchar_t
780
- sunos_usb_ep_index(uint8_t ep_addr)
781
- {
782
- return ((ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK) +
783
- ((ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? 16 : 0));
784
- }
785
-
786
- static int
787
- sunos_find_interface(struct libusb_device_handle *hdev,
788
- uint8_t endpoint, uint8_t *interface)
789
- {
790
- struct libusb_config_descriptor *config;
791
- int r;
792
- int iface_idx;
793
-
794
- r = libusb_get_active_config_descriptor(hdev->dev, &config);
795
- if (r < 0) {
796
- return (LIBUSB_ERROR_INVALID_PARAM);
797
- }
798
-
799
- for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) {
800
- const struct libusb_interface *iface =
801
- &config->interface[iface_idx];
802
- int altsetting_idx;
803
-
804
- for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting;
805
- altsetting_idx++) {
806
- const struct libusb_interface_descriptor *altsetting =
807
- &iface->altsetting[altsetting_idx];
808
- int ep_idx;
809
-
810
- for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints;
811
- ep_idx++) {
812
- const struct libusb_endpoint_descriptor *ep =
813
- &altsetting->endpoint[ep_idx];
814
- if (ep->bEndpointAddress == endpoint) {
815
- *interface = iface_idx;
816
- libusb_free_config_descriptor(config);
817
-
818
- return (LIBUSB_SUCCESS);
819
- }
820
- }
821
- }
822
- }
823
- libusb_free_config_descriptor(config);
824
-
825
- return (LIBUSB_ERROR_INVALID_PARAM);
826
- }
827
-
828
- static int
829
- sunos_check_device_and_status_open(struct libusb_device_handle *hdl,
830
- uint8_t ep_addr, int ep_type)
831
- {
832
- char filename[PATH_MAX + 1], statfilename[PATH_MAX + 1];
833
- char cfg_num[16], alt_num[16];
834
- int fd, fdstat, mode, e;
835
- uint8_t ifc = 0;
836
- uint8_t ep_index;
837
- sunos_dev_handle_priv_t *hpriv;
838
-
839
- usbi_dbg(HANDLE_CTX(hdl), "open ep 0x%02x", ep_addr);
840
- hpriv = usbi_get_device_handle_priv(hdl);
841
- ep_index = sunos_usb_ep_index(ep_addr);
842
- /* ep already opened */
843
- if ((hpriv->eps[ep_index].datafd > 0) &&
844
- (hpriv->eps[ep_index].statfd > 0)) {
845
- usbi_dbg(HANDLE_CTX(hdl), "ep 0x%02x already opened, return success",
846
- ep_addr);
847
-
848
- return (0);
849
- }
850
-
851
- if (sunos_find_interface(hdl, ep_addr, &ifc) < 0) {
852
- usbi_dbg(HANDLE_CTX(hdl), "can't find interface for endpoint 0x%02x",
853
- ep_addr);
854
-
855
- return (EACCES);
856
- }
857
-
858
- /* create filename */
859
- if (hpriv->config_index > 0) {
860
- (void) snprintf(cfg_num, sizeof(cfg_num), "cfg%d",
861
- hpriv->config_index + 1);
862
- } else {
863
- bzero(cfg_num, sizeof(cfg_num));
864
- }
865
-
866
- if (hpriv->altsetting[ifc] > 0) {
867
- (void) snprintf(alt_num, sizeof(alt_num), ".%d",
868
- hpriv->altsetting[ifc]);
869
- } else {
870
- bzero(alt_num, sizeof(alt_num));
871
- }
872
-
873
- e = snprintf(filename, sizeof (filename), "%s/%sif%d%s%s%d",
874
- hpriv->dpriv->ugenpath, cfg_num, ifc, alt_num,
875
- (ep_addr & LIBUSB_ENDPOINT_DIR_MASK) ? "in" : "out",
876
- ep_addr & LIBUSB_ENDPOINT_ADDRESS_MASK);
877
- if (e < 0 || e >= (int)sizeof (filename)) {
878
- usbi_dbg(HANDLE_CTX(hdl),
879
- "path buffer overflow for endpoint 0x%02x", ep_addr);
880
- return (EINVAL);
881
- }
882
-
883
- e = snprintf(statfilename, sizeof (statfilename), "%sstat", filename);
884
- if (e < 0 || e >= (int)sizeof (statfilename)) {
885
- usbi_dbg(HANDLE_CTX(hdl),
886
- "path buffer overflow for endpoint 0x%02x stat", ep_addr);
887
- return (EINVAL);
888
- }
889
-
890
- /*
891
- * In case configuration has been switched, the xfer endpoint needs
892
- * to be opened before the status endpoint, due to a ugen issue.
893
- * However, to enable the one transfer mode for an Interrupt-In pipe,
894
- * the status endpoint needs to be opened before the xfer endpoint.
895
- * So, open the xfer mode first and close it immediately
896
- * as a workaround. This will handle the configuration switch.
897
- * Then, open the status endpoint. If for an Interrupt-in pipe,
898
- * write the USB_EP_INTR_ONE_XFER control to the status endpoint
899
- * to enable the one transfer mode. Then, re-open the xfer mode.
900
- */
901
- if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
902
- mode = O_RDWR;
903
- } else if (ep_addr & LIBUSB_ENDPOINT_IN) {
904
- mode = O_RDONLY;
905
- } else {
906
- mode = O_WRONLY;
907
- }
908
- /* Open the xfer endpoint first */
909
- if ((fd = open(filename, mode)) == -1) {
910
- usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", filename, errno,
911
- strerror(errno));
912
-
913
- return (errno);
914
- }
915
- /* And immediately close the xfer endpoint */
916
- (void) close(fd);
917
-
918
- /*
919
- * Open the status endpoint.
920
- * If for an Interrupt-IN pipe, need to enable the one transfer mode
921
- * by writing USB_EP_INTR_ONE_XFER control to the status endpoint
922
- * before opening the xfer endpoint
923
- */
924
- if ((ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) &&
925
- (ep_addr & LIBUSB_ENDPOINT_IN)) {
926
- char control = USB_EP_INTR_ONE_XFER;
927
- ssize_t count;
928
-
929
- /* Open the status endpoint with RDWR */
930
- if ((fdstat = open(statfilename, O_RDWR)) == -1) {
931
- usbi_dbg(HANDLE_CTX(hdl), "can't open %s RDWR: errno %d (%s)",
932
- statfilename, errno, strerror(errno));
933
-
934
- return (errno);
935
- } else {
936
- count = write(fdstat, &control, sizeof(control));
937
- if (count != 1) {
938
- /* this should have worked */
939
- usbi_dbg(HANDLE_CTX(hdl), "can't write to %s: errno %d (%s)",
940
- statfilename, errno, strerror(errno));
941
- (void) close(fdstat);
942
-
943
- return (errno);
944
- }
945
- }
946
- } else {
947
- if ((fdstat = open(statfilename, O_RDONLY)) == -1) {
948
- usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", statfilename, errno,
949
- strerror(errno));
950
-
951
- return (errno);
952
- }
953
- }
954
-
955
- /* Re-open the xfer endpoint */
956
- if ((fd = open(filename, mode)) == -1) {
957
- usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", filename, errno,
958
- strerror(errno));
959
- (void) close(fdstat);
960
-
961
- return (errno);
962
- }
963
-
964
- hpriv->eps[ep_index].datafd = fd;
965
- hpriv->eps[ep_index].statfd = fdstat;
966
- usbi_dbg(HANDLE_CTX(hdl), "ep=0x%02x datafd=%d, statfd=%d", ep_addr, fd, fdstat);
967
-
968
- return (0);
969
- }
970
-
971
- int
972
- sunos_open(struct libusb_device_handle *handle)
973
- {
974
- sunos_dev_handle_priv_t *hpriv;
975
- sunos_dev_priv_t *dpriv;
976
- int i;
977
- int ret;
978
-
979
- hpriv = usbi_get_device_handle_priv(handle);
980
- dpriv = usbi_get_device_priv(handle->dev);
981
- hpriv->dpriv = dpriv;
982
-
983
- /* set all file descriptors to "closed" */
984
- for (i = 0; i < USB_MAXENDPOINTS; i++) {
985
- hpriv->eps[i].datafd = -1;
986
- hpriv->eps[i].statfd = -1;
987
- }
988
-
989
- if (sunos_kernel_driver_active(handle, 0)) {
990
- /* pretend we can open the device */
991
- return (LIBUSB_SUCCESS);
992
- }
993
-
994
- if ((ret = sunos_usb_open_ep0(hpriv, dpriv)) != LIBUSB_SUCCESS) {
995
- usbi_dbg(HANDLE_CTX(handle), "fail: %d", ret);
996
- return (ret);
997
- }
998
-
999
- return (LIBUSB_SUCCESS);
1000
- }
1001
-
1002
- void
1003
- sunos_close(struct libusb_device_handle *handle)
1004
- {
1005
- sunos_dev_handle_priv_t *hpriv;
1006
-
1007
- usbi_dbg(HANDLE_CTX(handle), " ");
1008
-
1009
- hpriv = usbi_get_device_handle_priv(handle);
1010
-
1011
- sunos_usb_close_all_eps(hpriv);
1012
- sunos_usb_close_ep0(hpriv);
1013
- }
1014
-
1015
- int
1016
- sunos_get_active_config_descriptor(struct libusb_device *dev,
1017
- void *buf, size_t len)
1018
- {
1019
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(dev);
1020
- struct libusb_config_descriptor *cfg;
1021
- int proplen;
1022
- di_node_t node;
1023
- uint8_t *rdata;
1024
-
1025
- /*
1026
- * Keep raw configuration descriptors updated, in case config
1027
- * has ever been changed through setCfg.
1028
- */
1029
- if ((node = di_init(dpriv->phypath, DINFOCPYALL)) == DI_NODE_NIL) {
1030
- usbi_dbg(DEVICE_CTX(dev), "di_int() failed: errno %d (%s)", errno,
1031
- strerror(errno));
1032
- return (LIBUSB_ERROR_IO);
1033
- }
1034
- proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
1035
- "usb-raw-cfg-descriptors", &rdata);
1036
- if (proplen <= 0) {
1037
- usbi_dbg(DEVICE_CTX(dev), "can't find raw config descriptors");
1038
-
1039
- return (LIBUSB_ERROR_IO);
1040
- }
1041
- dpriv->raw_cfgdescr = realloc(dpriv->raw_cfgdescr, proplen);
1042
- if (dpriv->raw_cfgdescr == NULL) {
1043
- return (LIBUSB_ERROR_NO_MEM);
1044
- } else {
1045
- bcopy(rdata, dpriv->raw_cfgdescr, proplen);
1046
- dpriv->cfgvalue = ((struct libusb_config_descriptor *)
1047
- rdata)->bConfigurationValue;
1048
- }
1049
- di_fini(node);
1050
-
1051
- cfg = (struct libusb_config_descriptor *)dpriv->raw_cfgdescr;
1052
- len = MIN(len, libusb_le16_to_cpu(cfg->wTotalLength));
1053
- memcpy(buf, dpriv->raw_cfgdescr, len);
1054
- usbi_dbg(DEVICE_CTX(dev), "path:%s len %zu", dpriv->phypath, len);
1055
-
1056
- return (len);
1057
- }
1058
-
1059
- int
1060
- sunos_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
1061
- void *buf, size_t len)
1062
- {
1063
- UNUSED(idx);
1064
- /* XXX */
1065
- return(sunos_get_active_config_descriptor(dev, buf, len));
1066
- }
1067
-
1068
- int
1069
- sunos_get_configuration(struct libusb_device_handle *handle, uint8_t *config)
1070
- {
1071
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(handle->dev);
1072
-
1073
- *config = dpriv->cfgvalue;
1074
-
1075
- usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %u", *config);
1076
-
1077
- return (LIBUSB_SUCCESS);
1078
- }
1079
-
1080
- int
1081
- sunos_set_configuration(struct libusb_device_handle *handle, int config)
1082
- {
1083
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(handle->dev);
1084
- sunos_dev_handle_priv_t *hpriv;
1085
-
1086
- usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %d", config);
1087
- hpriv = usbi_get_device_handle_priv(handle);
1088
-
1089
- if (dpriv->ugenpath == NULL)
1090
- return (LIBUSB_ERROR_NOT_SUPPORTED);
1091
-
1092
- if (config < 1)
1093
- return (LIBUSB_ERROR_NOT_SUPPORTED);
1094
-
1095
- dpriv->cfgvalue = config;
1096
- hpriv->config_index = config - 1;
1097
-
1098
- return (LIBUSB_SUCCESS);
1099
- }
1100
-
1101
- int
1102
- sunos_claim_interface(struct libusb_device_handle *handle, uint8_t iface)
1103
- {
1104
- UNUSED(handle);
1105
-
1106
- usbi_dbg(HANDLE_CTX(handle), "iface %u", iface);
1107
-
1108
- return (LIBUSB_SUCCESS);
1109
- }
1110
-
1111
- int
1112
- sunos_release_interface(struct libusb_device_handle *handle, uint8_t iface)
1113
- {
1114
- sunos_dev_handle_priv_t *hpriv = usbi_get_device_handle_priv(handle);
1115
-
1116
- usbi_dbg(HANDLE_CTX(handle), "iface %u", iface);
1117
-
1118
- /* XXX: can we release it? */
1119
- hpriv->altsetting[iface] = 0;
1120
-
1121
- return (LIBUSB_SUCCESS);
1122
- }
1123
-
1124
- int
1125
- sunos_set_interface_altsetting(struct libusb_device_handle *handle, uint8_t iface,
1126
- uint8_t altsetting)
1127
- {
1128
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(handle->dev);
1129
- sunos_dev_handle_priv_t *hpriv = usbi_get_device_handle_priv(handle);
1130
-
1131
- usbi_dbg(HANDLE_CTX(handle), "iface %u, setting %u", iface, altsetting);
1132
-
1133
- if (dpriv->ugenpath == NULL)
1134
- return (LIBUSB_ERROR_NOT_FOUND);
1135
-
1136
- /* XXX: can we switch altsetting? */
1137
- hpriv->altsetting[iface] = altsetting;
1138
-
1139
- return (LIBUSB_SUCCESS);
1140
- }
1141
-
1142
- static void
1143
- usb_dump_data(const void *data, size_t size)
1144
- {
1145
- const uint8_t *p = data;
1146
- size_t i;
1147
-
1148
- if (getenv("LIBUSB_DEBUG") == NULL) {
1149
- return;
1150
- }
1151
-
1152
- (void) fprintf(stderr, "data dump:");
1153
- for (i = 0; i < size; i++) {
1154
- if (i % 16 == 0) {
1155
- (void) fprintf(stderr, "\n%08zx ", i);
1156
- }
1157
- (void) fprintf(stderr, "%02x ", p[i]);
1158
- }
1159
- (void) fprintf(stderr, "\n");
1160
- }
1161
-
1162
- static void
1163
- sunos_async_callback(union sigval arg)
1164
- {
1165
- struct sunos_transfer_priv *tpriv =
1166
- (struct sunos_transfer_priv *)arg.sival_ptr;
1167
- struct libusb_transfer *xfer = tpriv->transfer;
1168
- struct aiocb *aiocb = &tpriv->aiocb;
1169
- int ret;
1170
- sunos_dev_handle_priv_t *hpriv;
1171
- uint8_t ep;
1172
- libusb_device_handle *dev_handle;
1173
-
1174
- dev_handle = xfer->dev_handle;
1175
-
1176
- /* libusb can forcibly interrupt transfer in do_close() */
1177
- if (dev_handle != NULL) {
1178
- hpriv = usbi_get_device_handle_priv(dev_handle);
1179
- ep = sunos_usb_ep_index(xfer->endpoint);
1180
-
1181
- ret = aio_error(aiocb);
1182
- if (ret != 0) {
1183
- xfer->status = sunos_usb_get_status(TRANSFER_CTX(xfer), hpriv->eps[ep].statfd);
1184
- } else {
1185
- xfer->actual_length =
1186
- LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred =
1187
- aio_return(aiocb);
1188
- }
1189
-
1190
- usb_dump_data(xfer->buffer, xfer->actual_length);
1191
-
1192
- usbi_dbg(TRANSFER_CTX(xfer), "ret=%d, len=%d, actual_len=%d", ret, xfer->length,
1193
- xfer->actual_length);
1194
-
1195
- /* async notification */
1196
- usbi_signal_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer));
1197
- }
1198
- }
1199
-
1200
- static int
1201
- sunos_do_async_io(struct libusb_transfer *transfer)
1202
- {
1203
- int ret = -1;
1204
- struct aiocb *aiocb;
1205
- sunos_dev_handle_priv_t *hpriv;
1206
- uint8_t ep;
1207
- struct sunos_transfer_priv *tpriv;
1208
-
1209
- usbi_dbg(TRANSFER_CTX(transfer), " ");
1210
-
1211
- tpriv = usbi_get_transfer_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer));
1212
- hpriv = usbi_get_device_handle_priv(transfer->dev_handle);
1213
- ep = sunos_usb_ep_index(transfer->endpoint);
1214
-
1215
- tpriv->transfer = transfer;
1216
- aiocb = &tpriv->aiocb;
1217
- bzero(aiocb, sizeof(*aiocb));
1218
- aiocb->aio_fildes = hpriv->eps[ep].datafd;
1219
- aiocb->aio_buf = transfer->buffer;
1220
- aiocb->aio_nbytes = transfer->length;
1221
- aiocb->aio_lio_opcode =
1222
- ((transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) ==
1223
- LIBUSB_ENDPOINT_IN) ? LIO_READ:LIO_WRITE;
1224
- aiocb->aio_sigevent.sigev_notify = SIGEV_THREAD;
1225
- aiocb->aio_sigevent.sigev_value.sival_ptr = tpriv;
1226
- aiocb->aio_sigevent.sigev_notify_function = sunos_async_callback;
1227
-
1228
- if (aiocb->aio_lio_opcode == LIO_READ) {
1229
- ret = aio_read(aiocb);
1230
- } else {
1231
- ret = aio_write(aiocb);
1232
- }
1233
-
1234
- return (ret);
1235
- }
1236
-
1237
- /* return the number of bytes read/written */
1238
- static ssize_t
1239
- usb_do_io(struct libusb_context *ctx, int fd, int stat_fd, void *data, size_t size, int flag, int *status)
1240
- {
1241
- int error;
1242
- ssize_t ret = -1;
1243
-
1244
- usbi_dbg(ctx, "usb_do_io(): datafd=%d statfd=%d size=0x%zx flag=%s",
1245
- fd, stat_fd, size, flag? "WRITE":"READ");
1246
-
1247
- switch (flag) {
1248
- case READ:
1249
- errno = 0;
1250
- ret = read(fd, data, size);
1251
- usb_dump_data(data, size);
1252
- break;
1253
- case WRITE:
1254
- usb_dump_data(data, size);
1255
- errno = 0;
1256
- ret = write(fd, data, size);
1257
- break;
1258
- }
1259
-
1260
- usbi_dbg(ctx, "usb_do_io(): amount=%zd", ret);
1261
-
1262
- if (ret < 0) {
1263
- int save_errno = errno;
1264
-
1265
- usbi_dbg(ctx, "TID=%x io %s errno %d (%s)", pthread_self(),
1266
- flag?"WRITE":"READ", errno, strerror(errno));
1267
-
1268
- /* sunos_usb_get_status will do a read and overwrite errno */
1269
- error = sunos_usb_get_status(ctx, stat_fd);
1270
- usbi_dbg(ctx, "io status=%d errno %d (%s)", error,
1271
- save_errno, strerror(save_errno));
1272
-
1273
- if (status) {
1274
- *status = save_errno;
1275
- }
1276
-
1277
- return (save_errno);
1278
-
1279
- } else if (status) {
1280
- *status = 0;
1281
- }
1282
-
1283
- return (ret);
1284
- }
1285
-
1286
- static int
1287
- solaris_submit_ctrl_on_default(struct libusb_transfer *transfer)
1288
- {
1289
- ssize_t ret = -1, setup_ret;
1290
- int status;
1291
- sunos_dev_handle_priv_t *hpriv;
1292
- struct libusb_device_handle *hdl = transfer->dev_handle;
1293
- uint16_t wLength;
1294
- uint8_t *data = transfer->buffer;
1295
-
1296
- hpriv = usbi_get_device_handle_priv(hdl);
1297
- wLength = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
1298
-
1299
- if (hpriv->eps[0].datafd == -1) {
1300
- usbi_dbg(TRANSFER_CTX(transfer), "ep0 not opened");
1301
-
1302
- return (LIBUSB_ERROR_NOT_FOUND);
1303
- }
1304
-
1305
- if ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
1306
- usbi_dbg(TRANSFER_CTX(transfer), "IN request");
1307
- ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd,
1308
- hpriv->eps[0].statfd, data, LIBUSB_CONTROL_SETUP_SIZE,
1309
- WRITE, &status);
1310
- } else {
1311
- usbi_dbg(TRANSFER_CTX(transfer), "OUT request");
1312
- ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd, hpriv->eps[0].statfd,
1313
- transfer->buffer, transfer->length, WRITE,
1314
- (int *)&transfer->status);
1315
- }
1316
-
1317
- setup_ret = ret;
1318
- if (ret < (ssize_t)LIBUSB_CONTROL_SETUP_SIZE) {
1319
- usbi_dbg(TRANSFER_CTX(transfer), "error sending control msg: %zd", ret);
1320
-
1321
- return (LIBUSB_ERROR_IO);
1322
- }
1323
-
1324
- ret = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
1325
-
1326
- /* Read the remaining bytes for IN request */
1327
- if ((wLength) && ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) ==
1328
- LIBUSB_ENDPOINT_IN)) {
1329
- usbi_dbg(TRANSFER_CTX(transfer), "DATA: %d", transfer->length - (int)setup_ret);
1330
- ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd,
1331
- hpriv->eps[0].statfd,
1332
- transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE,
1333
- wLength, READ, (int *)&transfer->status);
1334
- }
1335
-
1336
- if (ret >= 0) {
1337
- LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->transferred = ret;
1338
- }
1339
- usbi_dbg(TRANSFER_CTX(transfer), "Done: ctrl data bytes %zd", ret);
1340
-
1341
- /**
1342
- * Sync transfer handling.
1343
- * We should release transfer lock here and later get it back
1344
- * as usbi_handle_transfer_completion() takes its own transfer lock.
1345
- */
1346
- usbi_mutex_unlock(&LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->lock);
1347
- ret = usbi_handle_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer),
1348
- transfer->status);
1349
- usbi_mutex_lock(&LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->lock);
1350
-
1351
- return (ret);
1352
- }
1353
-
1354
- int
1355
- sunos_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
1356
- {
1357
- int ret;
1358
-
1359
- usbi_dbg(HANDLE_CTX(handle), "endpoint=0x%02x", endpoint);
1360
-
1361
- ret = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT |
1362
- LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_REQUEST_TYPE_STANDARD,
1363
- LIBUSB_REQUEST_CLEAR_FEATURE, 0, endpoint, NULL, 0, 1000);
1364
-
1365
- usbi_dbg(HANDLE_CTX(handle), "ret=%d", ret);
1366
-
1367
- return (ret);
1368
- }
1369
-
1370
- void
1371
- sunos_destroy_device(struct libusb_device *dev)
1372
- {
1373
- sunos_dev_priv_t *dpriv = usbi_get_device_priv(dev);
1374
-
1375
- usbi_dbg(DEVICE_CTX(dev), "destroy everything");
1376
- free(dpriv->raw_cfgdescr);
1377
- free(dpriv->ugenpath);
1378
- free(dpriv->phypath);
1379
- }
1380
-
1381
- int
1382
- sunos_submit_transfer(struct usbi_transfer *itransfer)
1383
- {
1384
- struct libusb_transfer *transfer;
1385
- struct libusb_device_handle *hdl;
1386
- int err = 0;
1387
-
1388
- transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1389
- hdl = transfer->dev_handle;
1390
-
1391
- err = sunos_check_device_and_status_open(hdl,
1392
- transfer->endpoint, transfer->type);
1393
- if (err != 0) {
1394
- return (_errno_to_libusb(err));
1395
- }
1396
-
1397
- switch (transfer->type) {
1398
- case LIBUSB_TRANSFER_TYPE_CONTROL:
1399
- /* sync transfer */
1400
- usbi_dbg(ITRANSFER_CTX(itransfer), "CTRL transfer: %d", transfer->length);
1401
- err = solaris_submit_ctrl_on_default(transfer);
1402
- break;
1403
-
1404
- case LIBUSB_TRANSFER_TYPE_BULK:
1405
- /* fallthru */
1406
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1407
- if (transfer->type == LIBUSB_TRANSFER_TYPE_BULK)
1408
- usbi_dbg(ITRANSFER_CTX(itransfer), "BULK transfer: %d", transfer->length);
1409
- else
1410
- usbi_dbg(ITRANSFER_CTX(itransfer), "INTR transfer: %d", transfer->length);
1411
- err = sunos_do_async_io(transfer);
1412
- break;
1413
-
1414
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1415
- /* Isochronous/Stream is not supported */
1416
-
1417
- /* fallthru */
1418
- case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1419
- if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
1420
- usbi_dbg(ITRANSFER_CTX(itransfer), "ISOC transfer: %d", transfer->length);
1421
- else
1422
- usbi_dbg(ITRANSFER_CTX(itransfer), "BULK STREAM transfer: %d", transfer->length);
1423
- err = LIBUSB_ERROR_NOT_SUPPORTED;
1424
- break;
1425
- }
1426
-
1427
- return (err);
1428
- }
1429
-
1430
- int
1431
- sunos_cancel_transfer(struct usbi_transfer *itransfer)
1432
- {
1433
- sunos_xfer_priv_t *tpriv;
1434
- sunos_dev_handle_priv_t *hpriv;
1435
- struct libusb_transfer *transfer;
1436
- struct aiocb *aiocb;
1437
- uint8_t ep;
1438
- int ret;
1439
-
1440
- tpriv = usbi_get_transfer_priv(itransfer);
1441
- aiocb = &tpriv->aiocb;
1442
- transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1443
- hpriv = usbi_get_device_handle_priv(transfer->dev_handle);
1444
- ep = sunos_usb_ep_index(transfer->endpoint);
1445
-
1446
- ret = aio_cancel(hpriv->eps[ep].datafd, aiocb);
1447
-
1448
- usbi_dbg(ITRANSFER_CTX(itransfer), "aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes,
1449
- hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)?
1450
- strerror(0):strerror(errno));
1451
-
1452
- if (ret != AIO_CANCELED) {
1453
- ret = _errno_to_libusb(errno);
1454
- } else {
1455
- /*
1456
- * we don't need to call usbi_handle_transfer_cancellation(),
1457
- * because we'll handle everything in sunos_async_callback.
1458
- */
1459
- ret = LIBUSB_SUCCESS;
1460
- }
1461
-
1462
- return (ret);
1463
- }
1464
-
1465
- int
1466
- sunos_handle_transfer_completion(struct usbi_transfer *itransfer)
1467
- {
1468
- return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
1469
- }
1470
-
1471
- int
1472
- _errno_to_libusb(int err)
1473
- {
1474
- usbi_dbg(NULL, "error: %s (%d)", strerror(err), err);
1475
-
1476
- switch (err) {
1477
- case EIO:
1478
- return (LIBUSB_ERROR_IO);
1479
- case EACCES:
1480
- return (LIBUSB_ERROR_ACCESS);
1481
- case ENOENT:
1482
- return (LIBUSB_ERROR_NO_DEVICE);
1483
- case ENOMEM:
1484
- return (LIBUSB_ERROR_NO_MEM);
1485
- case ETIMEDOUT:
1486
- return (LIBUSB_ERROR_TIMEOUT);
1487
- }
1488
-
1489
- return (LIBUSB_ERROR_OTHER);
1490
- }
1491
-
1492
- /*
1493
- * sunos_usb_get_status:
1494
- * gets status of endpoint
1495
- *
1496
- * Returns: ugen's last cmd status
1497
- */
1498
- static int
1499
- sunos_usb_get_status(struct libusb_context *ctx, int fd)
1500
- {
1501
- int status;
1502
- ssize_t ret;
1503
-
1504
- usbi_dbg(ctx, "sunos_usb_get_status(): fd=%d", fd);
1505
-
1506
- ret = read(fd, &status, sizeof(status));
1507
- if (ret == sizeof(status)) {
1508
- switch (status) {
1509
- case USB_LC_STAT_NOERROR:
1510
- usbi_dbg(ctx, "No Error");
1511
- break;
1512
- case USB_LC_STAT_CRC:
1513
- usbi_dbg(ctx, "CRC Timeout Detected\n");
1514
- break;
1515
- case USB_LC_STAT_BITSTUFFING:
1516
- usbi_dbg(ctx, "Bit Stuffing Violation\n");
1517
- break;
1518
- case USB_LC_STAT_DATA_TOGGLE_MM:
1519
- usbi_dbg(ctx, "Data Toggle Mismatch\n");
1520
- break;
1521
- case USB_LC_STAT_STALL:
1522
- usbi_dbg(ctx, "End Point Stalled\n");
1523
- break;
1524
- case USB_LC_STAT_DEV_NOT_RESP:
1525
- usbi_dbg(ctx, "Device is Not Responding\n");
1526
- break;
1527
- case USB_LC_STAT_PID_CHECKFAILURE:
1528
- usbi_dbg(ctx, "PID Check Failure\n");
1529
- break;
1530
- case USB_LC_STAT_UNEXP_PID:
1531
- usbi_dbg(ctx, "Unexpected PID\n");
1532
- break;
1533
- case USB_LC_STAT_DATA_OVERRUN:
1534
- usbi_dbg(ctx, "Data Exceeded Size\n");
1535
- break;
1536
- case USB_LC_STAT_DATA_UNDERRUN:
1537
- usbi_dbg(ctx, "Less data received\n");
1538
- break;
1539
- case USB_LC_STAT_BUFFER_OVERRUN:
1540
- usbi_dbg(ctx, "Buffer Size Exceeded\n");
1541
- break;
1542
- case USB_LC_STAT_BUFFER_UNDERRUN:
1543
- usbi_dbg(ctx, "Buffer Underrun\n");
1544
- break;
1545
- case USB_LC_STAT_TIMEOUT:
1546
- usbi_dbg(ctx, "Command Timed Out\n");
1547
- break;
1548
- case USB_LC_STAT_NOT_ACCESSED:
1549
- usbi_dbg(ctx, "Not Accessed by h/w\n");
1550
- break;
1551
- case USB_LC_STAT_UNSPECIFIED_ERR:
1552
- usbi_dbg(ctx, "Unspecified Error\n");
1553
- break;
1554
- case USB_LC_STAT_NO_BANDWIDTH:
1555
- usbi_dbg(ctx, "No Bandwidth\n");
1556
- break;
1557
- case USB_LC_STAT_HW_ERR:
1558
- usbi_dbg(ctx, "Host Controller h/w Error\n");
1559
- break;
1560
- case USB_LC_STAT_SUSPENDED:
1561
- usbi_dbg(ctx, "Device was Suspended\n");
1562
- break;
1563
- case USB_LC_STAT_DISCONNECTED:
1564
- usbi_dbg(ctx, "Device was Disconnected\n");
1565
- break;
1566
- case USB_LC_STAT_INTR_BUF_FULL:
1567
- usbi_dbg(ctx, "Interrupt buffer was full\n");
1568
- break;
1569
- case USB_LC_STAT_INVALID_REQ:
1570
- usbi_dbg(ctx, "Request was Invalid\n");
1571
- break;
1572
- case USB_LC_STAT_INTERRUPTED:
1573
- usbi_dbg(ctx, "Request was Interrupted\n");
1574
- break;
1575
- case USB_LC_STAT_NO_RESOURCES:
1576
- usbi_dbg(ctx, "No resources available for "
1577
- "request\n");
1578
- break;
1579
- case USB_LC_STAT_INTR_POLLING_FAILED:
1580
- usbi_dbg(ctx, "Failed to Restart Poll");
1581
- break;
1582
- default:
1583
- usbi_dbg(ctx, "Error Not Determined %d\n",
1584
- status);
1585
- break;
1586
- }
1587
- } else {
1588
- usbi_dbg(ctx, "read stat error: %s",strerror(errno));
1589
- status = -1;
1590
- }
1591
-
1592
- return (status);
1593
- }
1594
-
1595
- const struct usbi_os_backend usbi_backend = {
1596
- .name = "Solaris",
1597
- .caps = 0,
1598
- .get_device_list = sunos_get_device_list,
1599
- .get_active_config_descriptor = sunos_get_active_config_descriptor,
1600
- .get_config_descriptor = sunos_get_config_descriptor,
1601
- .open = sunos_open,
1602
- .close = sunos_close,
1603
- .get_configuration = sunos_get_configuration,
1604
- .set_configuration = sunos_set_configuration,
1605
- .claim_interface = sunos_claim_interface,
1606
- .release_interface = sunos_release_interface,
1607
- .set_interface_altsetting = sunos_set_interface_altsetting,
1608
- .clear_halt = sunos_clear_halt,
1609
- .kernel_driver_active = sunos_kernel_driver_active,
1610
- .detach_kernel_driver = sunos_detach_kernel_driver,
1611
- .attach_kernel_driver = sunos_attach_kernel_driver,
1612
- .destroy_device = sunos_destroy_device,
1613
- .submit_transfer = sunos_submit_transfer,
1614
- .cancel_transfer = sunos_cancel_transfer,
1615
- .handle_transfer_completion = sunos_handle_transfer_completion,
1616
- .device_priv_size = sizeof(sunos_dev_priv_t),
1617
- .device_handle_priv_size = sizeof(sunos_dev_handle_priv_t),
1618
- .transfer_priv_size = sizeof(sunos_xfer_priv_t),
1619
- };