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