1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2019 Nathan Hjelm <hjelmn@users.sourceforge.net>
5 * Copyright © 2019 Google LLC. All rights reserved.
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
31 #include <sys/types.h>
34 #include <sys/sysctl.h>
36 #include <mach/clock.h>
37 #include <mach/clock_types.h>
38 #include <mach/mach_host.h>
39 #include <mach/mach_port.h>
41 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
42 * function. Its use is also conditionalized to only older deployment targets. */
43 #define OBJC_SILENCE_GC_DEPRECATIONS 1
45 #include <AvailabilityMacros.h>
46 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
47 #include <objc/objc-auto.h>
50 #include "darwin_usb.h"
52 static pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
53 static int init_count = 0;
55 /* async event thread */
56 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
57 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
59 #if !defined(HAVE_CLOCK_GETTIME)
60 static clock_serv_t clock_realtime;
61 static clock_serv_t clock_monotonic;
64 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
66 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
67 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
69 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
70 static struct list_head darwin_cached_devices;
71 static const char *darwin_device_class = kIOUSBDeviceClassName;
73 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
75 /* async event thread */
76 static pthread_t libusb_darwin_at;
78 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
79 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface);
80 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface);
81 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
82 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
84 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
85 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
86 UInt64 old_session_id);
88 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
89 UInt64 *old_session_id);
91 #if defined(ENABLE_LOGGING)
92 static const char *darwin_error_str (IOReturn result) {
93 static char string_buffer[50];
95 case kIOReturnSuccess:
97 case kIOReturnNotOpen:
98 return "device not opened for exclusive access";
99 case kIOReturnNoDevice:
100 return "no connection to an IOService";
101 case kIOUSBNoAsyncPortErr:
102 return "no async port has been opened for interface";
103 case kIOReturnExclusiveAccess:
104 return "another process has device opened for exclusive access";
105 case kIOUSBPipeStalled:
106 return "pipe is stalled";
108 return "could not establish a connection to the Darwin kernel";
109 case kIOUSBTransactionTimeout:
110 return "transaction timed out";
111 case kIOReturnBadArgument:
112 return "invalid argument";
113 case kIOReturnAborted:
114 return "transaction aborted";
115 case kIOReturnNotResponding:
116 return "device not responding";
117 case kIOReturnOverrun:
118 return "data overrun";
119 case kIOReturnCannotWire:
120 return "physical memory can not be wired down";
121 case kIOReturnNoResources:
122 return "out of resources";
123 case kIOUSBHighSpeedSplitError:
124 return "high speed split error";
126 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
127 return string_buffer;
132 static enum libusb_error darwin_to_libusb (IOReturn result) {
134 case kIOReturnUnderrun:
135 case kIOReturnSuccess:
136 return LIBUSB_SUCCESS;
137 case kIOReturnNotOpen:
138 case kIOReturnNoDevice:
139 return LIBUSB_ERROR_NO_DEVICE;
140 case kIOReturnExclusiveAccess:
141 return LIBUSB_ERROR_ACCESS;
142 case kIOUSBPipeStalled:
143 return LIBUSB_ERROR_PIPE;
144 case kIOReturnBadArgument:
145 return LIBUSB_ERROR_INVALID_PARAM;
146 case kIOUSBTransactionTimeout:
147 return LIBUSB_ERROR_TIMEOUT;
148 case kIOReturnNotResponding:
149 case kIOReturnAborted:
151 case kIOUSBNoAsyncPortErr:
153 return LIBUSB_ERROR_OTHER;
157 /* this function must be called with the darwin_cached_devices_lock held */
158 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
159 cached_dev->refcount--;
160 /* free the device and remove it from the cache */
161 if (0 == cached_dev->refcount) {
162 list_del(&cached_dev->list);
164 if (cached_dev->device) {
165 (*(cached_dev->device))->Release(cached_dev->device);
166 cached_dev->device = NULL;
172 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
173 cached_dev->refcount++;
176 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) {
177 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
179 /* current interface */
180 struct darwin_interface *cInterface;
184 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
186 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
187 cInterface = &priv->interfaces[iface];
189 if (dev_handle->claimed_interfaces & (1U << iface)) {
190 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
191 if (cInterface->endpoint_addrs[i] == ep) {
198 *interface_out = cInterface;
200 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
201 return LIBUSB_SUCCESS;
207 /* No pipe found with the correct endpoint address */
208 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
210 return LIBUSB_ERROR_NOT_FOUND;
213 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
214 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
217 return kIOReturnError;
220 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
221 &kCFTypeDictionaryKeyCallBacks,
222 &kCFTypeDictionaryValueCallBacks);
224 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
225 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
226 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
228 if (propertyMatchDict && locationCF) {
229 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
230 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
232 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
234 /* release our references as per the Create Rule */
235 if (propertyMatchDict)
236 CFRelease (propertyMatchDict);
238 CFRelease (locationCF);
241 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
244 /* Returns 1 on success, 0 on failure. */
245 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
246 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
250 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
251 success = CFNumberGetValue(cfNumber, type, p);
254 CFRelease (cfNumber);
257 return (success != 0);
260 /* Returns 1 on success, 0 on failure. */
261 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
262 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
263 bool success = false;
266 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
267 CFIndex length = CFDataGetLength (cfData);
272 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
282 static usb_device_t **darwin_device_from_service (io_service_t service)
284 io_cf_plugin_ref_t *plugInInterface = NULL;
285 usb_device_t **device;
288 const int max_retries = 5;
290 /* The IOCreatePlugInInterfaceForService function might consistently return
291 an "out of resources" error with certain USB devices the first time we run
292 it. The reason is still unclear, but retrying fixes the problem */
293 for (int count = 0; count < max_retries; count++) {
294 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
295 kIOCFPlugInInterfaceID, &plugInInterface,
297 if (kIOReturnSuccess == kresult && plugInInterface) {
301 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
303 /* sleep for a little while before trying again */
304 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
307 if (kIOReturnSuccess != kresult || !plugInInterface) {
308 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
312 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
314 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
315 (*plugInInterface)->Release (plugInInterface);
320 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
322 struct darwin_cached_device *cached_device;
323 UInt64 old_session_id;
324 struct libusb_context *ctx;
325 io_service_t service;
328 usbi_mutex_lock(&active_contexts_lock);
330 while ((service = IOIteratorNext(add_devices))) {
331 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
332 if (ret < 0 || !cached_device->can_enumerate) {
336 /* add this device to each active context's device list */
337 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
338 process_new_device (ctx, cached_device, old_session_id);
341 if (cached_device->in_reenumerate) {
342 usbi_dbg ("cached device in reset state. reset complete...");
343 cached_device->in_reenumerate = false;
346 IOObjectRelease(service);
349 usbi_mutex_unlock(&active_contexts_lock);
352 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
354 struct libusb_device *dev = NULL;
355 struct libusb_context *ctx;
356 struct darwin_cached_device *old_device;
362 usbi_mutex_lock(&active_contexts_lock);
364 while ((device = IOIteratorNext (rem_devices)) != 0) {
365 bool is_reenumerating = false;
367 /* get the location from the i/o registry */
368 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
369 IOObjectRelease (device);
373 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
374 otherwise no cached device will ever get freed */
375 usbi_mutex_lock(&darwin_cached_devices_lock);
376 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
377 if (old_device->session == session) {
378 if (old_device->in_reenumerate) {
379 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
380 * will deref if needed. */
381 usbi_dbg ("detected device detatched due to re-enumeration");
383 /* the device object is no longer usable so go ahead and release it */
384 if (old_device->device) {
385 (*(old_device->device))->Release(old_device->device);
386 old_device->device = NULL;
389 is_reenumerating = true;
391 darwin_deref_cached_device (old_device);
398 usbi_mutex_unlock(&darwin_cached_devices_lock);
399 if (is_reenumerating) {
403 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
404 usbi_dbg ("notifying context %p of device disconnect", ctx);
406 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
408 /* signal the core that this device has been disconnected. the core will tear down this device
409 when the reference count reaches 0 */
410 usbi_disconnect_device(dev);
411 libusb_unref_device(dev);
416 usbi_mutex_unlock(&active_contexts_lock);
419 static void darwin_hotplug_poll (void)
421 /* not sure if 1 ms will be too long/short but it should work ok */
422 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
424 /* since a kernel thread may notify the IOIterators used for
425 * hotplug notification we can't just clear the iterators.
426 * instead just wait until all IOService providers are quiet */
427 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
430 static void darwin_clear_iterator (io_iterator_t iter) {
433 while ((device = IOIteratorNext (iter)) != 0)
434 IOObjectRelease (device);
437 static void darwin_fail_startup(void) {
438 pthread_mutex_lock (&libusb_darwin_at_mutex);
439 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
440 pthread_cond_signal (&libusb_darwin_at_cond);
441 pthread_mutex_unlock (&libusb_darwin_at_mutex);
445 static void *darwin_event_thread_main (void *arg0) {
447 struct libusb_context *ctx = (struct libusb_context *)arg0;
448 CFRunLoopRef runloop;
449 CFRunLoopSourceRef libusb_shutdown_cfsource;
450 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
452 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
453 /* Set this thread's name, so it can be seen in the debugger
454 and crash reports. */
455 pthread_setname_np ("org.libusb.device-hotplug");
458 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
459 /* Tell the Objective-C garbage collector about this thread.
460 This is required because, unlike NSThreads, pthreads are
461 not automatically registered. Although we don't use
462 Objective-C, we use CoreFoundation, which does.
463 Garbage collection support was entirely removed in 10.12,
464 so don't bother there. */
465 objc_registerThreadWithCollector();
468 /* hotplug (device arrival/removal) sources */
469 CFRunLoopSourceRef libusb_notification_cfsource;
470 io_notification_port_t libusb_notification_port;
471 io_iterator_t libusb_rem_device_iterator;
472 io_iterator_t libusb_add_device_iterator;
474 usbi_dbg ("creating hotplug event source");
476 runloop = CFRunLoopGetCurrent ();
479 /* add the shutdown cfsource to the run loop */
480 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
481 libusb_shutdown_cfsourcectx.info = runloop;
482 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
483 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
484 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
486 /* add the notification port to the run loop */
487 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
488 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
489 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
491 /* create notifications for removed devices */
492 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
493 IOServiceMatching(darwin_device_class),
494 darwin_devices_detached,
495 ctx, &libusb_rem_device_iterator);
497 if (kresult != kIOReturnSuccess) {
498 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
499 CFRelease (libusb_shutdown_cfsource);
501 darwin_fail_startup ();
504 /* create notifications for attached devices */
505 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
506 IOServiceMatching(darwin_device_class),
507 darwin_devices_attached,
508 ctx, &libusb_add_device_iterator);
510 if (kresult != kIOReturnSuccess) {
511 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
512 CFRelease (libusb_shutdown_cfsource);
514 darwin_fail_startup ();
518 darwin_clear_iterator (libusb_rem_device_iterator);
519 darwin_clear_iterator (libusb_add_device_iterator);
521 usbi_dbg ("darwin event thread ready to receive events");
523 /* signal the main thread that the hotplug runloop has been created. */
524 pthread_mutex_lock (&libusb_darwin_at_mutex);
525 libusb_darwin_acfl = runloop;
526 libusb_darwin_acfls = libusb_shutdown_cfsource;
527 pthread_cond_signal (&libusb_darwin_at_cond);
528 pthread_mutex_unlock (&libusb_darwin_at_mutex);
530 /* run the runloop */
533 usbi_dbg ("darwin event thread exiting");
535 /* signal the main thread that the hotplug runloop has finished. */
536 pthread_mutex_lock (&libusb_darwin_at_mutex);
537 libusb_darwin_acfls = NULL;
538 libusb_darwin_acfl = NULL;
539 pthread_cond_signal (&libusb_darwin_at_cond);
540 pthread_mutex_unlock (&libusb_darwin_at_mutex);
542 /* remove the notification cfsource */
543 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
545 /* remove the shutdown cfsource */
546 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
548 /* delete notification port */
549 IONotificationPortDestroy (libusb_notification_port);
551 /* delete iterators */
552 IOObjectRelease (libusb_rem_device_iterator);
553 IOObjectRelease (libusb_add_device_iterator);
555 CFRelease (libusb_shutdown_cfsource);
561 /* cleanup function to destroy cached devices */
562 static void darwin_cleanup_devices(void) {
563 struct darwin_cached_device *dev, *next;
565 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
566 darwin_deref_cached_device(dev);
569 darwin_cached_devices.prev = darwin_cached_devices.next = NULL;
572 static int darwin_init(struct libusb_context *ctx) {
576 pthread_mutex_lock (&libusb_darwin_init_mutex);
578 first_init = (1 == ++init_count);
582 assert (NULL == darwin_cached_devices.next);
583 list_init (&darwin_cached_devices);
585 #if !defined(HAVE_CLOCK_GETTIME)
586 /* create the clocks that will be used if clock_gettime() is not available */
587 host_name_port_t host_self;
589 host_self = mach_host_self();
590 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
591 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
592 mach_port_deallocate(mach_task_self(), host_self);
596 rc = darwin_scan_devices (ctx);
597 if (LIBUSB_SUCCESS != rc)
601 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
603 usbi_err (ctx, "could not create event thread, error %d", rc);
604 rc = LIBUSB_ERROR_OTHER;
608 pthread_mutex_lock (&libusb_darwin_at_mutex);
609 while (!libusb_darwin_acfl)
610 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
611 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
612 libusb_darwin_acfl = NULL;
613 rc = LIBUSB_ERROR_OTHER;
615 pthread_mutex_unlock (&libusb_darwin_at_mutex);
618 pthread_join (libusb_darwin_at, NULL);
622 if (LIBUSB_SUCCESS != rc) {
624 darwin_cleanup_devices ();
625 #if !defined(HAVE_CLOCK_GETTIME)
626 mach_port_deallocate(mach_task_self(), clock_realtime);
627 mach_port_deallocate(mach_task_self(), clock_monotonic);
633 pthread_mutex_unlock (&libusb_darwin_init_mutex);
638 static void darwin_exit (struct libusb_context *ctx) {
641 pthread_mutex_lock (&libusb_darwin_init_mutex);
643 if (0 == --init_count) {
644 /* stop the event runloop and wait for the thread to terminate. */
645 pthread_mutex_lock (&libusb_darwin_at_mutex);
646 CFRunLoopSourceSignal (libusb_darwin_acfls);
647 CFRunLoopWakeUp (libusb_darwin_acfl);
648 while (libusb_darwin_acfl)
649 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
650 pthread_mutex_unlock (&libusb_darwin_at_mutex);
651 pthread_join (libusb_darwin_at, NULL);
653 darwin_cleanup_devices ();
655 #if !defined(HAVE_CLOCK_GETTIME)
656 mach_port_deallocate(mach_task_self(), clock_realtime);
657 mach_port_deallocate(mach_task_self(), clock_monotonic);
661 pthread_mutex_unlock (&libusb_darwin_init_mutex);
664 static int darwin_get_device_descriptor(struct libusb_device *dev, void *buffer, int *host_endian) {
665 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
667 /* return cached copy */
668 memmove (buffer, &(priv->dev_descriptor), LIBUSB_DT_DEVICE_SIZE);
670 return LIBUSB_SUCCESS;
673 static int get_configuration_index (struct libusb_device *dev, int config_value) {
674 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
676 IOUSBConfigurationDescriptorPtr desc;
679 /* is there a simpler way to determine the index? */
680 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
681 if (kresult != kIOReturnSuccess)
682 return darwin_to_libusb (kresult);
684 for (i = 0 ; i < numConfig ; i++) {
685 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
687 if (desc->bConfigurationValue == config_value)
691 /* configuration not found */
692 return LIBUSB_ERROR_NOT_FOUND;
695 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
696 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
699 if (0 == priv->active_config)
700 return LIBUSB_ERROR_NOT_FOUND;
702 config_index = get_configuration_index (dev, priv->active_config);
703 if (config_index < 0)
706 assert(config_index >= 0 && config_index <= UINT8_MAX);
707 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
710 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
711 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
712 IOUSBConfigurationDescriptorPtr desc;
716 if (!priv || !priv->device)
717 return LIBUSB_ERROR_OTHER;
719 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
720 if (kresult == kIOReturnSuccess) {
721 /* copy descriptor */
722 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
723 len = libusb_le16_to_cpu(desc->wTotalLength);
725 memmove (buffer, desc, len);
728 ret = darwin_to_libusb (kresult);
729 if (ret != LIBUSB_SUCCESS)
735 /* check whether the os has configured the device */
736 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
737 usb_device_t **darwin_device = dev->device;
739 IOUSBConfigurationDescriptorPtr configDesc;
740 IOUSBFindInterfaceRequest request;
742 io_iterator_t interface_iterator;
743 io_service_t firstInterface;
745 if (dev->dev_descriptor.bNumConfigurations < 1) {
746 usbi_err (ctx, "device has no configurations");
747 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
750 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
752 if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) {
753 usbi_dbg ("ignoring configuration on root hub simulation");
754 dev->active_config = 0;
755 return LIBUSB_SUCCESS;
758 /* find the first configuration */
759 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
760 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
762 /* check if the device is already configured. there is probably a better way than iterating over the
763 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
764 might lock up on the device request) */
766 /* Setup the Interface Request */
767 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
768 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
769 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
770 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
772 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
773 if (kresult != kIOReturnSuccess)
774 return darwin_to_libusb (kresult);
777 firstInterface = IOIteratorNext(interface_iterator);
779 /* done with the interface iterator */
780 IOObjectRelease(interface_iterator);
782 if (firstInterface) {
783 IOObjectRelease (firstInterface);
785 /* device is configured */
786 if (dev->dev_descriptor.bNumConfigurations == 1)
787 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
788 dev->active_config = dev->first_config;
790 /* devices with more than one configuration should work with GetConfiguration */
791 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
794 dev->active_config = 0;
796 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
798 return LIBUSB_SUCCESS;
801 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
802 IOUSBDevRequestTO req;
804 assert(buffer_size <= UINT16_MAX);
806 memset (buffer, 0, buffer_size);
808 /* Set up request for descriptor/ */
809 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
810 req.bRequest = kUSBRqGetDescriptor;
811 req.wValue = (UInt16)(desc << 8);
812 req.wIndex = desc_index;
813 req.wLength = (UInt16)buffer_size;
815 req.noDataTimeout = 20;
816 req.completionTimeout = 100;
818 return (*device)->DeviceRequestTO (device, &req);
821 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
822 usb_device_t **device = dev->device;
824 long delay = 30000; // microseconds
825 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
827 IOReturn ret = 0, ret2;
829 UInt16 idProduct, idVendor;
831 dev->can_enumerate = 0;
833 (*device)->GetDeviceClass (device, &bDeviceClass);
834 (*device)->GetDeviceProduct (device, &idProduct);
835 (*device)->GetDeviceVendor (device, &idVendor);
837 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
838 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
839 * to follow the spec as closely as possible, try opening the device */
840 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
843 /**** retrieve device descriptor ****/
844 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
846 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
847 /* received an overrun error but we still received a device descriptor */
848 ret = kIOReturnSuccess;
850 if (kIOUSBVendorIDAppleComputer == idVendor) {
851 /* NTH: don't bother retrying or unsuspending Apple devices */
855 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
856 0 == dev->dev_descriptor.bcdUSB)) {
857 /* work around for incorrectly configured devices */
858 if (try_reconfigure && is_open) {
859 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
861 /* set the first configuration */
862 (*device)->SetConfiguration(device, 1);
864 /* don't try to reconfigure again */
868 ret = kIOUSBPipeStalled;
871 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
872 /* device may be suspended. unsuspend it and try again */
873 #if DeviceVersion >= 320
876 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
877 (void)(*device)->GetUSBDeviceInformation (device, &info);
879 /* note that the device was suspended */
880 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
885 /* try to unsuspend the device */
886 ret2 = (*device)->USBDeviceSuspend (device, 0);
887 if (kIOReturnSuccess != ret2) {
888 /* prevent log spew from poorly behaving devices. this indicates the
889 os actually had trouble communicating with the device */
890 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
898 if (kIOReturnSuccess != ret) {
899 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
900 /* sleep for a little while before trying again */
901 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
903 } while (kIOReturnSuccess != ret && retries--);
906 /* resuspend the device */
907 (void)(*device)->USBDeviceSuspend (device, 1);
910 (void) (*device)->USBDeviceClose (device);
912 if (ret != kIOReturnSuccess) {
913 /* a debug message was already printed out for this error */
914 if (LIBUSB_CLASS_HUB == bDeviceClass)
915 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
916 idVendor, idProduct, darwin_error_str (ret), ret);
918 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
919 idVendor, idProduct, darwin_error_str (ret), ret);
920 return darwin_to_libusb (ret);
923 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
924 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
925 /* not a valid device */
926 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
927 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
928 return LIBUSB_ERROR_NO_DEVICE;
931 usbi_dbg ("cached device descriptor:");
932 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
933 usbi_dbg (" bcdUSB: 0x%04x", dev->dev_descriptor.bcdUSB);
934 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
935 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
936 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
937 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
938 usbi_dbg (" idVendor: 0x%04x", dev->dev_descriptor.idVendor);
939 usbi_dbg (" idProduct: 0x%04x", dev->dev_descriptor.idProduct);
940 usbi_dbg (" bcdDevice: 0x%04x", dev->dev_descriptor.bcdDevice);
941 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
942 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
943 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
944 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
946 dev->can_enumerate = 1;
948 return LIBUSB_SUCCESS;
951 /* Returns 1 on success, 0 on failure. */
952 static bool get_device_port (io_service_t service, UInt8 *port) {
957 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
961 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
962 if (kIOReturnSuccess == kresult) {
963 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
964 IOObjectRelease (parent);
970 /* Returns 1 on success, 0 on failure. */
971 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
975 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
977 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
978 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
984 /* We ran out of parents */
988 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
989 UInt64 *old_session_id) {
990 struct darwin_cached_device *new_device;
991 UInt64 sessionID = 0, parent_sessionID = 0;
992 UInt32 locationID = 0;
993 enum libusb_error ret = LIBUSB_SUCCESS;
994 usb_device_t **device;
997 /* assuming sessionID != 0 normally (never seen it be 0) */
1001 /* get some info from the io registry */
1002 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1003 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1004 if (!get_device_port (service, &port)) {
1005 usbi_dbg("could not get connected port number");
1008 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1010 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1011 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1014 usbi_mutex_lock(&darwin_cached_devices_lock);
1016 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1017 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1018 sessionID, locationID, new_device->session, new_device->location);
1019 if (new_device->location == locationID && new_device->in_reenumerate) {
1020 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1021 *old_session_id = new_device->session;
1025 if (new_device->session == sessionID) {
1026 usbi_dbg("using cached device for device");
1027 *cached_out = new_device;
1035 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1037 device = darwin_device_from_service (service);
1039 ret = LIBUSB_ERROR_NO_DEVICE;
1043 if (!(*old_session_id)) {
1044 new_device = calloc (1, sizeof (*new_device));
1046 ret = LIBUSB_ERROR_NO_MEM;
1050 /* add this device to the cached device list */
1051 list_add(&new_device->list, &darwin_cached_devices);
1053 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1055 /* keep a reference to this device */
1056 darwin_ref_cached_device(new_device);
1058 (*device)->GetLocationID (device, &new_device->location);
1059 new_device->port = port;
1060 new_device->parent_session = parent_sessionID;
1063 /* keep track of devices regardless of if we successfully enumerate them to
1064 prevent them from being enumerated multiple times */
1065 *cached_out = new_device;
1067 new_device->session = sessionID;
1068 new_device->device = device;
1070 /* cache the device descriptor */
1071 ret = darwin_cache_device_descriptor(new_device);
1075 if (new_device->can_enumerate) {
1076 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1077 new_device->dev_descriptor.idVendor, 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 if (cached_device->parent_session > 0) {
1130 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1132 dev->parent_dev = NULL;
1135 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1138 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1139 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1140 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1141 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1142 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1144 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1145 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1148 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1151 ret = usbi_sanitize_device (dev);
1155 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1156 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1160 if (!cached_device->in_reenumerate && 0 == ret) {
1161 usbi_connect_device (dev);
1163 libusb_unref_device (dev);
1169 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1170 struct darwin_cached_device *cached_device;
1171 UInt64 old_session_id;
1172 io_iterator_t deviceIterator;
1173 io_service_t service;
1177 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1178 if (kresult != kIOReturnSuccess)
1179 return darwin_to_libusb (kresult);
1181 while ((service = IOIteratorNext (deviceIterator))) {
1182 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1183 if (ret < 0 || !cached_device->can_enumerate) {
1187 (void) process_new_device (ctx, cached_device, old_session_id);
1189 IOObjectRelease(service);
1192 IOObjectRelease(deviceIterator);
1194 return LIBUSB_SUCCESS;
1197 static int darwin_open (struct libusb_device_handle *dev_handle) {
1198 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1199 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1202 if (0 == dpriv->open_count) {
1203 /* try to open the device */
1204 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1205 if (kresult != kIOReturnSuccess) {
1206 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1208 if (kIOReturnExclusiveAccess != kresult) {
1209 return darwin_to_libusb (kresult);
1212 /* it is possible to perform some actions on a device that is not open so do not return an error */
1213 priv->is_open = false;
1215 priv->is_open = true;
1218 /* create async event source */
1219 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1220 if (kresult != kIOReturnSuccess) {
1221 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1223 if (priv->is_open) {
1224 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1227 priv->is_open = false;
1229 return darwin_to_libusb (kresult);
1232 CFRetain (libusb_darwin_acfl);
1234 /* add the cfSource to the aync run loop */
1235 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1238 /* device opened successfully */
1239 dpriv->open_count++;
1241 usbi_dbg ("device open for access");
1246 static void darwin_close (struct libusb_device_handle *dev_handle) {
1247 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1248 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1252 if (dpriv->open_count == 0) {
1253 /* something is probably very wrong if this is the case */
1254 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1258 dpriv->open_count--;
1260 /* make sure all interfaces are released */
1261 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1262 if (dev_handle->claimed_interfaces & (1U << i))
1263 libusb_release_interface (dev_handle, i);
1265 if (0 == dpriv->open_count) {
1266 /* delete the device's async event source */
1267 if (priv->cfSource) {
1268 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1269 CFRelease (priv->cfSource);
1270 priv->cfSource = NULL;
1271 CFRelease (libusb_darwin_acfl);
1274 if (priv->is_open) {
1275 /* close the device */
1276 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1277 if (kresult != kIOReturnSuccess) {
1278 /* Log the fact that we had a problem closing the file, however failing a
1279 * close isn't really an error, so return success anyway */
1280 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1286 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
1287 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1289 *config = (int) dpriv->active_config;
1291 return LIBUSB_SUCCESS;
1294 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1295 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1299 assert(config >= 0 && config <= UINT8_MAX);
1301 /* Setting configuration will invalidate the interface, so we need
1302 to reclaim it. First, dispose of existing interfaces, if any. */
1303 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1304 if (dev_handle->claimed_interfaces & (1U << i))
1305 darwin_release_interface (dev_handle, i);
1307 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1308 if (kresult != kIOReturnSuccess)
1309 return darwin_to_libusb (kresult);
1311 /* Reclaim any interfaces. */
1312 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1313 if (dev_handle->claimed_interfaces & (1U << i))
1314 darwin_claim_interface (dev_handle, i);
1316 dpriv->active_config = (UInt8)config;
1318 return LIBUSB_SUCCESS;
1321 static IOReturn darwin_get_interface (usb_device_t **darwin_device, int ifc, io_service_t *usbInterfacep) {
1322 IOUSBFindInterfaceRequest request;
1324 io_iterator_t interface_iterator;
1325 UInt8 bInterfaceNumber;
1328 *usbInterfacep = IO_OBJECT_NULL;
1330 /* Setup the Interface Request */
1331 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1332 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1333 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1334 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1336 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1337 if (kresult != kIOReturnSuccess)
1340 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1341 /* find the interface number */
1342 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1345 if (ret && bInterfaceNumber == ifc) {
1349 (void) IOObjectRelease (*usbInterfacep);
1352 /* done with the interface iterator */
1353 IOObjectRelease(interface_iterator);
1355 return kIOReturnSuccess;
1358 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1359 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1361 /* current interface */
1362 struct darwin_interface *cInterface = &priv->interfaces[iface];
1366 UInt8 numep, direction, number;
1367 UInt8 dont_care1, dont_care3;
1371 usbi_dbg ("building table of endpoints.");
1373 /* retrieve the total number of endpoints on this interface */
1374 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1375 if (kresult != kIOReturnSuccess) {
1376 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1377 return darwin_to_libusb (kresult);
1380 /* iterate through pipe references */
1381 for (UInt8 i = 1 ; i <= numep ; i++) {
1382 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1383 &dont_care2, &dont_care3);
1385 if (kresult != kIOReturnSuccess) {
1386 /* probably a buggy device. try to get the endpoint address from the descriptors */
1387 struct libusb_config_descriptor *config;
1388 const struct libusb_endpoint_descriptor *endpoint_desc;
1391 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1392 if (kresult != kIOReturnSuccess) {
1393 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1394 return darwin_to_libusb (kresult);
1397 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1398 if (LIBUSB_SUCCESS != rc) {
1402 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1404 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1406 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1409 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1410 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1413 cInterface->num_endpoints = numep;
1415 return LIBUSB_SUCCESS;
1418 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
1419 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1420 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1421 io_service_t usbInterface = IO_OBJECT_NULL;
1423 enum libusb_error ret;
1424 IOCFPlugInInterface **plugInInterface = NULL;
1427 assert(iface >= 0 && iface <= UINT8_MAX);
1429 /* current interface */
1430 struct darwin_interface *cInterface = &priv->interfaces[iface];
1432 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1433 if (kresult != kIOReturnSuccess)
1434 return darwin_to_libusb (kresult);
1436 /* make sure we have an interface */
1437 if (!usbInterface && dpriv->first_config != 0) {
1438 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1440 /* set the configuration */
1441 ret = darwin_set_configuration (dev_handle, dpriv->first_config);
1442 if (ret != LIBUSB_SUCCESS) {
1443 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1447 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1448 if (kresult != kIOReturnSuccess) {
1449 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1450 return darwin_to_libusb (kresult);
1454 if (!usbInterface) {
1455 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1456 return LIBUSB_ERROR_NOT_FOUND;
1459 /* get an interface to the device's interface */
1460 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1461 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1463 /* ignore release error */
1464 (void)IOObjectRelease (usbInterface);
1466 if (kresult != kIOReturnSuccess) {
1467 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1468 return darwin_to_libusb (kresult);
1471 if (!plugInInterface) {
1472 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1473 return LIBUSB_ERROR_NOT_FOUND;
1476 /* Do the actual claim */
1477 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1478 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1479 (LPVOID)&cInterface->interface);
1480 /* We no longer need the intermediate plug-in */
1481 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1482 (*plugInInterface)->Release (plugInInterface);
1483 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1484 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1485 return darwin_to_libusb (kresult);
1488 /* claim the interface */
1489 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1490 if (kresult != kIOReturnSuccess) {
1491 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1492 return darwin_to_libusb (kresult);
1495 /* update list of endpoints */
1496 ret = get_endpoints (dev_handle, iface);
1498 /* this should not happen */
1499 darwin_release_interface (dev_handle, iface);
1500 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1504 cInterface->cfSource = NULL;
1506 /* create async event source */
1507 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1508 if (kresult != kIOReturnSuccess) {
1509 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1511 /* can't continue without an async event source */
1512 (void)darwin_release_interface (dev_handle, iface);
1514 return darwin_to_libusb (kresult);
1517 /* add the cfSource to the async thread's run loop */
1518 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1520 usbi_dbg ("interface opened");
1522 return LIBUSB_SUCCESS;
1525 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
1526 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1529 /* current interface */
1530 struct darwin_interface *cInterface = &priv->interfaces[iface];
1532 /* Check to see if an interface is open */
1533 if (!cInterface->interface)
1534 return LIBUSB_SUCCESS;
1536 /* clean up endpoint data */
1537 cInterface->num_endpoints = 0;
1539 /* delete the interface's async event source */
1540 if (cInterface->cfSource) {
1541 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1542 CFRelease (cInterface->cfSource);
1545 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1546 if (kresult != kIOReturnSuccess)
1547 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1549 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1550 if (kresult != kIOReturnSuccess)
1551 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1553 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1555 return darwin_to_libusb (kresult);
1558 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
1559 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1561 enum libusb_error ret;
1563 /* current interface */
1564 struct darwin_interface *cInterface = &priv->interfaces[iface];
1566 if (!cInterface->interface)
1567 return LIBUSB_ERROR_NO_DEVICE;
1569 assert(altsetting >= 0 && altsetting <= UINT8_MAX);
1570 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, (UInt8)altsetting);
1571 if (kresult != kIOReturnSuccess)
1572 darwin_reset_device (dev_handle);
1574 /* update list of endpoints */
1575 ret = get_endpoints (dev_handle, iface);
1577 /* this should not happen */
1578 darwin_release_interface (dev_handle, iface);
1579 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1583 return darwin_to_libusb (kresult);
1586 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1587 /* current interface */
1588 struct darwin_interface *cInterface;
1592 /* determine the interface/endpoint to use */
1593 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1594 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1596 return LIBUSB_ERROR_NOT_FOUND;
1599 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1600 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1601 if (kresult != kIOReturnSuccess)
1602 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1604 return darwin_to_libusb (kresult);
1607 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1608 unsigned long claimed_interfaces) {
1609 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1610 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1611 int open_count = dpriv->open_count;
1614 /* clear claimed interfaces temporarily */
1615 dev_handle->claimed_interfaces = 0;
1617 /* close and re-open the device */
1618 priv->is_open = false;
1619 dpriv->open_count = 1;
1621 /* clean up open interfaces */
1622 (void) darwin_close (dev_handle);
1624 /* re-open the device */
1625 ret = darwin_open (dev_handle);
1626 dpriv->open_count = open_count;
1627 if (LIBUSB_SUCCESS != ret) {
1628 /* could not restore configuration */
1629 return LIBUSB_ERROR_NOT_FOUND;
1632 if (dpriv->active_config != active_config) {
1633 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1635 ret = darwin_set_configuration (dev_handle, active_config);
1636 if (LIBUSB_SUCCESS != ret) {
1637 usbi_dbg ("darwin/restore_state: could not restore configuration");
1638 return LIBUSB_ERROR_NOT_FOUND;
1642 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1644 if (claimed_interfaces) {
1645 for (int iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1646 if (!(claimed_interfaces & (1U << iface))) {
1650 usbi_dbg ("darwin/restore_state: re-claiming interface %d", iface);
1652 ret = darwin_claim_interface (dev_handle, iface);
1653 if (LIBUSB_SUCCESS != ret) {
1654 usbi_dbg ("darwin/restore_state: could not claim interface %d", iface);
1655 return LIBUSB_ERROR_NOT_FOUND;
1658 dev_handle->claimed_interfaces |= 1U << iface;
1662 usbi_dbg ("darwin/restore_state: device state restored");
1664 return LIBUSB_SUCCESS;
1667 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1668 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1669 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1670 int8_t active_config = dpriv->active_config;
1671 IOUSBDeviceDescriptor descriptor;
1672 IOUSBConfigurationDescriptorPtr cached_configuration;
1673 IOUSBConfigurationDescriptor *cached_configurations;
1677 if (dpriv->in_reenumerate) {
1678 /* ack, two (or more) threads are trying to reset the device! abort! */
1679 return LIBUSB_ERROR_NOT_FOUND;
1682 dpriv->in_reenumerate = true;
1684 /* store copies of descriptors so they can be compared after the reset */
1685 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1686 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1688 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1689 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1690 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1693 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1694 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1695 if (kresult != kIOReturnSuccess) {
1696 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1697 dpriv->in_reenumerate = false;
1698 return darwin_to_libusb (kresult);
1701 usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1703 while (dpriv->in_reenumerate) {
1704 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1705 nanosleep (&delay, NULL);
1708 /* compare descriptors */
1709 usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1711 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1712 /* device descriptor changed. need to return not found. */
1713 usbi_dbg ("darwin/reset_device: device descriptor changed");
1714 return LIBUSB_ERROR_NOT_FOUND;
1717 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1718 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1719 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1720 usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1721 return LIBUSB_ERROR_NOT_FOUND;
1725 usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1727 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1730 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
1731 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1732 io_service_t usbInterface;
1736 assert(interface >= 0 && interface <= UINT8_MAX);
1737 kresult = darwin_get_interface (dpriv->device, (uint8_t)interface, &usbInterface);
1738 if (kresult != kIOReturnSuccess) {
1739 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1741 return darwin_to_libusb (kresult);
1744 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1745 IOObjectRelease (usbInterface);
1757 static void darwin_destroy_device(struct libusb_device *dev) {
1758 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1761 /* need to hold the lock in case this is the last reference to the device */
1762 usbi_mutex_lock(&darwin_cached_devices_lock);
1763 darwin_deref_cached_device (dpriv->dev);
1765 usbi_mutex_unlock(&darwin_cached_devices_lock);
1769 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1770 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1773 uint8_t transferType;
1774 /* None of the values below are used in libusbx for bulk transfers */
1775 uint8_t direction, number, interval, pipeRef;
1776 uint16_t maxPacketSize;
1778 struct darwin_interface *cInterface;
1780 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1781 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1783 return LIBUSB_ERROR_NOT_FOUND;
1786 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1787 &transferType, &maxPacketSize, &interval);
1790 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1791 darwin_error_str(ret), ret);
1792 return darwin_to_libusb (ret);
1795 if (0 != (transfer->length % maxPacketSize)) {
1796 /* do not need a zero packet */
1797 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1800 /* submit the request */
1801 /* timeouts are unavailable on interrupt endpoints */
1802 if (transferType == kUSBInterrupt) {
1803 if (IS_XFERIN(transfer))
1804 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1805 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1807 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1808 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1810 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1812 if (IS_XFERIN(transfer))
1813 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1814 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1815 darwin_async_io_callback, itransfer);
1817 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1818 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1819 darwin_async_io_callback, itransfer);
1823 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1824 darwin_error_str(ret), ret);
1826 return darwin_to_libusb (ret);
1829 #if InterfaceVersion >= 550
1830 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1831 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1832 struct darwin_interface *cInterface;
1836 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1837 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1839 return LIBUSB_ERROR_NOT_FOUND;
1842 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1844 if (IS_XFERIN(transfer))
1845 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1846 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1847 transfer->timeout, darwin_async_io_callback, itransfer);
1849 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1850 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1851 transfer->timeout, darwin_async_io_callback, itransfer);
1854 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1855 darwin_error_str(ret), ret);
1857 return darwin_to_libusb (ret);
1861 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1862 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1863 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1866 uint8_t direction, number, interval, pipeRef, transferType;
1867 uint16_t maxPacketSize;
1869 AbsoluteTime atTime;
1872 struct darwin_interface *cInterface;
1874 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1875 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1876 free(tpriv->isoc_framelist);
1877 tpriv->isoc_framelist = NULL;
1880 if (!tpriv->isoc_framelist) {
1881 tpriv->num_iso_packets = transfer->num_iso_packets;
1882 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1883 if (!tpriv->isoc_framelist)
1884 return LIBUSB_ERROR_NO_MEM;
1887 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1888 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1889 unsigned int length = transfer->iso_packet_desc[i].length;
1890 assert(length <= UINT16_MAX);
1891 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1894 /* determine the interface/endpoint to use */
1895 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1896 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1898 return LIBUSB_ERROR_NOT_FOUND;
1901 /* determine the properties of this endpoint and the speed of the device */
1902 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1903 &transferType, &maxPacketSize, &interval);
1905 /* Last but not least we need the bus frame number */
1906 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1907 if (kresult != kIOReturnSuccess) {
1908 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1909 free(tpriv->isoc_framelist);
1910 tpriv->isoc_framelist = NULL;
1912 return darwin_to_libusb (kresult);
1915 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1916 &transferType, &maxPacketSize, &interval);
1918 /* schedule for a frame a little in the future */
1921 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1922 frame = cInterface->frames[transfer->endpoint];
1924 /* submit the request */
1925 if (IS_XFERIN(transfer))
1926 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1927 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1930 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1931 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1934 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1936 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1938 /* High/super speed */
1939 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1941 if (kresult != kIOReturnSuccess) {
1942 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1943 darwin_error_str(kresult));
1944 free (tpriv->isoc_framelist);
1945 tpriv->isoc_framelist = NULL;
1948 return darwin_to_libusb (kresult);
1951 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1952 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1953 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1954 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1955 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1959 memset(&tpriv->req, 0, sizeof(tpriv->req));
1961 /* IOUSBDeviceInterface expects the request in cpu endianness */
1962 tpriv->req.bmRequestType = setup->bmRequestType;
1963 tpriv->req.bRequest = setup->bRequest;
1964 /* these values should be in bus order from libusb_fill_control_setup */
1965 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1966 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1967 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1968 /* data is stored after the libusb control block */
1969 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1970 tpriv->req.completionTimeout = transfer->timeout;
1971 tpriv->req.noDataTimeout = transfer->timeout;
1973 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1975 /* all transfers in libusb-1.0 are async */
1977 if (transfer->endpoint) {
1978 struct darwin_interface *cInterface;
1981 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1982 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1984 return LIBUSB_ERROR_NOT_FOUND;
1987 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1989 /* control request on endpoint 0 */
1990 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1992 if (kresult != kIOReturnSuccess)
1993 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
1995 return darwin_to_libusb (kresult);
1998 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1999 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2001 switch (transfer->type) {
2002 case LIBUSB_TRANSFER_TYPE_CONTROL:
2003 return submit_control_transfer(itransfer);
2004 case LIBUSB_TRANSFER_TYPE_BULK:
2005 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2006 return submit_bulk_transfer(itransfer);
2007 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2008 return submit_iso_transfer(itransfer);
2009 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2010 #if InterfaceVersion >= 550
2011 return submit_stream_transfer(itransfer);
2013 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2014 return LIBUSB_ERROR_NOT_SUPPORTED;
2017 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2018 return LIBUSB_ERROR_INVALID_PARAM;
2022 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2023 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2024 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2027 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2030 return LIBUSB_ERROR_NO_DEVICE;
2032 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2034 return darwin_to_libusb (kresult);
2037 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2038 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2039 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2040 struct darwin_interface *cInterface;
2041 uint8_t pipeRef, iface;
2044 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2045 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2047 return LIBUSB_ERROR_NOT_FOUND;
2051 return LIBUSB_ERROR_NO_DEVICE;
2053 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2055 /* abort transactions */
2056 #if InterfaceVersion >= 550
2057 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2058 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2061 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2063 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2065 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2066 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2068 return darwin_to_libusb (kresult);
2071 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2072 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2074 switch (transfer->type) {
2075 case LIBUSB_TRANSFER_TYPE_CONTROL:
2076 return cancel_control_transfer(itransfer);
2077 case LIBUSB_TRANSFER_TYPE_BULK:
2078 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2079 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2080 return darwin_abort_transfers (itransfer);
2082 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2083 return LIBUSB_ERROR_INVALID_PARAM;
2087 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2088 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2089 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2090 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2092 usbi_dbg ("an async io operation has completed");
2094 /* if requested write a zero packet */
2095 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2096 struct darwin_interface *cInterface;
2099 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2101 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2104 tpriv->result = result;
2105 tpriv->size = (UInt32) (uintptr_t) arg0;
2107 /* signal the core that this transfer is complete */
2108 usbi_signal_transfer_completion(itransfer);
2111 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2112 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2113 result = kIOUSBTransactionTimeout;
2116 case kIOReturnUnderrun:
2117 case kIOReturnSuccess:
2118 return LIBUSB_TRANSFER_COMPLETED;
2119 case kIOReturnAborted:
2120 return LIBUSB_TRANSFER_CANCELLED;
2121 case kIOUSBPipeStalled:
2122 usbi_dbg ("transfer error: pipe is stalled");
2123 return LIBUSB_TRANSFER_STALL;
2124 case kIOReturnOverrun:
2125 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2126 return LIBUSB_TRANSFER_OVERFLOW;
2127 case kIOUSBTransactionTimeout:
2128 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2129 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2130 return LIBUSB_TRANSFER_TIMED_OUT;
2132 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2133 return LIBUSB_TRANSFER_ERROR;
2137 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2138 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2139 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2140 bool isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2141 bool isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
2142 bool isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
2143 bool isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
2146 if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
2147 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2148 return LIBUSB_ERROR_INVALID_PARAM;
2151 usbi_dbg ("handling %s completion with kernel status %d",
2152 isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
2154 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2155 if (isIsoc && tpriv->isoc_framelist) {
2156 /* copy isochronous results back */
2158 for (i = 0; i < transfer->num_iso_packets ; i++) {
2159 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2160 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2161 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2164 itransfer->transferred += tpriv->size;
2167 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2168 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2171 #if !defined(HAVE_CLOCK_GETTIME)
2172 int usbi_clock_gettime(int clk_id, struct timespec *tp) {
2173 mach_timespec_t sys_time;
2174 clock_serv_t clock_ref;
2177 case USBI_CLOCK_REALTIME:
2178 /* CLOCK_REALTIME represents time since the epoch */
2179 clock_ref = clock_realtime;
2181 case USBI_CLOCK_MONOTONIC:
2182 /* use system boot time as reference for the monotonic clock */
2183 clock_ref = clock_monotonic;
2190 clock_get_time (clock_ref, &sys_time);
2192 tp->tv_sec = sys_time.tv_sec;
2193 tp->tv_nsec = sys_time.tv_nsec;
2199 #if InterfaceVersion >= 550
2200 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2201 int num_endpoints) {
2202 struct darwin_interface *cInterface;
2203 UInt32 supportsStreams;
2207 /* find the mimimum number of supported streams on the endpoint list */
2208 for (i = 0 ; i < num_endpoints ; ++i) {
2209 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2213 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2214 if (num_streams > supportsStreams)
2215 num_streams = supportsStreams;
2218 /* it is an error if any endpoint in endpoints does not support streams */
2219 if (0 == num_streams)
2220 return LIBUSB_ERROR_INVALID_PARAM;
2222 /* create the streams */
2223 for (i = 0 ; i < num_endpoints ; ++i) {
2224 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2226 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2227 if (kIOReturnSuccess != rc)
2228 return darwin_to_libusb(rc);
2231 assert(num_streams <= INT_MAX);
2232 return (int)num_streams;
2235 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2236 struct darwin_interface *cInterface;
2237 UInt32 supportsStreams;
2241 for (int i = 0 ; i < num_endpoints ; ++i) {
2242 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2245 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2246 if (0 == supportsStreams)
2247 return LIBUSB_ERROR_INVALID_PARAM;
2249 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2250 if (kIOReturnSuccess != rc)
2251 return darwin_to_libusb(rc);
2254 return LIBUSB_SUCCESS;
2258 const struct usbi_os_backend usbi_backend = {
2261 .init = darwin_init,
2262 .exit = darwin_exit,
2263 .get_device_descriptor = darwin_get_device_descriptor,
2264 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2265 .get_config_descriptor = darwin_get_config_descriptor,
2266 .hotplug_poll = darwin_hotplug_poll,
2268 .open = darwin_open,
2269 .close = darwin_close,
2270 .get_configuration = darwin_get_configuration,
2271 .set_configuration = darwin_set_configuration,
2272 .claim_interface = darwin_claim_interface,
2273 .release_interface = darwin_release_interface,
2275 .set_interface_altsetting = darwin_set_interface_altsetting,
2276 .clear_halt = darwin_clear_halt,
2277 .reset_device = darwin_reset_device,
2279 #if InterfaceVersion >= 550
2280 .alloc_streams = darwin_alloc_streams,
2281 .free_streams = darwin_free_streams,
2284 .kernel_driver_active = darwin_kernel_driver_active,
2286 .destroy_device = darwin_destroy_device,
2288 .submit_transfer = darwin_submit_transfer,
2289 .cancel_transfer = darwin_cancel_transfer,
2291 .handle_transfer_completion = darwin_handle_transfer_completion,
2293 .device_priv_size = sizeof(struct darwin_device_priv),
2294 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2295 .transfer_priv_size = sizeof(struct darwin_transfer_priv),