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
@@ -366,6 +366,7 @@ struct usbi_transfer {
366
366
  struct list_head list;
367
367
  struct timeval timeout;
368
368
  int transferred;
369
+ uint32_t stream_id;
369
370
  uint8_t flags;
370
371
 
371
372
  /* this lock is held during libusb_submit_transfer() and
@@ -700,7 +701,7 @@ struct usbi_os_backend {
700
701
  * (LE). If it returns the multi-byte values in host-endian format,
701
702
  * set the host_endian output parameter to "1".
702
703
  *
703
- * Return 0 on success or a LIBUSB_ERROR code on failure.
704
+ * Return the length read on success or a LIBUSB_ERROR code on failure.
704
705
  */
705
706
  int (*get_config_descriptor)(struct libusb_device *device,
706
707
  uint8_t config_index, unsigned char *buffer, size_t len,
@@ -843,6 +844,14 @@ struct usbi_os_backend {
843
844
  */
844
845
  int (*reset_device)(struct libusb_device_handle *handle);
845
846
 
847
+ /* Alloc num_streams usb3 bulk streams on the passed in endpoints */
848
+ int (*alloc_streams)(struct libusb_device_handle *handle,
849
+ uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
850
+
851
+ /* Free usb3 bulk streams allocated with alloc_streams */
852
+ int (*free_streams)(struct libusb_device_handle *handle,
853
+ unsigned char *endpoints, int num_endpoints);
854
+
846
855
  /* Determine if a kernel driver is active on an interface. Optional.
847
856
  *
848
857
  * The presence of a kernel driver on an interface indicates that any
@@ -1,7 +1,7 @@
1
1
  /* -*- Mode: C; indent-tabs-mode:nil -*- */
2
2
  /*
3
3
  * darwin backend for libusb 1.0
4
- * Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net>
4
+ * Copyright © 2008-2014 Nathan Hjelm <hjelmn@users.sourceforge.net>
5
5
  *
6
6
  * This library is free software; you can redistribute it and/or
7
7
  * modify it under the terms of the GNU Lesser General Public
@@ -151,7 +151,7 @@ static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
151
151
  cached_dev->refcount++;
152
152
  }
153
153
 
154
- static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp) {
154
+ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp, struct darwin_interface **interface_out) {
155
155
  struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
156
156
 
157
157
  /* current interface */
@@ -168,8 +168,14 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
168
168
  for (i = 0 ; i < cInterface->num_endpoints ; i++) {
169
169
  if (cInterface->endpoint_addrs[i] == ep) {
170
170
  *pipep = i + 1;
171
- *ifcp = iface;
172
- usbi_dbg ("pipe %d on interface %d matches", *pipep, *ifcp);
171
+
172
+ if (ifcp)
173
+ *ifcp = iface;
174
+
175
+ if (interface_out)
176
+ *interface_out = cInterface;
177
+
178
+ usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
173
179
  return 0;
174
180
  }
175
181
  }
@@ -179,7 +185,7 @@ static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, ui
179
185
  /* No pipe found with the correct endpoint address */
180
186
  usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
181
187
 
182
- return -1;
188
+ return LIBUSB_ERROR_NOT_FOUND;
183
189
  }
184
190
 
185
191
  static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
@@ -278,6 +284,8 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
278
284
  UInt64 session;
279
285
  int ret;
280
286
 
287
+ usbi_mutex_lock(&active_contexts_lock);
288
+
281
289
  while ((device = IOIteratorNext (rem_devices)) != 0) {
282
290
  /* get the location from the i/o registry */
283
291
  ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
@@ -285,8 +293,6 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
285
293
  if (!ret)
286
294
  continue;
287
295
 
288
- usbi_mutex_lock(&active_contexts_lock);
289
-
290
296
  list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
291
297
  usbi_dbg ("notifying context %p of device disconnect", ctx);
292
298
 
@@ -298,9 +304,20 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
298
304
  libusb_unref_device(dev);
299
305
  }
300
306
  }
301
-
302
- usbi_mutex_unlock(&active_contexts_lock);
303
307
  }
308
+
309
+ usbi_mutex_unlock(&active_contexts_lock);
310
+ }
311
+
312
+ static void darwin_hotplug_poll (void)
313
+ {
314
+ /* not sure if 5 seconds will be too long/short but it should work ok */
315
+ mach_timespec_t timeout = {.tv_sec = 5, .tv_nsec = 0};
316
+
317
+ /* since a kernel thread may nodify the IOInterators used for
318
+ * hotplug notidication we can't just clear the iterators.
319
+ * instead just wait until all IOService providers are quiet */
320
+ (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
304
321
  }
305
322
 
306
323
  static void darwin_clear_iterator (io_iterator_t iter) {
@@ -346,8 +363,8 @@ static void *darwin_event_thread_main (void *arg0) {
346
363
  /* create notifications for removed devices */
347
364
  kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
348
365
  IOServiceMatching(kIOUSBDeviceClassName),
349
- (IOServiceMatchingCallback)darwin_devices_detached,
350
- (void *)ctx, &libusb_rem_device_iterator);
366
+ darwin_devices_detached,
367
+ ctx, &libusb_rem_device_iterator);
351
368
 
352
369
  if (kresult != kIOReturnSuccess) {
353
370
  usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
@@ -358,8 +375,8 @@ static void *darwin_event_thread_main (void *arg0) {
358
375
  /* create notifications for attached devices */
359
376
  kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
360
377
  IOServiceMatching(kIOUSBDeviceClassName),
361
- (IOServiceMatchingCallback)darwin_devices_attached,
362
- (void *)ctx, &libusb_add_device_iterator);
378
+ darwin_devices_attached,
379
+ ctx, &libusb_add_device_iterator);
363
380
 
364
381
  if (kresult != kIOReturnSuccess) {
365
382
  usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
@@ -401,7 +418,8 @@ static void *darwin_event_thread_main (void *arg0) {
401
418
  pthread_exit (NULL);
402
419
  }
403
420
 
404
- static void _darwin_finalize(void) {
421
+ /* cleanup function to destroy cached devices */
422
+ static void __attribute__((destructor)) _darwin_finalize(void) {
405
423
  struct darwin_cached_device *dev, *next;
406
424
 
407
425
  usbi_mutex_lock(&darwin_cached_devices_lock);
@@ -413,7 +431,6 @@ static void _darwin_finalize(void) {
413
431
 
414
432
  static int darwin_init(struct libusb_context *ctx) {
415
433
  host_name_port_t host_self;
416
- static int initted = 0;
417
434
  int rc;
418
435
 
419
436
  rc = darwin_scan_devices (ctx);
@@ -424,17 +441,12 @@ static int darwin_init(struct libusb_context *ctx) {
424
441
  if (OSAtomicIncrement32Barrier(&initCount) == 1) {
425
442
  /* create the clocks that will be used */
426
443
 
427
- if (!initted) {
428
- initted = 1;
429
- atexit(_darwin_finalize);
430
- }
431
-
432
444
  host_self = mach_host_self();
433
445
  host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
434
446
  host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
435
447
  mach_port_deallocate(mach_task_self(), host_self);
436
448
 
437
- pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, (void *)ctx);
449
+ pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
438
450
 
439
451
  pthread_mutex_lock (&libusb_darwin_at_mutex);
440
452
  while (!libusb_darwin_acfl)
@@ -528,7 +540,7 @@ static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t confi
528
540
  if (ret != LIBUSB_SUCCESS)
529
541
  return ret;
530
542
 
531
- return len;
543
+ return (int) len;
532
544
  }
533
545
 
534
546
  /* check whether the os has configured the device */
@@ -1126,7 +1138,7 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1126
1138
 
1127
1139
  usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
1128
1140
 
1129
- cInterface->endpoint_addrs[i - 1] = ((direction << 7 & LIBUSB_ENDPOINT_DIR_MASK) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1141
+ cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1130
1142
  }
1131
1143
 
1132
1144
  cInterface->num_endpoints = numep;
@@ -1298,22 +1310,18 @@ static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_hand
1298
1310
  }
1299
1311
 
1300
1312
  static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1301
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1302
-
1303
1313
  /* current interface */
1304
1314
  struct darwin_interface *cInterface;
1305
- uint8_t pipeRef, iface;
1306
1315
  IOReturn kresult;
1316
+ uint8_t pipeRef;
1307
1317
 
1308
1318
  /* determine the interface/endpoint to use */
1309
- if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, &iface) != 0) {
1319
+ if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1310
1320
  usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1311
1321
 
1312
1322
  return LIBUSB_ERROR_NOT_FOUND;
1313
1323
  }
1314
1324
 
1315
- cInterface = &priv->interfaces[iface];
1316
-
1317
1325
  /* newer versions of darwin support clearing additional bits on the device's endpoint */
1318
1326
  kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1319
1327
  if (kresult)
@@ -1427,24 +1435,21 @@ static void darwin_destroy_device(struct libusb_device *dev) {
1427
1435
 
1428
1436
  static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1429
1437
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1430
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1431
1438
 
1432
1439
  IOReturn ret;
1433
1440
  uint8_t transferType;
1434
- /* None of the values below are used in libusb for bulk transfers */
1435
- uint8_t direction, number, interval, pipeRef, iface;
1441
+ /* None of the values below are used in libusbx for bulk transfers */
1442
+ uint8_t direction, number, interval, pipeRef;
1436
1443
  uint16_t maxPacketSize;
1437
1444
 
1438
1445
  struct darwin_interface *cInterface;
1439
1446
 
1440
- if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1447
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1441
1448
  usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1442
1449
 
1443
1450
  return LIBUSB_ERROR_NOT_FOUND;
1444
1451
  }
1445
1452
 
1446
- cInterface = &priv->interfaces[iface];
1447
-
1448
1453
  ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1449
1454
  &transferType, &maxPacketSize, &interval);
1450
1455
 
@@ -1488,13 +1493,44 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1488
1493
  return darwin_to_libusb (ret);
1489
1494
  }
1490
1495
 
1496
+ #if InterfaceVersion >= 550
1497
+ static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1498
+ struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1499
+ struct darwin_interface *cInterface;
1500
+ uint8_t pipeRef;
1501
+ IOReturn ret;
1502
+
1503
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1504
+ usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1505
+
1506
+ return LIBUSB_ERROR_NOT_FOUND;
1507
+ }
1508
+
1509
+ itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1510
+
1511
+ if (IS_XFERIN(transfer))
1512
+ ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1513
+ transfer->buffer, transfer->length, transfer->timeout,
1514
+ transfer->timeout, darwin_async_io_callback, (void *)itransfer);
1515
+ else
1516
+ ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1517
+ transfer->buffer, transfer->length, transfer->timeout,
1518
+ transfer->timeout, darwin_async_io_callback, (void *)itransfer);
1519
+
1520
+ if (ret)
1521
+ usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1522
+ darwin_error_str(ret), ret);
1523
+
1524
+ return darwin_to_libusb (ret);
1525
+ }
1526
+ #endif
1527
+
1491
1528
  static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1492
1529
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1493
1530
  struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1494
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1495
1531
 
1496
1532
  IOReturn kresult;
1497
- uint8_t direction, number, interval, pipeRef, iface, transferType;
1533
+ uint8_t direction, number, interval, pipeRef, transferType;
1498
1534
  uint16_t maxPacketSize;
1499
1535
  UInt64 frame;
1500
1536
  AbsoluteTime atTime;
@@ -1520,14 +1556,12 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1520
1556
  tpriv->isoc_framelist[i].frReqCount = transfer->iso_packet_desc[i].length;
1521
1557
 
1522
1558
  /* determine the interface/endpoint to use */
1523
- if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1559
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1524
1560
  usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1525
1561
 
1526
1562
  return LIBUSB_ERROR_NOT_FOUND;
1527
1563
  }
1528
1564
 
1529
- cInterface = &priv->interfaces[iface];
1530
-
1531
1565
  /* determine the properties of this endpoint and the speed of the device */
1532
1566
  (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1533
1567
  &transferType, &maxPacketSize, &interval);
@@ -1582,7 +1616,6 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
1582
1616
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1583
1617
  struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1584
1618
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1585
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1586
1619
  struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1587
1620
 
1588
1621
  IOReturn kresult;
@@ -1607,16 +1640,14 @@ static int submit_control_transfer(struct usbi_transfer *itransfer) {
1607
1640
 
1608
1641
  if (transfer->endpoint) {
1609
1642
  struct darwin_interface *cInterface;
1610
- uint8_t pipeRef, iface;
1643
+ uint8_t pipeRef;
1611
1644
 
1612
- if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1645
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1613
1646
  usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1614
1647
 
1615
1648
  return LIBUSB_ERROR_NOT_FOUND;
1616
1649
  }
1617
1650
 
1618
- cInterface = &priv->interfaces[iface];
1619
-
1620
1651
  kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1621
1652
  } else
1622
1653
  /* control request on endpoint 0 */
@@ -1639,6 +1670,13 @@ static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1639
1670
  return submit_bulk_transfer(itransfer);
1640
1671
  case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1641
1672
  return submit_iso_transfer(itransfer);
1673
+ case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1674
+ #if InterfaceVersion >= 550
1675
+ return submit_stream_transfer(itransfer);
1676
+ #else
1677
+ usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
1678
+ return LIBUSB_ERROR_NOT_SUPPORTED;
1679
+ #endif
1642
1680
  default:
1643
1681
  usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1644
1682
  return LIBUSB_ERROR_INVALID_PARAM;
@@ -1663,26 +1701,28 @@ static int cancel_control_transfer(struct usbi_transfer *itransfer) {
1663
1701
  static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
1664
1702
  struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1665
1703
  struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1666
- struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1667
1704
  struct darwin_interface *cInterface;
1668
1705
  uint8_t pipeRef, iface;
1669
1706
  IOReturn kresult;
1670
1707
 
1671
- if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1708
+ if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
1672
1709
  usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1673
1710
 
1674
1711
  return LIBUSB_ERROR_NOT_FOUND;
1675
1712
  }
1676
1713
 
1677
- cInterface = &priv->interfaces[iface];
1678
-
1679
1714
  if (!dpriv->device)
1680
1715
  return LIBUSB_ERROR_NO_DEVICE;
1681
1716
 
1682
1717
  usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
1683
1718
 
1684
1719
  /* abort transactions */
1685
- (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
1720
+ #if InterfaceVersion >= 550
1721
+ if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
1722
+ (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
1723
+ else
1724
+ #endif
1725
+ (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
1686
1726
 
1687
1727
  usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
1688
1728
 
@@ -1730,10 +1770,9 @@ static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0)
1730
1770
  /* if requested write a zero packet */
1731
1771
  if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
1732
1772
  struct darwin_interface *cInterface;
1733
- uint8_t iface, pipeRef;
1773
+ uint8_t pipeRef;
1734
1774
 
1735
- (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface);
1736
- cInterface = &priv->interfaces[iface];
1775
+ (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
1737
1776
 
1738
1777
  (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
1739
1778
  }
@@ -1864,6 +1903,64 @@ static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
1864
1903
  return 0;
1865
1904
  }
1866
1905
 
1906
+ #if InterfaceVersion >= 550
1907
+ static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
1908
+ int num_endpoints) {
1909
+ struct darwin_interface *cInterface;
1910
+ UInt32 supportsStreams;
1911
+ uint8_t pipeRef;
1912
+ int rc, i;
1913
+
1914
+ /* find the mimimum number of supported streams on the endpoint list */
1915
+ for (i = 0 ; i < num_endpoints ; ++i) {
1916
+ if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
1917
+ return rc;
1918
+ }
1919
+
1920
+ (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
1921
+ if (num_streams > supportsStreams)
1922
+ num_streams = supportsStreams;
1923
+ }
1924
+
1925
+ /* it is an error if any endpoint in endpoints does not support streams */
1926
+ if (0 == num_streams)
1927
+ return LIBUSB_ERROR_INVALID_PARAM;
1928
+
1929
+ /* create the streams */
1930
+ for (i = 0 ; i < num_endpoints ; ++i) {
1931
+ (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
1932
+
1933
+ rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
1934
+ if (kIOReturnSuccess != rc)
1935
+ return darwin_to_libusb(rc);
1936
+ }
1937
+
1938
+ return num_streams;
1939
+ }
1940
+
1941
+ static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
1942
+ struct darwin_interface *cInterface;
1943
+ UInt32 supportsStreams;
1944
+ uint8_t pipeRef;
1945
+ int rc;
1946
+
1947
+ for (int i = 0 ; i < num_endpoints ; ++i) {
1948
+ if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
1949
+ return rc;
1950
+
1951
+ (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
1952
+ if (0 == supportsStreams)
1953
+ return LIBUSB_ERROR_INVALID_PARAM;
1954
+
1955
+ rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
1956
+ if (kIOReturnSuccess != rc)
1957
+ return darwin_to_libusb(rc);
1958
+ }
1959
+
1960
+ return LIBUSB_SUCCESS;
1961
+ }
1962
+ #endif
1963
+
1867
1964
  const struct usbi_os_backend darwin_backend = {
1868
1965
  .name = "Darwin",
1869
1966
  .caps = 0,
@@ -1873,6 +1970,7 @@ const struct usbi_os_backend darwin_backend = {
1873
1970
  .get_device_descriptor = darwin_get_device_descriptor,
1874
1971
  .get_active_config_descriptor = darwin_get_active_config_descriptor,
1875
1972
  .get_config_descriptor = darwin_get_config_descriptor,
1973
+ .hotplug_poll = darwin_hotplug_poll,
1876
1974
 
1877
1975
  .open = darwin_open,
1878
1976
  .close = darwin_close,
@@ -1885,6 +1983,11 @@ const struct usbi_os_backend darwin_backend = {
1885
1983
  .clear_halt = darwin_clear_halt,
1886
1984
  .reset_device = darwin_reset_device,
1887
1985
 
1986
+ #if InterfaceVersion >= 550
1987
+ .alloc_streams = darwin_alloc_streams,
1988
+ .free_streams = darwin_free_streams,
1989
+ #endif
1990
+
1888
1991
  .kernel_driver_active = darwin_kernel_driver_active,
1889
1992
  .detach_kernel_driver = darwin_detach_kernel_driver,
1890
1993
  .attach_kernel_driver = darwin_attach_kernel_driver,