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.
- package/LICENSE +18 -4
- package/README.md +25 -516
- package/dist/index.d.ts +67 -13
- package/dist/index.js +333 -64
- package/index.d.ts +89 -0
- package/index.js +583 -0
- package/package.json +53 -33
- package/CHANGELOG.md +0 -294
- package/binding.gyp +0 -128
- package/dist/index.js.map +0 -1
- package/dist/usb/bindings.d.ts +0 -266
- package/dist/usb/bindings.js +0 -10
- package/dist/usb/bindings.js.map +0 -1
- package/dist/usb/capability.d.ts +0 -13
- package/dist/usb/capability.js +0 -17
- package/dist/usb/capability.js.map +0 -1
- package/dist/usb/descriptors.d.ts +0 -128
- package/dist/usb/descriptors.js +0 -3
- package/dist/usb/descriptors.js.map +0 -1
- package/dist/usb/device.d.ts +0 -100
- package/dist/usb/device.js +0 -297
- package/dist/usb/device.js.map +0 -1
- package/dist/usb/endpoint.d.ts +0 -94
- package/dist/usb/endpoint.js +0 -219
- package/dist/usb/endpoint.js.map +0 -1
- package/dist/usb/index.d.ts +0 -31
- package/dist/usb/index.js +0 -116
- package/dist/usb/index.js.map +0 -1
- package/dist/usb/interface.d.ts +0 -80
- package/dist/usb/interface.js +0 -133
- package/dist/usb/interface.js.map +0 -1
- package/dist/webusb/index.d.ts +0 -64
- package/dist/webusb/index.js +0 -295
- package/dist/webusb/index.js.map +0 -1
- package/dist/webusb/webusb-device.d.ts +0 -54
- package/dist/webusb/webusb-device.js +0 -434
- package/dist/webusb/webusb-device.js.map +0 -1
- package/libusb/.clang-tidy +0 -34
- package/libusb/.codespellrc +0 -3
- package/libusb/.private/README.txt +0 -5
- package/libusb/.private/appveyor_build.sh +0 -26
- package/libusb/.private/bm.sh +0 -54
- package/libusb/.private/ci-build.sh +0 -92
- package/libusb/.private/ci-container-build.sh +0 -67
- package/libusb/.private/post-rewrite.sh +0 -32
- package/libusb/.private/pre-commit.sh +0 -52
- package/libusb/.private/wbs.txt +0 -43
- package/libusb/.travis.yml +0 -58
- package/libusb/AUTHORS +0 -231
- package/libusb/COPYING +0 -504
- package/libusb/ChangeLog +0 -365
- package/libusb/HACKING +0 -25
- package/libusb/INSTALL_WIN.txt +0 -52
- package/libusb/KEYS +0 -123
- package/libusb/Makefile.am +0 -50
- package/libusb/NEWS +0 -2
- package/libusb/PORTING +0 -94
- package/libusb/README +0 -29
- package/libusb/README.git +0 -41
- package/libusb/TODO +0 -2
- package/libusb/Xcode/common.xcconfig +0 -92
- package/libusb/Xcode/config.h +0 -31
- package/libusb/Xcode/debug.xcconfig +0 -32
- package/libusb/Xcode/libusb.xcconfig +0 -21
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +0 -1391
- package/libusb/Xcode/libusb_debug.xcconfig +0 -21
- package/libusb/Xcode/libusb_release.xcconfig +0 -21
- package/libusb/Xcode/release.xcconfig +0 -30
- package/libusb/android/README +0 -152
- package/libusb/android/config.h +0 -55
- package/libusb/android/examples/unrooted_android.c +0 -301
- package/libusb/android/examples/unrooted_android.h +0 -36
- package/libusb/android/jni/Android.mk +0 -23
- package/libusb/android/jni/Application.mk +0 -40
- package/libusb/android/jni/examples.mk +0 -168
- package/libusb/android/jni/libusb.mk +0 -60
- package/libusb/android/jni/tests.mk +0 -45
- package/libusb/appveyor.yml +0 -108
- package/libusb/autogen.sh +0 -10
- package/libusb/bootstrap.sh +0 -10
- package/libusb/configure.ac +0 -450
- package/libusb/doc/Makefile.in +0 -22
- package/libusb/doc/doxygen.cfg.in +0 -2571
- package/libusb/doc/libusb.png +0 -0
- package/libusb/examples/Makefile.am +0 -12
- package/libusb/examples/dpfp.c +0 -711
- package/libusb/examples/ezusb.c +0 -846
- package/libusb/examples/ezusb.h +0 -109
- package/libusb/examples/fxload.c +0 -310
- package/libusb/examples/hotplugtest.c +0 -147
- package/libusb/examples/listdevs.c +0 -73
- package/libusb/examples/sam3u_benchmark.c +0 -228
- package/libusb/examples/testlibusb.c +0 -312
- package/libusb/examples/xusb.c +0 -1254
- package/libusb/libusb/Makefile.am +0 -98
- package/libusb/libusb/Makefile.am.extra +0 -26
- package/libusb/libusb/core.c +0 -2925
- package/libusb/libusb/descriptor.c +0 -1558
- package/libusb/libusb/hotplug.c +0 -489
- package/libusb/libusb/io.c +0 -2865
- package/libusb/libusb/libusb-1.0.def +0 -199
- package/libusb/libusb/libusb-1.0.rc +0 -53
- package/libusb/libusb/libusb.h +0 -2421
- package/libusb/libusb/libusbi.h +0 -1535
- package/libusb/libusb/os/darwin_usb.c +0 -2977
- package/libusb/libusb/os/darwin_usb.h +0 -156
- package/libusb/libusb/os/emscripten_webusb.cpp +0 -875
- package/libusb/libusb/os/events_posix.c +0 -340
- package/libusb/libusb/os/events_posix.h +0 -62
- package/libusb/libusb/os/events_windows.c +0 -214
- package/libusb/libusb/os/events_windows.h +0 -46
- package/libusb/libusb/os/haiku_pollfs.cpp +0 -372
- package/libusb/libusb/os/haiku_usb.h +0 -113
- package/libusb/libusb/os/haiku_usb_backend.cpp +0 -532
- package/libusb/libusb/os/haiku_usb_raw.cpp +0 -231
- package/libusb/libusb/os/haiku_usb_raw.h +0 -188
- package/libusb/libusb/os/linux_netlink.c +0 -401
- package/libusb/libusb/os/linux_udev.c +0 -321
- package/libusb/libusb/os/linux_usbfs.c +0 -2829
- package/libusb/libusb/os/linux_usbfs.h +0 -221
- package/libusb/libusb/os/netbsd_usb.c +0 -617
- package/libusb/libusb/os/null_usb.c +0 -111
- package/libusb/libusb/os/openbsd_usb.c +0 -700
- package/libusb/libusb/os/sunos_usb.c +0 -1619
- package/libusb/libusb/os/sunos_usb.h +0 -79
- package/libusb/libusb/os/threads_posix.c +0 -126
- package/libusb/libusb/os/threads_posix.h +0 -98
- package/libusb/libusb/os/threads_windows.c +0 -40
- package/libusb/libusb/os/threads_windows.h +0 -113
- package/libusb/libusb/os/windows_common.c +0 -923
- package/libusb/libusb/os/windows_common.h +0 -424
- package/libusb/libusb/os/windows_usbdk.c +0 -724
- package/libusb/libusb/os/windows_usbdk.h +0 -106
- package/libusb/libusb/os/windows_winusb.c +0 -4766
- package/libusb/libusb/os/windows_winusb.h +0 -787
- package/libusb/libusb/strerror.c +0 -223
- package/libusb/libusb/sync.c +0 -342
- package/libusb/libusb/version.h +0 -18
- package/libusb/libusb/version_nano.h +0 -1
- package/libusb/libusb-1.0.pc.in +0 -11
- package/libusb/msvc/Base.props +0 -60
- package/libusb/msvc/Configuration.Application.props +0 -7
- package/libusb/msvc/Configuration.Base.props +0 -47
- package/libusb/msvc/Configuration.DynamicLibrary.props +0 -21
- package/libusb/msvc/Configuration.StaticLibrary.props +0 -7
- package/libusb/msvc/ProjectConfigurations.Base.props +0 -69
- package/libusb/msvc/build_all.ps1 +0 -17
- package/libusb/msvc/config.h +0 -58
- package/libusb/msvc/dpfp.vcxproj +0 -33
- package/libusb/msvc/dpfp_threaded.vcxproj +0 -38
- package/libusb/msvc/fxload.vcxproj +0 -46
- package/libusb/msvc/getopt/getopt.c +0 -1060
- package/libusb/msvc/getopt/getopt.h +0 -180
- package/libusb/msvc/getopt/getopt1.c +0 -188
- package/libusb/msvc/getopt.vcxproj +0 -33
- package/libusb/msvc/hotplugtest.vcxproj +0 -32
- package/libusb/msvc/init_context.vcxproj +0 -35
- package/libusb/msvc/libusb.sln +0 -542
- package/libusb/msvc/libusb_dll.vcxproj +0 -61
- package/libusb/msvc/libusb_static.vcxproj +0 -49
- package/libusb/msvc/listdevs.vcxproj +0 -32
- package/libusb/msvc/sam3u_benchmark.vcxproj +0 -33
- package/libusb/msvc/set_option.vcxproj +0 -35
- package/libusb/msvc/stress.vcxproj +0 -35
- package/libusb/msvc/stress_mt.vcxproj +0 -33
- package/libusb/msvc/testlibusb.vcxproj +0 -32
- package/libusb/msvc/xusb.vcxproj +0 -38
- package/libusb/tests/Makefile.am +0 -40
- package/libusb/tests/init_context.c +0 -153
- package/libusb/tests/libusb_testlib.h +0 -76
- package/libusb/tests/macos.c +0 -130
- package/libusb/tests/set_option.c +0 -253
- package/libusb/tests/stress.c +0 -172
- package/libusb/tests/stress_mt.c +0 -267
- package/libusb/tests/testlib.c +0 -184
- package/libusb/tests/umockdev.c +0 -1175
- package/libusb/tests/webusb-test-shim/index.js +0 -12
- package/libusb/tests/webusb-test-shim/package-lock.json +0 -50
- package/libusb/tests/webusb-test-shim/package.json +0 -10
- package/libusb.gypi +0 -154
- package/libusb_config/config.h +0 -1
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-arm64/node.napi.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +0 -439
- package/src/helpers.h +0 -64
- package/src/hotplug/hotplug.h +0 -22
- package/src/hotplug/libusb.cc +0 -90
- package/src/hotplug/windows.cc +0 -168
- package/src/node_usb.cc +0 -314
- package/src/node_usb.h +0 -131
- package/src/thread_name.cc +0 -79
- package/src/thread_name.h +0 -11
- package/src/transfer.cc +0 -143
- package/src/uv_async_queue.h +0 -41
- package/test/usb.coffee +0 -250
- package/test/webusb.coffee +0 -227
- 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 **)®buf);
|
|
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
|
-
};
|