1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
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.
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.
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.
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
30 #include <sys/types.h>
33 #include <sys/sysctl.h>
35 #include <mach/clock.h>
36 #include <mach/clock_types.h>
37 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
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
44 /* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate
45 * does not return error status on macOS. */
46 #define DARWIN_REENUMERATE_TIMEOUT_US 10000000
48 #include <AvailabilityMacros.h>
49 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
50 #include <objc/objc-auto.h>
53 #include "darwin_usb.h"
55 static int init_count = 0;
57 /* async event thread */
58 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
59 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
61 #if !defined(HAVE_CLOCK_GETTIME)
62 static clock_serv_t clock_realtime;
63 static clock_serv_t clock_monotonic;
66 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
68 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
69 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
71 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
72 static struct list_head darwin_cached_devices;
73 static const char *darwin_device_class = "IOUSBDevice";
75 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
77 /* async event thread */
78 static pthread_t libusb_darwin_at;
80 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
81 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
82 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
83 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
84 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
85 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
86 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
88 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
89 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
90 UInt64 old_session_id);
92 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
93 UInt64 *old_session_id);
95 #if defined(ENABLE_LOGGING)
96 static const char *darwin_error_str (IOReturn result) {
97 static char string_buffer[50];
99 case kIOReturnSuccess:
101 case kIOReturnNotOpen:
102 return "device not opened for exclusive access";
103 case kIOReturnNoDevice:
104 return "no connection to an IOService";
105 case kIOUSBNoAsyncPortErr:
106 return "no async port has been opened for interface";
107 case kIOReturnExclusiveAccess:
108 return "another process has device opened for exclusive access";
109 case kIOUSBPipeStalled:
110 return "pipe is stalled";
112 return "could not establish a connection to the Darwin kernel";
113 case kIOUSBTransactionTimeout:
114 return "transaction timed out";
115 case kIOReturnBadArgument:
116 return "invalid argument";
117 case kIOReturnAborted:
118 return "transaction aborted";
119 case kIOReturnNotResponding:
120 return "device not responding";
121 case kIOReturnOverrun:
122 return "data overrun";
123 case kIOReturnCannotWire:
124 return "physical memory can not be wired down";
125 case kIOReturnNoResources:
126 return "out of resources";
127 case kIOUSBHighSpeedSplitError:
128 return "high speed split error";
129 case kIOUSBUnknownPipeErr:
130 return "pipe ref not recognized";
132 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
133 return string_buffer;
138 static enum libusb_error darwin_to_libusb (IOReturn result) {
140 case kIOReturnUnderrun:
141 case kIOReturnSuccess:
142 return LIBUSB_SUCCESS;
143 case kIOReturnNotOpen:
144 case kIOReturnNoDevice:
145 return LIBUSB_ERROR_NO_DEVICE;
146 case kIOReturnExclusiveAccess:
147 return LIBUSB_ERROR_ACCESS;
148 case kIOUSBPipeStalled:
149 return LIBUSB_ERROR_PIPE;
150 case kIOReturnBadArgument:
151 return LIBUSB_ERROR_INVALID_PARAM;
152 case kIOUSBTransactionTimeout:
153 return LIBUSB_ERROR_TIMEOUT;
154 case kIOReturnNotResponding:
155 case kIOReturnAborted:
157 case kIOUSBNoAsyncPortErr:
158 case kIOUSBUnknownPipeErr:
160 return LIBUSB_ERROR_OTHER;
164 /* this function must be called with the darwin_cached_devices_lock held */
165 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
166 cached_dev->refcount--;
167 /* free the device and remove it from the cache */
168 if (0 == cached_dev->refcount) {
169 list_del(&cached_dev->list);
171 if (cached_dev->device) {
172 (*(cached_dev->device))->Release(cached_dev->device);
173 cached_dev->device = NULL;
175 IOObjectRelease (cached_dev->service);
180 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
181 cached_dev->refcount++;
184 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) {
185 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
187 /* current interface */
188 struct darwin_interface *cInterface;
192 struct libusb_context *ctx = HANDLE_CTX(dev_handle);
194 usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
196 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
197 cInterface = &priv->interfaces[iface];
199 if (dev_handle->claimed_interfaces & (1U << iface)) {
200 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
201 if (cInterface->endpoint_addrs[i] == ep) {
208 *interface_out = cInterface;
210 usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
211 return LIBUSB_SUCCESS;
217 /* No pipe found with the correct endpoint address */
218 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
220 return LIBUSB_ERROR_NOT_FOUND;
223 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
224 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
227 return kIOReturnError;
230 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
231 &kCFTypeDictionaryKeyCallBacks,
232 &kCFTypeDictionaryValueCallBacks);
234 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
235 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
236 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
238 if (propertyMatchDict && locationCF) {
239 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
240 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
242 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
244 /* release our references as per the Create Rule */
245 if (propertyMatchDict)
246 CFRelease (propertyMatchDict);
248 CFRelease (locationCF);
251 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
254 /* Returns 1 on success, 0 on failure. */
255 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
256 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
260 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
261 success = CFNumberGetValue(cfNumber, type, p);
264 CFRelease (cfNumber);
267 return (success != 0);
270 /* Returns 1 on success, 0 on failure. */
271 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
272 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
273 bool success = false;
276 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
277 CFIndex length = CFDataGetLength (cfData);
282 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
292 static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
294 io_cf_plugin_ref_t *plugInInterface = NULL;
295 usb_device_t **device;
298 const int max_retries = 5;
300 /* The IOCreatePlugInInterfaceForService function might consistently return
301 an "out of resources" error with certain USB devices the first time we run
302 it. The reason is still unclear, but retrying fixes the problem */
303 for (int count = 0; count < max_retries; count++) {
304 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
305 kIOCFPlugInInterfaceID, &plugInInterface,
307 if (kIOReturnSuccess == kresult && plugInInterface) {
311 usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
313 /* sleep for a little while before trying again */
314 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
317 if (kIOReturnSuccess != kresult || !plugInInterface) {
318 usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
322 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
324 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
325 (*plugInInterface)->Release (plugInInterface);
330 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
332 struct darwin_cached_device *cached_device;
333 UInt64 old_session_id;
334 struct libusb_context *ctx;
335 io_service_t service;
338 usbi_mutex_lock(&active_contexts_lock);
340 while ((service = IOIteratorNext(add_devices))) {
341 ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
342 if (ret < 0 || !cached_device->can_enumerate) {
346 /* add this device to each active context's device list */
347 for_each_context(ctx) {
348 process_new_device (ctx, cached_device, old_session_id);
351 if (cached_device->in_reenumerate) {
352 usbi_dbg (NULL, "cached device in reset state. reset complete...");
353 cached_device->in_reenumerate = false;
356 IOObjectRelease(service);
359 usbi_mutex_unlock(&active_contexts_lock);
362 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
364 struct libusb_device *dev = NULL;
365 struct libusb_context *ctx;
366 struct darwin_cached_device *old_device;
369 UInt64 session, locationID;
372 usbi_mutex_lock(&active_contexts_lock);
374 while ((device = IOIteratorNext (rem_devices)) != 0) {
375 bool is_reenumerating = false;
377 /* get the location from the i/o registry */
378 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
379 (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
380 IOObjectRelease (device);
384 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
385 otherwise no cached device will ever get freed */
386 usbi_mutex_lock(&darwin_cached_devices_lock);
387 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
388 if (old_device->session == session) {
389 if (old_device->in_reenumerate) {
390 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
391 * will deref if needed. */
392 usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
393 session, locationID);
395 /* the device object is no longer usable so go ahead and release it */
396 if (old_device->device) {
397 (*(old_device->device))->Release(old_device->device);
398 old_device->device = NULL;
401 is_reenumerating = true;
403 darwin_deref_cached_device (old_device);
410 usbi_mutex_unlock(&darwin_cached_devices_lock);
411 if (is_reenumerating) {
415 for_each_context(ctx) {
416 usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
418 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
420 /* signal the core that this device has been disconnected. the core will tear down this device
421 when the reference count reaches 0 */
422 usbi_disconnect_device(dev);
423 libusb_unref_device(dev);
428 usbi_mutex_unlock(&active_contexts_lock);
431 static void darwin_hotplug_poll (void)
433 /* not sure if 1 ms will be too long/short but it should work ok */
434 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
436 /* since a kernel thread may notify the IOIterators used for
437 * hotplug notification we can't just clear the iterators.
438 * instead just wait until all IOService providers are quiet */
439 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
442 static void darwin_clear_iterator (io_iterator_t iter) {
445 while ((device = IOIteratorNext (iter)) != 0)
446 IOObjectRelease (device);
449 static void darwin_fail_startup(void) {
450 pthread_mutex_lock (&libusb_darwin_at_mutex);
451 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
452 pthread_cond_signal (&libusb_darwin_at_cond);
453 pthread_mutex_unlock (&libusb_darwin_at_mutex);
457 static void *darwin_event_thread_main (void *arg0) {
459 struct libusb_context *ctx = (struct libusb_context *)arg0;
460 CFRunLoopRef runloop;
461 CFRunLoopSourceRef libusb_shutdown_cfsource;
462 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
464 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
465 /* Set this thread's name, so it can be seen in the debugger
466 and crash reports. */
467 pthread_setname_np ("org.libusb.device-hotplug");
470 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
471 /* Tell the Objective-C garbage collector about this thread.
472 This is required because, unlike NSThreads, pthreads are
473 not automatically registered. Although we don't use
474 Objective-C, we use CoreFoundation, which does.
475 Garbage collection support was entirely removed in 10.12,
476 so don't bother there. */
477 objc_registerThreadWithCollector();
480 /* hotplug (device arrival/removal) sources */
481 CFRunLoopSourceRef libusb_notification_cfsource;
482 io_notification_port_t libusb_notification_port;
483 io_iterator_t libusb_rem_device_iterator;
484 io_iterator_t libusb_add_device_iterator;
486 usbi_dbg (ctx, "creating hotplug event source");
488 runloop = CFRunLoopGetCurrent ();
491 /* add the shutdown cfsource to the run loop */
492 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
493 libusb_shutdown_cfsourcectx.info = runloop;
494 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
495 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
496 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
498 /* add the notification port to the run loop */
499 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
500 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
501 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
503 /* create notifications for removed devices */
504 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
505 IOServiceMatching(darwin_device_class),
506 darwin_devices_detached,
507 ctx, &libusb_rem_device_iterator);
509 if (kresult != kIOReturnSuccess) {
510 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
511 CFRelease (libusb_shutdown_cfsource);
513 darwin_fail_startup ();
516 /* create notifications for attached devices */
517 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
518 IOServiceMatching(darwin_device_class),
519 darwin_devices_attached,
520 ctx, &libusb_add_device_iterator);
522 if (kresult != kIOReturnSuccess) {
523 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
524 CFRelease (libusb_shutdown_cfsource);
526 darwin_fail_startup ();
530 darwin_clear_iterator (libusb_rem_device_iterator);
531 darwin_clear_iterator (libusb_add_device_iterator);
533 usbi_dbg (ctx, "darwin event thread ready to receive events");
535 /* signal the main thread that the hotplug runloop has been created. */
536 pthread_mutex_lock (&libusb_darwin_at_mutex);
537 libusb_darwin_acfl = runloop;
538 libusb_darwin_acfls = libusb_shutdown_cfsource;
539 pthread_cond_signal (&libusb_darwin_at_cond);
540 pthread_mutex_unlock (&libusb_darwin_at_mutex);
542 /* run the runloop */
545 usbi_dbg (ctx, "darwin event thread exiting");
547 /* signal the main thread that the hotplug runloop has finished. */
548 pthread_mutex_lock (&libusb_darwin_at_mutex);
549 libusb_darwin_acfls = NULL;
550 libusb_darwin_acfl = NULL;
551 pthread_cond_signal (&libusb_darwin_at_cond);
552 pthread_mutex_unlock (&libusb_darwin_at_mutex);
554 /* remove the notification cfsource */
555 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
557 /* remove the shutdown cfsource */
558 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
560 /* delete notification port */
561 IONotificationPortDestroy (libusb_notification_port);
563 /* delete iterators */
564 IOObjectRelease (libusb_rem_device_iterator);
565 IOObjectRelease (libusb_add_device_iterator);
567 CFRelease (libusb_shutdown_cfsource);
573 /* cleanup function to destroy cached devices */
574 static void darwin_cleanup_devices(void) {
575 struct darwin_cached_device *dev, *next;
577 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
578 darwin_deref_cached_device(dev);
582 static int darwin_init(struct libusb_context *ctx) {
586 first_init = (1 == ++init_count);
590 if (NULL == darwin_cached_devices.next) {
591 list_init (&darwin_cached_devices);
593 assert(list_empty(&darwin_cached_devices));
594 #if !defined(HAVE_CLOCK_GETTIME)
595 /* create the clocks that will be used if clock_gettime() is not available */
596 host_name_port_t host_self;
598 host_self = mach_host_self();
599 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
600 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
601 mach_port_deallocate(mach_task_self(), host_self);
605 rc = darwin_scan_devices (ctx);
606 if (LIBUSB_SUCCESS != rc)
610 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
612 usbi_err (ctx, "could not create event thread, error %d", rc);
613 rc = LIBUSB_ERROR_OTHER;
617 pthread_mutex_lock (&libusb_darwin_at_mutex);
618 while (!libusb_darwin_acfl)
619 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
620 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
621 libusb_darwin_acfl = NULL;
622 rc = LIBUSB_ERROR_OTHER;
624 pthread_mutex_unlock (&libusb_darwin_at_mutex);
627 pthread_join (libusb_darwin_at, NULL);
631 if (LIBUSB_SUCCESS != rc) {
633 darwin_cleanup_devices ();
634 #if !defined(HAVE_CLOCK_GETTIME)
635 mach_port_deallocate(mach_task_self(), clock_realtime);
636 mach_port_deallocate(mach_task_self(), clock_monotonic);
645 static void darwin_exit (struct libusb_context *ctx) {
648 if (0 == --init_count) {
649 /* stop the event runloop and wait for the thread to terminate. */
650 pthread_mutex_lock (&libusb_darwin_at_mutex);
651 CFRunLoopSourceSignal (libusb_darwin_acfls);
652 CFRunLoopWakeUp (libusb_darwin_acfl);
653 while (libusb_darwin_acfl)
654 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
655 pthread_mutex_unlock (&libusb_darwin_at_mutex);
656 pthread_join (libusb_darwin_at, NULL);
658 darwin_cleanup_devices ();
660 #if !defined(HAVE_CLOCK_GETTIME)
661 mach_port_deallocate(mach_task_self(), clock_realtime);
662 mach_port_deallocate(mach_task_self(), clock_monotonic);
667 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
668 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
670 IOUSBConfigurationDescriptorPtr desc;
673 /* is there a simpler way to determine the index? */
674 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
675 if (kresult != kIOReturnSuccess)
676 return darwin_to_libusb (kresult);
678 for (i = 0 ; i < numConfig ; i++) {
679 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
681 if (desc->bConfigurationValue == config_value)
685 /* configuration not found */
686 return LIBUSB_ERROR_NOT_FOUND;
689 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
690 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
693 if (0 == priv->active_config)
694 return LIBUSB_ERROR_NOT_FOUND;
696 config_index = get_configuration_index (dev, priv->active_config);
697 if (config_index < 0)
700 assert(config_index >= 0 && config_index <= UINT8_MAX);
701 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
704 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
705 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
706 IOUSBConfigurationDescriptorPtr desc;
710 if (!priv || !priv->device)
711 return LIBUSB_ERROR_OTHER;
713 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
714 if (kresult == kIOReturnSuccess) {
715 /* copy descriptor */
716 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
717 len = libusb_le16_to_cpu(desc->wTotalLength);
719 memmove (buffer, desc, len);
722 ret = darwin_to_libusb (kresult);
723 if (ret != LIBUSB_SUCCESS)
729 /* check whether the os has configured the device */
730 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
731 usb_device_t **darwin_device = dev->device;
733 IOUSBConfigurationDescriptorPtr configDesc;
734 IOUSBFindInterfaceRequest request;
736 io_iterator_t interface_iterator;
737 io_service_t firstInterface;
739 if (dev->dev_descriptor.bNumConfigurations < 1) {
740 usbi_err (ctx, "device has no configurations");
741 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
744 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
746 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
747 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
748 usbi_dbg (ctx, "ignoring configuration on root hub simulation");
749 dev->active_config = 0;
750 return LIBUSB_SUCCESS;
753 /* find the first configuration */
754 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
755 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
757 /* check if the device is already configured. there is probably a better way than iterating over the
758 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
759 might lock up on the device request) */
761 /* Setup the Interface Request */
762 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
763 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
764 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
765 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
767 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
768 if (kresult != kIOReturnSuccess)
769 return darwin_to_libusb (kresult);
772 firstInterface = IOIteratorNext(interface_iterator);
774 /* done with the interface iterator */
775 IOObjectRelease(interface_iterator);
777 if (firstInterface) {
778 IOObjectRelease (firstInterface);
780 /* device is configured */
781 if (dev->dev_descriptor.bNumConfigurations == 1)
782 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
783 dev->active_config = dev->first_config;
785 /* devices with more than one configuration should work with GetConfiguration */
786 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
789 dev->active_config = 0;
791 usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
793 return LIBUSB_SUCCESS;
796 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
797 IOUSBDevRequestTO req;
799 assert(buffer_size <= UINT16_MAX);
801 memset (buffer, 0, buffer_size);
803 /* Set up request for descriptor/ */
804 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
805 req.bRequest = kUSBRqGetDescriptor;
806 req.wValue = (UInt16)(desc << 8);
807 req.wIndex = desc_index;
808 req.wLength = (UInt16)buffer_size;
810 req.noDataTimeout = 20;
811 req.completionTimeout = 100;
813 return (*device)->DeviceRequestTO (device, &req);
816 static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
817 usb_device_t **device = dev->device;
819 long delay = 30000; // microseconds
820 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
822 IOReturn ret = 0, ret2;
824 UInt16 idProduct, idVendor;
826 dev->can_enumerate = 0;
828 (*device)->GetDeviceClass (device, &bDeviceClass);
829 (*device)->GetDeviceProduct (device, &idProduct);
830 (*device)->GetDeviceVendor (device, &idVendor);
832 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
833 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
834 * to follow the spec as closely as possible, try opening the device */
835 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
838 /**** retrieve device descriptor ****/
839 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
841 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
842 /* received an overrun error but we still received a device descriptor */
843 ret = kIOReturnSuccess;
845 if (kIOUSBVendorIDAppleComputer == idVendor) {
846 /* NTH: don't bother retrying or unsuspending Apple devices */
850 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
851 0 == dev->dev_descriptor.bcdUSB)) {
852 /* work around for incorrectly configured devices */
853 if (try_reconfigure && is_open) {
854 usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
856 /* set the first configuration */
857 (*device)->SetConfiguration(device, 1);
859 /* don't try to reconfigure again */
863 ret = kIOUSBPipeStalled;
866 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
867 /* device may be suspended. unsuspend it and try again */
868 #if DeviceVersion >= 320
871 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
872 (void)(*device)->GetUSBDeviceInformation (device, &info);
874 /* note that the device was suspended */
875 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
880 /* try to unsuspend the device */
881 ret2 = (*device)->USBDeviceSuspend (device, 0);
882 if (kIOReturnSuccess != ret2) {
883 /* prevent log spew from poorly behaving devices. this indicates the
884 os actually had trouble communicating with the device */
885 usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
893 if (kIOReturnSuccess != ret) {
894 usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
895 /* sleep for a little while before trying again */
896 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
898 } while (kIOReturnSuccess != ret && retries--);
901 /* resuspend the device */
902 (void)(*device)->USBDeviceSuspend (device, 1);
905 (void) (*device)->USBDeviceClose (device);
907 if (ret != kIOReturnSuccess) {
908 /* a debug message was already printed out for this error */
909 if (LIBUSB_CLASS_HUB == bDeviceClass)
910 usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
911 idVendor, idProduct, darwin_error_str (ret), ret);
913 usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
914 idVendor, idProduct, darwin_error_str (ret), ret);
915 return darwin_to_libusb (ret);
918 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
919 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
920 /* not a valid device */
921 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
922 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
923 return LIBUSB_ERROR_NO_DEVICE;
926 usbi_dbg (ctx, "cached device descriptor:");
927 usbi_dbg (ctx, " bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
928 usbi_dbg (ctx, " bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
929 usbi_dbg (ctx, " bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
930 usbi_dbg (ctx, " bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
931 usbi_dbg (ctx, " bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
932 usbi_dbg (ctx, " bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
933 usbi_dbg (ctx, " idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
934 usbi_dbg (ctx, " idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
935 usbi_dbg (ctx, " bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
936 usbi_dbg (ctx, " iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
937 usbi_dbg (ctx, " iProduct: 0x%02x", dev->dev_descriptor.iProduct);
938 usbi_dbg (ctx, " iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
939 usbi_dbg (ctx, " bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
941 dev->can_enumerate = 1;
943 return LIBUSB_SUCCESS;
946 /* Returns 1 on success, 0 on failure. */
947 static bool get_device_port (io_service_t service, UInt8 *port) {
952 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
956 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
957 if (kIOReturnSuccess == kresult) {
958 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
959 IOObjectRelease (parent);
965 /* Returns 1 on success, 0 on failure. */
966 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
970 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
972 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
973 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
979 /* We ran out of parents */
983 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
984 UInt64 *old_session_id) {
985 struct darwin_cached_device *new_device;
986 UInt64 sessionID = 0, parent_sessionID = 0;
987 UInt32 locationID = 0;
988 enum libusb_error ret = LIBUSB_SUCCESS;
989 usb_device_t **device;
992 /* assuming sessionID != 0 normally (never seen it be 0) */
996 /* get some info from the io registry */
997 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
998 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
999 if (!get_device_port (service, &port)) {
1000 usbi_dbg(ctx, "could not get connected port number");
1003 usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
1005 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1006 usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
1009 usbi_mutex_lock(&darwin_cached_devices_lock);
1011 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1012 usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1013 sessionID, locationID, new_device->session, new_device->location);
1014 if (new_device->location == locationID && new_device->in_reenumerate) {
1015 usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
1016 *old_session_id = new_device->session;
1020 if (new_device->session == sessionID) {
1021 usbi_dbg(ctx, "using cached device for device");
1022 *cached_out = new_device;
1030 usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
1032 device = darwin_device_from_service (ctx, service);
1034 ret = LIBUSB_ERROR_NO_DEVICE;
1038 if (!(*old_session_id)) {
1039 new_device = calloc (1, sizeof (*new_device));
1041 ret = LIBUSB_ERROR_NO_MEM;
1045 /* add this device to the cached device list */
1046 list_add(&new_device->list, &darwin_cached_devices);
1048 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1050 /* keep a reference to this device */
1051 darwin_ref_cached_device(new_device);
1053 (*device)->GetLocationID (device, &new_device->location);
1054 new_device->port = port;
1055 new_device->parent_session = parent_sessionID;
1057 /* release the ref to old device's service */
1058 IOObjectRelease (new_device->service);
1061 /* keep track of devices regardless of if we successfully enumerate them to
1062 prevent them from being enumerated multiple times */
1063 *cached_out = new_device;
1065 new_device->session = sessionID;
1066 new_device->device = device;
1067 new_device->service = service;
1069 /* retain the service */
1070 IOObjectRetain (service);
1072 /* cache the device descriptor */
1073 ret = darwin_cache_device_descriptor(ctx, new_device);
1077 if (new_device->can_enumerate) {
1078 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1079 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1080 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1081 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1085 usbi_mutex_unlock(&darwin_cached_devices_lock);
1090 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1091 UInt64 old_session_id) {
1092 struct darwin_device_priv *priv;
1093 struct libusb_device *dev = NULL;
1095 enum libusb_error ret = LIBUSB_SUCCESS;
1098 /* check current active configuration (and cache the first configuration value--
1099 which may be used by claim_interface) */
1100 ret = darwin_check_configuration (ctx, cached_device);
1104 if (0 != old_session_id) {
1105 usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1106 ctx, old_session_id, cached_device->session);
1107 /* save the libusb device before the session id is updated */
1108 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1112 usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
1113 ctx, cached_device->session);
1115 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1117 return LIBUSB_ERROR_NO_MEM;
1120 priv = usbi_get_device_priv(dev);
1122 priv->dev = cached_device;
1123 darwin_ref_cached_device (priv->dev);
1124 dev->port_number = cached_device->port;
1125 /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
1126 (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
1127 dev->bus_number = cached_device->location >> 24;
1128 assert(cached_device->address <= UINT8_MAX);
1129 dev->device_address = (uint8_t)cached_device->address;
1131 priv = usbi_get_device_priv(dev);
1134 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1135 "mismatch between libusb and IOKit device descriptor sizes");
1136 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1137 usbi_localize_device_descriptor(&dev->device_descriptor);
1138 dev->session_data = cached_device->session;
1140 if (NULL != dev->parent_dev) {
1141 libusb_unref_device(dev->parent_dev);
1142 dev->parent_dev = NULL;
1145 if (cached_device->parent_session > 0) {
1146 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1149 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1152 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1153 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1154 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1155 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1156 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1158 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1159 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1162 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1165 ret = usbi_sanitize_device (dev);
1169 usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
1170 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1174 if (!cached_device->in_reenumerate && 0 == ret) {
1175 usbi_connect_device (dev);
1177 libusb_unref_device (dev);
1183 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1184 struct darwin_cached_device *cached_device;
1185 UInt64 old_session_id;
1186 io_iterator_t deviceIterator;
1187 io_service_t service;
1191 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1192 if (kresult != kIOReturnSuccess)
1193 return darwin_to_libusb (kresult);
1195 while ((service = IOIteratorNext (deviceIterator))) {
1196 ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
1197 if (ret < 0 || !cached_device->can_enumerate) {
1201 (void) process_new_device (ctx, cached_device, old_session_id);
1203 IOObjectRelease(service);
1206 IOObjectRelease(deviceIterator);
1208 return LIBUSB_SUCCESS;
1211 static int darwin_open (struct libusb_device_handle *dev_handle) {
1212 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1213 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1216 if (0 == dpriv->open_count) {
1217 /* try to open the device */
1218 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1219 if (kresult != kIOReturnSuccess) {
1220 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1222 if (kIOReturnExclusiveAccess != kresult) {
1223 return darwin_to_libusb (kresult);
1226 /* it is possible to perform some actions on a device that is not open so do not return an error */
1227 priv->is_open = false;
1229 priv->is_open = true;
1232 /* create async event source */
1233 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1234 if (kresult != kIOReturnSuccess) {
1235 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1237 if (priv->is_open) {
1238 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1241 priv->is_open = false;
1243 return darwin_to_libusb (kresult);
1246 CFRetain (libusb_darwin_acfl);
1248 /* add the cfSource to the aync run loop */
1249 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1252 /* device opened successfully */
1253 dpriv->open_count++;
1255 usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
1260 static void darwin_close (struct libusb_device_handle *dev_handle) {
1261 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1262 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1266 if (dpriv->open_count == 0) {
1267 /* something is probably very wrong if this is the case */
1268 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1272 dpriv->open_count--;
1273 if (NULL == dpriv->device) {
1274 usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
1278 /* make sure all interfaces are released */
1279 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1280 if (dev_handle->claimed_interfaces & (1U << i))
1281 libusb_release_interface (dev_handle, i);
1283 if (0 == dpriv->open_count) {
1284 /* delete the device's async event source */
1285 if (priv->cfSource) {
1286 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1287 CFRelease (priv->cfSource);
1288 priv->cfSource = NULL;
1289 CFRelease (libusb_darwin_acfl);
1292 if (priv->is_open) {
1293 /* close the device */
1294 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1295 if (kresult != kIOReturnSuccess) {
1296 /* Log the fact that we had a problem closing the file, however failing a
1297 * close isn't really an error, so return success anyway */
1298 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1304 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1305 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1307 *config = dpriv->active_config;
1309 return LIBUSB_SUCCESS;
1312 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1313 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1320 /* Setting configuration will invalidate the interface, so we need
1321 to reclaim it. First, dispose of existing interfaces, if any. */
1322 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1323 if (dev_handle->claimed_interfaces & (1U << i))
1324 darwin_release_interface (dev_handle, i);
1326 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1327 if (kresult != kIOReturnSuccess)
1328 return darwin_to_libusb (kresult);
1330 /* Reclaim any interfaces. */
1331 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1332 if (dev_handle->claimed_interfaces & (1U << i))
1333 darwin_claim_interface (dev_handle, i);
1335 dpriv->active_config = (UInt8)config;
1337 return LIBUSB_SUCCESS;
1340 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1341 IOUSBFindInterfaceRequest request;
1343 io_iterator_t interface_iterator;
1344 UInt8 bInterfaceNumber;
1347 *usbInterfacep = IO_OBJECT_NULL;
1349 /* Setup the Interface Request */
1350 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1351 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1352 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1353 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1355 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1356 if (kresult != kIOReturnSuccess)
1359 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1360 /* find the interface number */
1361 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1364 if (ret && bInterfaceNumber == ifc) {
1368 (void) IOObjectRelease (*usbInterfacep);
1371 /* done with the interface iterator */
1372 IOObjectRelease(interface_iterator);
1374 return kIOReturnSuccess;
1377 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1378 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1380 /* current interface */
1381 struct darwin_interface *cInterface = &priv->interfaces[iface];
1385 UInt8 numep, direction, number;
1386 UInt8 dont_care1, dont_care3;
1389 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1392 usbi_dbg (ctx, "building table of endpoints.");
1394 /* retrieve the total number of endpoints on this interface */
1395 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1396 if (kresult != kIOReturnSuccess) {
1397 usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1398 return darwin_to_libusb (kresult);
1401 /* iterate through pipe references */
1402 for (UInt8 i = 1 ; i <= numep ; i++) {
1403 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1404 &dont_care2, &dont_care3);
1406 if (kresult != kIOReturnSuccess) {
1407 /* probably a buggy device. try to get the endpoint address from the descriptors */
1408 struct libusb_config_descriptor *config;
1409 const struct libusb_endpoint_descriptor *endpoint_desc;
1412 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1413 if (kresult != kIOReturnSuccess) {
1414 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1415 return darwin_to_libusb (kresult);
1418 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1419 if (LIBUSB_SUCCESS != rc) {
1423 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1425 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1427 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1430 usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1431 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1434 cInterface->num_endpoints = numep;
1436 return LIBUSB_SUCCESS;
1439 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1440 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1441 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1442 io_service_t usbInterface = IO_OBJECT_NULL;
1444 enum libusb_error ret;
1445 IOCFPlugInInterface **plugInInterface = NULL;
1448 /* current interface */
1449 struct darwin_interface *cInterface = &priv->interfaces[iface];
1451 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1453 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1454 if (kresult != kIOReturnSuccess)
1455 return darwin_to_libusb (kresult);
1457 /* make sure we have an interface */
1458 if (!usbInterface && dpriv->first_config != 0) {
1459 usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
1461 /* set the configuration */
1462 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1463 if (ret != LIBUSB_SUCCESS) {
1464 usbi_err (ctx, "could not set configuration");
1468 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1469 if (kresult != kIOReturnSuccess) {
1470 usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
1471 return darwin_to_libusb (kresult);
1475 if (!usbInterface) {
1476 usbi_info (ctx, "interface not found");
1477 return LIBUSB_ERROR_NOT_FOUND;
1480 /* get an interface to the device's interface */
1481 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1482 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1484 /* ignore release error */
1485 (void)IOObjectRelease (usbInterface);
1487 if (kresult != kIOReturnSuccess) {
1488 usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1489 return darwin_to_libusb (kresult);
1492 if (!plugInInterface) {
1493 usbi_err (ctx, "plugin interface not found");
1494 return LIBUSB_ERROR_NOT_FOUND;
1497 /* Do the actual claim */
1498 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1499 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1500 (LPVOID)&cInterface->interface);
1501 /* We no longer need the intermediate plug-in */
1502 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1503 (*plugInInterface)->Release (plugInInterface);
1504 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1505 usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
1506 return darwin_to_libusb (kresult);
1509 /* claim the interface */
1510 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1511 if (kresult != kIOReturnSuccess) {
1512 usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
1513 return darwin_to_libusb (kresult);
1516 /* update list of endpoints */
1517 ret = get_endpoints (dev_handle, iface);
1519 /* this should not happen */
1520 darwin_release_interface (dev_handle, iface);
1521 usbi_err (ctx, "could not build endpoint table");
1525 cInterface->cfSource = NULL;
1527 /* create async event source */
1528 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1529 if (kresult != kIOReturnSuccess) {
1530 usbi_err (ctx, "could not create async event source");
1532 /* can't continue without an async event source */
1533 (void)darwin_release_interface (dev_handle, iface);
1535 return darwin_to_libusb (kresult);
1538 /* add the cfSource to the async thread's run loop */
1539 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1541 usbi_dbg (ctx, "interface opened");
1543 return LIBUSB_SUCCESS;
1546 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1547 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1550 /* current interface */
1551 struct darwin_interface *cInterface = &priv->interfaces[iface];
1553 /* Check to see if an interface is open */
1554 if (!cInterface->interface)
1555 return LIBUSB_SUCCESS;
1557 /* clean up endpoint data */
1558 cInterface->num_endpoints = 0;
1560 /* delete the interface's async event source */
1561 if (cInterface->cfSource) {
1562 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1563 CFRelease (cInterface->cfSource);
1566 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1567 if (kresult != kIOReturnSuccess)
1568 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1570 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1571 if (kresult != kIOReturnSuccess)
1572 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1574 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1576 return darwin_to_libusb (kresult);
1579 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1580 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1582 enum libusb_error ret;
1584 uint8_t old_alt_setting;
1586 /* current interface */
1587 struct darwin_interface *cInterface = &priv->interfaces[iface];
1589 if (!cInterface->interface)
1590 return LIBUSB_ERROR_NO_DEVICE;
1592 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1593 if (kresult == kIOReturnSuccess) {
1594 /* update the list of endpoints */
1595 ret = get_endpoints (dev_handle, iface);
1597 /* this should not happen */
1598 darwin_release_interface (dev_handle, iface);
1599 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1604 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1606 if (kresult != kIOUSBPipeStalled)
1607 return darwin_to_libusb (kresult);
1609 /* If a device only supports a default setting for the specified interface, then a STALL
1610 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1611 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1612 of the interface (as would have been done per 9.1.1.5) and return success. */
1614 /* For some reason we need to reclaim the interface after the pipe error */
1615 ret = darwin_claim_interface (dev_handle, iface);
1618 darwin_release_interface (dev_handle, iface);
1619 usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface");
1622 /* Return error if a change to another value was attempted */
1623 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &old_alt_setting);
1624 if (kresult == kIOReturnSuccess && altsetting != old_alt_setting)
1625 return LIBUSB_ERROR_PIPE;
1627 for (i = 0 ; i < cInterface->num_endpoints ; i++)
1628 darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1630 return LIBUSB_SUCCESS;
1633 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1634 /* current interface */
1635 struct darwin_interface *cInterface;
1639 /* determine the interface/endpoint to use */
1640 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1641 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1643 return LIBUSB_ERROR_NOT_FOUND;
1646 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1647 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1648 if (kresult != kIOReturnSuccess)
1649 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1651 return darwin_to_libusb (kresult);
1654 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1655 unsigned long claimed_interfaces) {
1656 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1657 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1658 int open_count = dpriv->open_count;
1661 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1663 /* clear claimed interfaces temporarily */
1664 dev_handle->claimed_interfaces = 0;
1666 /* close and re-open the device */
1667 priv->is_open = false;
1668 dpriv->open_count = 1;
1670 /* clean up open interfaces */
1671 (void) darwin_close (dev_handle);
1673 /* re-open the device */
1674 ret = darwin_open (dev_handle);
1675 dpriv->open_count = open_count;
1676 if (LIBUSB_SUCCESS != ret) {
1677 /* could not restore configuration */
1678 return LIBUSB_ERROR_NOT_FOUND;
1681 if (dpriv->active_config != active_config) {
1682 usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
1684 ret = darwin_set_configuration (dev_handle, active_config);
1685 if (LIBUSB_SUCCESS != ret) {
1686 usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
1687 return LIBUSB_ERROR_NOT_FOUND;
1691 usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
1693 if (claimed_interfaces) {
1694 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1695 if (!(claimed_interfaces & (1U << iface))) {
1699 usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
1701 ret = darwin_claim_interface (dev_handle, iface);
1702 if (LIBUSB_SUCCESS != ret) {
1703 usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
1704 return LIBUSB_ERROR_NOT_FOUND;
1707 dev_handle->claimed_interfaces |= 1U << iface;
1711 usbi_dbg (ctx, "darwin/restore_state: device state restored");
1713 return LIBUSB_SUCCESS;
1716 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1717 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1718 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1719 int8_t active_config = dpriv->active_config;
1721 IOUSBDeviceDescriptor descriptor;
1722 IOUSBConfigurationDescriptorPtr cached_configuration;
1723 IOUSBConfigurationDescriptor *cached_configurations;
1728 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1730 if (dpriv->in_reenumerate) {
1731 /* ack, two (or more) threads are trying to reset the device! abort! */
1732 return LIBUSB_ERROR_NOT_FOUND;
1735 dpriv->in_reenumerate = true;
1737 /* store copies of descriptors so they can be compared after the reset */
1738 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1739 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1741 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1742 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1743 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1746 /* if we need to release capture */
1747 if (HAS_CAPTURE_DEVICE()) {
1749 options |= kUSBReEnumerateCaptureDeviceMask;
1755 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1756 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1757 if (kresult != kIOReturnSuccess) {
1758 usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1759 dpriv->in_reenumerate = false;
1760 return darwin_to_libusb (kresult);
1763 /* capture mode does not re-enumerate but it does require re-open */
1765 usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
1766 dpriv->in_reenumerate = false;
1767 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1770 usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
1773 while (dpriv->in_reenumerate) {
1774 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1775 nanosleep (&delay, NULL);
1776 if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
1777 usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
1778 dpriv->in_reenumerate = false;
1779 return LIBUSB_ERROR_TIMEOUT;
1783 /* compare descriptors */
1784 usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
1786 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1787 /* device descriptor changed. need to return not found. */
1788 usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
1789 return LIBUSB_ERROR_NOT_FOUND;
1792 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1793 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1794 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1795 usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1796 return LIBUSB_ERROR_NOT_FOUND;
1800 usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
1802 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1805 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1806 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1809 if (dpriv->capture_count > 0) {
1810 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1811 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1812 return darwin_to_libusb (kresult);
1814 return darwin_reenumerate_device (dev_handle, false);
1818 static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
1819 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
1820 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
1821 &kCFTypeDictionaryKeyCallBacks,
1822 &kCFTypeDictionaryValueCallBacks);
1823 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
1824 CFTypeRef interfaceCF = CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);
1826 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
1827 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
1828 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);
1830 CFRelease (interfaceCF);
1831 CFRelease (locationCF);
1832 CFRelease (propertyMatchDict);
1834 return IOServiceGetMatchingService (kIOMasterPortDefault, matchingDict);
1837 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1838 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1839 io_service_t usb_interface, child = IO_OBJECT_NULL;
1841 /* locate the IO registry entry for this interface */
1842 usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
1843 if (0 == usb_interface) {
1844 /* check for the legacy class entry */
1845 usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
1846 if (0 == usb_interface) {
1847 return LIBUSB_ERROR_NOT_FOUND;
1851 /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
1852 (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
1853 IOObjectRelease (usb_interface);
1854 if (IO_OBJECT_NULL != child) {
1855 IOObjectRelease (child);
1863 static void darwin_destroy_device(struct libusb_device *dev) {
1864 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1867 /* need to hold the lock in case this is the last reference to the device */
1868 usbi_mutex_lock(&darwin_cached_devices_lock);
1869 darwin_deref_cached_device (dpriv->dev);
1871 usbi_mutex_unlock(&darwin_cached_devices_lock);
1875 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1876 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1879 uint8_t transferType;
1881 uint16_t maxPacketSize;
1883 struct darwin_interface *cInterface;
1884 #if InterfaceVersion >= 550
1885 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1887 /* None of the values below are used in libusb for bulk transfers */
1888 uint8_t direction, number, interval;
1891 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1892 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1894 return LIBUSB_ERROR_NOT_FOUND;
1897 #if InterfaceVersion >= 550
1898 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1900 transferType = pipeProperties.bTransferType;
1901 maxPacketSize = pipeProperties.wMaxPacketSize;
1903 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1904 &transferType, &maxPacketSize, &interval);
1908 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1909 darwin_error_str(ret), ret);
1910 return darwin_to_libusb (ret);
1913 if (0 != (transfer->length % maxPacketSize)) {
1914 /* do not need a zero packet */
1915 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1918 /* submit the request */
1919 /* timeouts are unavailable on interrupt endpoints */
1920 if (transferType == kUSBInterrupt) {
1921 if (IS_XFERIN(transfer))
1922 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1923 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1925 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1926 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1928 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1930 if (IS_XFERIN(transfer))
1931 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1932 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1933 darwin_async_io_callback, itransfer);
1935 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1936 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1937 darwin_async_io_callback, itransfer);
1941 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1942 darwin_error_str(ret), ret);
1944 return darwin_to_libusb (ret);
1947 #if InterfaceVersion >= 550
1948 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1949 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1950 struct darwin_interface *cInterface;
1954 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1955 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1957 return LIBUSB_ERROR_NOT_FOUND;
1960 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1962 if (IS_XFERIN(transfer))
1963 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1964 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1965 transfer->timeout, darwin_async_io_callback, itransfer);
1967 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1968 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1969 transfer->timeout, darwin_async_io_callback, itransfer);
1972 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1973 darwin_error_str(ret), ret);
1975 return darwin_to_libusb (ret);
1979 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1980 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1981 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1984 uint8_t direction, number, interval, pipeRef, transferType;
1985 uint16_t maxPacketSize;
1987 AbsoluteTime atTime;
1990 struct darwin_interface *cInterface;
1992 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1993 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1994 free(tpriv->isoc_framelist);
1995 tpriv->isoc_framelist = NULL;
1998 if (!tpriv->isoc_framelist) {
1999 tpriv->num_iso_packets = transfer->num_iso_packets;
2000 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
2001 if (!tpriv->isoc_framelist)
2002 return LIBUSB_ERROR_NO_MEM;
2005 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
2006 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
2007 unsigned int length = transfer->iso_packet_desc[i].length;
2008 assert(length <= UINT16_MAX);
2009 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
2012 /* determine the interface/endpoint to use */
2013 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2014 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2016 return LIBUSB_ERROR_NOT_FOUND;
2019 /* determine the properties of this endpoint and the speed of the device */
2020 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2021 &transferType, &maxPacketSize, &interval);
2023 /* Last but not least we need the bus frame number */
2024 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
2025 if (kresult != kIOReturnSuccess) {
2026 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
2027 free(tpriv->isoc_framelist);
2028 tpriv->isoc_framelist = NULL;
2030 return darwin_to_libusb (kresult);
2033 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2034 &transferType, &maxPacketSize, &interval);
2036 /* schedule for a frame a little in the future */
2039 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
2040 frame = cInterface->frames[transfer->endpoint];
2042 /* submit the request */
2043 if (IS_XFERIN(transfer))
2044 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2045 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2048 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2049 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2052 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
2054 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
2056 /* High/super speed */
2057 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
2059 if (kresult != kIOReturnSuccess) {
2060 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
2061 darwin_error_str(kresult));
2062 free (tpriv->isoc_framelist);
2063 tpriv->isoc_framelist = NULL;
2066 return darwin_to_libusb (kresult);
2069 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2070 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2071 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2072 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2073 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2077 memset(&tpriv->req, 0, sizeof(tpriv->req));
2079 /* IOUSBDeviceInterface expects the request in cpu endianness */
2080 tpriv->req.bmRequestType = setup->bmRequestType;
2081 tpriv->req.bRequest = setup->bRequest;
2082 /* these values should be in bus order from libusb_fill_control_setup */
2083 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2084 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2085 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2086 /* data is stored after the libusb control block */
2087 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2088 tpriv->req.completionTimeout = transfer->timeout;
2089 tpriv->req.noDataTimeout = transfer->timeout;
2091 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2093 /* all transfers in libusb-1.0 are async */
2095 if (transfer->endpoint) {
2096 struct darwin_interface *cInterface;
2099 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2100 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2102 return LIBUSB_ERROR_NOT_FOUND;
2105 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2107 /* control request on endpoint 0 */
2108 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2110 if (kresult != kIOReturnSuccess)
2111 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2113 return darwin_to_libusb (kresult);
2116 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2117 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2119 switch (transfer->type) {
2120 case LIBUSB_TRANSFER_TYPE_CONTROL:
2121 return submit_control_transfer(itransfer);
2122 case LIBUSB_TRANSFER_TYPE_BULK:
2123 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2124 return submit_bulk_transfer(itransfer);
2125 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2126 return submit_iso_transfer(itransfer);
2127 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2128 #if InterfaceVersion >= 550
2129 return submit_stream_transfer(itransfer);
2131 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2132 return LIBUSB_ERROR_NOT_SUPPORTED;
2135 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2136 return LIBUSB_ERROR_INVALID_PARAM;
2140 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2141 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2142 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2145 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2148 return LIBUSB_ERROR_NO_DEVICE;
2150 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2152 return darwin_to_libusb (kresult);
2155 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2156 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2157 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2158 struct darwin_interface *cInterface;
2159 uint8_t pipeRef, iface;
2162 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2164 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2165 usbi_err (ctx, "endpoint not found on any open interface");
2167 return LIBUSB_ERROR_NOT_FOUND;
2171 return LIBUSB_ERROR_NO_DEVICE;
2173 usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2175 /* abort transactions */
2176 #if InterfaceVersion >= 550
2177 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2178 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2181 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2183 usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
2185 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2186 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2188 return darwin_to_libusb (kresult);
2191 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2192 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2194 switch (transfer->type) {
2195 case LIBUSB_TRANSFER_TYPE_CONTROL:
2196 return cancel_control_transfer(itransfer);
2197 case LIBUSB_TRANSFER_TYPE_BULK:
2198 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2199 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2200 return darwin_abort_transfers (itransfer);
2202 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2203 return LIBUSB_ERROR_INVALID_PARAM;
2207 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2208 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2209 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2210 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2212 usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
2214 /* if requested write a zero packet */
2215 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2216 struct darwin_interface *cInterface;
2219 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2221 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2224 tpriv->result = result;
2225 tpriv->size = (UInt32) (uintptr_t) arg0;
2227 /* signal the core that this transfer is complete */
2228 usbi_signal_transfer_completion(itransfer);
2231 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2232 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2233 result = kIOUSBTransactionTimeout;
2235 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2238 case kIOReturnUnderrun:
2239 case kIOReturnSuccess:
2240 return LIBUSB_TRANSFER_COMPLETED;
2241 case kIOReturnAborted:
2242 return LIBUSB_TRANSFER_CANCELLED;
2243 case kIOUSBPipeStalled:
2244 usbi_dbg (ctx, "transfer error: pipe is stalled");
2245 return LIBUSB_TRANSFER_STALL;
2246 case kIOReturnOverrun:
2247 usbi_warn (ctx, "transfer error: data overrun");
2248 return LIBUSB_TRANSFER_OVERFLOW;
2249 case kIOUSBTransactionTimeout:
2250 usbi_warn (ctx, "transfer error: timed out");
2251 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2252 return LIBUSB_TRANSFER_TIMED_OUT;
2254 usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2255 return LIBUSB_TRANSFER_ERROR;
2259 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2260 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2261 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2262 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2263 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2264 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2265 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2267 if (transfer->type > max_transfer_type) {
2268 usbi_err (ctx, "unknown endpoint type %d", transfer->type);
2269 return LIBUSB_ERROR_INVALID_PARAM;
2272 if (NULL == tpriv) {
2273 usbi_err (ctx, "malformed request is missing transfer priv");
2274 return LIBUSB_ERROR_INVALID_PARAM;
2277 usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2279 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2280 if (is_isoc && tpriv->isoc_framelist) {
2281 /* copy isochronous results back */
2283 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2284 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2285 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2286 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2288 } else if (!is_isoc) {
2289 itransfer->transferred += tpriv->size;
2293 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2294 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2297 #if !defined(HAVE_CLOCK_GETTIME)
2298 void usbi_get_monotonic_time(struct timespec *tp) {
2299 mach_timespec_t sys_time;
2301 /* use system boot time as reference for the monotonic clock */
2302 clock_get_time (clock_monotonic, &sys_time);
2304 tp->tv_sec = sys_time.tv_sec;
2305 tp->tv_nsec = sys_time.tv_nsec;
2308 void usbi_get_real_time(struct timespec *tp) {
2309 mach_timespec_t sys_time;
2311 /* CLOCK_REALTIME represents time since the epoch */
2312 clock_get_time (clock_realtime, &sys_time);
2314 tp->tv_sec = sys_time.tv_sec;
2315 tp->tv_nsec = sys_time.tv_nsec;
2319 #if InterfaceVersion >= 550
2320 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2321 int num_endpoints) {
2322 struct darwin_interface *cInterface;
2323 UInt32 supportsStreams;
2327 /* find the minimum number of supported streams on the endpoint list */
2328 for (i = 0 ; i < num_endpoints ; ++i) {
2329 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2333 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2334 if (num_streams > supportsStreams)
2335 num_streams = supportsStreams;
2338 /* it is an error if any endpoint in endpoints does not support streams */
2339 if (0 == num_streams)
2340 return LIBUSB_ERROR_INVALID_PARAM;
2342 /* create the streams */
2343 for (i = 0 ; i < num_endpoints ; ++i) {
2344 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2346 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2347 if (kIOReturnSuccess != rc)
2348 return darwin_to_libusb(rc);
2351 assert(num_streams <= INT_MAX);
2352 return (int)num_streams;
2355 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2356 struct darwin_interface *cInterface;
2357 UInt32 supportsStreams;
2361 for (int i = 0 ; i < num_endpoints ; ++i) {
2362 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2365 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2366 if (0 == supportsStreams)
2367 return LIBUSB_ERROR_INVALID_PARAM;
2369 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2370 if (kIOReturnSuccess != rc)
2371 return darwin_to_libusb(rc);
2374 return LIBUSB_SUCCESS;
2378 #if InterfaceVersion >= 700
2380 /* macOS APIs for getting entitlement values */
2383 #include <Security/Security.h>
2385 typedef struct __SecTask *SecTaskRef;
2386 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2387 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2390 static bool darwin_has_capture_entitlements (void) {
2395 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2399 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2401 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2408 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2409 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2410 enum libusb_error err;
2412 usbi_mutex_lock(&darwin_cached_devices_lock);
2413 (*(dpriv->device))->Release(dpriv->device);
2414 dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
2415 if (!dpriv->device) {
2416 err = LIBUSB_ERROR_NO_DEVICE;
2418 err = LIBUSB_SUCCESS;
2420 usbi_mutex_unlock(&darwin_cached_devices_lock);
2425 /* On macOS, we capture an entire device at once, not individual interfaces. */
2427 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2429 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2431 enum libusb_error err;
2432 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
2434 if (HAS_CAPTURE_DEVICE()) {
2436 return LIBUSB_ERROR_NOT_SUPPORTED;
2439 if (dpriv->capture_count == 0) {
2440 usbi_dbg (ctx, "attempting to detach kernel driver from device");
2442 if (darwin_has_capture_entitlements ()) {
2443 /* request authorization */
2444 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2445 if (kresult != kIOReturnSuccess) {
2446 usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
2447 return darwin_to_libusb (kresult);
2450 /* we need start() to be called again for authorization status to refresh */
2451 err = darwin_reload_device (dev_handle);
2452 if (err != LIBUSB_SUCCESS) {
2456 usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
2459 /* reset device to release existing drivers */
2460 err = darwin_reenumerate_device (dev_handle, true);
2461 if (err != LIBUSB_SUCCESS) {
2465 dpriv->capture_count++;
2466 return LIBUSB_SUCCESS;
2470 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2472 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2474 if (HAS_CAPTURE_DEVICE()) {
2476 return LIBUSB_ERROR_NOT_SUPPORTED;
2479 dpriv->capture_count--;
2480 if (dpriv->capture_count > 0) {
2481 return LIBUSB_SUCCESS;
2484 usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
2486 /* reset device to attach kernel drivers */
2487 return darwin_reenumerate_device (dev_handle, false);
2490 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2491 enum libusb_error ret;
2492 if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
2493 ret = darwin_detach_kernel_driver (dev_handle, iface);
2494 if (ret != LIBUSB_SUCCESS) {
2495 usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
2499 return darwin_claim_interface (dev_handle, iface);
2502 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2503 enum libusb_error ret;
2504 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2506 ret = darwin_release_interface (dev_handle, iface);
2507 if (ret != LIBUSB_SUCCESS) {
2511 if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
2512 ret = darwin_attach_kernel_driver (dev_handle, iface);
2513 if (LIBUSB_SUCCESS != ret) {
2514 usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
2516 /* ignore the error as the interface was successfully released */
2519 return LIBUSB_SUCCESS;
2524 const struct usbi_os_backend usbi_backend = {
2526 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2527 .init = darwin_init,
2528 .exit = darwin_exit,
2529 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2530 .get_config_descriptor = darwin_get_config_descriptor,
2531 .hotplug_poll = darwin_hotplug_poll,
2533 .open = darwin_open,
2534 .close = darwin_close,
2535 .get_configuration = darwin_get_configuration,
2536 .set_configuration = darwin_set_configuration,
2538 .set_interface_altsetting = darwin_set_interface_altsetting,
2539 .clear_halt = darwin_clear_halt,
2540 .reset_device = darwin_reset_device,
2542 #if InterfaceVersion >= 550
2543 .alloc_streams = darwin_alloc_streams,
2544 .free_streams = darwin_free_streams,
2547 .kernel_driver_active = darwin_kernel_driver_active,
2549 #if InterfaceVersion >= 700
2550 .detach_kernel_driver = darwin_detach_kernel_driver,
2551 .attach_kernel_driver = darwin_attach_kernel_driver,
2552 .claim_interface = darwin_capture_claim_interface,
2553 .release_interface = darwin_capture_release_interface,
2555 .claim_interface = darwin_claim_interface,
2556 .release_interface = darwin_release_interface,
2559 .destroy_device = darwin_destroy_device,
2561 .submit_transfer = darwin_submit_transfer,
2562 .cancel_transfer = darwin_cancel_transfer,
2564 .handle_transfer_completion = darwin_handle_transfer_completion,
2566 .device_priv_size = sizeof(struct darwin_device_priv),
2567 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2568 .transfer_priv_size = sizeof(struct darwin_transfer_priv),