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 /* Both kIOMasterPortDefault or kIOMainPortDefault are synonyms for 0. */
58 static const mach_port_t darwin_default_master_port = 0;
60 /* async event thread */
61 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
62 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
64 #if !defined(HAVE_CLOCK_GETTIME)
65 static clock_serv_t clock_realtime;
66 static clock_serv_t clock_monotonic;
69 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
71 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
72 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
74 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
75 static struct list_head darwin_cached_devices;
76 static const char *darwin_device_class = "IOUSBDevice";
78 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
80 /* async event thread */
81 static pthread_t libusb_darwin_at;
83 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
84 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
85 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
86 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
87 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
88 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
89 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
91 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
92 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
93 UInt64 old_session_id);
95 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
96 UInt64 *old_session_id);
98 #if defined(ENABLE_LOGGING)
99 static const char *darwin_error_str (IOReturn result) {
100 static char string_buffer[50];
102 case kIOReturnSuccess:
104 case kIOReturnNotOpen:
105 return "device not opened for exclusive access";
106 case kIOReturnNoDevice:
107 return "no connection to an IOService";
108 case kIOUSBNoAsyncPortErr:
109 return "no async port has been opened for interface";
110 case kIOReturnExclusiveAccess:
111 return "another process has device opened for exclusive access";
112 case kIOUSBPipeStalled:
113 #if defined(kUSBHostReturnPipeStalled)
114 case kUSBHostReturnPipeStalled:
116 return "pipe is stalled";
118 return "could not establish a connection to the Darwin kernel";
119 case kIOUSBTransactionTimeout:
120 return "transaction timed out";
121 case kIOReturnBadArgument:
122 return "invalid argument";
123 case kIOReturnAborted:
124 return "transaction aborted";
125 case kIOReturnNotResponding:
126 return "device not responding";
127 case kIOReturnOverrun:
128 return "data overrun";
129 case kIOReturnCannotWire:
130 return "physical memory can not be wired down";
131 case kIOReturnNoResources:
132 return "out of resources";
133 case kIOUSBHighSpeedSplitError:
134 return "high speed split error";
135 case kIOUSBUnknownPipeErr:
136 return "pipe ref not recognized";
138 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
139 return string_buffer;
144 static enum libusb_error darwin_to_libusb (IOReturn result) {
146 case kIOReturnUnderrun:
147 case kIOReturnSuccess:
148 return LIBUSB_SUCCESS;
149 case kIOReturnNotOpen:
150 case kIOReturnNoDevice:
151 return LIBUSB_ERROR_NO_DEVICE;
152 case kIOReturnExclusiveAccess:
153 return LIBUSB_ERROR_ACCESS;
154 case kIOUSBPipeStalled:
155 #if defined(kUSBHostReturnPipeStalled)
156 case kUSBHostReturnPipeStalled:
158 return LIBUSB_ERROR_PIPE;
159 case kIOReturnBadArgument:
160 return LIBUSB_ERROR_INVALID_PARAM;
161 case kIOUSBTransactionTimeout:
162 return LIBUSB_ERROR_TIMEOUT;
163 case kIOReturnNotResponding:
164 case kIOReturnAborted:
166 case kIOUSBNoAsyncPortErr:
167 case kIOUSBUnknownPipeErr:
169 return LIBUSB_ERROR_OTHER;
173 /* this function must be called with the darwin_cached_devices_lock held */
174 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
175 cached_dev->refcount--;
176 /* free the device and remove it from the cache */
177 if (0 == cached_dev->refcount) {
178 list_del(&cached_dev->list);
180 if (cached_dev->device) {
181 (*(cached_dev->device))->Release(cached_dev->device);
182 cached_dev->device = NULL;
184 IOObjectRelease (cached_dev->service);
189 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
190 cached_dev->refcount++;
193 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) {
194 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
196 /* current interface */
197 struct darwin_interface *cInterface;
201 struct libusb_context *ctx = HANDLE_CTX(dev_handle);
203 usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
205 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
206 cInterface = &priv->interfaces[iface];
208 if (dev_handle->claimed_interfaces & (1U << iface)) {
209 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
210 if (cInterface->endpoint_addrs[i] == ep) {
217 *interface_out = cInterface;
219 usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
220 return LIBUSB_SUCCESS;
226 /* No pipe found with the correct endpoint address */
227 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
229 return LIBUSB_ERROR_NOT_FOUND;
232 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
233 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
236 return kIOReturnError;
239 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
240 &kCFTypeDictionaryKeyCallBacks,
241 &kCFTypeDictionaryValueCallBacks);
243 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
244 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
245 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
247 if (propertyMatchDict && locationCF) {
248 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
249 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
251 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
253 /* release our references as per the Create Rule */
254 if (propertyMatchDict)
255 CFRelease (propertyMatchDict);
257 CFRelease (locationCF);
260 return IOServiceGetMatchingServices(darwin_default_master_port, matchingDict, deviceIterator);
263 /* Returns 1 on success, 0 on failure. */
264 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
265 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
269 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
270 success = CFNumberGetValue(cfNumber, type, p);
273 CFRelease (cfNumber);
276 return (success != 0);
279 /* Returns 1 on success, 0 on failure. */
280 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
281 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
282 bool success = false;
285 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
286 CFIndex length = CFDataGetLength (cfData);
291 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
301 static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
303 io_cf_plugin_ref_t *plugInInterface = NULL;
304 usb_device_t **device;
307 const int max_retries = 5;
309 /* The IOCreatePlugInInterfaceForService function might consistently return
310 an "out of resources" error with certain USB devices the first time we run
311 it. The reason is still unclear, but retrying fixes the problem */
312 for (int count = 0; count < max_retries; count++) {
313 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
314 kIOCFPlugInInterfaceID, &plugInInterface,
316 if (kIOReturnSuccess == kresult && plugInInterface) {
320 usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
322 /* sleep for a little while before trying again */
323 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
326 if (kIOReturnSuccess != kresult || !plugInInterface) {
327 usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
331 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
333 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
334 (*plugInInterface)->Release (plugInInterface);
339 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
341 struct darwin_cached_device *cached_device;
342 UInt64 old_session_id;
343 struct libusb_context *ctx;
344 io_service_t service;
347 usbi_mutex_lock(&active_contexts_lock);
349 while ((service = IOIteratorNext(add_devices))) {
350 ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
351 if (ret < 0 || !cached_device->can_enumerate) {
355 /* add this device to each active context's device list */
356 for_each_context(ctx) {
357 process_new_device (ctx, cached_device, old_session_id);
360 if (cached_device->in_reenumerate) {
361 usbi_dbg (NULL, "cached device in reset state. reset complete...");
362 cached_device->in_reenumerate = false;
365 IOObjectRelease(service);
368 usbi_mutex_unlock(&active_contexts_lock);
371 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
373 struct libusb_device *dev = NULL;
374 struct libusb_context *ctx;
375 struct darwin_cached_device *old_device;
378 UInt64 session, locationID;
381 usbi_mutex_lock(&active_contexts_lock);
383 while ((device = IOIteratorNext (rem_devices)) != 0) {
384 bool is_reenumerating = false;
386 /* get the location from the i/o registry */
387 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
388 (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
389 IOObjectRelease (device);
393 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
394 otherwise no cached device will ever get freed */
395 usbi_mutex_lock(&darwin_cached_devices_lock);
396 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
397 if (old_device->session == session) {
398 if (old_device->in_reenumerate) {
399 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
400 * will deref if needed. */
401 usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
402 session, locationID);
404 /* the device object is no longer usable so go ahead and release it */
405 if (old_device->device) {
406 (*(old_device->device))->Release(old_device->device);
407 old_device->device = NULL;
410 is_reenumerating = true;
412 darwin_deref_cached_device (old_device);
419 usbi_mutex_unlock(&darwin_cached_devices_lock);
420 if (is_reenumerating) {
424 for_each_context(ctx) {
425 usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
427 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
429 /* signal the core that this device has been disconnected. the core will tear down this device
430 when the reference count reaches 0 */
431 usbi_disconnect_device(dev);
432 libusb_unref_device(dev);
437 usbi_mutex_unlock(&active_contexts_lock);
440 static void darwin_hotplug_poll (void)
442 /* not sure if 1 ms will be too long/short but it should work ok */
443 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
445 /* since a kernel thread may notify the IOIterators used for
446 * hotplug notification we can't just clear the iterators.
447 * instead just wait until all IOService providers are quiet */
448 (void) IOKitWaitQuiet (darwin_default_master_port, &timeout);
451 static void darwin_clear_iterator (io_iterator_t iter) {
454 while ((device = IOIteratorNext (iter)) != 0)
455 IOObjectRelease (device);
458 static void darwin_fail_startup(void) {
459 pthread_mutex_lock (&libusb_darwin_at_mutex);
460 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
461 pthread_cond_signal (&libusb_darwin_at_cond);
462 pthread_mutex_unlock (&libusb_darwin_at_mutex);
466 static void *darwin_event_thread_main (void *arg0) {
468 struct libusb_context *ctx = (struct libusb_context *)arg0;
469 CFRunLoopRef runloop;
470 CFRunLoopSourceRef libusb_shutdown_cfsource;
471 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
473 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
474 /* Set this thread's name, so it can be seen in the debugger
475 and crash reports. */
476 pthread_setname_np ("org.libusb.device-hotplug");
479 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
480 /* Tell the Objective-C garbage collector about this thread.
481 This is required because, unlike NSThreads, pthreads are
482 not automatically registered. Although we don't use
483 Objective-C, we use CoreFoundation, which does.
484 Garbage collection support was entirely removed in 10.12,
485 so don't bother there. */
486 objc_registerThreadWithCollector();
489 /* hotplug (device arrival/removal) sources */
490 CFRunLoopSourceRef libusb_notification_cfsource;
491 io_notification_port_t libusb_notification_port;
492 io_iterator_t libusb_rem_device_iterator;
493 io_iterator_t libusb_add_device_iterator;
495 usbi_dbg (ctx, "creating hotplug event source");
497 runloop = CFRunLoopGetCurrent ();
500 /* add the shutdown cfsource to the run loop */
501 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
502 libusb_shutdown_cfsourcectx.info = runloop;
503 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
504 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
505 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
507 /* add the notification port to the run loop */
508 libusb_notification_port = IONotificationPortCreate (darwin_default_master_port);
509 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
510 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
512 /* create notifications for removed devices */
513 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
514 IOServiceMatching(darwin_device_class),
515 darwin_devices_detached,
516 ctx, &libusb_rem_device_iterator);
518 if (kresult != kIOReturnSuccess) {
519 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
520 CFRelease (libusb_shutdown_cfsource);
522 darwin_fail_startup ();
525 /* create notifications for attached devices */
526 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
527 IOServiceMatching(darwin_device_class),
528 darwin_devices_attached,
529 ctx, &libusb_add_device_iterator);
531 if (kresult != kIOReturnSuccess) {
532 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
533 CFRelease (libusb_shutdown_cfsource);
535 darwin_fail_startup ();
539 darwin_clear_iterator (libusb_rem_device_iterator);
540 darwin_clear_iterator (libusb_add_device_iterator);
542 usbi_dbg (ctx, "darwin event thread ready to receive events");
544 /* signal the main thread that the hotplug runloop has been created. */
545 pthread_mutex_lock (&libusb_darwin_at_mutex);
546 libusb_darwin_acfl = runloop;
547 libusb_darwin_acfls = libusb_shutdown_cfsource;
548 pthread_cond_signal (&libusb_darwin_at_cond);
549 pthread_mutex_unlock (&libusb_darwin_at_mutex);
551 /* run the runloop */
554 usbi_dbg (ctx, "darwin event thread exiting");
556 /* signal the main thread that the hotplug runloop has finished. */
557 pthread_mutex_lock (&libusb_darwin_at_mutex);
558 libusb_darwin_acfls = NULL;
559 libusb_darwin_acfl = NULL;
560 pthread_cond_signal (&libusb_darwin_at_cond);
561 pthread_mutex_unlock (&libusb_darwin_at_mutex);
563 /* remove the notification cfsource */
564 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
566 /* remove the shutdown cfsource */
567 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
569 /* delete notification port */
570 IONotificationPortDestroy (libusb_notification_port);
572 /* delete iterators */
573 IOObjectRelease (libusb_rem_device_iterator);
574 IOObjectRelease (libusb_add_device_iterator);
576 CFRelease (libusb_shutdown_cfsource);
582 /* cleanup function to destroy cached devices */
583 static void darwin_cleanup_devices(void) {
584 struct darwin_cached_device *dev, *next;
586 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
587 darwin_deref_cached_device(dev);
591 static int darwin_init(struct libusb_context *ctx) {
595 first_init = (1 == ++init_count);
599 if (NULL == darwin_cached_devices.next) {
600 list_init (&darwin_cached_devices);
602 assert(list_empty(&darwin_cached_devices));
603 #if !defined(HAVE_CLOCK_GETTIME)
604 /* create the clocks that will be used if clock_gettime() is not available */
605 host_name_port_t host_self;
607 host_self = mach_host_self();
608 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
609 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
610 mach_port_deallocate(mach_task_self(), host_self);
614 rc = darwin_scan_devices (ctx);
615 if (LIBUSB_SUCCESS != rc)
619 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
621 usbi_err (ctx, "could not create event thread, error %d", rc);
622 rc = LIBUSB_ERROR_OTHER;
626 pthread_mutex_lock (&libusb_darwin_at_mutex);
627 while (!libusb_darwin_acfl)
628 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
629 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
630 libusb_darwin_acfl = NULL;
631 rc = LIBUSB_ERROR_OTHER;
633 pthread_mutex_unlock (&libusb_darwin_at_mutex);
636 pthread_join (libusb_darwin_at, NULL);
640 if (LIBUSB_SUCCESS != rc) {
642 darwin_cleanup_devices ();
643 #if !defined(HAVE_CLOCK_GETTIME)
644 mach_port_deallocate(mach_task_self(), clock_realtime);
645 mach_port_deallocate(mach_task_self(), clock_monotonic);
654 static void darwin_exit (struct libusb_context *ctx) {
657 if (0 == --init_count) {
658 /* stop the event runloop and wait for the thread to terminate. */
659 pthread_mutex_lock (&libusb_darwin_at_mutex);
660 CFRunLoopSourceSignal (libusb_darwin_acfls);
661 CFRunLoopWakeUp (libusb_darwin_acfl);
662 while (libusb_darwin_acfl)
663 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
664 pthread_mutex_unlock (&libusb_darwin_at_mutex);
665 pthread_join (libusb_darwin_at, NULL);
667 darwin_cleanup_devices ();
669 #if !defined(HAVE_CLOCK_GETTIME)
670 mach_port_deallocate(mach_task_self(), clock_realtime);
671 mach_port_deallocate(mach_task_self(), clock_monotonic);
676 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
677 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
679 IOUSBConfigurationDescriptorPtr desc;
682 /* is there a simpler way to determine the index? */
683 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
684 if (kresult != kIOReturnSuccess)
685 return darwin_to_libusb (kresult);
687 for (i = 0 ; i < numConfig ; i++) {
688 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
690 if (desc->bConfigurationValue == config_value)
694 /* configuration not found */
695 return LIBUSB_ERROR_NOT_FOUND;
698 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
699 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
702 if (0 == priv->active_config)
703 return LIBUSB_ERROR_NOT_FOUND;
705 config_index = get_configuration_index (dev, priv->active_config);
706 if (config_index < 0)
709 assert(config_index >= 0 && config_index <= UINT8_MAX);
710 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
713 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
714 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
715 IOUSBConfigurationDescriptorPtr desc;
719 if (!priv || !priv->device)
720 return LIBUSB_ERROR_OTHER;
722 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
723 if (kresult == kIOReturnSuccess) {
724 /* copy descriptor */
725 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
726 len = libusb_le16_to_cpu(desc->wTotalLength);
728 memmove (buffer, desc, len);
731 ret = darwin_to_libusb (kresult);
732 if (ret != LIBUSB_SUCCESS)
738 /* check whether the os has configured the device */
739 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
740 usb_device_t **darwin_device = dev->device;
742 IOUSBConfigurationDescriptorPtr configDesc;
743 IOUSBFindInterfaceRequest request;
745 io_iterator_t interface_iterator;
746 io_service_t firstInterface;
748 if (dev->dev_descriptor.bNumConfigurations < 1) {
749 usbi_err (ctx, "device has no configurations");
750 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
753 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
755 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
756 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
757 usbi_dbg (ctx, "ignoring configuration on root hub simulation");
758 dev->active_config = 0;
759 return LIBUSB_SUCCESS;
762 /* find the first configuration */
763 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
764 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
766 /* check if the device is already configured. there is probably a better way than iterating over the
767 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
768 might lock up on the device request) */
770 /* Setup the Interface Request */
771 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
772 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
773 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
774 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
776 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
777 if (kresult != kIOReturnSuccess)
778 return darwin_to_libusb (kresult);
781 firstInterface = IOIteratorNext(interface_iterator);
783 /* done with the interface iterator */
784 IOObjectRelease(interface_iterator);
786 if (firstInterface) {
787 IOObjectRelease (firstInterface);
789 /* device is configured */
790 if (dev->dev_descriptor.bNumConfigurations == 1)
791 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
792 dev->active_config = dev->first_config;
794 /* devices with more than one configuration should work with GetConfiguration */
795 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
798 dev->active_config = 0;
800 usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
802 return LIBUSB_SUCCESS;
805 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
806 IOUSBDevRequestTO req;
808 assert(buffer_size <= UINT16_MAX);
810 memset (buffer, 0, buffer_size);
812 /* Set up request for descriptor/ */
813 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
814 req.bRequest = kUSBRqGetDescriptor;
815 req.wValue = (UInt16)(desc << 8);
816 req.wIndex = desc_index;
817 req.wLength = (UInt16)buffer_size;
819 req.noDataTimeout = 20;
820 req.completionTimeout = 100;
822 return (*device)->DeviceRequestTO (device, &req);
825 static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
826 usb_device_t **device = dev->device;
828 long delay = 30000; // microseconds
829 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
831 IOReturn ret = 0, ret2;
833 UInt16 idProduct, idVendor;
835 dev->can_enumerate = 0;
837 (*device)->GetDeviceClass (device, &bDeviceClass);
838 (*device)->GetDeviceProduct (device, &idProduct);
839 (*device)->GetDeviceVendor (device, &idVendor);
841 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
842 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
843 * to follow the spec as closely as possible, try opening the device */
844 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
847 /**** retrieve device descriptor ****/
848 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
850 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
851 /* received an overrun error but we still received a device descriptor */
852 ret = kIOReturnSuccess;
854 if (kIOUSBVendorIDAppleComputer == idVendor) {
855 /* NTH: don't bother retrying or unsuspending Apple devices */
859 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
860 0 == dev->dev_descriptor.bcdUSB)) {
861 /* work around for incorrectly configured devices */
862 if (try_reconfigure && is_open) {
863 usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
865 /* set the first configuration */
866 (*device)->SetConfiguration(device, 1);
868 /* don't try to reconfigure again */
872 ret = kIOUSBPipeStalled;
875 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
876 /* device may be suspended. unsuspend it and try again */
877 #if DeviceVersion >= 320
880 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
881 (void)(*device)->GetUSBDeviceInformation (device, &info);
883 /* note that the device was suspended */
884 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
889 /* try to unsuspend the device */
890 ret2 = (*device)->USBDeviceSuspend (device, 0);
891 if (kIOReturnSuccess != ret2) {
892 /* prevent log spew from poorly behaving devices. this indicates the
893 os actually had trouble communicating with the device */
894 usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
902 if (kIOReturnSuccess != ret) {
903 usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
904 /* sleep for a little while before trying again */
905 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
907 } while (kIOReturnSuccess != ret && retries--);
910 /* resuspend the device */
911 (void)(*device)->USBDeviceSuspend (device, 1);
914 (void) (*device)->USBDeviceClose (device);
916 if (ret != kIOReturnSuccess) {
917 /* a debug message was already printed out for this error */
918 if (LIBUSB_CLASS_HUB == bDeviceClass)
919 usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
920 idVendor, idProduct, darwin_error_str (ret), ret);
922 usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
923 idVendor, idProduct, darwin_error_str (ret), ret);
924 return darwin_to_libusb (ret);
927 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
928 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
929 /* not a valid device */
930 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
931 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
932 return LIBUSB_ERROR_NO_DEVICE;
935 usbi_dbg (ctx, "cached device descriptor:");
936 usbi_dbg (ctx, " bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
937 usbi_dbg (ctx, " bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
938 usbi_dbg (ctx, " bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
939 usbi_dbg (ctx, " bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
940 usbi_dbg (ctx, " bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
941 usbi_dbg (ctx, " bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
942 usbi_dbg (ctx, " idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
943 usbi_dbg (ctx, " idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
944 usbi_dbg (ctx, " bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
945 usbi_dbg (ctx, " iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
946 usbi_dbg (ctx, " iProduct: 0x%02x", dev->dev_descriptor.iProduct);
947 usbi_dbg (ctx, " iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
948 usbi_dbg (ctx, " bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
950 dev->can_enumerate = 1;
952 return LIBUSB_SUCCESS;
955 /* Returns 1 on success, 0 on failure. */
956 static bool get_device_port (io_service_t service, UInt8 *port) {
961 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
965 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
966 if (kIOReturnSuccess == kresult) {
967 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
968 IOObjectRelease (parent);
974 /* Returns 1 on success, 0 on failure. */
975 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
979 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
981 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
982 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
988 /* We ran out of parents */
992 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
993 UInt64 *old_session_id) {
994 struct darwin_cached_device *new_device;
995 UInt64 sessionID = 0, parent_sessionID = 0;
996 UInt32 locationID = 0;
997 enum libusb_error ret = LIBUSB_SUCCESS;
998 usb_device_t **device;
1001 /* assuming sessionID != 0 normally (never seen it be 0) */
1002 *old_session_id = 0;
1005 /* get some info from the io registry */
1006 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1007 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1008 if (!get_device_port (service, &port)) {
1009 usbi_dbg(ctx, "could not get connected port number");
1012 usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
1014 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1015 usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
1018 usbi_mutex_lock(&darwin_cached_devices_lock);
1020 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1021 usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1022 sessionID, locationID, new_device->session, new_device->location);
1023 if (new_device->location == locationID && new_device->in_reenumerate) {
1024 usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
1025 *old_session_id = new_device->session;
1029 if (new_device->session == sessionID) {
1030 usbi_dbg(ctx, "using cached device for device");
1031 *cached_out = new_device;
1039 usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
1041 device = darwin_device_from_service (ctx, service);
1043 ret = LIBUSB_ERROR_NO_DEVICE;
1047 if (!(*old_session_id)) {
1048 new_device = calloc (1, sizeof (*new_device));
1050 ret = LIBUSB_ERROR_NO_MEM;
1054 /* add this device to the cached device list */
1055 list_add(&new_device->list, &darwin_cached_devices);
1057 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1059 /* keep a reference to this device */
1060 darwin_ref_cached_device(new_device);
1062 (*device)->GetLocationID (device, &new_device->location);
1063 new_device->port = port;
1064 new_device->parent_session = parent_sessionID;
1066 /* release the ref to old device's service */
1067 IOObjectRelease (new_device->service);
1070 /* keep track of devices regardless of if we successfully enumerate them to
1071 prevent them from being enumerated multiple times */
1072 *cached_out = new_device;
1074 new_device->session = sessionID;
1075 new_device->device = device;
1076 new_device->service = service;
1078 /* retain the service */
1079 IOObjectRetain (service);
1081 /* cache the device descriptor */
1082 ret = darwin_cache_device_descriptor(ctx, new_device);
1086 if (new_device->can_enumerate) {
1087 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1088 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1089 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1090 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1094 usbi_mutex_unlock(&darwin_cached_devices_lock);
1099 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1100 UInt64 old_session_id) {
1101 struct darwin_device_priv *priv;
1102 struct libusb_device *dev = NULL;
1104 enum libusb_error ret = LIBUSB_SUCCESS;
1107 /* check current active configuration (and cache the first configuration value--
1108 which may be used by claim_interface) */
1109 ret = darwin_check_configuration (ctx, cached_device);
1113 if (0 != old_session_id) {
1114 usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1115 ctx, old_session_id, cached_device->session);
1116 /* save the libusb device before the session id is updated */
1117 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1121 usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
1122 ctx, cached_device->session);
1124 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1126 return LIBUSB_ERROR_NO_MEM;
1129 priv = usbi_get_device_priv(dev);
1131 priv->dev = cached_device;
1132 darwin_ref_cached_device (priv->dev);
1133 dev->port_number = cached_device->port;
1134 /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
1135 (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
1136 dev->bus_number = cached_device->location >> 24;
1137 assert(cached_device->address <= UINT8_MAX);
1138 dev->device_address = (uint8_t)cached_device->address;
1140 priv = usbi_get_device_priv(dev);
1143 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1144 "mismatch between libusb and IOKit device descriptor sizes");
1145 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1146 usbi_localize_device_descriptor(&dev->device_descriptor);
1147 dev->session_data = cached_device->session;
1149 if (NULL != dev->parent_dev) {
1150 libusb_unref_device(dev->parent_dev);
1151 dev->parent_dev = NULL;
1154 if (cached_device->parent_session > 0) {
1155 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1158 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1161 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1162 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1163 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1164 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1165 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1167 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1168 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1171 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1174 ret = usbi_sanitize_device (dev);
1178 usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
1179 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1183 if (!cached_device->in_reenumerate && 0 == ret) {
1184 usbi_connect_device (dev);
1186 libusb_unref_device (dev);
1192 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1193 struct darwin_cached_device *cached_device;
1194 UInt64 old_session_id;
1195 io_iterator_t deviceIterator;
1196 io_service_t service;
1200 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1201 if (kresult != kIOReturnSuccess)
1202 return darwin_to_libusb (kresult);
1204 while ((service = IOIteratorNext (deviceIterator))) {
1205 ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
1206 if (ret < 0 || !cached_device->can_enumerate) {
1210 (void) process_new_device (ctx, cached_device, old_session_id);
1212 IOObjectRelease(service);
1215 IOObjectRelease(deviceIterator);
1217 return LIBUSB_SUCCESS;
1220 static int darwin_open (struct libusb_device_handle *dev_handle) {
1221 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1222 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1225 if (0 == dpriv->open_count) {
1226 /* try to open the device */
1227 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1228 if (kresult != kIOReturnSuccess) {
1229 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1231 if (kIOReturnExclusiveAccess != kresult) {
1232 return darwin_to_libusb (kresult);
1235 /* it is possible to perform some actions on a device that is not open so do not return an error */
1236 priv->is_open = false;
1238 priv->is_open = true;
1241 /* create async event source */
1242 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1243 if (kresult != kIOReturnSuccess) {
1244 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1246 if (priv->is_open) {
1247 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1250 priv->is_open = false;
1252 return darwin_to_libusb (kresult);
1255 CFRetain (libusb_darwin_acfl);
1257 /* add the cfSource to the async run loop */
1258 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1261 /* device opened successfully */
1262 dpriv->open_count++;
1264 usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
1269 static void darwin_close (struct libusb_device_handle *dev_handle) {
1270 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1271 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1275 if (dpriv->open_count == 0) {
1276 /* something is probably very wrong if this is the case */
1277 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1281 dpriv->open_count--;
1282 if (NULL == dpriv->device) {
1283 usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
1287 /* make sure all interfaces are released */
1288 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1289 if (dev_handle->claimed_interfaces & (1U << i))
1290 libusb_release_interface (dev_handle, i);
1292 if (0 == dpriv->open_count) {
1293 /* delete the device's async event source */
1294 if (priv->cfSource) {
1295 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1296 CFRelease (priv->cfSource);
1297 priv->cfSource = NULL;
1298 CFRelease (libusb_darwin_acfl);
1301 if (priv->is_open) {
1302 /* close the device */
1303 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1304 if (kresult != kIOReturnSuccess) {
1305 /* Log the fact that we had a problem closing the file, however failing a
1306 * close isn't really an error, so return success anyway */
1307 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1313 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1314 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1316 *config = dpriv->active_config;
1318 return LIBUSB_SUCCESS;
1321 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1322 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1329 /* Setting configuration will invalidate the interface, so we need
1330 to reclaim it. First, dispose of existing interfaces, if any. */
1331 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1332 if (dev_handle->claimed_interfaces & (1U << i))
1333 darwin_release_interface (dev_handle, i);
1335 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1336 if (kresult != kIOReturnSuccess)
1337 return darwin_to_libusb (kresult);
1339 /* Reclaim any interfaces. */
1340 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1341 if (dev_handle->claimed_interfaces & (1U << i))
1342 darwin_claim_interface (dev_handle, i);
1344 dpriv->active_config = (UInt8)config;
1346 return LIBUSB_SUCCESS;
1349 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1350 IOUSBFindInterfaceRequest request;
1352 io_iterator_t interface_iterator;
1353 UInt8 bInterfaceNumber;
1356 *usbInterfacep = IO_OBJECT_NULL;
1358 /* Setup the Interface Request */
1359 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1360 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1361 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1362 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1364 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1365 if (kresult != kIOReturnSuccess)
1368 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1369 /* find the interface number */
1370 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1373 if (ret && bInterfaceNumber == ifc) {
1377 (void) IOObjectRelease (*usbInterfacep);
1380 /* done with the interface iterator */
1381 IOObjectRelease(interface_iterator);
1383 return kIOReturnSuccess;
1386 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1387 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1389 /* current interface */
1390 struct darwin_interface *cInterface = &priv->interfaces[iface];
1394 UInt8 numep, direction, number;
1395 UInt8 dont_care1, dont_care3;
1398 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1401 usbi_dbg (ctx, "building table of endpoints.");
1403 /* retrieve the total number of endpoints on this interface */
1404 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1405 if (kresult != kIOReturnSuccess) {
1406 usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1407 return darwin_to_libusb (kresult);
1410 /* iterate through pipe references */
1411 for (UInt8 i = 1 ; i <= numep ; i++) {
1412 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1413 &dont_care2, &dont_care3);
1415 if (kresult != kIOReturnSuccess) {
1416 /* probably a buggy device. try to get the endpoint address from the descriptors */
1417 struct libusb_config_descriptor *config;
1418 const struct libusb_endpoint_descriptor *endpoint_desc;
1421 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1422 if (kresult != kIOReturnSuccess) {
1423 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1424 return darwin_to_libusb (kresult);
1427 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1428 if (LIBUSB_SUCCESS != rc) {
1432 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1434 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1436 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1439 usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1440 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1443 cInterface->num_endpoints = numep;
1445 return LIBUSB_SUCCESS;
1448 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1449 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1450 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1451 io_service_t usbInterface = IO_OBJECT_NULL;
1453 enum libusb_error ret;
1454 IOCFPlugInInterface **plugInInterface = NULL;
1457 /* current interface */
1458 struct darwin_interface *cInterface = &priv->interfaces[iface];
1460 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1462 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1463 if (kresult != kIOReturnSuccess)
1464 return darwin_to_libusb (kresult);
1466 /* make sure we have an interface */
1467 if (!usbInterface && dpriv->first_config != 0) {
1468 usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
1470 /* set the configuration */
1471 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1472 if (ret != LIBUSB_SUCCESS) {
1473 usbi_err (ctx, "could not set configuration");
1477 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1478 if (kresult != kIOReturnSuccess) {
1479 usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
1480 return darwin_to_libusb (kresult);
1484 if (!usbInterface) {
1485 usbi_info (ctx, "interface not found");
1486 return LIBUSB_ERROR_NOT_FOUND;
1489 /* get an interface to the device's interface */
1490 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1491 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1493 /* ignore release error */
1494 (void)IOObjectRelease (usbInterface);
1496 if (kresult != kIOReturnSuccess) {
1497 usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1498 return darwin_to_libusb (kresult);
1501 if (!plugInInterface) {
1502 usbi_err (ctx, "plugin interface not found");
1503 return LIBUSB_ERROR_NOT_FOUND;
1506 /* Do the actual claim */
1507 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1508 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1509 (LPVOID)&cInterface->interface);
1510 /* We no longer need the intermediate plug-in */
1511 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1512 (*plugInInterface)->Release (plugInInterface);
1513 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1514 usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
1515 return darwin_to_libusb (kresult);
1518 /* claim the interface */
1519 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1520 if (kresult != kIOReturnSuccess) {
1521 usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
1522 return darwin_to_libusb (kresult);
1525 /* update list of endpoints */
1526 ret = get_endpoints (dev_handle, iface);
1528 /* this should not happen */
1529 darwin_release_interface (dev_handle, iface);
1530 usbi_err (ctx, "could not build endpoint table");
1534 cInterface->cfSource = NULL;
1536 /* create async event source */
1537 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1538 if (kresult != kIOReturnSuccess) {
1539 usbi_err (ctx, "could not create async event source");
1541 /* can't continue without an async event source */
1542 (void)darwin_release_interface (dev_handle, iface);
1544 return darwin_to_libusb (kresult);
1547 /* add the cfSource to the async thread's run loop */
1548 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1550 usbi_dbg (ctx, "interface opened");
1552 return LIBUSB_SUCCESS;
1555 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1556 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1559 /* current interface */
1560 struct darwin_interface *cInterface = &priv->interfaces[iface];
1562 /* Check to see if an interface is open */
1563 if (!cInterface->interface)
1564 return LIBUSB_SUCCESS;
1566 /* clean up endpoint data */
1567 cInterface->num_endpoints = 0;
1569 /* delete the interface's async event source */
1570 if (cInterface->cfSource) {
1571 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1572 CFRelease (cInterface->cfSource);
1575 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1576 if (kresult != kIOReturnSuccess)
1577 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1579 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1580 if (kresult != kIOReturnSuccess)
1581 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1583 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1585 return darwin_to_libusb (kresult);
1588 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1589 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1591 enum libusb_error ret;
1593 uint8_t old_alt_setting;
1595 /* current interface */
1596 struct darwin_interface *cInterface = &priv->interfaces[iface];
1598 if (!cInterface->interface)
1599 return LIBUSB_ERROR_NO_DEVICE;
1601 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1602 if (kresult == kIOReturnSuccess) {
1603 /* update the list of endpoints */
1604 ret = get_endpoints (dev_handle, iface);
1606 /* this should not happen */
1607 darwin_release_interface (dev_handle, iface);
1608 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1613 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1615 ret = darwin_to_libusb(kresult);
1616 if (ret != LIBUSB_ERROR_PIPE) {
1617 return darwin_to_libusb (kresult);
1620 /* If a device only supports a default setting for the specified interface, then a STALL
1621 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1622 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1623 of the interface (as would have been done per 9.1.1.5) and return success. */
1625 /* For some reason we need to reclaim the interface after the pipe error */
1626 ret = darwin_claim_interface (dev_handle, iface);
1629 darwin_release_interface (dev_handle, iface);
1630 usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface");
1633 /* Return error if a change to another value was attempted */
1634 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &old_alt_setting);
1635 if (kresult == kIOReturnSuccess && altsetting != old_alt_setting)
1636 return LIBUSB_ERROR_PIPE;
1638 for (i = 0 ; i < cInterface->num_endpoints ; i++)
1639 darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1641 return LIBUSB_SUCCESS;
1644 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1645 /* current interface */
1646 struct darwin_interface *cInterface;
1650 /* determine the interface/endpoint to use */
1651 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1652 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1654 return LIBUSB_ERROR_NOT_FOUND;
1657 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1658 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1659 if (kresult != kIOReturnSuccess)
1660 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1662 return darwin_to_libusb (kresult);
1665 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1666 unsigned long claimed_interfaces) {
1667 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1668 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1669 int open_count = dpriv->open_count;
1672 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1674 /* clear claimed interfaces temporarily */
1675 dev_handle->claimed_interfaces = 0;
1677 /* close and re-open the device */
1678 priv->is_open = false;
1679 dpriv->open_count = 1;
1681 /* clean up open interfaces */
1682 (void) darwin_close (dev_handle);
1684 /* re-open the device */
1685 ret = darwin_open (dev_handle);
1686 dpriv->open_count = open_count;
1687 if (LIBUSB_SUCCESS != ret) {
1688 /* could not restore configuration */
1689 return LIBUSB_ERROR_NOT_FOUND;
1692 if (dpriv->active_config != active_config) {
1693 usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
1695 ret = darwin_set_configuration (dev_handle, active_config);
1696 if (LIBUSB_SUCCESS != ret) {
1697 usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
1698 return LIBUSB_ERROR_NOT_FOUND;
1702 usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
1704 if (claimed_interfaces) {
1705 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1706 if (!(claimed_interfaces & (1U << iface))) {
1710 usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
1712 ret = darwin_claim_interface (dev_handle, iface);
1713 if (LIBUSB_SUCCESS != ret) {
1714 usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
1715 return LIBUSB_ERROR_NOT_FOUND;
1718 dev_handle->claimed_interfaces |= 1U << iface;
1722 usbi_dbg (ctx, "darwin/restore_state: device state restored");
1724 return LIBUSB_SUCCESS;
1727 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1728 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1729 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1730 int8_t active_config = dpriv->active_config;
1732 IOUSBDeviceDescriptor descriptor;
1733 IOUSBConfigurationDescriptorPtr cached_configuration;
1734 IOUSBConfigurationDescriptor *cached_configurations;
1739 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1741 if (dpriv->in_reenumerate) {
1742 /* ack, two (or more) threads are trying to reset the device! abort! */
1743 return LIBUSB_ERROR_NOT_FOUND;
1746 dpriv->in_reenumerate = true;
1748 /* store copies of descriptors so they can be compared after the reset */
1749 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1750 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1752 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1753 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1754 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1757 /* if we need to release capture */
1758 if (HAS_CAPTURE_DEVICE()) {
1760 options |= kUSBReEnumerateCaptureDeviceMask;
1766 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1767 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1768 if (kresult != kIOReturnSuccess) {
1769 usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1770 dpriv->in_reenumerate = false;
1771 return darwin_to_libusb (kresult);
1774 /* capture mode does not re-enumerate but it does require re-open */
1776 usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
1777 dpriv->in_reenumerate = false;
1778 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1781 usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
1784 while (dpriv->in_reenumerate) {
1785 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1786 nanosleep (&delay, NULL);
1787 if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
1788 usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
1789 dpriv->in_reenumerate = false;
1790 return LIBUSB_ERROR_TIMEOUT;
1794 /* compare descriptors */
1795 usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
1797 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1798 /* device descriptor changed. need to return not found. */
1799 usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
1800 return LIBUSB_ERROR_NOT_FOUND;
1803 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1804 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1805 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1806 usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1807 return LIBUSB_ERROR_NOT_FOUND;
1811 usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
1813 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1816 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1817 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1820 if (dpriv->capture_count > 0) {
1821 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1822 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1823 return darwin_to_libusb (kresult);
1825 return darwin_reenumerate_device (dev_handle, false);
1829 static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
1830 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
1831 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
1832 &kCFTypeDictionaryKeyCallBacks,
1833 &kCFTypeDictionaryValueCallBacks);
1834 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
1835 CFTypeRef interfaceCF = CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);
1837 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
1838 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
1839 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);
1841 CFRelease (interfaceCF);
1842 CFRelease (locationCF);
1843 CFRelease (propertyMatchDict);
1845 return IOServiceGetMatchingService (darwin_default_master_port, matchingDict);
1848 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1849 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1850 io_service_t usb_interface, child = IO_OBJECT_NULL;
1852 /* locate the IO registry entry for this interface */
1853 usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
1854 if (0 == usb_interface) {
1855 /* check for the legacy class entry */
1856 usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
1857 if (0 == usb_interface) {
1858 return LIBUSB_ERROR_NOT_FOUND;
1862 /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
1863 (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
1864 IOObjectRelease (usb_interface);
1865 if (IO_OBJECT_NULL != child) {
1866 IOObjectRelease (child);
1874 static void darwin_destroy_device(struct libusb_device *dev) {
1875 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1878 /* need to hold the lock in case this is the last reference to the device */
1879 usbi_mutex_lock(&darwin_cached_devices_lock);
1880 darwin_deref_cached_device (dpriv->dev);
1882 usbi_mutex_unlock(&darwin_cached_devices_lock);
1886 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1887 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1890 uint8_t transferType;
1892 uint16_t maxPacketSize;
1894 struct darwin_interface *cInterface;
1895 #if InterfaceVersion >= 550
1896 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1898 /* None of the values below are used in libusb for bulk transfers */
1899 uint8_t direction, number, interval;
1902 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1903 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1905 return LIBUSB_ERROR_NOT_FOUND;
1908 #if InterfaceVersion >= 550
1909 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1911 transferType = pipeProperties.bTransferType;
1912 maxPacketSize = pipeProperties.wMaxPacketSize;
1914 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1915 &transferType, &maxPacketSize, &interval);
1919 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1920 darwin_error_str(ret), ret);
1921 return darwin_to_libusb (ret);
1924 if (0 != (transfer->length % maxPacketSize)) {
1925 /* do not need a zero packet */
1926 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1929 /* submit the request */
1930 /* timeouts are unavailable on interrupt endpoints */
1931 if (transferType == kUSBInterrupt) {
1932 if (IS_XFERIN(transfer))
1933 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1934 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1936 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1937 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1939 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1941 if (IS_XFERIN(transfer))
1942 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1943 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1944 darwin_async_io_callback, itransfer);
1946 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1947 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1948 darwin_async_io_callback, itransfer);
1952 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1953 darwin_error_str(ret), ret);
1955 return darwin_to_libusb (ret);
1958 #if InterfaceVersion >= 550
1959 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1960 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1961 struct darwin_interface *cInterface;
1965 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1966 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1968 return LIBUSB_ERROR_NOT_FOUND;
1971 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1973 if (IS_XFERIN(transfer))
1974 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1975 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1976 transfer->timeout, darwin_async_io_callback, itransfer);
1978 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1979 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1980 transfer->timeout, darwin_async_io_callback, itransfer);
1983 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1984 darwin_error_str(ret), ret);
1986 return darwin_to_libusb (ret);
1990 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1991 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1992 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1995 uint8_t direction, number, interval, pipeRef, transferType;
1996 uint16_t maxPacketSize;
1998 AbsoluteTime atTime;
2001 struct darwin_interface *cInterface;
2003 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
2004 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
2005 free(tpriv->isoc_framelist);
2006 tpriv->isoc_framelist = NULL;
2009 if (!tpriv->isoc_framelist) {
2010 tpriv->num_iso_packets = transfer->num_iso_packets;
2011 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
2012 if (!tpriv->isoc_framelist)
2013 return LIBUSB_ERROR_NO_MEM;
2016 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
2017 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
2018 unsigned int length = transfer->iso_packet_desc[i].length;
2019 assert(length <= UINT16_MAX);
2020 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
2023 /* determine the interface/endpoint to use */
2024 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2025 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2027 return LIBUSB_ERROR_NOT_FOUND;
2030 /* determine the properties of this endpoint and the speed of the device */
2031 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2032 &transferType, &maxPacketSize, &interval);
2034 /* Last but not least we need the bus frame number */
2035 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
2036 if (kresult != kIOReturnSuccess) {
2037 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
2038 free(tpriv->isoc_framelist);
2039 tpriv->isoc_framelist = NULL;
2041 return darwin_to_libusb (kresult);
2044 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2045 &transferType, &maxPacketSize, &interval);
2047 /* schedule for a frame a little in the future */
2050 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
2051 frame = cInterface->frames[transfer->endpoint];
2053 /* submit the request */
2054 if (IS_XFERIN(transfer))
2055 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2056 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2059 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2060 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2063 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
2065 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
2067 /* High/super speed */
2068 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
2070 if (kresult != kIOReturnSuccess) {
2071 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
2072 darwin_error_str(kresult));
2073 free (tpriv->isoc_framelist);
2074 tpriv->isoc_framelist = NULL;
2077 return darwin_to_libusb (kresult);
2080 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2081 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2082 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2083 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2084 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2088 memset(&tpriv->req, 0, sizeof(tpriv->req));
2090 /* IOUSBDeviceInterface expects the request in cpu endianness */
2091 tpriv->req.bmRequestType = setup->bmRequestType;
2092 tpriv->req.bRequest = setup->bRequest;
2093 /* these values should be in bus order from libusb_fill_control_setup */
2094 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2095 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2096 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2097 /* data is stored after the libusb control block */
2098 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2099 tpriv->req.completionTimeout = transfer->timeout;
2100 tpriv->req.noDataTimeout = transfer->timeout;
2102 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2104 /* all transfers in libusb-1.0 are async */
2106 if (transfer->endpoint) {
2107 struct darwin_interface *cInterface;
2110 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2111 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2113 return LIBUSB_ERROR_NOT_FOUND;
2116 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2118 /* control request on endpoint 0 */
2119 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2121 if (kresult != kIOReturnSuccess)
2122 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2124 return darwin_to_libusb (kresult);
2127 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2128 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2130 switch (transfer->type) {
2131 case LIBUSB_TRANSFER_TYPE_CONTROL:
2132 return submit_control_transfer(itransfer);
2133 case LIBUSB_TRANSFER_TYPE_BULK:
2134 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2135 return submit_bulk_transfer(itransfer);
2136 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2137 return submit_iso_transfer(itransfer);
2138 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2139 #if InterfaceVersion >= 550
2140 return submit_stream_transfer(itransfer);
2142 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2143 return LIBUSB_ERROR_NOT_SUPPORTED;
2146 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2147 return LIBUSB_ERROR_INVALID_PARAM;
2151 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2152 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2153 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2156 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2159 return LIBUSB_ERROR_NO_DEVICE;
2161 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2163 return darwin_to_libusb (kresult);
2166 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2167 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2168 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2169 struct darwin_interface *cInterface;
2170 uint8_t pipeRef, iface;
2173 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2175 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2176 usbi_err (ctx, "endpoint not found on any open interface");
2178 return LIBUSB_ERROR_NOT_FOUND;
2182 return LIBUSB_ERROR_NO_DEVICE;
2184 usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2186 /* abort transactions */
2187 #if InterfaceVersion >= 550
2188 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2189 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2192 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2194 usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
2196 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2197 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2199 return darwin_to_libusb (kresult);
2202 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2203 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2205 switch (transfer->type) {
2206 case LIBUSB_TRANSFER_TYPE_CONTROL:
2207 return cancel_control_transfer(itransfer);
2208 case LIBUSB_TRANSFER_TYPE_BULK:
2209 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2210 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2211 return darwin_abort_transfers (itransfer);
2213 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2214 return LIBUSB_ERROR_INVALID_PARAM;
2218 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2219 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2220 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2221 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2223 usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
2225 /* if requested write a zero packet */
2226 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2227 struct darwin_interface *cInterface;
2230 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2232 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2235 tpriv->result = result;
2236 tpriv->size = (UInt32) (uintptr_t) arg0;
2238 /* signal the core that this transfer is complete */
2239 usbi_signal_transfer_completion(itransfer);
2242 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2243 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2244 result = kIOUSBTransactionTimeout;
2246 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2249 case kIOReturnUnderrun:
2250 case kIOReturnSuccess:
2251 return LIBUSB_TRANSFER_COMPLETED;
2252 case kIOReturnAborted:
2253 return LIBUSB_TRANSFER_CANCELLED;
2254 case kIOUSBPipeStalled:
2255 usbi_dbg (ctx, "transfer error: pipe is stalled");
2256 return LIBUSB_TRANSFER_STALL;
2257 case kIOReturnOverrun:
2258 usbi_warn (ctx, "transfer error: data overrun");
2259 return LIBUSB_TRANSFER_OVERFLOW;
2260 case kIOUSBTransactionTimeout:
2261 usbi_warn (ctx, "transfer error: timed out");
2262 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2263 return LIBUSB_TRANSFER_TIMED_OUT;
2265 usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2266 return LIBUSB_TRANSFER_ERROR;
2270 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2271 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2272 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2273 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2274 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2275 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2276 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2278 if (transfer->type > max_transfer_type) {
2279 usbi_err (ctx, "unknown endpoint type %d", transfer->type);
2280 return LIBUSB_ERROR_INVALID_PARAM;
2283 if (NULL == tpriv) {
2284 usbi_err (ctx, "malformed request is missing transfer priv");
2285 return LIBUSB_ERROR_INVALID_PARAM;
2288 usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2290 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2291 if (is_isoc && tpriv->isoc_framelist) {
2292 /* copy isochronous results back */
2294 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2295 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2296 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2297 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2299 } else if (!is_isoc) {
2300 itransfer->transferred += tpriv->size;
2304 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2305 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2308 #if !defined(HAVE_CLOCK_GETTIME)
2309 void usbi_get_monotonic_time(struct timespec *tp) {
2310 mach_timespec_t sys_time;
2312 /* use system boot time as reference for the monotonic clock */
2313 clock_get_time (clock_monotonic, &sys_time);
2315 tp->tv_sec = sys_time.tv_sec;
2316 tp->tv_nsec = sys_time.tv_nsec;
2319 void usbi_get_real_time(struct timespec *tp) {
2320 mach_timespec_t sys_time;
2322 /* CLOCK_REALTIME represents time since the epoch */
2323 clock_get_time (clock_realtime, &sys_time);
2325 tp->tv_sec = sys_time.tv_sec;
2326 tp->tv_nsec = sys_time.tv_nsec;
2330 #if InterfaceVersion >= 550
2331 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2332 int num_endpoints) {
2333 struct darwin_interface *cInterface;
2334 UInt32 supportsStreams;
2338 /* find the minimum number of supported streams on the endpoint list */
2339 for (i = 0 ; i < num_endpoints ; ++i) {
2340 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2344 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2345 if (num_streams > supportsStreams)
2346 num_streams = supportsStreams;
2349 /* it is an error if any endpoint in endpoints does not support streams */
2350 if (0 == num_streams)
2351 return LIBUSB_ERROR_INVALID_PARAM;
2353 /* create the streams */
2354 for (i = 0 ; i < num_endpoints ; ++i) {
2355 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2357 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2358 if (kIOReturnSuccess != rc)
2359 return darwin_to_libusb(rc);
2362 assert(num_streams <= INT_MAX);
2363 return (int)num_streams;
2366 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2367 struct darwin_interface *cInterface;
2368 UInt32 supportsStreams;
2372 for (int i = 0 ; i < num_endpoints ; ++i) {
2373 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2376 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2377 if (0 == supportsStreams)
2378 return LIBUSB_ERROR_INVALID_PARAM;
2380 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2381 if (kIOReturnSuccess != rc)
2382 return darwin_to_libusb(rc);
2385 return LIBUSB_SUCCESS;
2389 #if InterfaceVersion >= 700
2391 /* macOS APIs for getting entitlement values */
2394 #include <Security/Security.h>
2396 typedef struct __SecTask *SecTaskRef;
2397 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2398 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2401 static bool darwin_has_capture_entitlements (void) {
2406 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2410 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2412 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2419 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2420 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2421 enum libusb_error err;
2423 usbi_mutex_lock(&darwin_cached_devices_lock);
2424 (*(dpriv->device))->Release(dpriv->device);
2425 dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
2426 if (!dpriv->device) {
2427 err = LIBUSB_ERROR_NO_DEVICE;
2429 err = LIBUSB_SUCCESS;
2431 usbi_mutex_unlock(&darwin_cached_devices_lock);
2436 /* On macOS, we capture an entire device at once, not individual interfaces. */
2438 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2440 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2442 enum libusb_error err;
2443 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
2445 if (HAS_CAPTURE_DEVICE()) {
2447 return LIBUSB_ERROR_NOT_SUPPORTED;
2450 if (dpriv->capture_count == 0) {
2451 usbi_dbg (ctx, "attempting to detach kernel driver from device");
2453 if (darwin_has_capture_entitlements ()) {
2454 /* request authorization */
2455 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2456 if (kresult != kIOReturnSuccess) {
2457 usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
2458 return darwin_to_libusb (kresult);
2461 /* we need start() to be called again for authorization status to refresh */
2462 err = darwin_reload_device (dev_handle);
2463 if (err != LIBUSB_SUCCESS) {
2467 usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
2468 if (0 != geteuid()) {
2469 usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
2470 return LIBUSB_ERROR_ACCESS;
2474 /* reset device to release existing drivers */
2475 err = darwin_reenumerate_device (dev_handle, true);
2476 if (err != LIBUSB_SUCCESS) {
2480 dpriv->capture_count++;
2481 return LIBUSB_SUCCESS;
2485 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2487 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2489 if (HAS_CAPTURE_DEVICE()) {
2491 return LIBUSB_ERROR_NOT_SUPPORTED;
2494 dpriv->capture_count--;
2495 if (dpriv->capture_count > 0) {
2496 return LIBUSB_SUCCESS;
2499 usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
2501 /* reset device to attach kernel drivers */
2502 return darwin_reenumerate_device (dev_handle, false);
2505 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2506 enum libusb_error ret;
2507 if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
2508 ret = darwin_detach_kernel_driver (dev_handle, iface);
2509 if (ret != LIBUSB_SUCCESS) {
2510 usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
2514 return darwin_claim_interface (dev_handle, iface);
2517 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2518 enum libusb_error ret;
2519 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2521 ret = darwin_release_interface (dev_handle, iface);
2522 if (ret != LIBUSB_SUCCESS) {
2526 if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
2527 ret = darwin_attach_kernel_driver (dev_handle, iface);
2528 if (LIBUSB_SUCCESS != ret) {
2529 usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
2531 /* ignore the error as the interface was successfully released */
2534 return LIBUSB_SUCCESS;
2539 const struct usbi_os_backend usbi_backend = {
2541 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2542 .init = darwin_init,
2543 .exit = darwin_exit,
2544 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2545 .get_config_descriptor = darwin_get_config_descriptor,
2546 .hotplug_poll = darwin_hotplug_poll,
2548 .open = darwin_open,
2549 .close = darwin_close,
2550 .get_configuration = darwin_get_configuration,
2551 .set_configuration = darwin_set_configuration,
2553 .set_interface_altsetting = darwin_set_interface_altsetting,
2554 .clear_halt = darwin_clear_halt,
2555 .reset_device = darwin_reset_device,
2557 #if InterfaceVersion >= 550
2558 .alloc_streams = darwin_alloc_streams,
2559 .free_streams = darwin_free_streams,
2562 .kernel_driver_active = darwin_kernel_driver_active,
2564 #if InterfaceVersion >= 700
2565 .detach_kernel_driver = darwin_detach_kernel_driver,
2566 .attach_kernel_driver = darwin_attach_kernel_driver,
2567 .claim_interface = darwin_capture_claim_interface,
2568 .release_interface = darwin_capture_release_interface,
2570 .claim_interface = darwin_claim_interface,
2571 .release_interface = darwin_release_interface,
2574 .destroy_device = darwin_destroy_device,
2576 .submit_transfer = darwin_submit_transfer,
2577 .cancel_transfer = darwin_cancel_transfer,
2579 .handle_transfer_completion = darwin_handle_transfer_completion,
2581 .device_priv_size = sizeof(struct darwin_device_priv),
2582 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2583 .transfer_priv_size = sizeof(struct darwin_transfer_priv),