libusb 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +3 -3
  5. data/History.md +8 -0
  6. data/README.md +1 -0
  7. data/Rakefile +14 -14
  8. data/ext/{libusb-1.0.18 → libusb-1.0.19}/AUTHORS +6 -0
  9. data/ext/{libusb-1.0.18 → libusb-1.0.19}/COPYING +0 -0
  10. data/ext/{libusb-1.0.18 → libusb-1.0.19}/ChangeLog +9 -2
  11. data/ext/{libusb-1.0.18 → libusb-1.0.19}/INSTALL +0 -0
  12. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Makefile.am +0 -0
  13. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Makefile.in +188 -156
  14. data/ext/{libusb-1.0.18 → libusb-1.0.19}/NEWS +0 -0
  15. data/ext/{libusb-1.0.18 → libusb-1.0.19}/PORTING +0 -0
  16. data/ext/{libusb-1.0.18 → libusb-1.0.19}/README +0 -0
  17. data/ext/{libusb-1.0.18 → libusb-1.0.19}/TODO +0 -0
  18. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/common.xcconfig +10 -1
  19. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/config.h +0 -0
  20. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/debug.xcconfig +0 -0
  21. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb.xcconfig +1 -1
  22. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb.xcodeproj/project.pbxproj +0 -0
  23. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb_debug.xcconfig +0 -0
  24. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/libusb_release.xcconfig +0 -0
  25. data/ext/{libusb-1.0.18 → libusb-1.0.19}/Xcode/release.xcconfig +1 -0
  26. data/ext/libusb-1.0.19/aclocal.m4 +1190 -0
  27. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/README +0 -0
  28. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/config.h +0 -0
  29. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/Android.mk +0 -0
  30. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/Application.mk +0 -0
  31. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/examples.mk +0 -0
  32. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/libusb.mk +0 -0
  33. data/ext/{libusb-1.0.18 → libusb-1.0.19}/android/jni/tests.mk +0 -0
  34. data/ext/{libusb-1.0.18 → libusb-1.0.19}/compile +7 -3
  35. data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.guess +116 -78
  36. data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.h.in +0 -3
  37. data/ext/{libusb-1.0.18 → libusb-1.0.19}/config.sub +66 -46
  38. data/ext/{libusb-1.0.18 → libusb-1.0.19}/configure +265 -208
  39. data/ext/{libusb-1.0.18 → libusb-1.0.19}/configure.ac +0 -0
  40. data/ext/{libusb-1.0.18 → libusb-1.0.19}/depcomp +269 -186
  41. data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/Makefile.am +0 -0
  42. data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/Makefile.in +72 -35
  43. data/ext/{libusb-1.0.18 → libusb-1.0.19}/doc/doxygen.cfg.in +1 -1
  44. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/Makefile.am +0 -0
  45. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/Makefile.in +134 -70
  46. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/dpfp.c +0 -0
  47. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/dpfp_threaded.c +0 -0
  48. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/ezusb.c +9 -5
  49. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/ezusb.h +0 -0
  50. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/fxload.c +1 -1
  51. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt.c +0 -0
  52. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt.h +0 -0
  53. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/getopt/getopt1.c +0 -0
  54. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/hotplugtest.c +0 -0
  55. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/listdevs.c +0 -0
  56. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/sam3u_benchmark.c +0 -0
  57. data/ext/{libusb-1.0.18 → libusb-1.0.19}/examples/xusb.c +22 -2
  58. data/ext/{libusb-1.0.18 → libusb-1.0.19}/install-sh +7 -7
  59. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb-1.0.pc.in +0 -0
  60. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/Makefile.am +0 -0
  61. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/Makefile.in +133 -93
  62. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/core.c +86 -15
  63. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/descriptor.c +0 -0
  64. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/hotplug.c +6 -1
  65. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/hotplug.h +0 -0
  66. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/io.c +54 -17
  67. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb-1.0.def +8 -0
  68. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb-1.0.rc +0 -0
  69. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusb.h +42 -2
  70. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/libusbi.h +10 -1
  71. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/darwin_usb.c +156 -53
  72. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/darwin_usb.h +1 -1
  73. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_netlink.c +26 -2
  74. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_udev.c +2 -1
  75. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_usbfs.c +93 -6
  76. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/linux_usbfs.h +12 -1
  77. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/netbsd_usb.c +6 -0
  78. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/openbsd_usb.c +6 -0
  79. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_posix.c +0 -0
  80. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_posix.h +0 -0
  81. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_windows.c +0 -0
  82. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/poll_windows.h +12 -6
  83. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_posix.c +0 -0
  84. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_posix.h +0 -0
  85. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_windows.c +0 -0
  86. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/threads_windows.h +0 -0
  87. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/wince_usb.c +8 -1
  88. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/wince_usb.h +0 -0
  89. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_common.h +0 -0
  90. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_usb.c +175 -42
  91. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/os/windows_usb.h +35 -0
  92. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/strerror.c +17 -2
  93. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/sync.c +0 -0
  94. data/ext/{libusb-1.0.18 → libusb-1.0.19}/libusb/version.h +1 -1
  95. data/ext/libusb-1.0.19/libusb/version_nano.h +1 -0
  96. data/ext/{libusb-1.0.18 → libusb-1.0.19}/ltmain.sh +3 -3
  97. data/ext/{libusb-1.0.18/aclocal.m4 → libusb-1.0.19/m4/libtool.m4} +36 -1734
  98. data/ext/libusb-1.0.19/m4/ltoptions.m4 +384 -0
  99. data/ext/libusb-1.0.19/m4/ltsugar.m4 +123 -0
  100. data/ext/libusb-1.0.19/m4/ltversion.m4 +23 -0
  101. data/ext/libusb-1.0.19/m4/lt~obsolete.m4 +98 -0
  102. data/ext/libusb-1.0.19/missing +215 -0
  103. data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/Makefile.am +0 -0
  104. data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/Makefile.in +128 -70
  105. data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/libusb_testlib.h +0 -0
  106. data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/stress.c +0 -0
  107. data/ext/{libusb-1.0.18 → libusb-1.0.19}/tests/testlib.c +0 -0
  108. data/lib/libusb.rb +3 -1
  109. data/lib/libusb/bos.rb +306 -0
  110. data/lib/libusb/call.rb +84 -0
  111. data/lib/libusb/constants.rb +4 -0
  112. data/lib/libusb/dev_handle.rb +77 -0
  113. data/lib/libusb/endpoint.rb +20 -0
  114. data/lib/libusb/ss_companion.rb +69 -0
  115. data/lib/libusb/transfer.rb +34 -0
  116. data/lib/libusb/version_gem.rb +1 -1
  117. data/libusb.gemspec +1 -0
  118. data/test/test_libusb_bos.rb +118 -0
  119. data/test/test_libusb_bulk_stream_transfer.rb +50 -0
  120. data/test/test_libusb_descriptors.rb +29 -0
  121. data/test/test_libusb_hotplug.rb +1 -1
  122. data/test/test_libusb_threads.rb +1 -1
  123. metadata +146 -124
  124. metadata.gz.sig +0 -0
  125. data/ext/libusb-1.0.18/libusb/version_nano.h +0 -1
  126. 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 endpoint_addrs[USB_MAXENDPOINTS];
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 (likely a usb interface). ignore*/
228
- return -1;
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
- return LIBUSB_ERROR_OTHER;
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 volatile int init_count = 0;
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
- urb->type = urb_type;
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
- return submit_bulk_transfer(itransfer, USBFS_URB_TYPE_BULK);
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, USBFS_URB_TYPE_INTERRUPT);
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
- int number_of_packets;
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)
@@ -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
- WINDOWS_UNSUPPORTED,
45
- WINDOWS_CE,
46
- WINDOWS_XP,
47
- WINDOWS_2003, // also includes XP 64
48
- WINDOWS_VISTA_AND_LATER,
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 enum windows_version windows_version;
56
+ extern int windows_version;
51
57
 
52
58
  #define MAX_FDS 256
53
59
 
@@ -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
- enum windows_version windows_version = WINDOWS_CE;
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,
@@ -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
- enum windows_version windows_version = WINDOWS_UNSUPPORTED;
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 indiscriminatly uses '\\?\', '\\.\', '##?#" or "##.#" for root prefixes.
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 consistancy with root prefix
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
- // Detect OS version
840
- memset(&os_version, 0, sizeof(OSVERSIONINFO));
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
- return LIBUSB_ERROR_NO_MEM;
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 = DEVICE_CTX(dev);
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 API",
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
- libusb_unref_device(parent_dev);
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
- // Keep track of devices that need unref
1584
- unref_list[unref_cur++] = dev;
1585
- if (unref_cur >= unref_size) {
1586
- unref_size += 64;
1587
- unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
1588
- if (unref_list == NULL) {
1589
- usbi_err(ctx, "could not realloc list for unref - aborting.");
1590
- LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
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
- libusb_unref_device(parent_dev);
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
- for (i=0; i<unref_cur; i++) {
1691
- safe_unref_device(unref_list[i]);
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 (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
2759
- continue;
2760
- }
2761
- found_filter = true;
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
  }