libusb 0.4.1 → 0.5.0
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +3 -3
- data/History.md +8 -0
- data/README.md +1 -0
- data/Rakefile +14 -14
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/AUTHORS +6 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/COPYING +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/ChangeLog +9 -2
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/INSTALL +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Makefile.am +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Makefile.in +188 -156
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/NEWS +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/PORTING +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/README +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/TODO +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/common.xcconfig +10 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/config.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/debug.xcconfig +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb.xcconfig +1 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb.xcodeproj/project.pbxproj +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb_debug.xcconfig +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb_release.xcconfig +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/release.xcconfig +1 -0
- data/ext/libusb-1.0.19/aclocal.m4 +1190 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/README +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/config.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/Android.mk +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/Application.mk +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/examples.mk +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/libusb.mk +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/tests.mk +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/compile +7 -3
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.guess +116 -78
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.h.in +0 -3
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.sub +66 -46
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/configure +265 -208
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/configure.ac +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/depcomp +269 -186
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/Makefile.am +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/Makefile.in +72 -35
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/Makefile.am +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/Makefile.in +134 -70
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/dpfp.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/dpfp_threaded.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/ezusb.c +9 -5
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/ezusb.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/fxload.c +1 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt1.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/hotplugtest.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/listdevs.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/sam3u_benchmark.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/xusb.c +22 -2
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/install-sh +7 -7
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb-1.0.pc.in +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/Makefile.am +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/Makefile.in +133 -93
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/core.c +86 -15
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/descriptor.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/hotplug.c +6 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/hotplug.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/io.c +54 -17
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb-1.0.def +8 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb-1.0.rc +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb.h +42 -2
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusbi.h +10 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/darwin_usb.c +156 -53
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/darwin_usb.h +1 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_netlink.c +26 -2
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_udev.c +2 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_usbfs.c +93 -6
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_usbfs.h +12 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/netbsd_usb.c +6 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/openbsd_usb.c +6 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_posix.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_posix.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_windows.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_windows.h +12 -6
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_posix.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_windows.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_windows.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/wince_usb.c +8 -1
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/wince_usb.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_common.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_usb.c +175 -42
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_usb.h +35 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/strerror.c +17 -2
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/sync.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/version.h +1 -1
- data/ext/libusb-1.0.19/libusb/version_nano.h +1 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/ltmain.sh +3 -3
- data/ext/{libusb-1.0.18/aclocal.m4 → libusb-1.0.19/m4/libtool.m4} +36 -1734
- data/ext/libusb-1.0.19/m4/ltoptions.m4 +384 -0
- data/ext/libusb-1.0.19/m4/ltsugar.m4 +123 -0
- data/ext/libusb-1.0.19/m4/ltversion.m4 +23 -0
- data/ext/libusb-1.0.19/m4/lt~obsolete.m4 +98 -0
- data/ext/libusb-1.0.19/missing +215 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/Makefile.am +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/Makefile.in +128 -70
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/libusb_testlib.h +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/stress.c +0 -0
- data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/testlib.c +0 -0
- data/lib/libusb.rb +3 -1
- data/lib/libusb/bos.rb +306 -0
- data/lib/libusb/call.rb +84 -0
- data/lib/libusb/constants.rb +4 -0
- data/lib/libusb/dev_handle.rb +77 -0
- data/lib/libusb/endpoint.rb +20 -0
- data/lib/libusb/ss_companion.rb +69 -0
- data/lib/libusb/transfer.rb +34 -0
- data/lib/libusb/version_gem.rb +1 -1
- data/libusb.gemspec +1 -0
- data/test/test_libusb_bos.rb +118 -0
- data/test/test_libusb_bulk_stream_transfer.rb +50 -0
- data/test/test_libusb_descriptors.rb +29 -0
- data/test/test_libusb_hotplug.rb +1 -1
- data/test/test_libusb_threads.rb +1 -1
- metadata +146 -124
- metadata.gz.sig +0 -0
- data/ext/libusb-1.0.18/libusb/version_nano.h +0 -1
- data/ext/libusb-1.0.18/missing +0 -331
|
@@ -137,7 +137,7 @@ struct darwin_device_handle_priv {
|
|
|
137
137
|
uint8_t num_endpoints;
|
|
138
138
|
CFRunLoopSourceRef cfSource;
|
|
139
139
|
uint64_t frames[256];
|
|
140
|
-
uint8_t
|
|
140
|
+
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
|
|
141
141
|
} interfaces[USB_MAXINTERFACES];
|
|
142
142
|
};
|
|
143
143
|
|
|
@@ -224,8 +224,32 @@ static int linux_netlink_parse(char *buffer, size_t len, int *detached, const ch
|
|
|
224
224
|
|
|
225
225
|
tmp = netlink_message_parse(buffer, len, "BUSNUM");
|
|
226
226
|
if (NULL == tmp) {
|
|
227
|
-
/* no bus number
|
|
228
|
-
|
|
227
|
+
/* no bus number. try "DEVICE" */
|
|
228
|
+
tmp = netlink_message_parse(buffer, len, "DEVICE");
|
|
229
|
+
if (NULL == tmp) {
|
|
230
|
+
/* not usb. ignore */
|
|
231
|
+
return -1;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Parse a device path such as /dev/bus/usb/003/004 */
|
|
235
|
+
char *pLastSlash = (char*)strrchr(tmp,'/');
|
|
236
|
+
if(NULL == pLastSlash) {
|
|
237
|
+
return -1;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
*devaddr = strtoul(pLastSlash + 1, NULL, 10);
|
|
241
|
+
if (errno) {
|
|
242
|
+
errno = 0;
|
|
243
|
+
return -1;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
*busnum = strtoul(pLastSlash - 3, NULL, 10);
|
|
247
|
+
if (errno) {
|
|
248
|
+
errno = 0;
|
|
249
|
+
return -1;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return 0;
|
|
229
253
|
}
|
|
230
254
|
|
|
231
255
|
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
|
|
@@ -61,7 +61,7 @@ int linux_udev_start_event_monitor(void)
|
|
|
61
61
|
udev_ctx = udev_new();
|
|
62
62
|
if (!udev_ctx) {
|
|
63
63
|
usbi_err(NULL, "could not create udev context");
|
|
64
|
-
|
|
64
|
+
goto err;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev");
|
|
@@ -119,6 +119,7 @@ err_free_monitor:
|
|
|
119
119
|
udev_monitor_fd = -1;
|
|
120
120
|
err_free_ctx:
|
|
121
121
|
udev_unref(udev_ctx);
|
|
122
|
+
err:
|
|
122
123
|
udev_ctx = NULL;
|
|
123
124
|
return LIBUSB_ERROR_OTHER;
|
|
124
125
|
}
|
|
@@ -119,7 +119,7 @@ static int sysfs_can_relate_devices = -1;
|
|
|
119
119
|
static int sysfs_has_descriptors = -1;
|
|
120
120
|
|
|
121
121
|
/* how many times have we initted (and not exited) ? */
|
|
122
|
-
static
|
|
122
|
+
static int init_count = 0;
|
|
123
123
|
|
|
124
124
|
/* Serialize hotplug start/stop */
|
|
125
125
|
usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER;
|
|
@@ -184,6 +184,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
|
184
184
|
struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
185
185
|
char path[PATH_MAX];
|
|
186
186
|
int fd;
|
|
187
|
+
int delay = 10000;
|
|
187
188
|
|
|
188
189
|
if (usbdev_names)
|
|
189
190
|
snprintf(path, PATH_MAX, "%s/usbdev%d.%d",
|
|
@@ -196,6 +197,18 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
|
|
196
197
|
if (fd != -1)
|
|
197
198
|
return fd; /* Success */
|
|
198
199
|
|
|
200
|
+
if (errno == ENOENT) {
|
|
201
|
+
if (!silent)
|
|
202
|
+
usbi_err(ctx, "File doesn't exist, wait %d ms and try again\n", delay/1000);
|
|
203
|
+
|
|
204
|
+
/* Wait 10ms for USB device path creation.*/
|
|
205
|
+
usleep(delay);
|
|
206
|
+
|
|
207
|
+
fd = open(path, mode);
|
|
208
|
+
if (fd != -1)
|
|
209
|
+
return fd; /* Success */
|
|
210
|
+
}
|
|
211
|
+
|
|
199
212
|
if (!silent) {
|
|
200
213
|
usbi_err(ctx, "libusb couldn't open USB device %s: %s",
|
|
201
214
|
path, strerror(errno));
|
|
@@ -1482,6 +1495,56 @@ out:
|
|
|
1482
1495
|
return ret;
|
|
1483
1496
|
}
|
|
1484
1497
|
|
|
1498
|
+
static int do_streams_ioctl(struct libusb_device_handle *handle, long req,
|
|
1499
|
+
uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
|
|
1500
|
+
{
|
|
1501
|
+
int r, fd = _device_handle_priv(handle)->fd;
|
|
1502
|
+
struct usbfs_streams *streams;
|
|
1503
|
+
|
|
1504
|
+
if (num_endpoints > 30) /* Max 15 in + 15 out eps */
|
|
1505
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1506
|
+
|
|
1507
|
+
streams = malloc(sizeof(struct usbfs_streams) + num_endpoints);
|
|
1508
|
+
if (!streams)
|
|
1509
|
+
return LIBUSB_ERROR_NO_MEM;
|
|
1510
|
+
|
|
1511
|
+
streams->num_streams = num_streams;
|
|
1512
|
+
streams->num_eps = num_endpoints;
|
|
1513
|
+
memcpy(streams->eps, endpoints, num_endpoints);
|
|
1514
|
+
|
|
1515
|
+
r = ioctl(fd, req, streams);
|
|
1516
|
+
|
|
1517
|
+
free(streams);
|
|
1518
|
+
|
|
1519
|
+
if (r < 0) {
|
|
1520
|
+
if (errno == ENOTTY)
|
|
1521
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
1522
|
+
else if (errno == EINVAL)
|
|
1523
|
+
return LIBUSB_ERROR_INVALID_PARAM;
|
|
1524
|
+
else if (errno == ENODEV)
|
|
1525
|
+
return LIBUSB_ERROR_NO_DEVICE;
|
|
1526
|
+
|
|
1527
|
+
usbi_err(HANDLE_CTX(handle),
|
|
1528
|
+
"streams-ioctl failed error %d errno %d", r, errno);
|
|
1529
|
+
return LIBUSB_ERROR_OTHER;
|
|
1530
|
+
}
|
|
1531
|
+
return r;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
static int op_alloc_streams(struct libusb_device_handle *handle,
|
|
1535
|
+
uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
|
|
1536
|
+
{
|
|
1537
|
+
return do_streams_ioctl(handle, IOCTL_USBFS_ALLOC_STREAMS,
|
|
1538
|
+
num_streams, endpoints, num_endpoints);
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
static int op_free_streams(struct libusb_device_handle *handle,
|
|
1542
|
+
unsigned char *endpoints, int num_endpoints)
|
|
1543
|
+
{
|
|
1544
|
+
return do_streams_ioctl(handle, IOCTL_USBFS_FREE_STREAMS, 0,
|
|
1545
|
+
endpoints, num_endpoints);
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1485
1548
|
static int op_kernel_driver_active(struct libusb_device_handle *handle,
|
|
1486
1549
|
int interface)
|
|
1487
1550
|
{
|
|
@@ -1689,8 +1752,7 @@ static void free_iso_urbs(struct linux_transfer_priv *tpriv)
|
|
|
1689
1752
|
tpriv->iso_urbs = NULL;
|
|
1690
1753
|
}
|
|
1691
1754
|
|
|
1692
|
-
static int submit_bulk_transfer(struct usbi_transfer *itransfer
|
|
1693
|
-
unsigned char urb_type)
|
|
1755
|
+
static int submit_bulk_transfer(struct usbi_transfer *itransfer)
|
|
1694
1756
|
{
|
|
1695
1757
|
struct libusb_transfer *transfer =
|
|
1696
1758
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
@@ -1778,7 +1840,19 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
|
|
|
1778
1840
|
for (i = 0; i < num_urbs; i++) {
|
|
1779
1841
|
struct usbfs_urb *urb = &urbs[i];
|
|
1780
1842
|
urb->usercontext = itransfer;
|
|
1781
|
-
|
|
1843
|
+
switch (transfer->type) {
|
|
1844
|
+
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
1845
|
+
urb->type = USBFS_URB_TYPE_BULK;
|
|
1846
|
+
urb->stream_id = 0;
|
|
1847
|
+
break;
|
|
1848
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
1849
|
+
urb->type = USBFS_URB_TYPE_BULK;
|
|
1850
|
+
urb->stream_id = itransfer->stream_id;
|
|
1851
|
+
break;
|
|
1852
|
+
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
1853
|
+
urb->type = USBFS_URB_TYPE_INTERRUPT;
|
|
1854
|
+
break;
|
|
1855
|
+
}
|
|
1782
1856
|
urb->endpoint = transfer->endpoint;
|
|
1783
1857
|
urb->buffer = transfer->buffer + (i * bulk_buffer_len);
|
|
1784
1858
|
/* don't set the short not ok flag for the last URB */
|
|
@@ -2061,9 +2135,10 @@ static int op_submit_transfer(struct usbi_transfer *itransfer)
|
|
|
2061
2135
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
2062
2136
|
return submit_control_transfer(itransfer);
|
|
2063
2137
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
2064
|
-
|
|
2138
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2139
|
+
return submit_bulk_transfer(itransfer);
|
|
2065
2140
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2066
|
-
return submit_bulk_transfer(itransfer
|
|
2141
|
+
return submit_bulk_transfer(itransfer);
|
|
2067
2142
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2068
2143
|
return submit_iso_transfer(itransfer);
|
|
2069
2144
|
default:
|
|
@@ -2081,6 +2156,7 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
|
|
|
2081
2156
|
|
|
2082
2157
|
switch (transfer->type) {
|
|
2083
2158
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
2159
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2084
2160
|
if (tpriv->reap_action == ERROR)
|
|
2085
2161
|
break;
|
|
2086
2162
|
/* else, fall through */
|
|
@@ -2111,6 +2187,7 @@ static void op_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
|
2111
2187
|
switch (transfer->type) {
|
|
2112
2188
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
2113
2189
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
2190
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2114
2191
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2115
2192
|
usbi_mutex_lock(&itransfer->lock);
|
|
2116
2193
|
if (tpriv->urbs)
|
|
@@ -2479,6 +2556,7 @@ static int reap_for_handle(struct libusb_device_handle *handle)
|
|
|
2479
2556
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2480
2557
|
return handle_iso_completion(itransfer, urb);
|
|
2481
2558
|
case LIBUSB_TRANSFER_TYPE_BULK:
|
|
2559
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2482
2560
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2483
2561
|
return handle_bulk_completion(itransfer, urb);
|
|
2484
2562
|
case LIBUSB_TRANSFER_TYPE_CONTROL:
|
|
@@ -2512,6 +2590,12 @@ static int op_handle_events(struct libusb_context *ctx,
|
|
|
2512
2590
|
break;
|
|
2513
2591
|
}
|
|
2514
2592
|
|
|
2593
|
+
if (!hpriv || hpriv->fd != pollfd->fd) {
|
|
2594
|
+
usbi_err(ctx, "cannot find handle for fd %d\n",
|
|
2595
|
+
pollfd->fd);
|
|
2596
|
+
continue;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2515
2599
|
if (pollfd->revents & POLLERR) {
|
|
2516
2600
|
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd);
|
|
2517
2601
|
usbi_handle_disconnect(handle);
|
|
@@ -2583,6 +2667,9 @@ const struct usbi_os_backend linux_usbfs_backend = {
|
|
|
2583
2667
|
.clear_halt = op_clear_halt,
|
|
2584
2668
|
.reset_device = op_reset_device,
|
|
2585
2669
|
|
|
2670
|
+
.alloc_streams = op_alloc_streams,
|
|
2671
|
+
.free_streams = op_free_streams,
|
|
2672
|
+
|
|
2586
2673
|
.kernel_driver_active = op_kernel_driver_active,
|
|
2587
2674
|
.detach_kernel_driver = op_detach_kernel_driver,
|
|
2588
2675
|
.attach_kernel_driver = op_attach_kernel_driver,
|
|
@@ -94,7 +94,10 @@ struct usbfs_urb {
|
|
|
94
94
|
int buffer_length;
|
|
95
95
|
int actual_length;
|
|
96
96
|
int start_frame;
|
|
97
|
-
|
|
97
|
+
union {
|
|
98
|
+
int number_of_packets; /* Only used for isoc urbs */
|
|
99
|
+
unsigned int stream_id; /* Only used with bulk streams */
|
|
100
|
+
};
|
|
98
101
|
int error_count;
|
|
99
102
|
unsigned int signr;
|
|
100
103
|
void *usercontext;
|
|
@@ -132,6 +135,12 @@ struct usbfs_disconnect_claim {
|
|
|
132
135
|
char driver[USBFS_MAXDRIVERNAME + 1];
|
|
133
136
|
};
|
|
134
137
|
|
|
138
|
+
struct usbfs_streams {
|
|
139
|
+
unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */
|
|
140
|
+
unsigned int num_eps;
|
|
141
|
+
unsigned char eps[0];
|
|
142
|
+
};
|
|
143
|
+
|
|
135
144
|
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
|
|
136
145
|
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
|
|
137
146
|
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
|
|
@@ -155,6 +164,8 @@ struct usbfs_disconnect_claim {
|
|
|
155
164
|
#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
|
|
156
165
|
#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
|
|
157
166
|
#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim)
|
|
167
|
+
#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams)
|
|
168
|
+
#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams)
|
|
158
169
|
|
|
159
170
|
extern usbi_mutex_static_t linux_hotplug_lock;
|
|
160
171
|
|
|
@@ -112,6 +112,9 @@ const struct usbi_os_backend netbsd_backend = {
|
|
|
112
112
|
netbsd_clear_halt,
|
|
113
113
|
netbsd_reset_device,
|
|
114
114
|
|
|
115
|
+
NULL, /* alloc_streams */
|
|
116
|
+
NULL, /* free_streams */
|
|
117
|
+
|
|
115
118
|
NULL, /* kernel_driver_active() */
|
|
116
119
|
NULL, /* detach_kernel_driver() */
|
|
117
120
|
NULL, /* attach_kernel_driver() */
|
|
@@ -458,6 +461,9 @@ netbsd_submit_transfer(struct usbi_transfer *itransfer)
|
|
|
458
461
|
}
|
|
459
462
|
err = _sync_gen_transfer(itransfer);
|
|
460
463
|
break;
|
|
464
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
465
|
+
err = LIBUSB_ERROR_NOT_SUPPORTED;
|
|
466
|
+
break;
|
|
461
467
|
}
|
|
462
468
|
|
|
463
469
|
if (err)
|
|
@@ -115,6 +115,9 @@ const struct usbi_os_backend openbsd_backend = {
|
|
|
115
115
|
obsd_clear_halt,
|
|
116
116
|
obsd_reset_device,
|
|
117
117
|
|
|
118
|
+
NULL, /* alloc_streams */
|
|
119
|
+
NULL, /* free_streams */
|
|
120
|
+
|
|
118
121
|
NULL, /* kernel_driver_active() */
|
|
119
122
|
NULL, /* detach_kernel_driver() */
|
|
120
123
|
NULL, /* attach_kernel_driver() */
|
|
@@ -504,6 +507,9 @@ obsd_submit_transfer(struct usbi_transfer *itransfer)
|
|
|
504
507
|
}
|
|
505
508
|
err = _sync_gen_transfer(itransfer);
|
|
506
509
|
break;
|
|
510
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
511
|
+
err = LIBUSB_ERROR_NOT_SUPPORTED;
|
|
512
|
+
break;
|
|
507
513
|
}
|
|
508
514
|
|
|
509
515
|
if (err)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -40,14 +40,20 @@
|
|
|
40
40
|
|
|
41
41
|
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
|
|
42
42
|
|
|
43
|
+
/* Windows versions */
|
|
43
44
|
enum windows_version {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
WINDOWS_CE = -2,
|
|
46
|
+
WINDOWS_UNDEFINED = -1,
|
|
47
|
+
WINDOWS_UNSUPPORTED = 0,
|
|
48
|
+
WINDOWS_XP = 0x51,
|
|
49
|
+
WINDOWS_2003 = 0x52, // Also XP x64
|
|
50
|
+
WINDOWS_VISTA = 0x60,
|
|
51
|
+
WINDOWS_7 = 0x61,
|
|
52
|
+
WINDOWS_8 = 0x62,
|
|
53
|
+
WINDOWS_8_1_OR_LATER = 0x63,
|
|
54
|
+
WINDOWS_MAX
|
|
49
55
|
};
|
|
50
|
-
extern
|
|
56
|
+
extern int windows_version;
|
|
51
57
|
|
|
52
58
|
#define MAX_FDS 256
|
|
53
59
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -38,7 +38,7 @@ unsigned __stdcall wince_clock_gettime_threaded(void* param);
|
|
|
38
38
|
uint64_t hires_frequency, hires_ticks_to_ps;
|
|
39
39
|
int errno;
|
|
40
40
|
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
|
|
41
|
-
|
|
41
|
+
int windows_version = WINDOWS_CE;
|
|
42
42
|
static int concurrent_usage = -1;
|
|
43
43
|
// Timer thread
|
|
44
44
|
// NB: index 0 is for monotonic and 1 is for the thread exit event
|
|
@@ -689,6 +689,8 @@ static int wince_submit_transfer(
|
|
|
689
689
|
return wince_submit_control_or_bulk_transfer(itransfer);
|
|
690
690
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
691
691
|
return wince_submit_iso_transfer(itransfer);
|
|
692
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
693
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
692
694
|
default:
|
|
693
695
|
usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
|
694
696
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
@@ -801,6 +803,8 @@ static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_
|
|
|
801
803
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
802
804
|
wince_transfer_callback (itransfer, io_result, io_size);
|
|
803
805
|
break;
|
|
806
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
807
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
804
808
|
default:
|
|
805
809
|
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
|
806
810
|
}
|
|
@@ -1005,6 +1009,9 @@ const struct usbi_os_backend wince_backend = {
|
|
|
1005
1009
|
wince_clear_halt,
|
|
1006
1010
|
wince_reset_device,
|
|
1007
1011
|
|
|
1012
|
+
NULL, /* alloc_streams */
|
|
1013
|
+
NULL, /* free_streams */
|
|
1014
|
+
|
|
1008
1015
|
wince_kernel_driver_active,
|
|
1009
1016
|
wince_detach_kernel_driver,
|
|
1010
1017
|
wince_attach_kernel_driver,
|
|
File without changes
|
|
File without changes
|
|
@@ -100,7 +100,8 @@ static int composite_copy_transfer_data(int sub_api, struct usbi_transfer *itran
|
|
|
100
100
|
// Global variables
|
|
101
101
|
uint64_t hires_frequency, hires_ticks_to_ps;
|
|
102
102
|
const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
|
|
103
|
-
|
|
103
|
+
int windows_version = WINDOWS_UNDEFINED;
|
|
104
|
+
static char windows_version_str[128] = "Windows Undefined";
|
|
104
105
|
// Concurrency
|
|
105
106
|
static int concurrent_usage = -1;
|
|
106
107
|
usbi_mutex_t autoclaim_lock;
|
|
@@ -209,7 +210,7 @@ static char* sanitize_path(const char* path)
|
|
|
209
210
|
size = safe_strlen(path)+1;
|
|
210
211
|
root_size = sizeof(root_prefix)-1;
|
|
211
212
|
|
|
212
|
-
// Microsoft
|
|
213
|
+
// Microsoft indiscriminately uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
|
|
213
214
|
if (!((size > 3) && (((path[0] == '\\') && (path[1] == '\\') && (path[3] == '\\')) ||
|
|
214
215
|
((path[0] == '#') && (path[1] == '#') && (path[3] == '#'))))) {
|
|
215
216
|
add_root = root_size;
|
|
@@ -221,7 +222,7 @@ static char* sanitize_path(const char* path)
|
|
|
221
222
|
|
|
222
223
|
safe_strcpy(&ret_path[add_root], size-add_root, path);
|
|
223
224
|
|
|
224
|
-
// Ensure
|
|
225
|
+
// Ensure consistency with root prefix
|
|
225
226
|
for (j=0; j<root_size; j++)
|
|
226
227
|
ret_path[j] = root_prefix[j];
|
|
227
228
|
|
|
@@ -804,6 +805,118 @@ static void auto_release(struct usbi_transfer *itransfer)
|
|
|
804
805
|
usbi_mutex_unlock(&autoclaim_lock);
|
|
805
806
|
}
|
|
806
807
|
|
|
808
|
+
/* Windows version dtection */
|
|
809
|
+
static BOOL is_x64(void)
|
|
810
|
+
{
|
|
811
|
+
BOOL ret = FALSE;
|
|
812
|
+
// Detect if we're running a 32 or 64 bit system
|
|
813
|
+
if (sizeof(uintptr_t) < 8) {
|
|
814
|
+
DLL_LOAD_PREFIXED(Kernel32.dll, p, IsWow64Process, FALSE);
|
|
815
|
+
if (pIsWow64Process != NULL) {
|
|
816
|
+
(*pIsWow64Process)(GetCurrentProcess(), &ret);
|
|
817
|
+
}
|
|
818
|
+
} else {
|
|
819
|
+
ret = TRUE;
|
|
820
|
+
}
|
|
821
|
+
return ret;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
static void get_windows_version(void)
|
|
825
|
+
{
|
|
826
|
+
OSVERSIONINFOEXA vi, vi2;
|
|
827
|
+
const char* w = 0;
|
|
828
|
+
const char* w64 = "32 bit";
|
|
829
|
+
char* vptr;
|
|
830
|
+
size_t vlen;
|
|
831
|
+
unsigned major, minor;
|
|
832
|
+
ULONGLONG major_equal, minor_equal;
|
|
833
|
+
BOOL ws;
|
|
834
|
+
|
|
835
|
+
memset(&vi, 0, sizeof(vi));
|
|
836
|
+
vi.dwOSVersionInfoSize = sizeof(vi);
|
|
837
|
+
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
|
|
838
|
+
memset(&vi, 0, sizeof(vi));
|
|
839
|
+
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
|
840
|
+
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
|
845
|
+
|
|
846
|
+
if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {
|
|
847
|
+
// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
|
|
848
|
+
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
|
|
849
|
+
|
|
850
|
+
major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
|
851
|
+
for (major = vi.dwMajorVersion; major <= 9; major++) {
|
|
852
|
+
memset(&vi2, 0, sizeof(vi2));
|
|
853
|
+
vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;
|
|
854
|
+
if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
|
|
855
|
+
continue;
|
|
856
|
+
if (vi.dwMajorVersion < major) {
|
|
857
|
+
vi.dwMajorVersion = major; vi.dwMinorVersion = 0;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
|
|
861
|
+
for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
|
|
862
|
+
memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);
|
|
863
|
+
vi2.dwMinorVersion = minor;
|
|
864
|
+
if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
|
|
865
|
+
continue;
|
|
866
|
+
vi.dwMinorVersion = minor;
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
|
|
875
|
+
ws = (vi.wProductType <= VER_NT_WORKSTATION);
|
|
876
|
+
windows_version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
|
|
877
|
+
switch (windows_version) {
|
|
878
|
+
case 0x50: w = "2000";
|
|
879
|
+
break;
|
|
880
|
+
case 0x51: w = "XP";
|
|
881
|
+
break;
|
|
882
|
+
case 0x52: w = ("2003");
|
|
883
|
+
break;
|
|
884
|
+
case 0x60: w = (ws?"Vista":"2008");
|
|
885
|
+
break;
|
|
886
|
+
case 0x61: w = (ws?"7":"2008_R2");
|
|
887
|
+
break;
|
|
888
|
+
case 0x62: w = (ws?"8":"2012");
|
|
889
|
+
break;
|
|
890
|
+
case 0x63: w = (ws?"8.1":"2012_R2");
|
|
891
|
+
break;
|
|
892
|
+
case 0x64: w = (ws?"8.2":"2012_R3");
|
|
893
|
+
break;
|
|
894
|
+
default:
|
|
895
|
+
if (windows_version < 0x50)
|
|
896
|
+
windows_version = WINDOWS_UNSUPPORTED;
|
|
897
|
+
else
|
|
898
|
+
w = "9 or later";
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (is_x64())
|
|
905
|
+
w64 = "64-bit";
|
|
906
|
+
|
|
907
|
+
vptr = &windows_version_str[sizeof("Windows ") - 1];
|
|
908
|
+
vlen = sizeof(windows_version_str) - sizeof("Windows ") - 1;
|
|
909
|
+
if (!w)
|
|
910
|
+
safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId==VER_PLATFORM_WIN32_NT?"NT":"??"),
|
|
911
|
+
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
|
|
912
|
+
else if (vi.wServicePackMinor)
|
|
913
|
+
safe_sprintf(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);
|
|
914
|
+
else if (vi.wServicePackMajor)
|
|
915
|
+
safe_sprintf(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
|
|
916
|
+
else
|
|
917
|
+
safe_sprintf(vptr, vlen, "%s %s", w, w64);
|
|
918
|
+
}
|
|
919
|
+
|
|
807
920
|
/*
|
|
808
921
|
* init: libusb backend init function
|
|
809
922
|
*
|
|
@@ -814,7 +927,6 @@ static void auto_release(struct usbi_transfer *itransfer)
|
|
|
814
927
|
static int windows_init(struct libusb_context *ctx)
|
|
815
928
|
{
|
|
816
929
|
int i, r = LIBUSB_ERROR_OTHER;
|
|
817
|
-
OSVERSIONINFO os_version;
|
|
818
930
|
HANDLE semaphore;
|
|
819
931
|
char sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
|
|
820
932
|
|
|
@@ -836,19 +948,8 @@ static int windows_init(struct libusb_context *ctx)
|
|
|
836
948
|
// NB: concurrent usage supposes that init calls are equally balanced with
|
|
837
949
|
// exit calls. If init is called more than exit, we will not exit properly
|
|
838
950
|
if ( ++concurrent_usage == 0 ) { // First init?
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
os_version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
842
|
-
windows_version = WINDOWS_UNSUPPORTED;
|
|
843
|
-
if ((GetVersionEx(&os_version) != 0) && (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
|
|
844
|
-
if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 1)) {
|
|
845
|
-
windows_version = WINDOWS_XP;
|
|
846
|
-
} else if ((os_version.dwMajorVersion == 5) && (os_version.dwMinorVersion == 2)) {
|
|
847
|
-
windows_version = WINDOWS_2003; // also includes XP 64
|
|
848
|
-
} else if (os_version.dwMajorVersion >= 6) {
|
|
849
|
-
windows_version = WINDOWS_VISTA_AND_LATER;
|
|
850
|
-
}
|
|
851
|
-
}
|
|
951
|
+
get_windows_version();
|
|
952
|
+
usbi_dbg(windows_version_str);
|
|
852
953
|
if (windows_version == WINDOWS_UNSUPPORTED) {
|
|
853
954
|
usbi_err(ctx, "This version of Windows is NOT supported");
|
|
854
955
|
r = LIBUSB_ERROR_NOT_SUPPORTED;
|
|
@@ -1028,6 +1129,7 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
|
|
|
1028
1129
|
|
|
1029
1130
|
// Dummy call to get the required data size. Initial failures are reported as info rather
|
|
1030
1131
|
// than error as they can occur for non-penalizing situations, such as with some hubs.
|
|
1132
|
+
// coverity[tainted_data_argument]
|
|
1031
1133
|
if (!DeviceIoControl(hub_handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, &cd_buf_short, size,
|
|
1032
1134
|
&cd_buf_short, size, &ret_size, NULL)) {
|
|
1033
1135
|
usbi_info(ctx, "could not access configuration descriptor (dummy) for '%s': %s", device_id, windows_error_str(0));
|
|
@@ -1078,7 +1180,7 @@ static int cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handle
|
|
|
1078
1180
|
// Cache the descriptor
|
|
1079
1181
|
priv->config_descriptor[i] = (unsigned char*) malloc(cd_data->wTotalLength);
|
|
1080
1182
|
if (priv->config_descriptor[i] == NULL)
|
|
1081
|
-
|
|
1183
|
+
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
|
|
1082
1184
|
memcpy(priv->config_descriptor[i], cd_data, cd_data->wTotalLength);
|
|
1083
1185
|
}
|
|
1084
1186
|
return LIBUSB_SUCCESS;
|
|
@@ -1093,14 +1195,16 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
|
1093
1195
|
HANDLE handle;
|
|
1094
1196
|
DWORD size;
|
|
1095
1197
|
USB_NODE_CONNECTION_INFORMATION_EX conn_info;
|
|
1198
|
+
USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2;
|
|
1096
1199
|
struct windows_device_priv *priv, *parent_priv;
|
|
1097
|
-
struct libusb_context *ctx
|
|
1200
|
+
struct libusb_context *ctx;
|
|
1098
1201
|
struct libusb_device* tmp_dev;
|
|
1099
1202
|
unsigned i;
|
|
1100
1203
|
|
|
1101
1204
|
if ((dev == NULL) || (parent_dev == NULL)) {
|
|
1102
1205
|
return LIBUSB_ERROR_NOT_FOUND;
|
|
1103
1206
|
}
|
|
1207
|
+
ctx = DEVICE_CTX(dev);
|
|
1104
1208
|
priv = _device_priv(dev);
|
|
1105
1209
|
parent_priv = _device_priv(parent_dev);
|
|
1106
1210
|
if (parent_priv->apib->id != USB_API_HUB) {
|
|
@@ -1148,6 +1252,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
|
1148
1252
|
}
|
|
1149
1253
|
size = sizeof(conn_info);
|
|
1150
1254
|
conn_info.ConnectionIndex = (ULONG)port_number;
|
|
1255
|
+
// coverity[tainted_data_argument]
|
|
1151
1256
|
if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size,
|
|
1152
1257
|
&conn_info, size, &size, NULL)) {
|
|
1153
1258
|
usbi_warn(ctx, "could not get node connection information for device '%s': %s",
|
|
@@ -1169,6 +1274,23 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
|
1169
1274
|
dev->num_configurations = 0;
|
|
1170
1275
|
priv->dev_descriptor.bNumConfigurations = 0;
|
|
1171
1276
|
}
|
|
1277
|
+
|
|
1278
|
+
// In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8
|
|
1279
|
+
if (windows_version >= WINDOWS_8) {
|
|
1280
|
+
memset(&conn_info_v2, 0, sizeof(conn_info_v2));
|
|
1281
|
+
size = sizeof(conn_info_v2);
|
|
1282
|
+
conn_info_v2.ConnectionIndex = (ULONG)port_number;
|
|
1283
|
+
conn_info_v2.Length = size;
|
|
1284
|
+
conn_info_v2.SupportedUsbProtocols.Usb300 = 1;
|
|
1285
|
+
if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2,
|
|
1286
|
+
&conn_info_v2, size, &conn_info_v2, size, &size, NULL)) {
|
|
1287
|
+
usbi_warn(ctx, "could not get node connection information (V2) for device '%s': %s",
|
|
1288
|
+
device_id, windows_error_str(0));
|
|
1289
|
+
} else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) {
|
|
1290
|
+
conn_info.Speed = 3;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1172
1294
|
safe_closehandle(handle);
|
|
1173
1295
|
|
|
1174
1296
|
if (conn_info.DeviceAddress > UINT8_MAX) {
|
|
@@ -1246,7 +1368,7 @@ static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
|
|
|
1246
1368
|
for (k=0; k<3; k++) {
|
|
1247
1369
|
j = get_sub_api(lookup[k].list, i);
|
|
1248
1370
|
if (j >= 0) {
|
|
1249
|
-
usbi_dbg("matched %s name against %s
|
|
1371
|
+
usbi_dbg("matched %s name against %s",
|
|
1250
1372
|
lookup[k].designation, (i!=USB_API_WINUSBX)?usb_api_backend[i].designation:sub_api_name[j]);
|
|
1251
1373
|
*api = i;
|
|
1252
1374
|
*sub_api = j;
|
|
@@ -1553,7 +1675,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
|
1553
1675
|
parent_priv = _device_priv(parent_dev);
|
|
1554
1676
|
// virtual USB devices are also listed during GEN - don't process these yet
|
|
1555
1677
|
if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
|
|
1556
|
-
|
|
1678
|
+
libusb_unref_device(parent_dev);
|
|
1557
1679
|
continue;
|
|
1558
1680
|
}
|
|
1559
1681
|
break;
|
|
@@ -1580,16 +1702,16 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
|
1580
1702
|
usbi_dbg("found existing device for session [%X] (%d.%d)",
|
|
1581
1703
|
session_id, dev->bus_number, dev->device_address);
|
|
1582
1704
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1705
|
+
// Keep track of devices that need unref
|
|
1706
|
+
unref_list[unref_cur++] = dev;
|
|
1707
|
+
if (unref_cur >= unref_size) {
|
|
1708
|
+
unref_size += 64;
|
|
1709
|
+
unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
|
|
1710
|
+
if (unref_list == NULL) {
|
|
1711
|
+
usbi_err(ctx, "could not realloc list for unref - aborting.");
|
|
1712
|
+
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1593
1715
|
priv = _device_priv(dev);
|
|
1594
1716
|
}
|
|
1595
1717
|
|
|
@@ -1675,7 +1797,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
|
1675
1797
|
break;
|
|
1676
1798
|
}
|
|
1677
1799
|
}
|
|
1678
|
-
|
|
1800
|
+
libusb_unref_device(parent_dev);
|
|
1679
1801
|
break;
|
|
1680
1802
|
}
|
|
1681
1803
|
}
|
|
@@ -1687,10 +1809,12 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
|
1687
1809
|
}
|
|
1688
1810
|
|
|
1689
1811
|
// Unref newly allocated devs
|
|
1690
|
-
|
|
1691
|
-
|
|
1812
|
+
if (unref_list != NULL) {
|
|
1813
|
+
for (i=0; i<unref_cur; i++) {
|
|
1814
|
+
safe_unref_device(unref_list[i]);
|
|
1815
|
+
}
|
|
1816
|
+
free(unref_list);
|
|
1692
1817
|
}
|
|
1693
|
-
safe_free(unref_list);
|
|
1694
1818
|
|
|
1695
1819
|
return r;
|
|
1696
1820
|
}
|
|
@@ -2019,6 +2143,8 @@ static int windows_submit_transfer(struct usbi_transfer *itransfer)
|
|
|
2019
2143
|
return submit_bulk_transfer(itransfer);
|
|
2020
2144
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2021
2145
|
return submit_iso_transfer(itransfer);
|
|
2146
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2147
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
2022
2148
|
default:
|
|
2023
2149
|
usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
|
|
2024
2150
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
@@ -2052,6 +2178,8 @@ static int windows_cancel_transfer(struct usbi_transfer *itransfer)
|
|
|
2052
2178
|
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
|
|
2053
2179
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2054
2180
|
return windows_abort_transfers(itransfer);
|
|
2181
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2182
|
+
return LIBUSB_ERROR_NOT_SUPPORTED;
|
|
2055
2183
|
default:
|
|
2056
2184
|
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
|
2057
2185
|
return LIBUSB_ERROR_INVALID_PARAM;
|
|
@@ -2111,6 +2239,9 @@ static void windows_handle_callback (struct usbi_transfer *itransfer, uint32_t i
|
|
|
2111
2239
|
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
|
|
2112
2240
|
windows_transfer_callback (itransfer, io_result, io_size);
|
|
2113
2241
|
break;
|
|
2242
|
+
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
|
|
2243
|
+
usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform");
|
|
2244
|
+
break;
|
|
2114
2245
|
default:
|
|
2115
2246
|
usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
|
|
2116
2247
|
}
|
|
@@ -2222,7 +2353,7 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
|
|
2222
2353
|
case 0:
|
|
2223
2354
|
WaitForSingleObject(timer_mutex, INFINITE);
|
|
2224
2355
|
// Requests to this thread are for hires always
|
|
2225
|
-
if (QueryPerformanceCounter(&hires_counter) != 0) {
|
|
2356
|
+
if ((QueryPerformanceCounter(&hires_counter) != 0) && (hires_frequency != 0)) {
|
|
2226
2357
|
timer_tp.tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
|
|
2227
2358
|
timer_tp.tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency)/1000) * hires_ticks_to_ps);
|
|
2228
2359
|
} else {
|
|
@@ -2317,6 +2448,9 @@ const struct usbi_os_backend windows_backend = {
|
|
|
2317
2448
|
windows_clear_halt,
|
|
2318
2449
|
windows_reset_device,
|
|
2319
2450
|
|
|
2451
|
+
NULL, /* alloc_streams */
|
|
2452
|
+
NULL, /* free_streams */
|
|
2453
|
+
|
|
2320
2454
|
windows_kernel_driver_active,
|
|
2321
2455
|
windows_detach_kernel_driver,
|
|
2322
2456
|
windows_attach_kernel_driver,
|
|
@@ -2395,7 +2529,7 @@ static int common_configure_endpoints(int sub_api, struct libusb_device_handle *
|
|
|
2395
2529
|
return LIBUSB_SUCCESS;
|
|
2396
2530
|
}
|
|
2397
2531
|
// These names must be uppercase
|
|
2398
|
-
const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB"};
|
|
2532
|
+
const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "USB3HUB", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB", "VUSB3HUB", "AMDHUB30"};
|
|
2399
2533
|
const char* composite_driver_names[] = {"USBCCGP"};
|
|
2400
2534
|
const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES;
|
|
2401
2535
|
const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"};
|
|
@@ -2755,11 +2889,10 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
|
|
|
2755
2889
|
usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0));
|
|
2756
2890
|
} else {
|
|
2757
2891
|
WinUSBX[sub_api].Free(winusb_handle);
|
|
2758
|
-
if (
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
break;
|
|
2892
|
+
if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle))
|
|
2893
|
+
found_filter = true;
|
|
2894
|
+
else
|
|
2895
|
+
usbi_err(ctx, "could not initialize filter driver for %s", filter_path);
|
|
2763
2896
|
}
|
|
2764
2897
|
}
|
|
2765
2898
|
}
|