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 = {&darwin_cached_devices, &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, unsigned char *buffer, size_t len, int *host_endian);
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 __attribute__((destructor)) _darwin_finalize(void) {
563 struct darwin_cached_device *dev, *next;
565 usbi_mutex_lock(&darwin_cached_devices_lock);
566 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
567 darwin_deref_cached_device(dev);
569 usbi_mutex_unlock(&darwin_cached_devices_lock);
572 static int darwin_init(struct libusb_context *ctx) {
576 pthread_mutex_lock (&libusb_darwin_init_mutex);
578 first_init = (1 == ++init_count);
581 #if !defined(HAVE_CLOCK_GETTIME)
583 /* create the clocks that will be used if clock_gettime() is not available */
584 host_name_port_t host_self;
586 host_self = mach_host_self();
587 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
588 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
589 mach_port_deallocate(mach_task_self(), host_self);
593 rc = darwin_scan_devices (ctx);
594 if (LIBUSB_SUCCESS != rc)
598 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
600 usbi_err (ctx, "could not create event thread, error %d", rc);
601 rc = LIBUSB_ERROR_OTHER;
605 pthread_mutex_lock (&libusb_darwin_at_mutex);
606 while (!libusb_darwin_acfl)
607 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
608 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
609 libusb_darwin_acfl = NULL;
610 rc = LIBUSB_ERROR_OTHER;
612 pthread_mutex_unlock (&libusb_darwin_at_mutex);
615 pthread_join (libusb_darwin_at, NULL);
619 if (LIBUSB_SUCCESS != rc) {
620 #if !defined(HAVE_CLOCK_GETTIME)
622 mach_port_deallocate(mach_task_self(), clock_realtime);
623 mach_port_deallocate(mach_task_self(), clock_monotonic);
629 pthread_mutex_unlock (&libusb_darwin_init_mutex);
634 static void darwin_exit (struct libusb_context *ctx) {
637 pthread_mutex_lock (&libusb_darwin_init_mutex);
639 if (0 == --init_count) {
640 /* stop the event runloop and wait for the thread to terminate. */
641 pthread_mutex_lock (&libusb_darwin_at_mutex);
642 CFRunLoopSourceSignal (libusb_darwin_acfls);
643 CFRunLoopWakeUp (libusb_darwin_acfl);
644 while (libusb_darwin_acfl)
645 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
646 pthread_mutex_unlock (&libusb_darwin_at_mutex);
647 pthread_join (libusb_darwin_at, NULL);
649 #if !defined(HAVE_CLOCK_GETTIME)
650 mach_port_deallocate(mach_task_self(), clock_realtime);
651 mach_port_deallocate(mach_task_self(), clock_monotonic);
655 pthread_mutex_unlock (&libusb_darwin_init_mutex);
658 static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
659 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
661 /* return cached copy */
662 memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
666 return LIBUSB_SUCCESS;
669 static int get_configuration_index (struct libusb_device *dev, int config_value) {
670 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
672 IOUSBConfigurationDescriptorPtr desc;
675 /* is there a simpler way to determine the index? */
676 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
677 if (kresult != kIOReturnSuccess)
678 return darwin_to_libusb (kresult);
680 for (i = 0 ; i < numConfig ; i++) {
681 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
683 if (desc->bConfigurationValue == config_value)
687 /* configuration not found */
688 return LIBUSB_ERROR_NOT_FOUND;
691 static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) {
692 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
695 if (0 == priv->active_config)
696 return LIBUSB_ERROR_NOT_FOUND;
698 config_index = get_configuration_index (dev, priv->active_config);
699 if (config_index < 0)
702 assert(config_index >= 0 && config_index <= UINT8_MAX);
703 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len, host_endian);
706 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) {
707 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
708 IOUSBConfigurationDescriptorPtr desc;
712 if (!priv || !priv->device)
713 return LIBUSB_ERROR_OTHER;
715 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
716 if (kresult == kIOReturnSuccess) {
717 /* copy descriptor */
718 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
719 len = libusb_le16_to_cpu(desc->wTotalLength);
721 memmove (buffer, desc, len);
723 /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */
727 ret = darwin_to_libusb (kresult);
728 if (ret != LIBUSB_SUCCESS)
734 /* check whether the os has configured the device */
735 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
736 usb_device_t **darwin_device = dev->device;
738 IOUSBConfigurationDescriptorPtr configDesc;
739 IOUSBFindInterfaceRequest request;
741 io_iterator_t interface_iterator;
742 io_service_t firstInterface;
744 if (dev->dev_descriptor.bNumConfigurations < 1) {
745 usbi_err (ctx, "device has no configurations");
746 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
749 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
751 if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == 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", 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", dev->dev_descriptor.idVendor);
938 usbi_dbg (" idProduct: 0x%04x", dev->dev_descriptor.idProduct);
939 usbi_dbg (" bcdDevice: 0x%04x", 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 new_device->dev_descriptor.idVendor, new_device->dev_descriptor.idProduct,
1077 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1081 usbi_mutex_unlock(&darwin_cached_devices_lock);
1086 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1087 UInt64 old_session_id) {
1088 struct darwin_device_priv *priv;
1089 struct libusb_device *dev = NULL;
1091 enum libusb_error ret = LIBUSB_SUCCESS;
1094 /* check current active configuration (and cache the first configuration value--
1095 which may be used by claim_interface) */
1096 ret = darwin_check_configuration (ctx, cached_device);
1100 if (0 != old_session_id) {
1101 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1102 ctx, old_session_id, cached_device->session);
1103 /* save the libusb device before the session id is updated */
1104 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1108 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1109 ctx, cached_device->session);
1111 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1113 return LIBUSB_ERROR_NO_MEM;
1116 priv = usbi_get_device_priv(dev);
1118 priv->dev = cached_device;
1119 darwin_ref_cached_device (priv->dev);
1120 dev->port_number = cached_device->port;
1121 dev->bus_number = cached_device->location >> 24;
1122 assert(cached_device->address <= UINT8_MAX);
1123 dev->device_address = (uint8_t)cached_device->address;
1125 priv = usbi_get_device_priv(dev);
1128 if (cached_device->parent_session > 0) {
1129 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1131 dev->parent_dev = NULL;
1134 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1137 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1138 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1139 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1140 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1141 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1143 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1144 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1147 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1150 ret = usbi_sanitize_device (dev);
1154 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1155 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1159 if (!cached_device->in_reenumerate && 0 == ret) {
1160 usbi_connect_device (dev);
1162 libusb_unref_device (dev);
1168 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1169 struct darwin_cached_device *cached_device;
1170 UInt64 old_session_id;
1171 io_iterator_t deviceIterator;
1172 io_service_t service;
1176 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1177 if (kresult != kIOReturnSuccess)
1178 return darwin_to_libusb (kresult);
1180 while ((service = IOIteratorNext (deviceIterator))) {
1181 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1182 if (ret < 0 || !cached_device->can_enumerate) {
1186 (void) process_new_device (ctx, cached_device, old_session_id);
1188 IOObjectRelease(service);
1191 IOObjectRelease(deviceIterator);
1193 return LIBUSB_SUCCESS;
1196 static int darwin_open (struct libusb_device_handle *dev_handle) {
1197 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1198 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1201 if (0 == dpriv->open_count) {
1202 /* try to open the device */
1203 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1204 if (kresult != kIOReturnSuccess) {
1205 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1207 if (kIOReturnExclusiveAccess != kresult) {
1208 return darwin_to_libusb (kresult);
1211 /* it is possible to perform some actions on a device that is not open so do not return an error */
1212 priv->is_open = false;
1214 priv->is_open = true;
1217 /* create async event source */
1218 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1219 if (kresult != kIOReturnSuccess) {
1220 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1222 if (priv->is_open) {
1223 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1226 priv->is_open = false;
1228 return darwin_to_libusb (kresult);
1231 CFRetain (libusb_darwin_acfl);
1233 /* add the cfSource to the aync run loop */
1234 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1237 /* device opened successfully */
1238 dpriv->open_count++;
1240 usbi_dbg ("device open for access");
1245 static void darwin_close (struct libusb_device_handle *dev_handle) {
1246 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1247 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1251 if (dpriv->open_count == 0) {
1252 /* something is probably very wrong if this is the case */
1253 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1257 dpriv->open_count--;
1259 /* make sure all interfaces are released */
1260 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1261 if (dev_handle->claimed_interfaces & (1U << i))
1262 libusb_release_interface (dev_handle, i);
1264 if (0 == dpriv->open_count) {
1265 /* delete the device's async event source */
1266 if (priv->cfSource) {
1267 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1268 CFRelease (priv->cfSource);
1269 priv->cfSource = NULL;
1270 CFRelease (libusb_darwin_acfl);
1273 if (priv->is_open) {
1274 /* close the device */
1275 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1276 if (kresult != kIOReturnSuccess) {
1277 /* Log the fact that we had a problem closing the file, however failing a
1278 * close isn't really an error, so return success anyway */
1279 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1285 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
1286 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1288 *config = (int) dpriv->active_config;
1290 return LIBUSB_SUCCESS;
1293 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1294 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1298 assert(config >= 0 && config <= UINT8_MAX);
1300 /* Setting configuration will invalidate the interface, so we need
1301 to reclaim it. First, dispose of existing interfaces, if any. */
1302 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1303 if (dev_handle->claimed_interfaces & (1U << i))
1304 darwin_release_interface (dev_handle, i);
1306 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1307 if (kresult != kIOReturnSuccess)
1308 return darwin_to_libusb (kresult);
1310 /* Reclaim any interfaces. */
1311 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1312 if (dev_handle->claimed_interfaces & (1U << i))
1313 darwin_claim_interface (dev_handle, i);
1315 dpriv->active_config = (UInt8)config;
1317 return LIBUSB_SUCCESS;
1320 static IOReturn darwin_get_interface (usb_device_t **darwin_device, int ifc, io_service_t *usbInterfacep) {
1321 IOUSBFindInterfaceRequest request;
1323 io_iterator_t interface_iterator;
1324 UInt8 bInterfaceNumber;
1327 *usbInterfacep = IO_OBJECT_NULL;
1329 /* Setup the Interface Request */
1330 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1331 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1332 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1333 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1335 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1336 if (kresult != kIOReturnSuccess)
1339 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1340 /* find the interface number */
1341 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1344 if (ret && bInterfaceNumber == ifc) {
1348 (void) IOObjectRelease (*usbInterfacep);
1351 /* done with the interface iterator */
1352 IOObjectRelease(interface_iterator);
1354 return kIOReturnSuccess;
1357 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1358 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1360 /* current interface */
1361 struct darwin_interface *cInterface = &priv->interfaces[iface];
1365 UInt8 numep, direction, number;
1366 UInt8 dont_care1, dont_care3;
1370 usbi_dbg ("building table of endpoints.");
1372 /* retrieve the total number of endpoints on this interface */
1373 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1374 if (kresult != kIOReturnSuccess) {
1375 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1376 return darwin_to_libusb (kresult);
1379 /* iterate through pipe references */
1380 for (UInt8 i = 1 ; i <= numep ; i++) {
1381 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1382 &dont_care2, &dont_care3);
1384 if (kresult != kIOReturnSuccess) {
1385 /* probably a buggy device. try to get the endpoint address from the descriptors */
1386 struct libusb_config_descriptor *config;
1387 const struct libusb_endpoint_descriptor *endpoint_desc;
1390 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1391 if (kresult != kIOReturnSuccess) {
1392 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1393 return darwin_to_libusb (kresult);
1396 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1397 if (LIBUSB_SUCCESS != rc) {
1401 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1403 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1405 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1408 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1409 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1412 cInterface->num_endpoints = numep;
1414 return LIBUSB_SUCCESS;
1417 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
1418 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1419 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1420 io_service_t usbInterface = IO_OBJECT_NULL;
1422 enum libusb_error ret;
1423 IOCFPlugInInterface **plugInInterface = NULL;
1426 assert(iface >= 0 && iface <= UINT8_MAX);
1428 /* current interface */
1429 struct darwin_interface *cInterface = &priv->interfaces[iface];
1431 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1432 if (kresult != kIOReturnSuccess)
1433 return darwin_to_libusb (kresult);
1435 /* make sure we have an interface */
1436 if (!usbInterface && dpriv->first_config != 0) {
1437 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1439 /* set the configuration */
1440 ret = darwin_set_configuration (dev_handle, dpriv->first_config);
1441 if (ret != LIBUSB_SUCCESS) {
1442 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1446 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1447 if (kresult != kIOReturnSuccess) {
1448 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1449 return darwin_to_libusb (kresult);
1453 if (!usbInterface) {
1454 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1455 return LIBUSB_ERROR_NOT_FOUND;
1458 /* get an interface to the device's interface */
1459 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1460 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1462 /* ignore release error */
1463 (void)IOObjectRelease (usbInterface);
1465 if (kresult != kIOReturnSuccess) {
1466 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1467 return darwin_to_libusb (kresult);
1470 if (!plugInInterface) {
1471 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1472 return LIBUSB_ERROR_NOT_FOUND;
1475 /* Do the actual claim */
1476 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1477 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1478 (LPVOID)&cInterface->interface);
1479 /* We no longer need the intermediate plug-in */
1480 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1481 (*plugInInterface)->Release (plugInInterface);
1482 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1483 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1484 return darwin_to_libusb (kresult);
1487 /* claim the interface */
1488 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1489 if (kresult != kIOReturnSuccess) {
1490 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1491 return darwin_to_libusb (kresult);
1494 /* update list of endpoints */
1495 ret = get_endpoints (dev_handle, iface);
1497 /* this should not happen */
1498 darwin_release_interface (dev_handle, iface);
1499 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1503 cInterface->cfSource = NULL;
1505 /* create async event source */
1506 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1507 if (kresult != kIOReturnSuccess) {
1508 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1510 /* can't continue without an async event source */
1511 (void)darwin_release_interface (dev_handle, iface);
1513 return darwin_to_libusb (kresult);
1516 /* add the cfSource to the async thread's run loop */
1517 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1519 usbi_dbg ("interface opened");
1521 return LIBUSB_SUCCESS;
1524 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
1525 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1528 /* current interface */
1529 struct darwin_interface *cInterface = &priv->interfaces[iface];
1531 /* Check to see if an interface is open */
1532 if (!cInterface->interface)
1533 return LIBUSB_SUCCESS;
1535 /* clean up endpoint data */
1536 cInterface->num_endpoints = 0;
1538 /* delete the interface's async event source */
1539 if (cInterface->cfSource) {
1540 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1541 CFRelease (cInterface->cfSource);
1544 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1545 if (kresult != kIOReturnSuccess)
1546 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1548 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1549 if (kresult != kIOReturnSuccess)
1550 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1552 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1554 return darwin_to_libusb (kresult);
1557 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
1558 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1560 enum libusb_error ret;
1562 /* current interface */
1563 struct darwin_interface *cInterface = &priv->interfaces[iface];
1565 if (!cInterface->interface)
1566 return LIBUSB_ERROR_NO_DEVICE;
1568 assert(altsetting >= 0 && altsetting <= UINT8_MAX);
1569 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, (UInt8)altsetting);
1570 if (kresult != kIOReturnSuccess)
1571 darwin_reset_device (dev_handle);
1573 /* update list of endpoints */
1574 ret = get_endpoints (dev_handle, iface);
1576 /* this should not happen */
1577 darwin_release_interface (dev_handle, iface);
1578 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1582 return darwin_to_libusb (kresult);
1585 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1586 /* current interface */
1587 struct darwin_interface *cInterface;
1591 /* determine the interface/endpoint to use */
1592 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1593 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1595 return LIBUSB_ERROR_NOT_FOUND;
1598 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1599 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1600 if (kresult != kIOReturnSuccess)
1601 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1603 return darwin_to_libusb (kresult);
1606 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1607 unsigned long claimed_interfaces) {
1608 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1609 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1610 int open_count = dpriv->open_count;
1613 /* clear claimed interfaces temporarily */
1614 dev_handle->claimed_interfaces = 0;
1616 /* close and re-open the device */
1617 priv->is_open = false;
1618 dpriv->open_count = 1;
1620 /* clean up open interfaces */
1621 (void) darwin_close (dev_handle);
1623 /* re-open the device */
1624 ret = darwin_open (dev_handle);
1625 dpriv->open_count = open_count;
1626 if (LIBUSB_SUCCESS != ret) {
1627 /* could not restore configuration */
1628 return LIBUSB_ERROR_NOT_FOUND;
1631 if (dpriv->active_config != active_config) {
1632 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1634 ret = darwin_set_configuration (dev_handle, active_config);
1635 if (LIBUSB_SUCCESS != ret) {
1636 usbi_dbg ("darwin/restore_state: could not restore configuration");
1637 return LIBUSB_ERROR_NOT_FOUND;
1641 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1643 if (claimed_interfaces) {
1644 for (int iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1645 if (!(claimed_interfaces & (1U << iface))) {
1649 usbi_dbg ("darwin/restore_state: re-claiming interface %d", iface);
1651 ret = darwin_claim_interface (dev_handle, iface);
1652 if (LIBUSB_SUCCESS != ret) {
1653 usbi_dbg ("darwin/restore_state: could not claim interface %d", iface);
1654 return LIBUSB_ERROR_NOT_FOUND;
1657 dev_handle->claimed_interfaces |= 1U << iface;
1661 usbi_dbg ("darwin/restore_state: device state restored");
1663 return LIBUSB_SUCCESS;
1666 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1667 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1668 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1669 int8_t active_config = dpriv->active_config;
1670 IOUSBDeviceDescriptor descriptor;
1671 IOUSBConfigurationDescriptorPtr cached_configuration;
1672 IOUSBConfigurationDescriptor *cached_configurations;
1676 if (dpriv->in_reenumerate) {
1677 /* ack, two (or more) threads are trying to reset the device! abort! */
1678 return LIBUSB_ERROR_NOT_FOUND;
1681 dpriv->in_reenumerate = true;
1683 /* store copies of descriptors so they can be compared after the reset */
1684 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1685 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1687 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1688 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1689 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1692 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1693 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1694 if (kresult != kIOReturnSuccess) {
1695 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1696 dpriv->in_reenumerate = false;
1697 return darwin_to_libusb (kresult);
1700 usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1702 while (dpriv->in_reenumerate) {
1703 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1704 nanosleep (&delay, NULL);
1707 /* compare descriptors */
1708 usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1710 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1711 /* device descriptor changed. need to return not found. */
1712 usbi_dbg ("darwin/reset_device: device descriptor changed");
1713 return LIBUSB_ERROR_NOT_FOUND;
1716 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1717 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1718 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1719 usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1720 return LIBUSB_ERROR_NOT_FOUND;
1724 usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1726 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1729 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
1730 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1731 io_service_t usbInterface;
1735 assert(interface >= 0 && interface <= UINT8_MAX);
1736 kresult = darwin_get_interface (dpriv->device, (uint8_t)interface, &usbInterface);
1737 if (kresult != kIOReturnSuccess) {
1738 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1740 return darwin_to_libusb (kresult);
1743 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1744 IOObjectRelease (usbInterface);
1756 static void darwin_destroy_device(struct libusb_device *dev) {
1757 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1760 /* need to hold the lock in case this is the last reference to the device */
1761 usbi_mutex_lock(&darwin_cached_devices_lock);
1762 darwin_deref_cached_device (dpriv->dev);
1764 usbi_mutex_unlock(&darwin_cached_devices_lock);
1768 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1769 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1772 uint8_t transferType;
1773 /* None of the values below are used in libusbx for bulk transfers */
1774 uint8_t direction, number, interval, pipeRef;
1775 uint16_t maxPacketSize;
1777 struct darwin_interface *cInterface;
1779 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1780 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1782 return LIBUSB_ERROR_NOT_FOUND;
1785 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1786 &transferType, &maxPacketSize, &interval);
1789 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1790 darwin_error_str(ret), ret);
1791 return darwin_to_libusb (ret);
1794 if (0 != (transfer->length % maxPacketSize)) {
1795 /* do not need a zero packet */
1796 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1799 /* submit the request */
1800 /* timeouts are unavailable on interrupt endpoints */
1801 if (transferType == kUSBInterrupt) {
1802 if (IS_XFERIN(transfer))
1803 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1804 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1806 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1807 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1809 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1811 if (IS_XFERIN(transfer))
1812 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1813 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1814 darwin_async_io_callback, itransfer);
1816 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1817 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1818 darwin_async_io_callback, itransfer);
1822 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1823 darwin_error_str(ret), ret);
1825 return darwin_to_libusb (ret);
1828 #if InterfaceVersion >= 550
1829 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1830 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1831 struct darwin_interface *cInterface;
1835 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1836 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1838 return LIBUSB_ERROR_NOT_FOUND;
1841 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1843 if (IS_XFERIN(transfer))
1844 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1845 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1846 transfer->timeout, darwin_async_io_callback, itransfer);
1848 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1849 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1850 transfer->timeout, darwin_async_io_callback, itransfer);
1853 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1854 darwin_error_str(ret), ret);
1856 return darwin_to_libusb (ret);
1860 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1861 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1862 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1865 uint8_t direction, number, interval, pipeRef, transferType;
1866 uint16_t maxPacketSize;
1868 AbsoluteTime atTime;
1871 struct darwin_interface *cInterface;
1873 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1874 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1875 free(tpriv->isoc_framelist);
1876 tpriv->isoc_framelist = NULL;
1879 if (!tpriv->isoc_framelist) {
1880 tpriv->num_iso_packets = transfer->num_iso_packets;
1881 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1882 if (!tpriv->isoc_framelist)
1883 return LIBUSB_ERROR_NO_MEM;
1886 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1887 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1888 unsigned int length = transfer->iso_packet_desc[i].length;
1889 assert(length <= UINT16_MAX);
1890 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1893 /* determine the interface/endpoint to use */
1894 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1895 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1897 return LIBUSB_ERROR_NOT_FOUND;
1900 /* determine the properties of this endpoint and the speed of the device */
1901 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1902 &transferType, &maxPacketSize, &interval);
1904 /* Last but not least we need the bus frame number */
1905 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1906 if (kresult != kIOReturnSuccess) {
1907 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1908 free(tpriv->isoc_framelist);
1909 tpriv->isoc_framelist = NULL;
1911 return darwin_to_libusb (kresult);
1914 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1915 &transferType, &maxPacketSize, &interval);
1917 /* schedule for a frame a little in the future */
1920 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1921 frame = cInterface->frames[transfer->endpoint];
1923 /* submit the request */
1924 if (IS_XFERIN(transfer))
1925 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1926 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1929 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1930 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1933 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1935 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1937 /* High/super speed */
1938 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1940 if (kresult != kIOReturnSuccess) {
1941 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1942 darwin_error_str(kresult));
1943 free (tpriv->isoc_framelist);
1944 tpriv->isoc_framelist = NULL;
1947 return darwin_to_libusb (kresult);
1950 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1951 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1952 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1953 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1954 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1958 memset(&tpriv->req, 0, sizeof(tpriv->req));
1960 /* IOUSBDeviceInterface expects the request in cpu endianness */
1961 tpriv->req.bmRequestType = setup->bmRequestType;
1962 tpriv->req.bRequest = setup->bRequest;
1963 /* these values should be in bus order from libusb_fill_control_setup */
1964 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1965 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1966 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1967 /* data is stored after the libusb control block */
1968 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1969 tpriv->req.completionTimeout = transfer->timeout;
1970 tpriv->req.noDataTimeout = transfer->timeout;
1972 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1974 /* all transfers in libusb-1.0 are async */
1976 if (transfer->endpoint) {
1977 struct darwin_interface *cInterface;
1980 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1981 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1983 return LIBUSB_ERROR_NOT_FOUND;
1986 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1988 /* control request on endpoint 0 */
1989 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1991 if (kresult != kIOReturnSuccess)
1992 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
1994 return darwin_to_libusb (kresult);
1997 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1998 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2000 switch (transfer->type) {
2001 case LIBUSB_TRANSFER_TYPE_CONTROL:
2002 return submit_control_transfer(itransfer);
2003 case LIBUSB_TRANSFER_TYPE_BULK:
2004 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2005 return submit_bulk_transfer(itransfer);
2006 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2007 return submit_iso_transfer(itransfer);
2008 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2009 #if InterfaceVersion >= 550
2010 return submit_stream_transfer(itransfer);
2012 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2013 return LIBUSB_ERROR_NOT_SUPPORTED;
2016 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2017 return LIBUSB_ERROR_INVALID_PARAM;
2021 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2022 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2023 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2026 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2029 return LIBUSB_ERROR_NO_DEVICE;
2031 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2033 return darwin_to_libusb (kresult);
2036 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2037 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2038 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2039 struct darwin_interface *cInterface;
2040 uint8_t pipeRef, iface;
2043 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2044 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2046 return LIBUSB_ERROR_NOT_FOUND;
2050 return LIBUSB_ERROR_NO_DEVICE;
2052 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2054 /* abort transactions */
2055 #if InterfaceVersion >= 550
2056 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2057 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2060 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2062 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2064 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2065 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2067 return darwin_to_libusb (kresult);
2070 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2071 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2073 switch (transfer->type) {
2074 case LIBUSB_TRANSFER_TYPE_CONTROL:
2075 return cancel_control_transfer(itransfer);
2076 case LIBUSB_TRANSFER_TYPE_BULK:
2077 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2078 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2079 return darwin_abort_transfers (itransfer);
2081 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2082 return LIBUSB_ERROR_INVALID_PARAM;
2086 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2087 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2088 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2089 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2091 usbi_dbg ("an async io operation has completed");
2093 /* if requested write a zero packet */
2094 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2095 struct darwin_interface *cInterface;
2098 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2100 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2103 tpriv->result = result;
2104 tpriv->size = (UInt32) (uintptr_t) arg0;
2106 /* signal the core that this transfer is complete */
2107 usbi_signal_transfer_completion(itransfer);
2110 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2111 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2112 result = kIOUSBTransactionTimeout;
2115 case kIOReturnUnderrun:
2116 case kIOReturnSuccess:
2117 return LIBUSB_TRANSFER_COMPLETED;
2118 case kIOReturnAborted:
2119 return LIBUSB_TRANSFER_CANCELLED;
2120 case kIOUSBPipeStalled:
2121 usbi_dbg ("transfer error: pipe is stalled");
2122 return LIBUSB_TRANSFER_STALL;
2123 case kIOReturnOverrun:
2124 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2125 return LIBUSB_TRANSFER_OVERFLOW;
2126 case kIOUSBTransactionTimeout:
2127 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2128 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2129 return LIBUSB_TRANSFER_TIMED_OUT;
2131 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2132 return LIBUSB_TRANSFER_ERROR;
2136 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2137 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2138 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2139 bool isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2140 bool isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
2141 bool isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
2142 bool isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
2145 if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
2146 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2147 return LIBUSB_ERROR_INVALID_PARAM;
2150 usbi_dbg ("handling %s completion with kernel status %d",
2151 isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
2153 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2154 if (isIsoc && tpriv->isoc_framelist) {
2155 /* copy isochronous results back */
2157 for (i = 0; i < transfer->num_iso_packets ; i++) {
2158 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2159 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2160 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2163 itransfer->transferred += tpriv->size;
2166 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2167 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2170 #if !defined(HAVE_CLOCK_GETTIME)
2171 int usbi_clock_gettime(int clk_id, struct timespec *tp) {
2172 mach_timespec_t sys_time;
2173 clock_serv_t clock_ref;
2176 case USBI_CLOCK_REALTIME:
2177 /* CLOCK_REALTIME represents time since the epoch */
2178 clock_ref = clock_realtime;
2180 case USBI_CLOCK_MONOTONIC:
2181 /* use system boot time as reference for the monotonic clock */
2182 clock_ref = clock_monotonic;
2189 clock_get_time (clock_ref, &sys_time);
2191 tp->tv_sec = sys_time.tv_sec;
2192 tp->tv_nsec = sys_time.tv_nsec;
2198 #if InterfaceVersion >= 550
2199 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2200 int num_endpoints) {
2201 struct darwin_interface *cInterface;
2202 UInt32 supportsStreams;
2206 /* find the mimimum number of supported streams on the endpoint list */
2207 for (i = 0 ; i < num_endpoints ; ++i) {
2208 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2212 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2213 if (num_streams > supportsStreams)
2214 num_streams = supportsStreams;
2217 /* it is an error if any endpoint in endpoints does not support streams */
2218 if (0 == num_streams)
2219 return LIBUSB_ERROR_INVALID_PARAM;
2221 /* create the streams */
2222 for (i = 0 ; i < num_endpoints ; ++i) {
2223 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2225 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2226 if (kIOReturnSuccess != rc)
2227 return darwin_to_libusb(rc);
2230 assert(num_streams <= INT_MAX);
2231 return (int)num_streams;
2234 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2235 struct darwin_interface *cInterface;
2236 UInt32 supportsStreams;
2240 for (int i = 0 ; i < num_endpoints ; ++i) {
2241 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2244 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2245 if (0 == supportsStreams)
2246 return LIBUSB_ERROR_INVALID_PARAM;
2248 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2249 if (kIOReturnSuccess != rc)
2250 return darwin_to_libusb(rc);
2253 return LIBUSB_SUCCESS;
2257 const struct usbi_os_backend usbi_backend = {
2260 .init = darwin_init,
2261 .exit = darwin_exit,
2262 .get_device_descriptor = darwin_get_device_descriptor,
2263 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2264 .get_config_descriptor = darwin_get_config_descriptor,
2265 .hotplug_poll = darwin_hotplug_poll,
2267 .open = darwin_open,
2268 .close = darwin_close,
2269 .get_configuration = darwin_get_configuration,
2270 .set_configuration = darwin_set_configuration,
2271 .claim_interface = darwin_claim_interface,
2272 .release_interface = darwin_release_interface,
2274 .set_interface_altsetting = darwin_set_interface_altsetting,
2275 .clear_halt = darwin_clear_halt,
2276 .reset_device = darwin_reset_device,
2278 #if InterfaceVersion >= 550
2279 .alloc_streams = darwin_alloc_streams,
2280 .free_streams = darwin_free_streams,
2283 .kernel_driver_active = darwin_kernel_driver_active,
2285 .destroy_device = darwin_destroy_device,
2287 .submit_transfer = darwin_submit_transfer,
2288 .cancel_transfer = darwin_cancel_transfer,
2290 .handle_transfer_completion = darwin_handle_transfer_completion,
2292 .device_priv_size = sizeof(struct darwin_device_priv),
2293 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2294 .transfer_priv_size = sizeof(struct darwin_transfer_priv),