libusb 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,