libusb 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|