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 pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
56 static int init_count = 0;
58 /* async event thread */
59 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
60 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
62 #if !defined(HAVE_CLOCK_GETTIME)
63 static clock_serv_t clock_realtime;
64 static clock_serv_t clock_monotonic;
67 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
69 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
70 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
72 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
73 static struct list_head darwin_cached_devices;
74 static const char *darwin_device_class = "IOUSBDevice";
76 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
78 /* async event thread */
79 static pthread_t libusb_darwin_at;
81 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
82 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
83 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
84 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
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(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;
179 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
180 cached_dev->refcount++;
183 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) {
184 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
186 /* current interface */
187 struct darwin_interface *cInterface;
191 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
193 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
194 cInterface = &priv->interfaces[iface];
196 if (dev_handle->claimed_interfaces & (1U << iface)) {
197 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
198 if (cInterface->endpoint_addrs[i] == ep) {
205 *interface_out = cInterface;
207 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
208 return LIBUSB_SUCCESS;
214 /* No pipe found with the correct endpoint address */
215 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
217 return LIBUSB_ERROR_NOT_FOUND;
220 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
221 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
224 return kIOReturnError;
227 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
228 &kCFTypeDictionaryKeyCallBacks,
229 &kCFTypeDictionaryValueCallBacks);
231 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
232 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
233 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
235 if (propertyMatchDict && locationCF) {
236 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
237 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
239 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
241 /* release our references as per the Create Rule */
242 if (propertyMatchDict)
243 CFRelease (propertyMatchDict);
245 CFRelease (locationCF);
248 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
251 /* Returns 1 on success, 0 on failure. */
252 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
253 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
257 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
258 success = CFNumberGetValue(cfNumber, type, p);
261 CFRelease (cfNumber);
264 return (success != 0);
267 /* Returns 1 on success, 0 on failure. */
268 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
269 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
270 bool success = false;
273 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
274 CFIndex length = CFDataGetLength (cfData);
279 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
289 static usb_device_t **darwin_device_from_service (io_service_t service)
291 io_cf_plugin_ref_t *plugInInterface = NULL;
292 usb_device_t **device;
295 const int max_retries = 5;
297 /* The IOCreatePlugInInterfaceForService function might consistently return
298 an "out of resources" error with certain USB devices the first time we run
299 it. The reason is still unclear, but retrying fixes the problem */
300 for (int count = 0; count < max_retries; count++) {
301 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
302 kIOCFPlugInInterfaceID, &plugInInterface,
304 if (kIOReturnSuccess == kresult && plugInInterface) {
308 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
310 /* sleep for a little while before trying again */
311 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
314 if (kIOReturnSuccess != kresult || !plugInInterface) {
315 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
319 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
321 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
322 (*plugInInterface)->Release (plugInInterface);
327 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
329 struct darwin_cached_device *cached_device;
330 UInt64 old_session_id;
331 struct libusb_context *ctx;
332 io_service_t service;
335 usbi_mutex_lock(&active_contexts_lock);
337 while ((service = IOIteratorNext(add_devices))) {
338 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
339 if (ret < 0 || !cached_device->can_enumerate) {
343 /* add this device to each active context's device list */
344 for_each_context(ctx) {
345 process_new_device (ctx, cached_device, old_session_id);
348 if (cached_device->in_reenumerate) {
349 usbi_dbg ("cached device in reset state. reset complete...");
350 cached_device->in_reenumerate = false;
353 IOObjectRelease(service);
356 usbi_mutex_unlock(&active_contexts_lock);
359 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
361 struct libusb_device *dev = NULL;
362 struct libusb_context *ctx;
363 struct darwin_cached_device *old_device;
369 usbi_mutex_lock(&active_contexts_lock);
371 while ((device = IOIteratorNext (rem_devices)) != 0) {
372 bool is_reenumerating = false;
374 /* get the location from the i/o registry */
375 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
376 IOObjectRelease (device);
380 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
381 otherwise no cached device will ever get freed */
382 usbi_mutex_lock(&darwin_cached_devices_lock);
383 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
384 if (old_device->session == session) {
385 if (old_device->in_reenumerate) {
386 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
387 * will deref if needed. */
388 usbi_dbg ("detected device detached due to re-enumeration");
390 /* the device object is no longer usable so go ahead and release it */
391 if (old_device->device) {
392 (*(old_device->device))->Release(old_device->device);
393 old_device->device = NULL;
396 is_reenumerating = true;
398 darwin_deref_cached_device (old_device);
405 usbi_mutex_unlock(&darwin_cached_devices_lock);
406 if (is_reenumerating) {
410 for_each_context(ctx) {
411 usbi_dbg ("notifying context %p of device disconnect", ctx);
413 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
415 /* signal the core that this device has been disconnected. the core will tear down this device
416 when the reference count reaches 0 */
417 usbi_disconnect_device(dev);
418 libusb_unref_device(dev);
423 usbi_mutex_unlock(&active_contexts_lock);
426 static void darwin_hotplug_poll (void)
428 /* not sure if 1 ms will be too long/short but it should work ok */
429 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
431 /* since a kernel thread may notify the IOIterators used for
432 * hotplug notification we can't just clear the iterators.
433 * instead just wait until all IOService providers are quiet */
434 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
437 static void darwin_clear_iterator (io_iterator_t iter) {
440 while ((device = IOIteratorNext (iter)) != 0)
441 IOObjectRelease (device);
444 static void darwin_fail_startup(void) {
445 pthread_mutex_lock (&libusb_darwin_at_mutex);
446 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
447 pthread_cond_signal (&libusb_darwin_at_cond);
448 pthread_mutex_unlock (&libusb_darwin_at_mutex);
452 static void *darwin_event_thread_main (void *arg0) {
454 struct libusb_context *ctx = (struct libusb_context *)arg0;
455 CFRunLoopRef runloop;
456 CFRunLoopSourceRef libusb_shutdown_cfsource;
457 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
459 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
460 /* Set this thread's name, so it can be seen in the debugger
461 and crash reports. */
462 pthread_setname_np ("org.libusb.device-hotplug");
465 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
466 /* Tell the Objective-C garbage collector about this thread.
467 This is required because, unlike NSThreads, pthreads are
468 not automatically registered. Although we don't use
469 Objective-C, we use CoreFoundation, which does.
470 Garbage collection support was entirely removed in 10.12,
471 so don't bother there. */
472 objc_registerThreadWithCollector();
475 /* hotplug (device arrival/removal) sources */
476 CFRunLoopSourceRef libusb_notification_cfsource;
477 io_notification_port_t libusb_notification_port;
478 io_iterator_t libusb_rem_device_iterator;
479 io_iterator_t libusb_add_device_iterator;
481 usbi_dbg ("creating hotplug event source");
483 runloop = CFRunLoopGetCurrent ();
486 /* add the shutdown cfsource to the run loop */
487 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
488 libusb_shutdown_cfsourcectx.info = runloop;
489 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
490 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
491 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
493 /* add the notification port to the run loop */
494 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
495 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
496 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
498 /* create notifications for removed devices */
499 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
500 IOServiceMatching(darwin_device_class),
501 darwin_devices_detached,
502 ctx, &libusb_rem_device_iterator);
504 if (kresult != kIOReturnSuccess) {
505 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
506 CFRelease (libusb_shutdown_cfsource);
508 darwin_fail_startup ();
511 /* create notifications for attached devices */
512 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
513 IOServiceMatching(darwin_device_class),
514 darwin_devices_attached,
515 ctx, &libusb_add_device_iterator);
517 if (kresult != kIOReturnSuccess) {
518 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
519 CFRelease (libusb_shutdown_cfsource);
521 darwin_fail_startup ();
525 darwin_clear_iterator (libusb_rem_device_iterator);
526 darwin_clear_iterator (libusb_add_device_iterator);
528 usbi_dbg ("darwin event thread ready to receive events");
530 /* signal the main thread that the hotplug runloop has been created. */
531 pthread_mutex_lock (&libusb_darwin_at_mutex);
532 libusb_darwin_acfl = runloop;
533 libusb_darwin_acfls = libusb_shutdown_cfsource;
534 pthread_cond_signal (&libusb_darwin_at_cond);
535 pthread_mutex_unlock (&libusb_darwin_at_mutex);
537 /* run the runloop */
540 usbi_dbg ("darwin event thread exiting");
542 /* signal the main thread that the hotplug runloop has finished. */
543 pthread_mutex_lock (&libusb_darwin_at_mutex);
544 libusb_darwin_acfls = NULL;
545 libusb_darwin_acfl = NULL;
546 pthread_cond_signal (&libusb_darwin_at_cond);
547 pthread_mutex_unlock (&libusb_darwin_at_mutex);
549 /* remove the notification cfsource */
550 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
552 /* remove the shutdown cfsource */
553 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
555 /* delete notification port */
556 IONotificationPortDestroy (libusb_notification_port);
558 /* delete iterators */
559 IOObjectRelease (libusb_rem_device_iterator);
560 IOObjectRelease (libusb_add_device_iterator);
562 CFRelease (libusb_shutdown_cfsource);
568 /* cleanup function to destroy cached devices */
569 static void darwin_cleanup_devices(void) {
570 struct darwin_cached_device *dev, *next;
572 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
573 darwin_deref_cached_device(dev);
576 darwin_cached_devices.prev = darwin_cached_devices.next = NULL;
579 static int darwin_init(struct libusb_context *ctx) {
583 pthread_mutex_lock (&libusb_darwin_init_mutex);
585 first_init = (1 == ++init_count);
589 assert (NULL == darwin_cached_devices.next);
590 list_init (&darwin_cached_devices);
592 #if !defined(HAVE_CLOCK_GETTIME)
593 /* create the clocks that will be used if clock_gettime() is not available */
594 host_name_port_t host_self;
596 host_self = mach_host_self();
597 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
598 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
599 mach_port_deallocate(mach_task_self(), host_self);
603 rc = darwin_scan_devices (ctx);
604 if (LIBUSB_SUCCESS != rc)
608 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
610 usbi_err (ctx, "could not create event thread, error %d", rc);
611 rc = LIBUSB_ERROR_OTHER;
615 pthread_mutex_lock (&libusb_darwin_at_mutex);
616 while (!libusb_darwin_acfl)
617 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
618 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
619 libusb_darwin_acfl = NULL;
620 rc = LIBUSB_ERROR_OTHER;
622 pthread_mutex_unlock (&libusb_darwin_at_mutex);
625 pthread_join (libusb_darwin_at, NULL);
629 if (LIBUSB_SUCCESS != rc) {
631 darwin_cleanup_devices ();
632 #if !defined(HAVE_CLOCK_GETTIME)
633 mach_port_deallocate(mach_task_self(), clock_realtime);
634 mach_port_deallocate(mach_task_self(), clock_monotonic);
640 pthread_mutex_unlock (&libusb_darwin_init_mutex);
645 static void darwin_exit (struct libusb_context *ctx) {
648 pthread_mutex_lock (&libusb_darwin_init_mutex);
650 if (0 == --init_count) {
651 /* stop the event runloop and wait for the thread to terminate. */
652 pthread_mutex_lock (&libusb_darwin_at_mutex);
653 CFRunLoopSourceSignal (libusb_darwin_acfls);
654 CFRunLoopWakeUp (libusb_darwin_acfl);
655 while (libusb_darwin_acfl)
656 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
657 pthread_mutex_unlock (&libusb_darwin_at_mutex);
658 pthread_join (libusb_darwin_at, NULL);
660 darwin_cleanup_devices ();
662 #if !defined(HAVE_CLOCK_GETTIME)
663 mach_port_deallocate(mach_task_self(), clock_realtime);
664 mach_port_deallocate(mach_task_self(), clock_monotonic);
668 pthread_mutex_unlock (&libusb_darwin_init_mutex);
671 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
672 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
674 IOUSBConfigurationDescriptorPtr desc;
677 /* is there a simpler way to determine the index? */
678 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
679 if (kresult != kIOReturnSuccess)
680 return darwin_to_libusb (kresult);
682 for (i = 0 ; i < numConfig ; i++) {
683 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
685 if (desc->bConfigurationValue == config_value)
689 /* configuration not found */
690 return LIBUSB_ERROR_NOT_FOUND;
693 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
694 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
697 if (0 == priv->active_config)
698 return LIBUSB_ERROR_NOT_FOUND;
700 config_index = get_configuration_index (dev, priv->active_config);
701 if (config_index < 0)
704 assert(config_index >= 0 && config_index <= UINT8_MAX);
705 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
708 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
709 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
710 IOUSBConfigurationDescriptorPtr desc;
714 if (!priv || !priv->device)
715 return LIBUSB_ERROR_OTHER;
717 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
718 if (kresult == kIOReturnSuccess) {
719 /* copy descriptor */
720 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
721 len = libusb_le16_to_cpu(desc->wTotalLength);
723 memmove (buffer, desc, len);
726 ret = darwin_to_libusb (kresult);
727 if (ret != LIBUSB_SUCCESS)
733 /* check whether the os has configured the device */
734 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
735 usb_device_t **darwin_device = dev->device;
737 IOUSBConfigurationDescriptorPtr configDesc;
738 IOUSBFindInterfaceRequest request;
740 io_iterator_t interface_iterator;
741 io_service_t firstInterface;
743 if (dev->dev_descriptor.bNumConfigurations < 1) {
744 usbi_err (ctx, "device has no configurations");
745 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
748 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
750 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
751 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
752 usbi_dbg ("ignoring configuration on root hub simulation");
753 dev->active_config = 0;
754 return LIBUSB_SUCCESS;
757 /* find the first configuration */
758 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
759 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
761 /* check if the device is already configured. there is probably a better way than iterating over the
762 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
763 might lock up on the device request) */
765 /* Setup the Interface Request */
766 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
767 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
768 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
769 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
771 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
772 if (kresult != kIOReturnSuccess)
773 return darwin_to_libusb (kresult);
776 firstInterface = IOIteratorNext(interface_iterator);
778 /* done with the interface iterator */
779 IOObjectRelease(interface_iterator);
781 if (firstInterface) {
782 IOObjectRelease (firstInterface);
784 /* device is configured */
785 if (dev->dev_descriptor.bNumConfigurations == 1)
786 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
787 dev->active_config = dev->first_config;
789 /* devices with more than one configuration should work with GetConfiguration */
790 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
793 dev->active_config = 0;
795 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
797 return LIBUSB_SUCCESS;
800 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
801 IOUSBDevRequestTO req;
803 assert(buffer_size <= UINT16_MAX);
805 memset (buffer, 0, buffer_size);
807 /* Set up request for descriptor/ */
808 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
809 req.bRequest = kUSBRqGetDescriptor;
810 req.wValue = (UInt16)(desc << 8);
811 req.wIndex = desc_index;
812 req.wLength = (UInt16)buffer_size;
814 req.noDataTimeout = 20;
815 req.completionTimeout = 100;
817 return (*device)->DeviceRequestTO (device, &req);
820 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
821 usb_device_t **device = dev->device;
823 long delay = 30000; // microseconds
824 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
826 IOReturn ret = 0, ret2;
828 UInt16 idProduct, idVendor;
830 dev->can_enumerate = 0;
832 (*device)->GetDeviceClass (device, &bDeviceClass);
833 (*device)->GetDeviceProduct (device, &idProduct);
834 (*device)->GetDeviceVendor (device, &idVendor);
836 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
837 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
838 * to follow the spec as closely as possible, try opening the device */
839 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
842 /**** retrieve device descriptor ****/
843 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
845 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
846 /* received an overrun error but we still received a device descriptor */
847 ret = kIOReturnSuccess;
849 if (kIOUSBVendorIDAppleComputer == idVendor) {
850 /* NTH: don't bother retrying or unsuspending Apple devices */
854 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
855 0 == dev->dev_descriptor.bcdUSB)) {
856 /* work around for incorrectly configured devices */
857 if (try_reconfigure && is_open) {
858 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
860 /* set the first configuration */
861 (*device)->SetConfiguration(device, 1);
863 /* don't try to reconfigure again */
867 ret = kIOUSBPipeStalled;
870 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
871 /* device may be suspended. unsuspend it and try again */
872 #if DeviceVersion >= 320
875 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
876 (void)(*device)->GetUSBDeviceInformation (device, &info);
878 /* note that the device was suspended */
879 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
884 /* try to unsuspend the device */
885 ret2 = (*device)->USBDeviceSuspend (device, 0);
886 if (kIOReturnSuccess != ret2) {
887 /* prevent log spew from poorly behaving devices. this indicates the
888 os actually had trouble communicating with the device */
889 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
897 if (kIOReturnSuccess != ret) {
898 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
899 /* sleep for a little while before trying again */
900 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
902 } while (kIOReturnSuccess != ret && retries--);
905 /* resuspend the device */
906 (void)(*device)->USBDeviceSuspend (device, 1);
909 (void) (*device)->USBDeviceClose (device);
911 if (ret != kIOReturnSuccess) {
912 /* a debug message was already printed out for this error */
913 if (LIBUSB_CLASS_HUB == bDeviceClass)
914 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
915 idVendor, idProduct, darwin_error_str (ret), ret);
917 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
918 idVendor, idProduct, darwin_error_str (ret), ret);
919 return darwin_to_libusb (ret);
922 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
923 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
924 /* not a valid device */
925 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
926 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
927 return LIBUSB_ERROR_NO_DEVICE;
930 usbi_dbg ("cached device descriptor:");
931 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
932 usbi_dbg (" bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
933 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
934 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
935 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
936 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
937 usbi_dbg (" idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
938 usbi_dbg (" idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
939 usbi_dbg (" bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
940 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
941 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
942 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
943 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
945 dev->can_enumerate = 1;
947 return LIBUSB_SUCCESS;
950 /* Returns 1 on success, 0 on failure. */
951 static bool get_device_port (io_service_t service, UInt8 *port) {
956 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
960 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
961 if (kIOReturnSuccess == kresult) {
962 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
963 IOObjectRelease (parent);
969 /* Returns 1 on success, 0 on failure. */
970 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
974 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
976 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
977 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
983 /* We ran out of parents */
987 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
988 UInt64 *old_session_id) {
989 struct darwin_cached_device *new_device;
990 UInt64 sessionID = 0, parent_sessionID = 0;
991 UInt32 locationID = 0;
992 enum libusb_error ret = LIBUSB_SUCCESS;
993 usb_device_t **device;
996 /* assuming sessionID != 0 normally (never seen it be 0) */
1000 /* get some info from the io registry */
1001 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1002 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1003 if (!get_device_port (service, &port)) {
1004 usbi_dbg("could not get connected port number");
1007 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1009 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1010 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1013 usbi_mutex_lock(&darwin_cached_devices_lock);
1015 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1016 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1017 sessionID, locationID, new_device->session, new_device->location);
1018 if (new_device->location == locationID && new_device->in_reenumerate) {
1019 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1020 *old_session_id = new_device->session;
1024 if (new_device->session == sessionID) {
1025 usbi_dbg("using cached device for device");
1026 *cached_out = new_device;
1034 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1036 device = darwin_device_from_service (service);
1038 ret = LIBUSB_ERROR_NO_DEVICE;
1042 if (!(*old_session_id)) {
1043 new_device = calloc (1, sizeof (*new_device));
1045 ret = LIBUSB_ERROR_NO_MEM;
1049 /* add this device to the cached device list */
1050 list_add(&new_device->list, &darwin_cached_devices);
1052 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1054 /* keep a reference to this device */
1055 darwin_ref_cached_device(new_device);
1057 (*device)->GetLocationID (device, &new_device->location);
1058 new_device->port = port;
1059 new_device->parent_session = parent_sessionID;
1062 /* keep track of devices regardless of if we successfully enumerate them to
1063 prevent them from being enumerated multiple times */
1064 *cached_out = new_device;
1066 new_device->session = sessionID;
1067 new_device->device = device;
1069 /* cache the device descriptor */
1070 ret = darwin_cache_device_descriptor(new_device);
1074 if (new_device->can_enumerate) {
1075 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1076 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1077 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1078 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1082 usbi_mutex_unlock(&darwin_cached_devices_lock);
1087 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1088 UInt64 old_session_id) {
1089 struct darwin_device_priv *priv;
1090 struct libusb_device *dev = NULL;
1092 enum libusb_error ret = LIBUSB_SUCCESS;
1095 /* check current active configuration (and cache the first configuration value--
1096 which may be used by claim_interface) */
1097 ret = darwin_check_configuration (ctx, cached_device);
1101 if (0 != old_session_id) {
1102 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1103 ctx, old_session_id, cached_device->session);
1104 /* save the libusb device before the session id is updated */
1105 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1109 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1110 ctx, cached_device->session);
1112 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1114 return LIBUSB_ERROR_NO_MEM;
1117 priv = usbi_get_device_priv(dev);
1119 priv->dev = cached_device;
1120 darwin_ref_cached_device (priv->dev);
1121 dev->port_number = cached_device->port;
1122 dev->bus_number = cached_device->location >> 24;
1123 assert(cached_device->address <= UINT8_MAX);
1124 dev->device_address = (uint8_t)cached_device->address;
1126 priv = usbi_get_device_priv(dev);
1129 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1130 "mismatch between libusb and IOKit device descriptor sizes");
1131 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1132 usbi_localize_device_descriptor(&dev->device_descriptor);
1133 dev->session_data = cached_device->session;
1135 if (cached_device->parent_session > 0) {
1136 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1138 dev->parent_dev = NULL;
1141 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1144 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1145 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1146 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1147 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1148 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1150 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1151 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1154 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1157 ret = usbi_sanitize_device (dev);
1161 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1162 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1166 if (!cached_device->in_reenumerate && 0 == ret) {
1167 usbi_connect_device (dev);
1169 libusb_unref_device (dev);
1175 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1176 struct darwin_cached_device *cached_device;
1177 UInt64 old_session_id;
1178 io_iterator_t deviceIterator;
1179 io_service_t service;
1183 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1184 if (kresult != kIOReturnSuccess)
1185 return darwin_to_libusb (kresult);
1187 while ((service = IOIteratorNext (deviceIterator))) {
1188 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1189 if (ret < 0 || !cached_device->can_enumerate) {
1193 (void) process_new_device (ctx, cached_device, old_session_id);
1195 IOObjectRelease(service);
1198 IOObjectRelease(deviceIterator);
1200 return LIBUSB_SUCCESS;
1203 static int darwin_open (struct libusb_device_handle *dev_handle) {
1204 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1205 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1208 if (0 == dpriv->open_count) {
1209 /* try to open the device */
1210 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1211 if (kresult != kIOReturnSuccess) {
1212 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1214 if (kIOReturnExclusiveAccess != kresult) {
1215 return darwin_to_libusb (kresult);
1218 /* it is possible to perform some actions on a device that is not open so do not return an error */
1219 priv->is_open = false;
1221 priv->is_open = true;
1224 /* create async event source */
1225 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1226 if (kresult != kIOReturnSuccess) {
1227 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1229 if (priv->is_open) {
1230 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1233 priv->is_open = false;
1235 return darwin_to_libusb (kresult);
1238 CFRetain (libusb_darwin_acfl);
1240 /* add the cfSource to the aync run loop */
1241 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1244 /* device opened successfully */
1245 dpriv->open_count++;
1247 usbi_dbg ("device open for access");
1252 static void darwin_close (struct libusb_device_handle *dev_handle) {
1253 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1254 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1258 if (dpriv->open_count == 0) {
1259 /* something is probably very wrong if this is the case */
1260 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1264 dpriv->open_count--;
1266 /* make sure all interfaces are released */
1267 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1268 if (dev_handle->claimed_interfaces & (1U << i))
1269 libusb_release_interface (dev_handle, i);
1271 if (0 == dpriv->open_count) {
1272 /* delete the device's async event source */
1273 if (priv->cfSource) {
1274 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1275 CFRelease (priv->cfSource);
1276 priv->cfSource = NULL;
1277 CFRelease (libusb_darwin_acfl);
1280 if (priv->is_open) {
1281 /* close the device */
1282 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1283 if (kresult != kIOReturnSuccess) {
1284 /* Log the fact that we had a problem closing the file, however failing a
1285 * close isn't really an error, so return success anyway */
1286 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1292 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1293 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1295 *config = dpriv->active_config;
1297 return LIBUSB_SUCCESS;
1300 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1301 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1308 /* Setting configuration will invalidate the interface, so we need
1309 to reclaim it. First, dispose of existing interfaces, if any. */
1310 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1311 if (dev_handle->claimed_interfaces & (1U << i))
1312 darwin_release_interface (dev_handle, i);
1314 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1315 if (kresult != kIOReturnSuccess)
1316 return darwin_to_libusb (kresult);
1318 /* Reclaim any interfaces. */
1319 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1320 if (dev_handle->claimed_interfaces & (1U << i))
1321 darwin_claim_interface (dev_handle, i);
1323 dpriv->active_config = (UInt8)config;
1325 return LIBUSB_SUCCESS;
1328 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1329 IOUSBFindInterfaceRequest request;
1331 io_iterator_t interface_iterator;
1332 UInt8 bInterfaceNumber;
1335 *usbInterfacep = IO_OBJECT_NULL;
1337 /* Setup the Interface Request */
1338 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1339 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1340 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1341 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1343 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1344 if (kresult != kIOReturnSuccess)
1347 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1348 /* find the interface number */
1349 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1352 if (ret && bInterfaceNumber == ifc) {
1356 (void) IOObjectRelease (*usbInterfacep);
1359 /* done with the interface iterator */
1360 IOObjectRelease(interface_iterator);
1362 return kIOReturnSuccess;
1365 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1366 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1368 /* current interface */
1369 struct darwin_interface *cInterface = &priv->interfaces[iface];
1373 UInt8 numep, direction, number;
1374 UInt8 dont_care1, dont_care3;
1378 usbi_dbg ("building table of endpoints.");
1380 /* retrieve the total number of endpoints on this interface */
1381 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1382 if (kresult != kIOReturnSuccess) {
1383 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1384 return darwin_to_libusb (kresult);
1387 /* iterate through pipe references */
1388 for (UInt8 i = 1 ; i <= numep ; i++) {
1389 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1390 &dont_care2, &dont_care3);
1392 if (kresult != kIOReturnSuccess) {
1393 /* probably a buggy device. try to get the endpoint address from the descriptors */
1394 struct libusb_config_descriptor *config;
1395 const struct libusb_endpoint_descriptor *endpoint_desc;
1398 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1399 if (kresult != kIOReturnSuccess) {
1400 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1401 return darwin_to_libusb (kresult);
1404 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1405 if (LIBUSB_SUCCESS != rc) {
1409 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1411 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1413 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1416 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1417 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1420 cInterface->num_endpoints = numep;
1422 return LIBUSB_SUCCESS;
1425 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1426 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1427 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1428 io_service_t usbInterface = IO_OBJECT_NULL;
1430 enum libusb_error ret;
1431 IOCFPlugInInterface **plugInInterface = NULL;
1434 /* current interface */
1435 struct darwin_interface *cInterface = &priv->interfaces[iface];
1437 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1438 if (kresult != kIOReturnSuccess)
1439 return darwin_to_libusb (kresult);
1441 /* make sure we have an interface */
1442 if (!usbInterface && dpriv->first_config != 0) {
1443 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1445 /* set the configuration */
1446 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1447 if (ret != LIBUSB_SUCCESS) {
1448 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1452 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1453 if (kresult != kIOReturnSuccess) {
1454 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1455 return darwin_to_libusb (kresult);
1459 if (!usbInterface) {
1460 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1461 return LIBUSB_ERROR_NOT_FOUND;
1464 /* get an interface to the device's interface */
1465 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1466 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1468 /* ignore release error */
1469 (void)IOObjectRelease (usbInterface);
1471 if (kresult != kIOReturnSuccess) {
1472 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1473 return darwin_to_libusb (kresult);
1476 if (!plugInInterface) {
1477 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1478 return LIBUSB_ERROR_NOT_FOUND;
1481 /* Do the actual claim */
1482 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1483 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1484 (LPVOID)&cInterface->interface);
1485 /* We no longer need the intermediate plug-in */
1486 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1487 (*plugInInterface)->Release (plugInInterface);
1488 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1489 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1490 return darwin_to_libusb (kresult);
1493 /* claim the interface */
1494 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1495 if (kresult != kIOReturnSuccess) {
1496 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1497 return darwin_to_libusb (kresult);
1500 /* update list of endpoints */
1501 ret = get_endpoints (dev_handle, iface);
1503 /* this should not happen */
1504 darwin_release_interface (dev_handle, iface);
1505 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1509 cInterface->cfSource = NULL;
1511 /* create async event source */
1512 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1513 if (kresult != kIOReturnSuccess) {
1514 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1516 /* can't continue without an async event source */
1517 (void)darwin_release_interface (dev_handle, iface);
1519 return darwin_to_libusb (kresult);
1522 /* add the cfSource to the async thread's run loop */
1523 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1525 usbi_dbg ("interface opened");
1527 return LIBUSB_SUCCESS;
1530 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1531 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1534 /* current interface */
1535 struct darwin_interface *cInterface = &priv->interfaces[iface];
1537 /* Check to see if an interface is open */
1538 if (!cInterface->interface)
1539 return LIBUSB_SUCCESS;
1541 /* clean up endpoint data */
1542 cInterface->num_endpoints = 0;
1544 /* delete the interface's async event source */
1545 if (cInterface->cfSource) {
1546 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1547 CFRelease (cInterface->cfSource);
1550 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1551 if (kresult != kIOReturnSuccess)
1552 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1554 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1555 if (kresult != kIOReturnSuccess)
1556 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1558 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1560 return darwin_to_libusb (kresult);
1563 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1564 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1566 enum libusb_error ret;
1568 /* current interface */
1569 struct darwin_interface *cInterface = &priv->interfaces[iface];
1571 if (!cInterface->interface)
1572 return LIBUSB_ERROR_NO_DEVICE;
1574 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1575 /* If a device only supports a default setting for the specified interface, then a STALL
1576 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1577 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints,
1578 and hide errors.Current implementation resets the entire device, instead of single
1579 interface, due to historic reasons. */
1580 if (kresult != kIOReturnSuccess) {
1581 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1582 darwin_reset_device (dev_handle);
1585 /* update list of endpoints */
1586 ret = get_endpoints (dev_handle, iface);
1588 /* this should not happen */
1589 darwin_release_interface (dev_handle, iface);
1590 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1596 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1597 /* current interface */
1598 struct darwin_interface *cInterface;
1602 /* determine the interface/endpoint to use */
1603 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1604 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1606 return LIBUSB_ERROR_NOT_FOUND;
1609 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1610 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1611 if (kresult != kIOReturnSuccess)
1612 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1614 return darwin_to_libusb (kresult);
1617 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1618 unsigned long claimed_interfaces) {
1619 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1620 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1621 int open_count = dpriv->open_count;
1624 /* clear claimed interfaces temporarily */
1625 dev_handle->claimed_interfaces = 0;
1627 /* close and re-open the device */
1628 priv->is_open = false;
1629 dpriv->open_count = 1;
1631 /* clean up open interfaces */
1632 (void) darwin_close (dev_handle);
1634 /* re-open the device */
1635 ret = darwin_open (dev_handle);
1636 dpriv->open_count = open_count;
1637 if (LIBUSB_SUCCESS != ret) {
1638 /* could not restore configuration */
1639 return LIBUSB_ERROR_NOT_FOUND;
1642 if (dpriv->active_config != active_config) {
1643 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1645 ret = darwin_set_configuration (dev_handle, active_config);
1646 if (LIBUSB_SUCCESS != ret) {
1647 usbi_dbg ("darwin/restore_state: could not restore configuration");
1648 return LIBUSB_ERROR_NOT_FOUND;
1652 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1654 if (claimed_interfaces) {
1655 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1656 if (!(claimed_interfaces & (1U << iface))) {
1660 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1662 ret = darwin_claim_interface (dev_handle, iface);
1663 if (LIBUSB_SUCCESS != ret) {
1664 usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
1665 return LIBUSB_ERROR_NOT_FOUND;
1668 dev_handle->claimed_interfaces |= 1U << iface;
1672 usbi_dbg ("darwin/restore_state: device state restored");
1674 return LIBUSB_SUCCESS;
1677 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle) {
1678 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1679 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1680 int8_t active_config = dpriv->active_config;
1681 IOUSBDeviceDescriptor descriptor;
1682 IOUSBConfigurationDescriptorPtr cached_configuration;
1683 IOUSBConfigurationDescriptor *cached_configurations;
1688 if (dpriv->in_reenumerate) {
1689 /* ack, two (or more) threads are trying to reset the device! abort! */
1690 return LIBUSB_ERROR_NOT_FOUND;
1693 dpriv->in_reenumerate = true;
1695 /* store copies of descriptors so they can be compared after the reset */
1696 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1697 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1699 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1700 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1701 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1704 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1705 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1706 if (kresult != kIOReturnSuccess) {
1707 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1708 dpriv->in_reenumerate = false;
1709 return darwin_to_libusb (kresult);
1712 usbi_dbg ("darwin/reenumerate_device: waiting for re-enumeration to complete...");
1715 while (dpriv->in_reenumerate) {
1716 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1717 nanosleep (&delay, NULL);
1718 if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
1719 usbi_err (HANDLE_CTX (dev_handle), "darwin/reenumerate_device: timeout waiting for reenumerate");
1720 dpriv->in_reenumerate = false;
1721 return LIBUSB_ERROR_TIMEOUT;
1725 /* compare descriptors */
1726 usbi_dbg ("darwin/reenumerate_device: checking whether descriptors changed");
1728 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1729 /* device descriptor changed. need to return not found. */
1730 usbi_dbg ("darwin/reenumerate_device: device descriptor changed");
1731 return LIBUSB_ERROR_NOT_FOUND;
1734 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1735 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1736 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1737 usbi_dbg ("darwin/reenumerate_device: configuration descriptor %d changed", i);
1738 return LIBUSB_ERROR_NOT_FOUND;
1742 usbi_dbg ("darwin/reenumerate_device: device reset complete. restoring state...");
1744 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1747 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1748 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1749 io_service_t usbInterface;
1753 kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1754 if (kresult != kIOReturnSuccess) {
1755 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1757 return darwin_to_libusb (kresult);
1760 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1761 IOObjectRelease (usbInterface);
1773 static void darwin_destroy_device(struct libusb_device *dev) {
1774 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1777 /* need to hold the lock in case this is the last reference to the device */
1778 usbi_mutex_lock(&darwin_cached_devices_lock);
1779 darwin_deref_cached_device (dpriv->dev);
1781 usbi_mutex_unlock(&darwin_cached_devices_lock);
1785 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1786 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1789 uint8_t transferType;
1791 uint16_t maxPacketSize;
1793 struct darwin_interface *cInterface;
1794 #if InterfaceVersion >= 550
1795 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1797 /* None of the values below are used in libusb for bulk transfers */
1798 uint8_t direction, number, interval;
1801 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1802 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1804 return LIBUSB_ERROR_NOT_FOUND;
1807 #if InterfaceVersion >= 550
1808 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1810 transferType = pipeProperties.bTransferType;
1811 maxPacketSize = pipeProperties.wMaxPacketSize;
1813 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1814 &transferType, &maxPacketSize, &interval);
1818 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1819 darwin_error_str(ret), ret);
1820 return darwin_to_libusb (ret);
1823 if (0 != (transfer->length % maxPacketSize)) {
1824 /* do not need a zero packet */
1825 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1828 /* submit the request */
1829 /* timeouts are unavailable on interrupt endpoints */
1830 if (transferType == kUSBInterrupt) {
1831 if (IS_XFERIN(transfer))
1832 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1833 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1835 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1836 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1838 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1840 if (IS_XFERIN(transfer))
1841 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1842 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1843 darwin_async_io_callback, itransfer);
1845 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1846 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1847 darwin_async_io_callback, itransfer);
1851 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1852 darwin_error_str(ret), ret);
1854 return darwin_to_libusb (ret);
1857 #if InterfaceVersion >= 550
1858 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1859 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1860 struct darwin_interface *cInterface;
1864 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1865 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1867 return LIBUSB_ERROR_NOT_FOUND;
1870 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1872 if (IS_XFERIN(transfer))
1873 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1874 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1875 transfer->timeout, darwin_async_io_callback, itransfer);
1877 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1878 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1879 transfer->timeout, darwin_async_io_callback, itransfer);
1882 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1883 darwin_error_str(ret), ret);
1885 return darwin_to_libusb (ret);
1889 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1890 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1891 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1894 uint8_t direction, number, interval, pipeRef, transferType;
1895 uint16_t maxPacketSize;
1897 AbsoluteTime atTime;
1900 struct darwin_interface *cInterface;
1902 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1903 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1904 free(tpriv->isoc_framelist);
1905 tpriv->isoc_framelist = NULL;
1908 if (!tpriv->isoc_framelist) {
1909 tpriv->num_iso_packets = transfer->num_iso_packets;
1910 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1911 if (!tpriv->isoc_framelist)
1912 return LIBUSB_ERROR_NO_MEM;
1915 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1916 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1917 unsigned int length = transfer->iso_packet_desc[i].length;
1918 assert(length <= UINT16_MAX);
1919 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1922 /* determine the interface/endpoint to use */
1923 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1924 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1926 return LIBUSB_ERROR_NOT_FOUND;
1929 /* determine the properties of this endpoint and the speed of the device */
1930 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1931 &transferType, &maxPacketSize, &interval);
1933 /* Last but not least we need the bus frame number */
1934 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1935 if (kresult != kIOReturnSuccess) {
1936 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1937 free(tpriv->isoc_framelist);
1938 tpriv->isoc_framelist = NULL;
1940 return darwin_to_libusb (kresult);
1943 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1944 &transferType, &maxPacketSize, &interval);
1946 /* schedule for a frame a little in the future */
1949 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1950 frame = cInterface->frames[transfer->endpoint];
1952 /* submit the request */
1953 if (IS_XFERIN(transfer))
1954 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1955 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1958 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1959 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1962 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1964 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1966 /* High/super speed */
1967 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1969 if (kresult != kIOReturnSuccess) {
1970 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1971 darwin_error_str(kresult));
1972 free (tpriv->isoc_framelist);
1973 tpriv->isoc_framelist = NULL;
1976 return darwin_to_libusb (kresult);
1979 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1980 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1981 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1982 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1983 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1987 memset(&tpriv->req, 0, sizeof(tpriv->req));
1989 /* IOUSBDeviceInterface expects the request in cpu endianness */
1990 tpriv->req.bmRequestType = setup->bmRequestType;
1991 tpriv->req.bRequest = setup->bRequest;
1992 /* these values should be in bus order from libusb_fill_control_setup */
1993 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1994 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1995 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1996 /* data is stored after the libusb control block */
1997 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1998 tpriv->req.completionTimeout = transfer->timeout;
1999 tpriv->req.noDataTimeout = transfer->timeout;
2001 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2003 /* all transfers in libusb-1.0 are async */
2005 if (transfer->endpoint) {
2006 struct darwin_interface *cInterface;
2009 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2010 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2012 return LIBUSB_ERROR_NOT_FOUND;
2015 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2017 /* control request on endpoint 0 */
2018 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2020 if (kresult != kIOReturnSuccess)
2021 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2023 return darwin_to_libusb (kresult);
2026 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2027 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2029 switch (transfer->type) {
2030 case LIBUSB_TRANSFER_TYPE_CONTROL:
2031 return submit_control_transfer(itransfer);
2032 case LIBUSB_TRANSFER_TYPE_BULK:
2033 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2034 return submit_bulk_transfer(itransfer);
2035 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2036 return submit_iso_transfer(itransfer);
2037 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2038 #if InterfaceVersion >= 550
2039 return submit_stream_transfer(itransfer);
2041 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2042 return LIBUSB_ERROR_NOT_SUPPORTED;
2045 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2046 return LIBUSB_ERROR_INVALID_PARAM;
2050 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2051 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2052 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2055 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2058 return LIBUSB_ERROR_NO_DEVICE;
2060 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2062 return darwin_to_libusb (kresult);
2065 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2066 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2067 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2068 struct darwin_interface *cInterface;
2069 uint8_t pipeRef, iface;
2072 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2073 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2075 return LIBUSB_ERROR_NOT_FOUND;
2079 return LIBUSB_ERROR_NO_DEVICE;
2081 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2083 /* abort transactions */
2084 #if InterfaceVersion >= 550
2085 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2086 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2089 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2091 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2093 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2094 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2096 return darwin_to_libusb (kresult);
2099 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2100 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2102 switch (transfer->type) {
2103 case LIBUSB_TRANSFER_TYPE_CONTROL:
2104 return cancel_control_transfer(itransfer);
2105 case LIBUSB_TRANSFER_TYPE_BULK:
2106 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2107 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2108 return darwin_abort_transfers (itransfer);
2110 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2111 return LIBUSB_ERROR_INVALID_PARAM;
2115 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2116 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2117 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2118 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2120 usbi_dbg ("an async io operation has completed");
2122 /* if requested write a zero packet */
2123 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2124 struct darwin_interface *cInterface;
2127 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2129 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2132 tpriv->result = result;
2133 tpriv->size = (UInt32) (uintptr_t) arg0;
2135 /* signal the core that this transfer is complete */
2136 usbi_signal_transfer_completion(itransfer);
2139 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2140 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2141 result = kIOUSBTransactionTimeout;
2144 case kIOReturnUnderrun:
2145 case kIOReturnSuccess:
2146 return LIBUSB_TRANSFER_COMPLETED;
2147 case kIOReturnAborted:
2148 return LIBUSB_TRANSFER_CANCELLED;
2149 case kIOUSBPipeStalled:
2150 usbi_dbg ("transfer error: pipe is stalled");
2151 return LIBUSB_TRANSFER_STALL;
2152 case kIOReturnOverrun:
2153 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2154 return LIBUSB_TRANSFER_OVERFLOW;
2155 case kIOUSBTransactionTimeout:
2156 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2157 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2158 return LIBUSB_TRANSFER_TIMED_OUT;
2160 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2161 return LIBUSB_TRANSFER_ERROR;
2165 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2166 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2167 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2168 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2169 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2170 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2172 if (transfer->type > max_transfer_type) {
2173 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2174 return LIBUSB_ERROR_INVALID_PARAM;
2177 if (NULL == tpriv) {
2178 usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
2179 return LIBUSB_ERROR_INVALID_PARAM;
2182 usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2184 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2185 if (is_isoc && tpriv->isoc_framelist) {
2186 /* copy isochronous results back */
2188 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2189 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2190 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2191 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2193 } else if (!is_isoc) {
2194 itransfer->transferred += tpriv->size;
2198 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2199 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2202 #if !defined(HAVE_CLOCK_GETTIME)
2203 void usbi_get_monotonic_time(struct timespec *tp) {
2204 mach_timespec_t sys_time;
2206 /* use system boot time as reference for the monotonic clock */
2207 clock_get_time (clock_monotonic, &sys_time);
2209 tp->tv_sec = sys_time.tv_sec;
2210 tp->tv_nsec = sys_time.tv_nsec;
2213 void usbi_get_real_time(struct timespec *tp) {
2214 mach_timespec_t sys_time;
2216 /* CLOCK_REALTIME represents time since the epoch */
2217 clock_get_time (clock_realtime, &sys_time);
2219 tp->tv_sec = sys_time.tv_sec;
2220 tp->tv_nsec = sys_time.tv_nsec;
2224 #if InterfaceVersion >= 550
2225 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2226 int num_endpoints) {
2227 struct darwin_interface *cInterface;
2228 UInt32 supportsStreams;
2232 /* find the minimum number of supported streams on the endpoint list */
2233 for (i = 0 ; i < num_endpoints ; ++i) {
2234 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2238 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2239 if (num_streams > supportsStreams)
2240 num_streams = supportsStreams;
2243 /* it is an error if any endpoint in endpoints does not support streams */
2244 if (0 == num_streams)
2245 return LIBUSB_ERROR_INVALID_PARAM;
2247 /* create the streams */
2248 for (i = 0 ; i < num_endpoints ; ++i) {
2249 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2251 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2252 if (kIOReturnSuccess != rc)
2253 return darwin_to_libusb(rc);
2256 assert(num_streams <= INT_MAX);
2257 return (int)num_streams;
2260 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2261 struct darwin_interface *cInterface;
2262 UInt32 supportsStreams;
2266 for (int i = 0 ; i < num_endpoints ; ++i) {
2267 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2270 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2271 if (0 == supportsStreams)
2272 return LIBUSB_ERROR_INVALID_PARAM;
2274 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2275 if (kIOReturnSuccess != rc)
2276 return darwin_to_libusb(rc);
2279 return LIBUSB_SUCCESS;
2283 const struct usbi_os_backend usbi_backend = {
2286 .init = darwin_init,
2287 .exit = darwin_exit,
2288 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2289 .get_config_descriptor = darwin_get_config_descriptor,
2290 .hotplug_poll = darwin_hotplug_poll,
2292 .open = darwin_open,
2293 .close = darwin_close,
2294 .get_configuration = darwin_get_configuration,
2295 .set_configuration = darwin_set_configuration,
2296 .claim_interface = darwin_claim_interface,
2297 .release_interface = darwin_release_interface,
2299 .set_interface_altsetting = darwin_set_interface_altsetting,
2300 .clear_halt = darwin_clear_halt,
2301 .reset_device = darwin_reenumerate_device,
2303 #if InterfaceVersion >= 550
2304 .alloc_streams = darwin_alloc_streams,
2305 .free_streams = darwin_free_streams,
2308 .kernel_driver_active = darwin_kernel_driver_active,
2310 .destroy_device = darwin_destroy_device,
2312 .submit_transfer = darwin_submit_transfer,
2313 .cancel_transfer = darwin_cancel_transfer,
2315 .handle_transfer_completion = darwin_handle_transfer_completion,
2317 .device_priv_size = sizeof(struct darwin_device_priv),
2318 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2319 .transfer_priv_size = sizeof(struct darwin_transfer_priv),