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