core: Kill the 'host_endian' argument for most functions
[platform/upstream/libusb.git] / libusb / os / darwin_usb.c
1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
2 /*
3  * darwin backend for libusb 1.0
4  * Copyright © 2008-2019 Nathan Hjelm <hjelmn@users.sourceforge.net>
5  * Copyright © 2019      Google LLC. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <config.h>
23 #include <assert.h>
24 #include <time.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #include <pthread.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/sysctl.h>
35
36 #include <mach/clock.h>
37 #include <mach/clock_types.h>
38 #include <mach/mach_host.h>
39 #include <mach/mach_port.h>
40
41 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
42  * function. Its use is also conditionalized to only older deployment targets. */
43 #define OBJC_SILENCE_GC_DEPRECATIONS 1
44
45 #include <AvailabilityMacros.h>
46 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
47   #include <objc/objc-auto.h>
48 #endif
49
50 #include "darwin_usb.h"
51
52 static pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
53 static int init_count = 0;
54
55 /* async event thread */
56 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
57 static pthread_cond_t  libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
58
59 #if !defined(HAVE_CLOCK_GETTIME)
60 static clock_serv_t clock_realtime;
61 static clock_serv_t clock_monotonic;
62 #endif
63
64 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
65
66 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
67 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
68
69 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
70 static struct list_head darwin_cached_devices;
71 static const char *darwin_device_class = kIOUSBDeviceClassName;
72
73 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
74
75 /* async event thread */
76 static pthread_t libusb_darwin_at;
77
78 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len);
79 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface);
80 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface);
81 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
82 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
83
84 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
85 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
86                                              UInt64 old_session_id);
87
88 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
89                                                   UInt64 *old_session_id);
90
91 #if defined(ENABLE_LOGGING)
92 static const char *darwin_error_str (IOReturn result) {
93   static char string_buffer[50];
94   switch (result) {
95   case kIOReturnSuccess:
96     return "no error";
97   case kIOReturnNotOpen:
98     return "device not opened for exclusive access";
99   case kIOReturnNoDevice:
100     return "no connection to an IOService";
101   case kIOUSBNoAsyncPortErr:
102     return "no async port has been opened for interface";
103   case kIOReturnExclusiveAccess:
104     return "another process has device opened for exclusive access";
105   case kIOUSBPipeStalled:
106     return "pipe is stalled";
107   case kIOReturnError:
108     return "could not establish a connection to the Darwin kernel";
109   case kIOUSBTransactionTimeout:
110     return "transaction timed out";
111   case kIOReturnBadArgument:
112     return "invalid argument";
113   case kIOReturnAborted:
114     return "transaction aborted";
115   case kIOReturnNotResponding:
116     return "device not responding";
117   case kIOReturnOverrun:
118     return "data overrun";
119   case kIOReturnCannotWire:
120     return "physical memory can not be wired down";
121   case kIOReturnNoResources:
122     return "out of resources";
123   case kIOUSBHighSpeedSplitError:
124     return "high speed split error";
125   default:
126     snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
127     return string_buffer;
128   }
129 }
130 #endif
131
132 static enum libusb_error darwin_to_libusb (IOReturn result) {
133   switch (result) {
134   case kIOReturnUnderrun:
135   case kIOReturnSuccess:
136     return LIBUSB_SUCCESS;
137   case kIOReturnNotOpen:
138   case kIOReturnNoDevice:
139     return LIBUSB_ERROR_NO_DEVICE;
140   case kIOReturnExclusiveAccess:
141     return LIBUSB_ERROR_ACCESS;
142   case kIOUSBPipeStalled:
143     return LIBUSB_ERROR_PIPE;
144   case kIOReturnBadArgument:
145     return LIBUSB_ERROR_INVALID_PARAM;
146   case kIOUSBTransactionTimeout:
147     return LIBUSB_ERROR_TIMEOUT;
148   case kIOReturnNotResponding:
149   case kIOReturnAborted:
150   case kIOReturnError:
151   case kIOUSBNoAsyncPortErr:
152   default:
153     return LIBUSB_ERROR_OTHER;
154   }
155 }
156
157 /* this function must be called with the darwin_cached_devices_lock held */
158 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
159   cached_dev->refcount--;
160   /* free the device and remove it from the cache */
161   if (0 == cached_dev->refcount) {
162     list_del(&cached_dev->list);
163
164     if (cached_dev->device) {
165       (*(cached_dev->device))->Release(cached_dev->device);
166       cached_dev->device = NULL;
167     }
168     free (cached_dev);
169   }
170 }
171
172 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
173   cached_dev->refcount++;
174 }
175
176 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) {
177   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
178
179   /* current interface */
180   struct darwin_interface *cInterface;
181
182   uint8_t i, iface;
183
184   usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
185
186   for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
187     cInterface = &priv->interfaces[iface];
188
189     if (dev_handle->claimed_interfaces & (1U << iface)) {
190       for (i = 0 ; i < cInterface->num_endpoints ; i++) {
191         if (cInterface->endpoint_addrs[i] == ep) {
192           *pipep = i + 1;
193
194           if (ifcp)
195             *ifcp = iface;
196
197           if (interface_out)
198             *interface_out = cInterface;
199
200           usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
201           return LIBUSB_SUCCESS;
202         }
203       }
204     }
205   }
206
207   /* No pipe found with the correct endpoint address */
208   usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
209
210   return LIBUSB_ERROR_NOT_FOUND;
211 }
212
213 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
214   CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
215
216   if (!matchingDict)
217     return kIOReturnError;
218
219   if (location) {
220     CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
221                                                                          &kCFTypeDictionaryKeyCallBacks,
222                                                                          &kCFTypeDictionaryValueCallBacks);
223
224     /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
225          internally (CFNumberType of locationID is kCFNumberSInt32Type) */
226     CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
227
228     if (propertyMatchDict && locationCF) {
229       CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
230       CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
231     }
232     /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
233
234     /* release our references as per the Create Rule */
235     if (propertyMatchDict)
236       CFRelease (propertyMatchDict);
237     if (locationCF)
238       CFRelease (locationCF);
239   }
240
241   return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
242 }
243
244 /* Returns 1 on success, 0 on failure. */
245 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
246   CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
247   Boolean success = 0;
248
249   if (cfNumber) {
250     if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
251       success = CFNumberGetValue(cfNumber, type, p);
252     }
253
254     CFRelease (cfNumber);
255   }
256
257   return (success != 0);
258 }
259
260 /* Returns 1 on success, 0 on failure. */
261 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
262   CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
263   bool success = false;
264
265   if (cfData) {
266     if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
267       CFIndex length = CFDataGetLength (cfData);
268       if (length < size) {
269         size = length;
270       }
271
272       CFDataGetBytes (cfData, CFRangeMake(0, size), p);
273       success = true;
274     }
275
276     CFRelease (cfData);
277   }
278
279   return success;
280 }
281
282 static usb_device_t **darwin_device_from_service (io_service_t service)
283 {
284   io_cf_plugin_ref_t *plugInInterface = NULL;
285   usb_device_t **device;
286   IOReturn kresult;
287   SInt32 score;
288   const int max_retries = 5;
289
290   /* The IOCreatePlugInInterfaceForService function might consistently return
291      an "out of resources" error with certain USB devices the first time we run 
292      it. The reason is still unclear, but retrying fixes the problem */
293   for (int count = 0; count < max_retries; count++) {
294     kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
295                                                 kIOCFPlugInInterfaceID, &plugInInterface,
296                                                 &score);
297     if (kIOReturnSuccess == kresult && plugInInterface) {
298       break;
299     }
300
301     usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
302
303     /* sleep for a little while before trying again */
304     nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
305   }
306
307   if (kIOReturnSuccess != kresult || !plugInInterface) {
308     usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
309     return NULL;
310   }
311
312   (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
313                                            (LPVOID)&device);
314   /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
315   (*plugInInterface)->Release (plugInInterface);
316
317   return device;
318 }
319
320 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
321   UNUSED(ptr);
322   struct darwin_cached_device *cached_device;
323   UInt64 old_session_id;
324   struct libusb_context *ctx;
325   io_service_t service;
326   int ret;
327
328   usbi_mutex_lock(&active_contexts_lock);
329
330   while ((service = IOIteratorNext(add_devices))) {
331     ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
332     if (ret < 0 || !cached_device->can_enumerate) {
333       continue;
334     }
335
336     /* add this device to each active context's device list */
337     list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
338       process_new_device (ctx, cached_device, old_session_id);
339     }
340
341     if (cached_device->in_reenumerate) {
342       usbi_dbg ("cached device in reset state. reset complete...");
343       cached_device->in_reenumerate = false;
344     }
345
346     IOObjectRelease(service);
347   }
348
349   usbi_mutex_unlock(&active_contexts_lock);
350 }
351
352 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
353   UNUSED(ptr);
354   struct libusb_device *dev = NULL;
355   struct libusb_context *ctx;
356   struct darwin_cached_device *old_device;
357
358   io_service_t device;
359   UInt64 session;
360   int ret;
361
362   usbi_mutex_lock(&active_contexts_lock);
363
364   while ((device = IOIteratorNext (rem_devices)) != 0) {
365     bool is_reenumerating = false;
366
367     /* get the location from the i/o registry */
368     ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
369     IOObjectRelease (device);
370     if (!ret)
371       continue;
372
373     /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
374        otherwise no cached device will ever get freed */
375     usbi_mutex_lock(&darwin_cached_devices_lock);
376     list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
377       if (old_device->session == session) {
378         if (old_device->in_reenumerate) {
379           /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
380            * will deref if needed. */
381           usbi_dbg ("detected device detatched due to re-enumeration");
382
383           /* the device object is no longer usable so go ahead and release it */
384           if (old_device->device) {
385             (*(old_device->device))->Release(old_device->device);
386             old_device->device = NULL;
387           }
388
389           is_reenumerating = true;
390         } else {
391           darwin_deref_cached_device (old_device);
392         }
393
394         break;
395       }
396     }
397
398     usbi_mutex_unlock(&darwin_cached_devices_lock);
399     if (is_reenumerating) {
400       continue;
401     }
402
403     list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
404       usbi_dbg ("notifying context %p of device disconnect", ctx);
405
406       dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
407       if (dev) {
408         /* signal the core that this device has been disconnected. the core will tear down this device
409            when the reference count reaches 0 */
410         usbi_disconnect_device(dev);
411         libusb_unref_device(dev);
412       }
413     }
414   }
415
416   usbi_mutex_unlock(&active_contexts_lock);
417 }
418
419 static void darwin_hotplug_poll (void)
420 {
421   /* not sure if 1 ms will be too long/short but it should work ok */
422   mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
423
424   /* since a kernel thread may notify the IOIterators used for
425    * hotplug notification we can't just clear the iterators.
426    * instead just wait until all IOService providers are quiet */
427   (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
428 }
429
430 static void darwin_clear_iterator (io_iterator_t iter) {
431   io_service_t device;
432
433   while ((device = IOIteratorNext (iter)) != 0)
434     IOObjectRelease (device);
435 }
436
437 static void darwin_fail_startup(void) {
438   pthread_mutex_lock (&libusb_darwin_at_mutex);
439   libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
440   pthread_cond_signal (&libusb_darwin_at_cond);
441   pthread_mutex_unlock (&libusb_darwin_at_mutex);
442   pthread_exit (NULL);
443 }
444
445 static void *darwin_event_thread_main (void *arg0) {
446   IOReturn kresult;
447   struct libusb_context *ctx = (struct libusb_context *)arg0;
448   CFRunLoopRef runloop;
449   CFRunLoopSourceRef libusb_shutdown_cfsource;
450   CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
451
452 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
453   /* Set this thread's name, so it can be seen in the debugger
454      and crash reports. */
455   pthread_setname_np ("org.libusb.device-hotplug");
456 #endif
457
458 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
459   /* Tell the Objective-C garbage collector about this thread.
460      This is required because, unlike NSThreads, pthreads are
461      not automatically registered. Although we don't use
462      Objective-C, we use CoreFoundation, which does.
463      Garbage collection support was entirely removed in 10.12,
464      so don't bother there. */
465   objc_registerThreadWithCollector();
466 #endif
467
468   /* hotplug (device arrival/removal) sources */
469   CFRunLoopSourceRef     libusb_notification_cfsource;
470   io_notification_port_t libusb_notification_port;
471   io_iterator_t          libusb_rem_device_iterator;
472   io_iterator_t          libusb_add_device_iterator;
473
474   usbi_dbg ("creating hotplug event source");
475
476   runloop = CFRunLoopGetCurrent ();
477   CFRetain (runloop);
478
479   /* add the shutdown cfsource to the run loop */
480   memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
481   libusb_shutdown_cfsourcectx.info = runloop;
482   libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
483   libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
484   CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
485
486   /* add the notification port to the run loop */
487   libusb_notification_port     = IONotificationPortCreate (kIOMasterPortDefault);
488   libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
489   CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
490
491   /* create notifications for removed devices */
492   kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
493                                               IOServiceMatching(darwin_device_class),
494                                               darwin_devices_detached,
495                                               ctx, &libusb_rem_device_iterator);
496
497   if (kresult != kIOReturnSuccess) {
498     usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
499     CFRelease (libusb_shutdown_cfsource);
500     CFRelease (runloop);
501     darwin_fail_startup ();
502   }
503
504   /* create notifications for attached devices */
505   kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
506                                               IOServiceMatching(darwin_device_class),
507                                               darwin_devices_attached,
508                                               ctx, &libusb_add_device_iterator);
509
510   if (kresult != kIOReturnSuccess) {
511     usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
512     CFRelease (libusb_shutdown_cfsource);
513     CFRelease (runloop);
514     darwin_fail_startup ();
515   }
516
517   /* arm notifiers */
518   darwin_clear_iterator (libusb_rem_device_iterator);
519   darwin_clear_iterator (libusb_add_device_iterator);
520
521   usbi_dbg ("darwin event thread ready to receive events");
522
523   /* signal the main thread that the hotplug runloop has been created. */
524   pthread_mutex_lock (&libusb_darwin_at_mutex);
525   libusb_darwin_acfl = runloop;
526   libusb_darwin_acfls = libusb_shutdown_cfsource;
527   pthread_cond_signal (&libusb_darwin_at_cond);
528   pthread_mutex_unlock (&libusb_darwin_at_mutex);
529
530   /* run the runloop */
531   CFRunLoopRun();
532
533   usbi_dbg ("darwin event thread exiting");
534
535   /* signal the main thread that the hotplug runloop has finished. */
536   pthread_mutex_lock (&libusb_darwin_at_mutex);
537   libusb_darwin_acfls = NULL;
538   libusb_darwin_acfl = NULL;
539   pthread_cond_signal (&libusb_darwin_at_cond);
540   pthread_mutex_unlock (&libusb_darwin_at_mutex);
541
542   /* remove the notification cfsource */
543   CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
544
545   /* remove the shutdown cfsource */
546   CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
547
548   /* delete notification port */
549   IONotificationPortDestroy (libusb_notification_port);
550
551   /* delete iterators */
552   IOObjectRelease (libusb_rem_device_iterator);
553   IOObjectRelease (libusb_add_device_iterator);
554
555   CFRelease (libusb_shutdown_cfsource);
556   CFRelease (runloop);
557
558   pthread_exit (NULL);
559 }
560
561 /* cleanup function to destroy cached devices */
562 static void darwin_cleanup_devices(void) {
563   struct darwin_cached_device *dev, *next;
564
565   list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
566     darwin_deref_cached_device(dev);
567   }
568
569   darwin_cached_devices.prev = darwin_cached_devices.next = NULL;
570 }
571
572 static int darwin_init(struct libusb_context *ctx) {
573   bool first_init;
574   int rc;
575
576   pthread_mutex_lock (&libusb_darwin_init_mutex);
577
578   first_init = (1 == ++init_count);
579
580   do {
581     if (first_init) {
582       assert (NULL == darwin_cached_devices.next);
583       list_init (&darwin_cached_devices);
584
585 #if !defined(HAVE_CLOCK_GETTIME)
586       /* create the clocks that will be used if clock_gettime() is not available */
587       host_name_port_t host_self;
588
589       host_self = mach_host_self();
590       host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
591       host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
592       mach_port_deallocate(mach_task_self(), host_self);
593 #endif
594     }
595
596     rc = darwin_scan_devices (ctx);
597     if (LIBUSB_SUCCESS != rc)
598       break;
599
600     if (first_init) {
601       rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
602       if (0 != rc) {
603         usbi_err (ctx, "could not create event thread, error %d", rc);
604         rc = LIBUSB_ERROR_OTHER;
605         break;
606       }
607
608       pthread_mutex_lock (&libusb_darwin_at_mutex);
609       while (!libusb_darwin_acfl)
610         pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
611       if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
612         libusb_darwin_acfl = NULL;
613         rc = LIBUSB_ERROR_OTHER;
614       }
615       pthread_mutex_unlock (&libusb_darwin_at_mutex);
616
617       if (0 != rc)
618         pthread_join (libusb_darwin_at, NULL);
619     }
620   } while (0);
621
622   if (LIBUSB_SUCCESS != rc) {
623     if (first_init) {
624       darwin_cleanup_devices ();
625 #if !defined(HAVE_CLOCK_GETTIME)
626       mach_port_deallocate(mach_task_self(), clock_realtime);
627       mach_port_deallocate(mach_task_self(), clock_monotonic);
628 #endif
629     }
630     --init_count;
631   }
632
633   pthread_mutex_unlock (&libusb_darwin_init_mutex);
634
635   return rc;
636 }
637
638 static void darwin_exit (struct libusb_context *ctx) {
639   UNUSED(ctx);
640
641   pthread_mutex_lock (&libusb_darwin_init_mutex);
642
643   if (0 == --init_count) {
644     /* stop the event runloop and wait for the thread to terminate. */
645     pthread_mutex_lock (&libusb_darwin_at_mutex);
646     CFRunLoopSourceSignal (libusb_darwin_acfls);
647     CFRunLoopWakeUp (libusb_darwin_acfl);
648     while (libusb_darwin_acfl)
649       pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
650     pthread_mutex_unlock (&libusb_darwin_at_mutex);
651     pthread_join (libusb_darwin_at, NULL);
652
653     darwin_cleanup_devices ();
654
655 #if !defined(HAVE_CLOCK_GETTIME)
656     mach_port_deallocate(mach_task_self(), clock_realtime);
657     mach_port_deallocate(mach_task_self(), clock_monotonic);
658 #endif
659   }
660
661   pthread_mutex_unlock (&libusb_darwin_init_mutex);
662 }
663
664 static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
665   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
666
667   /* return cached copy */
668   memmove (buffer, &(priv->dev_descriptor), LIBUSB_DT_DEVICE_SIZE);
669
670   return LIBUSB_SUCCESS;
671 }
672
673 static int get_configuration_index (struct libusb_device *dev, int config_value) {
674   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
675   UInt8 i, numConfig;
676   IOUSBConfigurationDescriptorPtr desc;
677   IOReturn kresult;
678
679   /* is there a simpler way to determine the index? */
680   kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
681   if (kresult != kIOReturnSuccess)
682     return darwin_to_libusb (kresult);
683
684   for (i = 0 ; i < numConfig ; i++) {
685     (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
686
687     if (desc->bConfigurationValue == config_value)
688       return i;
689   }
690
691   /* configuration not found */
692   return LIBUSB_ERROR_NOT_FOUND;
693 }
694
695 static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len) {
696   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
697   int config_index;
698
699   if (0 == priv->active_config)
700     return LIBUSB_ERROR_NOT_FOUND;
701
702   config_index = get_configuration_index (dev, priv->active_config);
703   if (config_index < 0)
704     return config_index;
705
706   assert(config_index >= 0 && config_index <= UINT8_MAX);
707   return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
708 }
709
710 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len) {
711   struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
712   IOUSBConfigurationDescriptorPtr desc;
713   IOReturn kresult;
714   int ret;
715
716   if (!priv || !priv->device)
717     return LIBUSB_ERROR_OTHER;
718
719   kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
720   if (kresult == kIOReturnSuccess) {
721     /* copy descriptor */
722     if (libusb_le16_to_cpu(desc->wTotalLength) < len)
723       len = libusb_le16_to_cpu(desc->wTotalLength);
724
725     memmove (buffer, desc, len);
726   }
727
728   ret = darwin_to_libusb (kresult);
729   if (ret != LIBUSB_SUCCESS)
730     return ret;
731
732   return (int) len;
733 }
734
735 /* check whether the os has configured the device */
736 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
737   usb_device_t **darwin_device = dev->device;
738
739   IOUSBConfigurationDescriptorPtr configDesc;
740   IOUSBFindInterfaceRequest request;
741   IOReturn                  kresult;
742   io_iterator_t             interface_iterator;
743   io_service_t              firstInterface;
744
745   if (dev->dev_descriptor.bNumConfigurations < 1) {
746     usbi_err (ctx, "device has no configurations");
747     return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
748   }
749
750   /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
751      not usable anyway */
752   if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) {
753     usbi_dbg ("ignoring configuration on root hub simulation");
754     dev->active_config = 0;
755     return LIBUSB_SUCCESS;
756   }
757
758   /* find the first configuration */
759   kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
760   dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
761
762   /* check if the device is already configured. there is probably a better way than iterating over the
763      to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
764      might lock up on the device request) */
765
766   /* Setup the Interface Request */
767   request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
768   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
769   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
770   request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;
771
772   kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
773   if (kresult != kIOReturnSuccess)
774     return darwin_to_libusb (kresult);
775
776   /* iterate once */
777   firstInterface = IOIteratorNext(interface_iterator);
778
779   /* done with the interface iterator */
780   IOObjectRelease(interface_iterator);
781
782   if (firstInterface) {
783     IOObjectRelease (firstInterface);
784
785     /* device is configured */
786     if (dev->dev_descriptor.bNumConfigurations == 1)
787       /* to avoid problems with some devices get the configurations value from the configuration descriptor */
788       dev->active_config = dev->first_config;
789     else
790       /* devices with more than one configuration should work with GetConfiguration */
791       (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
792   } else
793     /* not configured */
794     dev->active_config = 0;
795   
796   usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
797
798   return LIBUSB_SUCCESS;
799 }
800
801 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
802   IOUSBDevRequestTO req;
803
804   assert(buffer_size <= UINT16_MAX);
805
806   memset (buffer, 0, buffer_size);
807
808   /* Set up request for descriptor/ */
809   req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
810   req.bRequest      = kUSBRqGetDescriptor;
811   req.wValue        = (UInt16)(desc << 8);
812   req.wIndex        = desc_index;
813   req.wLength       = (UInt16)buffer_size;
814   req.pData         = buffer;
815   req.noDataTimeout = 20;
816   req.completionTimeout = 100;
817
818   return (*device)->DeviceRequestTO (device, &req);
819 }
820
821 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
822   usb_device_t **device = dev->device;
823   int retries = 1;
824   long delay = 30000; // microseconds
825   int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
826   int is_open = 0;
827   IOReturn ret = 0, ret2;
828   UInt8 bDeviceClass;
829   UInt16 idProduct, idVendor;
830
831   dev->can_enumerate = 0;
832
833   (*device)->GetDeviceClass (device, &bDeviceClass);
834   (*device)->GetDeviceProduct (device, &idProduct);
835   (*device)->GetDeviceVendor (device, &idVendor);
836
837   /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
838    * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request.  Still,
839    * to follow the spec as closely as possible, try opening the device */
840   is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
841
842   do {
843     /**** retrieve device descriptor ****/
844     ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
845
846     if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
847       /* received an overrun error but we still received a device descriptor */
848       ret = kIOReturnSuccess;
849
850     if (kIOUSBVendorIDAppleComputer == idVendor) {
851       /* NTH: don't bother retrying or unsuspending Apple devices */
852       break;
853     }
854
855     if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
856                                     0 == dev->dev_descriptor.bcdUSB)) {
857       /* work around for incorrectly configured devices */
858       if (try_reconfigure && is_open) {
859         usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
860
861         /* set the first configuration */
862         (*device)->SetConfiguration(device, 1);
863
864         /* don't try to reconfigure again */
865         try_reconfigure = 0;
866       }
867
868       ret = kIOUSBPipeStalled;
869     }
870
871     if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
872       /* device may be suspended. unsuspend it and try again */
873 #if DeviceVersion >= 320
874       UInt32 info = 0;
875
876       /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
877       (void)(*device)->GetUSBDeviceInformation (device, &info);
878
879       /* note that the device was suspended */
880       if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
881         try_unsuspend = 1;
882 #endif
883
884       if (try_unsuspend) {
885         /* try to unsuspend the device */
886         ret2 = (*device)->USBDeviceSuspend (device, 0);
887         if (kIOReturnSuccess != ret2) {
888           /* prevent log spew from poorly behaving devices.  this indicates the
889              os actually had trouble communicating with the device */
890           usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
891         } else
892           unsuspended = 1;
893
894         try_unsuspend = 0;
895       }
896     }
897
898     if (kIOReturnSuccess != ret) {
899       usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
900       /* sleep for a little while before trying again */
901       nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
902     }
903   } while (kIOReturnSuccess != ret && retries--);
904
905   if (unsuspended)
906     /* resuspend the device */
907     (void)(*device)->USBDeviceSuspend (device, 1);
908
909   if (is_open)
910     (void) (*device)->USBDeviceClose (device);
911
912   if (ret != kIOReturnSuccess) {
913     /* a debug message was already printed out for this error */
914     if (LIBUSB_CLASS_HUB == bDeviceClass)
915       usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
916                 idVendor, idProduct, darwin_error_str (ret), ret);
917     else
918       usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
919                  idVendor, idProduct, darwin_error_str (ret), ret);
920     return darwin_to_libusb (ret);
921   }
922
923   /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
924   if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
925     /* not a valid device */
926     usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
927                idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
928     return LIBUSB_ERROR_NO_DEVICE;
929   }
930
931   usbi_dbg ("cached device descriptor:");
932   usbi_dbg ("  bDescriptorType:    0x%02x", dev->dev_descriptor.bDescriptorType);
933   usbi_dbg ("  bcdUSB:             0x%04x", dev->dev_descriptor.bcdUSB);
934   usbi_dbg ("  bDeviceClass:       0x%02x", dev->dev_descriptor.bDeviceClass);
935   usbi_dbg ("  bDeviceSubClass:    0x%02x", dev->dev_descriptor.bDeviceSubClass);
936   usbi_dbg ("  bDeviceProtocol:    0x%02x", dev->dev_descriptor.bDeviceProtocol);
937   usbi_dbg ("  bMaxPacketSize0:    0x%02x", dev->dev_descriptor.bMaxPacketSize0);
938   usbi_dbg ("  idVendor:           0x%04x", dev->dev_descriptor.idVendor);
939   usbi_dbg ("  idProduct:          0x%04x", dev->dev_descriptor.idProduct);
940   usbi_dbg ("  bcdDevice:          0x%04x", dev->dev_descriptor.bcdDevice);
941   usbi_dbg ("  iManufacturer:      0x%02x", dev->dev_descriptor.iManufacturer);
942   usbi_dbg ("  iProduct:           0x%02x", dev->dev_descriptor.iProduct);
943   usbi_dbg ("  iSerialNumber:      0x%02x", dev->dev_descriptor.iSerialNumber);
944   usbi_dbg ("  bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
945
946   dev->can_enumerate = 1;
947
948   return LIBUSB_SUCCESS;
949 }
950
951 /* Returns 1 on success, 0 on failure. */
952 static bool get_device_port (io_service_t service, UInt8 *port) {
953   IOReturn kresult;
954   io_service_t parent;
955   bool ret = false;
956
957   if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
958     return true;
959   }
960
961   kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
962   if (kIOReturnSuccess == kresult) {
963     ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
964     IOObjectRelease (parent);
965   }
966
967   return ret;
968 }
969
970 /* Returns 1 on success, 0 on failure. */
971 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
972   IOReturn kresult;
973   io_service_t parent;
974
975   /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
976   parent = service;
977   while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
978     if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
979         /* Success */
980         return true;
981     }
982   }
983
984   /* We ran out of parents */
985   return false;
986 }
987
988 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
989                                                   UInt64 *old_session_id) {
990   struct darwin_cached_device *new_device;
991   UInt64 sessionID = 0, parent_sessionID = 0;
992   UInt32 locationID = 0;
993   enum libusb_error ret = LIBUSB_SUCCESS;
994   usb_device_t **device;
995   UInt8 port = 0;
996
997   /* assuming sessionID != 0 normally (never seen it be 0) */
998   *old_session_id = 0;
999   *cached_out = NULL;
1000
1001   /* get some info from the io registry */
1002   (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1003   (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1004   if (!get_device_port (service, &port)) {
1005     usbi_dbg("could not get connected port number");
1006   }
1007
1008   usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1009
1010   if (get_device_parent_sessionID(service, &parent_sessionID)) {
1011     usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1012   }
1013
1014   usbi_mutex_lock(&darwin_cached_devices_lock);
1015   do {
1016     list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1017       usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1018                sessionID, locationID, new_device->session, new_device->location);
1019       if (new_device->location == locationID && new_device->in_reenumerate) {
1020         usbi_dbg ("found cached device with matching location that is being re-enumerated");
1021         *old_session_id = new_device->session;
1022         break;
1023       }
1024
1025       if (new_device->session == sessionID) {
1026         usbi_dbg("using cached device for device");
1027         *cached_out = new_device;
1028         break;
1029       }
1030     }
1031
1032     if (*cached_out)
1033       break;
1034
1035     usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1036
1037     device = darwin_device_from_service (service);
1038     if (!device) {
1039       ret = LIBUSB_ERROR_NO_DEVICE;
1040       break;
1041     }
1042
1043     if (!(*old_session_id)) {
1044       new_device = calloc (1, sizeof (*new_device));
1045       if (!new_device) {
1046         ret = LIBUSB_ERROR_NO_MEM;
1047         break;
1048       }
1049
1050       /* add this device to the cached device list */
1051       list_add(&new_device->list, &darwin_cached_devices);
1052
1053       (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1054
1055       /* keep a reference to this device */
1056       darwin_ref_cached_device(new_device);
1057
1058       (*device)->GetLocationID (device, &new_device->location);
1059       new_device->port = port;
1060       new_device->parent_session = parent_sessionID;
1061     }
1062
1063     /* keep track of devices regardless of if we successfully enumerate them to
1064        prevent them from being enumerated multiple times */
1065     *cached_out = new_device;
1066
1067     new_device->session = sessionID;
1068     new_device->device = device;
1069
1070     /* cache the device descriptor */
1071     ret = darwin_cache_device_descriptor(new_device);
1072     if (ret)
1073       break;
1074
1075     if (new_device->can_enumerate) {
1076       snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1077                new_device->dev_descriptor.idVendor, new_device->dev_descriptor.idProduct,
1078                new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1079     }
1080   } while (0);
1081
1082   usbi_mutex_unlock(&darwin_cached_devices_lock);
1083
1084   return ret;
1085 }
1086
1087 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1088                                              UInt64 old_session_id) {
1089   struct darwin_device_priv *priv;
1090   struct libusb_device *dev = NULL;
1091   UInt8 devSpeed;
1092   enum libusb_error ret = LIBUSB_SUCCESS;
1093
1094   do {
1095     /* check current active configuration (and cache the first configuration value--
1096        which may be used by claim_interface) */
1097     ret = darwin_check_configuration (ctx, cached_device);
1098     if (ret)
1099       break;
1100
1101     if (0 != old_session_id) {
1102       usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1103                 ctx, old_session_id, cached_device->session);
1104       /* save the libusb device before the session id is updated */
1105       dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1106     }
1107
1108     if (!dev) {
1109       usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1110                 ctx, cached_device->session);
1111
1112       dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1113       if (!dev) {
1114         return LIBUSB_ERROR_NO_MEM;
1115       }
1116
1117       priv = usbi_get_device_priv(dev);
1118
1119       priv->dev = cached_device;
1120       darwin_ref_cached_device (priv->dev);
1121       dev->port_number    = cached_device->port;
1122       dev->bus_number     = cached_device->location >> 24;
1123       assert(cached_device->address <= UINT8_MAX);
1124       dev->device_address = (uint8_t)cached_device->address;
1125     } else {
1126       priv = usbi_get_device_priv(dev);
1127     }
1128
1129     if (cached_device->parent_session > 0) {
1130       dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1131     } else {
1132       dev->parent_dev = NULL;
1133     }
1134
1135     (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1136
1137     switch (devSpeed) {
1138     case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1139     case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1140     case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1141 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1142     case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1143 #endif
1144 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1145     case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1146 #endif
1147     default:
1148       usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1149     }
1150
1151     ret = usbi_sanitize_device (dev);
1152     if (ret < 0)
1153       break;
1154
1155     usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1156               dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1157
1158   } while (0);
1159
1160   if (!cached_device->in_reenumerate && 0 == ret) {
1161     usbi_connect_device (dev);
1162   } else {
1163     libusb_unref_device (dev);
1164   }
1165
1166   return ret;
1167 }
1168
1169 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1170   struct darwin_cached_device *cached_device;
1171   UInt64 old_session_id;
1172   io_iterator_t deviceIterator;
1173   io_service_t service;
1174   IOReturn kresult;
1175   int ret;
1176
1177   kresult = usb_setup_device_iterator (&deviceIterator, 0);
1178   if (kresult != kIOReturnSuccess)
1179     return darwin_to_libusb (kresult);
1180
1181   while ((service = IOIteratorNext (deviceIterator))) {
1182     ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1183     if (ret < 0 || !cached_device->can_enumerate) {
1184       continue;
1185     }
1186
1187     (void) process_new_device (ctx, cached_device, old_session_id);
1188
1189     IOObjectRelease(service);
1190   }
1191
1192   IOObjectRelease(deviceIterator);
1193
1194   return LIBUSB_SUCCESS;
1195 }
1196
1197 static int darwin_open (struct libusb_device_handle *dev_handle) {
1198   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1199   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1200   IOReturn kresult;
1201
1202   if (0 == dpriv->open_count) {
1203     /* try to open the device */
1204     kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1205     if (kresult != kIOReturnSuccess) {
1206       usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1207
1208       if (kIOReturnExclusiveAccess != kresult) {
1209         return darwin_to_libusb (kresult);
1210       }
1211
1212       /* it is possible to perform some actions on a device that is not open so do not return an error */
1213       priv->is_open = false;
1214     } else {
1215       priv->is_open = true;
1216     }
1217
1218     /* create async event source */
1219     kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1220     if (kresult != kIOReturnSuccess) {
1221       usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1222
1223       if (priv->is_open) {
1224         (*(dpriv->device))->USBDeviceClose (dpriv->device);
1225       }
1226
1227       priv->is_open = false;
1228
1229       return darwin_to_libusb (kresult);
1230     }
1231
1232     CFRetain (libusb_darwin_acfl);
1233
1234     /* add the cfSource to the aync run loop */
1235     CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1236   }
1237
1238   /* device opened successfully */
1239   dpriv->open_count++;
1240
1241   usbi_dbg ("device open for access");
1242
1243   return 0;
1244 }
1245
1246 static void darwin_close (struct libusb_device_handle *dev_handle) {
1247   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1248   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1249   IOReturn kresult;
1250   int i;
1251
1252   if (dpriv->open_count == 0) {
1253     /* something is probably very wrong if this is the case */
1254     usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1255     return;
1256   }
1257
1258   dpriv->open_count--;
1259
1260   /* make sure all interfaces are released */
1261   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1262     if (dev_handle->claimed_interfaces & (1U << i))
1263       libusb_release_interface (dev_handle, i);
1264
1265   if (0 == dpriv->open_count) {
1266     /* delete the device's async event source */
1267     if (priv->cfSource) {
1268       CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1269       CFRelease (priv->cfSource);
1270       priv->cfSource = NULL;
1271       CFRelease (libusb_darwin_acfl);
1272     }
1273
1274     if (priv->is_open) {
1275       /* close the device */
1276       kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1277       if (kresult != kIOReturnSuccess) {
1278         /* Log the fact that we had a problem closing the file, however failing a
1279          * close isn't really an error, so return success anyway */
1280         usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1281       }
1282     }
1283   }
1284 }
1285
1286 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
1287   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1288
1289   *config = (int) dpriv->active_config;
1290
1291   return LIBUSB_SUCCESS;
1292 }
1293
1294 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1295   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1296   IOReturn kresult;
1297   int i;
1298
1299   assert(config >= 0 && config <= UINT8_MAX);
1300
1301   /* Setting configuration will invalidate the interface, so we need
1302      to reclaim it. First, dispose of existing interfaces, if any. */
1303   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1304     if (dev_handle->claimed_interfaces & (1U << i))
1305       darwin_release_interface (dev_handle, i);
1306
1307   kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1308   if (kresult != kIOReturnSuccess)
1309     return darwin_to_libusb (kresult);
1310
1311   /* Reclaim any interfaces. */
1312   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1313     if (dev_handle->claimed_interfaces & (1U << i))
1314       darwin_claim_interface (dev_handle, i);
1315
1316   dpriv->active_config = (UInt8)config;
1317
1318   return LIBUSB_SUCCESS;
1319 }
1320
1321 static IOReturn darwin_get_interface (usb_device_t **darwin_device, int ifc, io_service_t *usbInterfacep) {
1322   IOUSBFindInterfaceRequest request;
1323   IOReturn                  kresult;
1324   io_iterator_t             interface_iterator;
1325   UInt8                     bInterfaceNumber;
1326   bool                      ret;
1327
1328   *usbInterfacep = IO_OBJECT_NULL;
1329
1330   /* Setup the Interface Request */
1331   request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
1332   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1333   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1334   request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;
1335
1336   kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1337   if (kresult != kIOReturnSuccess)
1338     return kresult;
1339
1340   while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1341     /* find the interface number */
1342     ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1343                                        &bInterfaceNumber);
1344
1345     if (ret && bInterfaceNumber == ifc) {
1346       break;
1347     }
1348
1349     (void) IOObjectRelease (*usbInterfacep);
1350   }
1351
1352   /* done with the interface iterator */
1353   IOObjectRelease(interface_iterator);
1354
1355   return kIOReturnSuccess;
1356 }
1357
1358 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1359   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1360
1361   /* current interface */
1362   struct darwin_interface *cInterface = &priv->interfaces[iface];
1363
1364   IOReturn kresult;
1365
1366   UInt8 numep, direction, number;
1367   UInt8 dont_care1, dont_care3;
1368   UInt16 dont_care2;
1369   int rc;
1370
1371   usbi_dbg ("building table of endpoints.");
1372
1373   /* retrieve the total number of endpoints on this interface */
1374   kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1375   if (kresult != kIOReturnSuccess) {
1376     usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1377     return darwin_to_libusb (kresult);
1378   }
1379
1380   /* iterate through pipe references */
1381   for (UInt8 i = 1 ; i <= numep ; i++) {
1382     kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1383                                                             &dont_care2, &dont_care3);
1384
1385     if (kresult != kIOReturnSuccess) {
1386       /* probably a buggy device. try to get the endpoint address from the descriptors */
1387       struct libusb_config_descriptor *config;
1388       const struct libusb_endpoint_descriptor *endpoint_desc;
1389       UInt8 alt_setting;
1390
1391       kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1392       if (kresult != kIOReturnSuccess) {
1393         usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1394         return darwin_to_libusb (kresult);
1395       }
1396
1397       rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1398       if (LIBUSB_SUCCESS != rc) {
1399         return rc;
1400       }
1401
1402       endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1403
1404       cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1405     } else {
1406       cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1407     }
1408
1409     usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1410               cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1411   }
1412
1413   cInterface->num_endpoints = numep;
1414
1415   return LIBUSB_SUCCESS;
1416 }
1417
1418 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
1419   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1420   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1421   io_service_t          usbInterface = IO_OBJECT_NULL;
1422   IOReturn              kresult;
1423   enum libusb_error     ret;
1424   IOCFPlugInInterface **plugInInterface = NULL;
1425   SInt32                score;
1426
1427   assert(iface >= 0 && iface <= UINT8_MAX);
1428
1429   /* current interface */
1430   struct darwin_interface *cInterface = &priv->interfaces[iface];
1431
1432   kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1433   if (kresult != kIOReturnSuccess)
1434     return darwin_to_libusb (kresult);
1435
1436   /* make sure we have an interface */
1437   if (!usbInterface && dpriv->first_config != 0) {
1438     usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1439
1440     /* set the configuration */
1441     ret = darwin_set_configuration (dev_handle, dpriv->first_config);
1442     if (ret != LIBUSB_SUCCESS) {
1443       usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1444       return ret;
1445     }
1446
1447     kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1448     if (kresult != kIOReturnSuccess) {
1449       usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1450       return darwin_to_libusb (kresult);
1451     }
1452   }
1453
1454   if (!usbInterface) {
1455     usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1456     return LIBUSB_ERROR_NOT_FOUND;
1457   }
1458
1459   /* get an interface to the device's interface */
1460   kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1461                                                kIOCFPlugInInterfaceID, &plugInInterface, &score);
1462
1463   /* ignore release error */
1464   (void)IOObjectRelease (usbInterface);
1465
1466   if (kresult != kIOReturnSuccess) {
1467     usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1468     return darwin_to_libusb (kresult);
1469   }
1470
1471   if (!plugInInterface) {
1472     usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1473     return LIBUSB_ERROR_NOT_FOUND;
1474   }
1475
1476   /* Do the actual claim */
1477   kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1478                                                CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1479                                                (LPVOID)&cInterface->interface);
1480   /* We no longer need the intermediate plug-in */
1481   /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1482   (*plugInInterface)->Release (plugInInterface);
1483   if (kresult != kIOReturnSuccess || !cInterface->interface) {
1484     usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1485     return darwin_to_libusb (kresult);
1486   }
1487
1488   /* claim the interface */
1489   kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1490   if (kresult != kIOReturnSuccess) {
1491     usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1492     return darwin_to_libusb (kresult);
1493   }
1494
1495   /* update list of endpoints */
1496   ret = get_endpoints (dev_handle, iface);
1497   if (ret) {
1498     /* this should not happen */
1499     darwin_release_interface (dev_handle, iface);
1500     usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1501     return ret;
1502   }
1503
1504   cInterface->cfSource = NULL;
1505
1506   /* create async event source */
1507   kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1508   if (kresult != kIOReturnSuccess) {
1509     usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1510
1511     /* can't continue without an async event source */
1512     (void)darwin_release_interface (dev_handle, iface);
1513
1514     return darwin_to_libusb (kresult);
1515   }
1516
1517   /* add the cfSource to the async thread's run loop */
1518   CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1519
1520   usbi_dbg ("interface opened");
1521
1522   return LIBUSB_SUCCESS;
1523 }
1524
1525 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
1526   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1527   IOReturn kresult;
1528
1529   /* current interface */
1530   struct darwin_interface *cInterface = &priv->interfaces[iface];
1531
1532   /* Check to see if an interface is open */
1533   if (!cInterface->interface)
1534     return LIBUSB_SUCCESS;
1535
1536   /* clean up endpoint data */
1537   cInterface->num_endpoints = 0;
1538
1539   /* delete the interface's async event source */
1540   if (cInterface->cfSource) {
1541     CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1542     CFRelease (cInterface->cfSource);
1543   }
1544
1545   kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1546   if (kresult != kIOReturnSuccess)
1547     usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1548
1549   kresult = (*(cInterface->interface))->Release(cInterface->interface);
1550   if (kresult != kIOReturnSuccess)
1551     usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1552
1553   cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1554
1555   return darwin_to_libusb (kresult);
1556 }
1557
1558 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
1559   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1560   IOReturn kresult;
1561   enum libusb_error ret;
1562
1563   /* current interface */
1564   struct darwin_interface *cInterface = &priv->interfaces[iface];
1565
1566   if (!cInterface->interface)
1567     return LIBUSB_ERROR_NO_DEVICE;
1568
1569   assert(altsetting >= 0 && altsetting <= UINT8_MAX);
1570   kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, (UInt8)altsetting);
1571   if (kresult != kIOReturnSuccess)
1572     darwin_reset_device (dev_handle);
1573
1574   /* update list of endpoints */
1575   ret = get_endpoints (dev_handle, iface);
1576   if (ret) {
1577     /* this should not happen */
1578     darwin_release_interface (dev_handle, iface);
1579     usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1580     return ret;
1581   }
1582
1583   return darwin_to_libusb (kresult);
1584 }
1585
1586 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1587   /* current interface */
1588   struct darwin_interface *cInterface;
1589   IOReturn kresult;
1590   uint8_t pipeRef;
1591
1592   /* determine the interface/endpoint to use */
1593   if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1594     usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1595
1596     return LIBUSB_ERROR_NOT_FOUND;
1597   }
1598
1599   /* newer versions of darwin support clearing additional bits on the device's endpoint */
1600   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1601   if (kresult != kIOReturnSuccess)
1602     usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1603
1604   return darwin_to_libusb (kresult);
1605 }
1606
1607 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1608                                  unsigned long claimed_interfaces) {
1609   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1610   struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1611   int open_count = dpriv->open_count;
1612   int ret;
1613
1614   /* clear claimed interfaces temporarily */
1615   dev_handle->claimed_interfaces = 0;
1616
1617   /* close and re-open the device */
1618   priv->is_open = false;
1619   dpriv->open_count = 1;
1620
1621   /* clean up open interfaces */
1622   (void) darwin_close (dev_handle);
1623
1624   /* re-open the device */
1625   ret = darwin_open (dev_handle);
1626   dpriv->open_count = open_count;
1627   if (LIBUSB_SUCCESS != ret) {
1628     /* could not restore configuration */
1629     return LIBUSB_ERROR_NOT_FOUND;
1630   }
1631
1632   if (dpriv->active_config != active_config) {
1633     usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1634
1635     ret = darwin_set_configuration (dev_handle, active_config);
1636     if (LIBUSB_SUCCESS != ret) {
1637       usbi_dbg ("darwin/restore_state: could not restore configuration");
1638       return LIBUSB_ERROR_NOT_FOUND;
1639     }
1640   }
1641
1642   usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1643
1644   if (claimed_interfaces) {
1645     for (int iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1646       if (!(claimed_interfaces & (1U << iface))) {
1647         continue;
1648       }
1649
1650       usbi_dbg ("darwin/restore_state: re-claiming interface %d", iface);
1651
1652       ret = darwin_claim_interface (dev_handle, iface);
1653       if (LIBUSB_SUCCESS != ret) {
1654         usbi_dbg ("darwin/restore_state: could not claim interface %d", iface);
1655         return LIBUSB_ERROR_NOT_FOUND;
1656       }
1657
1658       dev_handle->claimed_interfaces |= 1U << iface;
1659     }
1660   }
1661
1662   usbi_dbg ("darwin/restore_state: device state restored");
1663
1664   return LIBUSB_SUCCESS;
1665 }
1666
1667 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1668   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1669   unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1670   int8_t active_config = dpriv->active_config;
1671   IOUSBDeviceDescriptor descriptor;
1672   IOUSBConfigurationDescriptorPtr cached_configuration;
1673   IOUSBConfigurationDescriptor *cached_configurations;
1674   IOReturn kresult;
1675   UInt8 i;
1676
1677   if (dpriv->in_reenumerate) {
1678     /* ack, two (or more) threads are trying to reset the device! abort! */
1679     return LIBUSB_ERROR_NOT_FOUND;
1680   }
1681
1682   dpriv->in_reenumerate = true;
1683
1684   /* store copies of descriptors so they can be compared after the reset */
1685   memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1686   cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1687
1688   for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1689     (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1690     memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1691   }
1692
1693   /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1694   kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1695   if (kresult != kIOReturnSuccess) {
1696     usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1697     dpriv->in_reenumerate = false;
1698     return darwin_to_libusb (kresult);
1699   }
1700
1701   usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1702
1703   while (dpriv->in_reenumerate) {
1704     struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1705     nanosleep (&delay, NULL);
1706   }
1707
1708   /* compare descriptors */
1709   usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1710
1711   if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1712     /* device descriptor changed. need to return not found. */
1713     usbi_dbg ("darwin/reset_device: device descriptor changed");
1714     return LIBUSB_ERROR_NOT_FOUND;
1715   }
1716
1717   for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1718     (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1719     if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1720       usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1721       return LIBUSB_ERROR_NOT_FOUND;
1722     }
1723   }
1724
1725   usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1726
1727   return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1728 }
1729
1730 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
1731   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1732   io_service_t usbInterface;
1733   CFTypeRef driver;
1734   IOReturn kresult;
1735
1736   assert(interface >= 0 && interface <= UINT8_MAX);
1737   kresult = darwin_get_interface (dpriv->device, (uint8_t)interface, &usbInterface);
1738   if (kresult != kIOReturnSuccess) {
1739     usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1740
1741     return darwin_to_libusb (kresult);
1742   }
1743
1744   driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1745   IOObjectRelease (usbInterface);
1746
1747   if (driver) {
1748     CFRelease (driver);
1749
1750     return 1;
1751   }
1752
1753   /* no driver */
1754   return 0;
1755 }
1756
1757 static void darwin_destroy_device(struct libusb_device *dev) {
1758   struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1759
1760   if (dpriv->dev) {
1761     /* need to hold the lock in case this is the last reference to the device */
1762     usbi_mutex_lock(&darwin_cached_devices_lock);
1763     darwin_deref_cached_device (dpriv->dev);
1764     dpriv->dev = NULL;
1765     usbi_mutex_unlock(&darwin_cached_devices_lock);
1766   }
1767 }
1768
1769 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1770   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1771
1772   IOReturn               ret;
1773   uint8_t                transferType;
1774   /* None of the values below are used in libusbx for bulk transfers */
1775   uint8_t                direction, number, interval, pipeRef;
1776   uint16_t               maxPacketSize;
1777
1778   struct darwin_interface *cInterface;
1779
1780   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1781     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1782
1783     return LIBUSB_ERROR_NOT_FOUND;
1784   }
1785
1786   ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1787                                                        &transferType, &maxPacketSize, &interval);
1788
1789   if (ret) {
1790     usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1791               darwin_error_str(ret), ret);
1792     return darwin_to_libusb (ret);
1793   }
1794
1795   if (0 != (transfer->length % maxPacketSize)) {
1796     /* do not need a zero packet */
1797     transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1798   }
1799
1800   /* submit the request */
1801   /* timeouts are unavailable on interrupt endpoints */
1802   if (transferType == kUSBInterrupt) {
1803     if (IS_XFERIN(transfer))
1804       ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1805                                                       (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1806     else
1807       ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1808                                                        (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1809   } else {
1810     itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1811
1812     if (IS_XFERIN(transfer))
1813       ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1814                                                         (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1815                                                         darwin_async_io_callback, itransfer);
1816     else
1817       ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1818                                                          (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1819                                                          darwin_async_io_callback, itransfer);
1820   }
1821
1822   if (ret)
1823     usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1824                darwin_error_str(ret), ret);
1825
1826   return darwin_to_libusb (ret);
1827 }
1828
1829 #if InterfaceVersion >= 550
1830 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1831   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1832   struct darwin_interface *cInterface;
1833   uint8_t pipeRef;
1834   IOReturn ret;
1835
1836   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1837     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1838
1839     return LIBUSB_ERROR_NOT_FOUND;
1840   }
1841
1842   itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1843
1844   if (IS_XFERIN(transfer))
1845     ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1846                                                              transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1847                                                              transfer->timeout, darwin_async_io_callback, itransfer);
1848   else
1849     ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1850                                                               transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1851                                                               transfer->timeout, darwin_async_io_callback, itransfer);
1852
1853   if (ret)
1854     usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1855                darwin_error_str(ret), ret);
1856
1857   return darwin_to_libusb (ret);
1858 }
1859 #endif
1860
1861 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1862   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1863   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1864
1865   IOReturn kresult;
1866   uint8_t direction, number, interval, pipeRef, transferType;
1867   uint16_t maxPacketSize;
1868   UInt64 frame;
1869   AbsoluteTime atTime;
1870   int i;
1871
1872   struct darwin_interface *cInterface;
1873
1874   /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1875   if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1876     free(tpriv->isoc_framelist);
1877     tpriv->isoc_framelist = NULL;
1878   }
1879
1880   if (!tpriv->isoc_framelist) {
1881     tpriv->num_iso_packets = transfer->num_iso_packets;
1882     tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1883     if (!tpriv->isoc_framelist)
1884       return LIBUSB_ERROR_NO_MEM;
1885   }
1886
1887   /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1888   for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1889     unsigned int length = transfer->iso_packet_desc[i].length;
1890     assert(length <= UINT16_MAX);
1891     tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1892   }
1893
1894   /* determine the interface/endpoint to use */
1895   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1896     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1897
1898     return LIBUSB_ERROR_NOT_FOUND;
1899   }
1900
1901   /* determine the properties of this endpoint and the speed of the device */
1902   (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1903                                                  &transferType, &maxPacketSize, &interval);
1904
1905   /* Last but not least we need the bus frame number */
1906   kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1907   if (kresult != kIOReturnSuccess) {
1908     usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1909     free(tpriv->isoc_framelist);
1910     tpriv->isoc_framelist = NULL;
1911
1912     return darwin_to_libusb (kresult);
1913   }
1914
1915   (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1916                                                  &transferType, &maxPacketSize, &interval);
1917
1918   /* schedule for a frame a little in the future */
1919   frame += 4;
1920
1921   if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1922     frame = cInterface->frames[transfer->endpoint];
1923
1924   /* submit the request */
1925   if (IS_XFERIN(transfer))
1926     kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1927                                                              (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1928                                                              itransfer);
1929   else
1930     kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1931                                                               (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1932                                                               itransfer);
1933
1934   if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1935     /* Full speed */
1936     cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1937   else
1938     /* High/super speed */
1939     cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1940
1941   if (kresult != kIOReturnSuccess) {
1942     usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1943                darwin_error_str(kresult));
1944     free (tpriv->isoc_framelist);
1945     tpriv->isoc_framelist = NULL;
1946   }
1947
1948   return darwin_to_libusb (kresult);
1949 }
1950
1951 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1952   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1953   struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1954   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1955   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1956
1957   IOReturn               kresult;
1958
1959   memset(&tpriv->req, 0, sizeof(tpriv->req));
1960
1961   /* IOUSBDeviceInterface expects the request in cpu endianness */
1962   tpriv->req.bmRequestType     = setup->bmRequestType;
1963   tpriv->req.bRequest          = setup->bRequest;
1964   /* these values should be in bus order from libusb_fill_control_setup */
1965   tpriv->req.wValue            = OSSwapLittleToHostInt16 (setup->wValue);
1966   tpriv->req.wIndex            = OSSwapLittleToHostInt16 (setup->wIndex);
1967   tpriv->req.wLength           = OSSwapLittleToHostInt16 (setup->wLength);
1968   /* data is stored after the libusb control block */
1969   tpriv->req.pData             = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1970   tpriv->req.completionTimeout = transfer->timeout;
1971   tpriv->req.noDataTimeout     = transfer->timeout;
1972
1973   itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1974
1975   /* all transfers in libusb-1.0 are async */
1976
1977   if (transfer->endpoint) {
1978     struct darwin_interface *cInterface;
1979     uint8_t                 pipeRef;
1980
1981     if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1982       usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1983
1984       return LIBUSB_ERROR_NOT_FOUND;
1985     }
1986
1987     kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1988   } else
1989     /* control request on endpoint 0 */
1990     kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1991
1992   if (kresult != kIOReturnSuccess)
1993     usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
1994
1995   return darwin_to_libusb (kresult);
1996 }
1997
1998 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1999   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2000
2001   switch (transfer->type) {
2002   case LIBUSB_TRANSFER_TYPE_CONTROL:
2003     return submit_control_transfer(itransfer);
2004   case LIBUSB_TRANSFER_TYPE_BULK:
2005   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2006     return submit_bulk_transfer(itransfer);
2007   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2008     return submit_iso_transfer(itransfer);
2009   case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2010 #if InterfaceVersion >= 550
2011     return submit_stream_transfer(itransfer);
2012 #else
2013     usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2014     return LIBUSB_ERROR_NOT_SUPPORTED;
2015 #endif
2016   default:
2017     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2018     return LIBUSB_ERROR_INVALID_PARAM;
2019   }
2020 }
2021
2022 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2023   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2024   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2025   IOReturn kresult;
2026
2027   usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2028
2029   if (!dpriv->device)
2030     return LIBUSB_ERROR_NO_DEVICE;
2031
2032   kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2033
2034   return darwin_to_libusb (kresult);
2035 }
2036
2037 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2038   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2039   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2040   struct darwin_interface *cInterface;
2041   uint8_t pipeRef, iface;
2042   IOReturn kresult;
2043
2044   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2045     usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2046
2047     return LIBUSB_ERROR_NOT_FOUND;
2048   }
2049
2050   if (!dpriv->device)
2051     return LIBUSB_ERROR_NO_DEVICE;
2052
2053   usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2054
2055   /* abort transactions */
2056 #if InterfaceVersion >= 550
2057   if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2058     (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2059   else
2060 #endif
2061     (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2062
2063   usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2064
2065   /* newer versions of darwin support clearing additional bits on the device's endpoint */
2066   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2067
2068   return darwin_to_libusb (kresult);
2069 }
2070
2071 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2072   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2073
2074   switch (transfer->type) {
2075   case LIBUSB_TRANSFER_TYPE_CONTROL:
2076     return cancel_control_transfer(itransfer);
2077   case LIBUSB_TRANSFER_TYPE_BULK:
2078   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2079   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2080     return darwin_abort_transfers (itransfer);
2081   default:
2082     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2083     return LIBUSB_ERROR_INVALID_PARAM;
2084   }
2085 }
2086
2087 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2088   struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2089   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2090   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2091
2092   usbi_dbg ("an async io operation has completed");
2093
2094   /* if requested write a zero packet */
2095   if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2096     struct darwin_interface *cInterface;
2097     uint8_t pipeRef;
2098
2099     (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2100
2101     (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2102   }
2103
2104   tpriv->result = result;
2105   tpriv->size = (UInt32) (uintptr_t) arg0;
2106
2107   /* signal the core that this transfer is complete */
2108   usbi_signal_transfer_completion(itransfer);
2109 }
2110
2111 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2112   if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2113     result = kIOUSBTransactionTimeout;
2114
2115   switch (result) {
2116   case kIOReturnUnderrun:
2117   case kIOReturnSuccess:
2118     return LIBUSB_TRANSFER_COMPLETED;
2119   case kIOReturnAborted:
2120     return LIBUSB_TRANSFER_CANCELLED;
2121   case kIOUSBPipeStalled:
2122     usbi_dbg ("transfer error: pipe is stalled");
2123     return LIBUSB_TRANSFER_STALL;
2124   case kIOReturnOverrun:
2125     usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2126     return LIBUSB_TRANSFER_OVERFLOW;
2127   case kIOUSBTransactionTimeout:
2128     usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2129     itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2130     return LIBUSB_TRANSFER_TIMED_OUT;
2131   default:
2132     usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2133     return LIBUSB_TRANSFER_ERROR;
2134   }
2135 }
2136
2137 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2138   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2139   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2140   bool isIsoc      = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2141   bool isBulk      = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
2142   bool isControl   = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
2143   bool isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
2144   int i;
2145
2146   if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
2147     usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2148     return LIBUSB_ERROR_INVALID_PARAM;
2149   }
2150
2151   usbi_dbg ("handling %s completion with kernel status %d",
2152              isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
2153
2154   if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2155     if (isIsoc && tpriv->isoc_framelist) {
2156       /* copy isochronous results back */
2157
2158       for (i = 0; i < transfer->num_iso_packets ; i++) {
2159         struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2160         lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2161         lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2162       }
2163     } else if (!isIsoc)
2164       itransfer->transferred += tpriv->size;
2165   }
2166
2167   /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2168   return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2169 }
2170
2171 #if !defined(HAVE_CLOCK_GETTIME)
2172 int usbi_clock_gettime(int clk_id, struct timespec *tp) {
2173   mach_timespec_t sys_time;
2174   clock_serv_t clock_ref;
2175
2176   switch (clk_id) {
2177   case USBI_CLOCK_REALTIME:
2178     /* CLOCK_REALTIME represents time since the epoch */
2179     clock_ref = clock_realtime;
2180     break;
2181   case USBI_CLOCK_MONOTONIC:
2182     /* use system boot time as reference for the monotonic clock */
2183     clock_ref = clock_monotonic;
2184     break;
2185   default:
2186     errno = EINVAL;
2187     return -1;
2188   }
2189
2190   clock_get_time (clock_ref, &sys_time);
2191
2192   tp->tv_sec  = sys_time.tv_sec;
2193   tp->tv_nsec = sys_time.tv_nsec;
2194
2195   return 0;
2196 }
2197 #endif
2198
2199 #if InterfaceVersion >= 550
2200 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2201                                  int num_endpoints) {
2202   struct darwin_interface *cInterface;
2203   UInt32 supportsStreams;
2204   uint8_t pipeRef;
2205   int rc, i;
2206
2207   /* find the mimimum number of supported streams on the endpoint list */
2208   for (i = 0 ; i < num_endpoints ; ++i) {
2209     if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2210       return rc;
2211     }
2212
2213     (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2214     if (num_streams > supportsStreams)
2215       num_streams = supportsStreams;
2216   }
2217
2218   /* it is an error if any endpoint in endpoints does not support streams */
2219   if (0 == num_streams)
2220     return LIBUSB_ERROR_INVALID_PARAM;
2221
2222   /* create the streams */
2223   for (i = 0 ; i < num_endpoints ; ++i) {
2224     (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2225
2226     rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2227     if (kIOReturnSuccess != rc)
2228       return darwin_to_libusb(rc);
2229   }
2230
2231   assert(num_streams <= INT_MAX);
2232   return (int)num_streams;
2233 }
2234
2235 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2236   struct darwin_interface *cInterface;
2237   UInt32 supportsStreams;
2238   uint8_t pipeRef;
2239   int rc;
2240
2241   for (int i = 0 ; i < num_endpoints ; ++i) {
2242     if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2243       return rc;
2244
2245     (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2246     if (0 == supportsStreams)
2247       return LIBUSB_ERROR_INVALID_PARAM;
2248
2249     rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2250     if (kIOReturnSuccess != rc)
2251       return darwin_to_libusb(rc);
2252   }
2253
2254   return LIBUSB_SUCCESS;
2255 }
2256 #endif
2257
2258 const struct usbi_os_backend usbi_backend = {
2259         .name = "Darwin",
2260         .caps = 0,
2261         .init = darwin_init,
2262         .exit = darwin_exit,
2263         .get_device_descriptor = darwin_get_device_descriptor,
2264         .get_active_config_descriptor = darwin_get_active_config_descriptor,
2265         .get_config_descriptor = darwin_get_config_descriptor,
2266         .hotplug_poll = darwin_hotplug_poll,
2267
2268         .open = darwin_open,
2269         .close = darwin_close,
2270         .get_configuration = darwin_get_configuration,
2271         .set_configuration = darwin_set_configuration,
2272         .claim_interface = darwin_claim_interface,
2273         .release_interface = darwin_release_interface,
2274
2275         .set_interface_altsetting = darwin_set_interface_altsetting,
2276         .clear_halt = darwin_clear_halt,
2277         .reset_device = darwin_reset_device,
2278
2279 #if InterfaceVersion >= 550
2280         .alloc_streams = darwin_alloc_streams,
2281         .free_streams = darwin_free_streams,
2282 #endif
2283
2284         .kernel_driver_active = darwin_kernel_driver_active,
2285
2286         .destroy_device = darwin_destroy_device,
2287
2288         .submit_transfer = darwin_submit_transfer,
2289         .cancel_transfer = darwin_cancel_transfer,
2290
2291         .handle_transfer_completion = darwin_handle_transfer_completion,
2292
2293         .device_priv_size = sizeof(struct darwin_device_priv),
2294         .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2295         .transfer_priv_size = sizeof(struct darwin_transfer_priv),
2296 };