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