1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2020 Nathan Hjelm <hjelmn@cs.unm.edu>
5 * Copyright © 2019-2020 Google LLC. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <sys/types.h>
33 #include <sys/sysctl.h>
35 #include <mach/clock.h>
36 #include <mach/clock_types.h>
37 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
40 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
41 * function. Its use is also conditionalized to only older deployment targets. */
42 #define OBJC_SILENCE_GC_DEPRECATIONS 1
44 #include <AvailabilityMacros.h>
45 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
46 #include <objc/objc-auto.h>
49 #include "darwin_usb.h"
51 static pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
52 static int init_count = 0;
54 /* async event thread */
55 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
56 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
58 #if !defined(HAVE_CLOCK_GETTIME)
59 static clock_serv_t clock_realtime;
60 static clock_serv_t clock_monotonic;
63 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
65 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
66 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
68 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
69 static struct list_head darwin_cached_devices;
70 static const char *darwin_device_class = "IOUSBDevice";
72 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
74 /* async event thread */
75 static pthread_t libusb_darwin_at;
77 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
78 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
79 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
80 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
81 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
83 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
84 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
85 UInt64 old_session_id);
87 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
88 UInt64 *old_session_id);
90 #if defined(ENABLE_LOGGING)
91 static const char *darwin_error_str (IOReturn result) {
92 static char string_buffer[50];
94 case kIOReturnSuccess:
96 case kIOReturnNotOpen:
97 return "device not opened for exclusive access";
98 case kIOReturnNoDevice:
99 return "no connection to an IOService";
100 case kIOUSBNoAsyncPortErr:
101 return "no async port has been opened for interface";
102 case kIOReturnExclusiveAccess:
103 return "another process has device opened for exclusive access";
104 case kIOUSBPipeStalled:
105 return "pipe is stalled";
107 return "could not establish a connection to the Darwin kernel";
108 case kIOUSBTransactionTimeout:
109 return "transaction timed out";
110 case kIOReturnBadArgument:
111 return "invalid argument";
112 case kIOReturnAborted:
113 return "transaction aborted";
114 case kIOReturnNotResponding:
115 return "device not responding";
116 case kIOReturnOverrun:
117 return "data overrun";
118 case kIOReturnCannotWire:
119 return "physical memory can not be wired down";
120 case kIOReturnNoResources:
121 return "out of resources";
122 case kIOUSBHighSpeedSplitError:
123 return "high speed split error";
124 case kIOUSBUnknownPipeErr:
125 return "pipe ref not recognized";
127 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
128 return string_buffer;
133 static enum libusb_error darwin_to_libusb (IOReturn result) {
135 case kIOReturnUnderrun:
136 case kIOReturnSuccess:
137 return LIBUSB_SUCCESS;
138 case kIOReturnNotOpen:
139 case kIOReturnNoDevice:
140 return LIBUSB_ERROR_NO_DEVICE;
141 case kIOReturnExclusiveAccess:
142 return LIBUSB_ERROR_ACCESS;
143 case kIOUSBPipeStalled:
144 return LIBUSB_ERROR_PIPE;
145 case kIOReturnBadArgument:
146 return LIBUSB_ERROR_INVALID_PARAM;
147 case kIOUSBTransactionTimeout:
148 return LIBUSB_ERROR_TIMEOUT;
149 case kIOReturnNotResponding:
150 case kIOReturnAborted:
152 case kIOUSBNoAsyncPortErr:
153 case kIOUSBUnknownPipeErr:
155 return LIBUSB_ERROR_OTHER;
159 /* this function must be called with the darwin_cached_devices_lock held */
160 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
161 cached_dev->refcount--;
162 /* free the device and remove it from the cache */
163 if (0 == cached_dev->refcount) {
164 list_del(&cached_dev->list);
166 if (cached_dev->device) {
167 (*(cached_dev->device))->Release(cached_dev->device);
168 cached_dev->device = NULL;
174 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
175 cached_dev->refcount++;
178 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) {
179 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
181 /* current interface */
182 struct darwin_interface *cInterface;
186 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
188 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
189 cInterface = &priv->interfaces[iface];
191 if (dev_handle->claimed_interfaces & (1U << iface)) {
192 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
193 if (cInterface->endpoint_addrs[i] == ep) {
200 *interface_out = cInterface;
202 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
203 return LIBUSB_SUCCESS;
209 /* No pipe found with the correct endpoint address */
210 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
212 return LIBUSB_ERROR_NOT_FOUND;
215 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
216 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
219 return kIOReturnError;
222 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
223 &kCFTypeDictionaryKeyCallBacks,
224 &kCFTypeDictionaryValueCallBacks);
226 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
227 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
228 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
230 if (propertyMatchDict && locationCF) {
231 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
232 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
234 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
236 /* release our references as per the Create Rule */
237 if (propertyMatchDict)
238 CFRelease (propertyMatchDict);
240 CFRelease (locationCF);
243 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
246 /* Returns 1 on success, 0 on failure. */
247 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
248 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
252 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
253 success = CFNumberGetValue(cfNumber, type, p);
256 CFRelease (cfNumber);
259 return (success != 0);
262 /* Returns 1 on success, 0 on failure. */
263 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
264 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
265 bool success = false;
268 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
269 CFIndex length = CFDataGetLength (cfData);
274 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
284 static usb_device_t **darwin_device_from_service (io_service_t service)
286 io_cf_plugin_ref_t *plugInInterface = NULL;
287 usb_device_t **device;
290 const int max_retries = 5;
292 /* The IOCreatePlugInInterfaceForService function might consistently return
293 an "out of resources" error with certain USB devices the first time we run
294 it. The reason is still unclear, but retrying fixes the problem */
295 for (int count = 0; count < max_retries; count++) {
296 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
297 kIOCFPlugInInterfaceID, &plugInInterface,
299 if (kIOReturnSuccess == kresult && plugInInterface) {
303 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
305 /* sleep for a little while before trying again */
306 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
309 if (kIOReturnSuccess != kresult || !plugInInterface) {
310 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
314 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
316 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
317 (*plugInInterface)->Release (plugInInterface);
322 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
324 struct darwin_cached_device *cached_device;
325 UInt64 old_session_id;
326 struct libusb_context *ctx;
327 io_service_t service;
330 usbi_mutex_lock(&active_contexts_lock);
332 while ((service = IOIteratorNext(add_devices))) {
333 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
334 if (ret < 0 || !cached_device->can_enumerate) {
338 /* add this device to each active context's device list */
339 for_each_context(ctx) {
340 process_new_device (ctx, cached_device, old_session_id);
343 if (cached_device->in_reenumerate) {
344 usbi_dbg ("cached device in reset state. reset complete...");
345 cached_device->in_reenumerate = false;
348 IOObjectRelease(service);
351 usbi_mutex_unlock(&active_contexts_lock);
354 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
356 struct libusb_device *dev = NULL;
357 struct libusb_context *ctx;
358 struct darwin_cached_device *old_device;
364 usbi_mutex_lock(&active_contexts_lock);
366 while ((device = IOIteratorNext (rem_devices)) != 0) {
367 bool is_reenumerating = false;
369 /* get the location from the i/o registry */
370 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
371 IOObjectRelease (device);
375 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
376 otherwise no cached device will ever get freed */
377 usbi_mutex_lock(&darwin_cached_devices_lock);
378 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
379 if (old_device->session == session) {
380 if (old_device->in_reenumerate) {
381 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
382 * will deref if needed. */
383 usbi_dbg ("detected device detached due to re-enumeration");
385 /* the device object is no longer usable so go ahead and release it */
386 if (old_device->device) {
387 (*(old_device->device))->Release(old_device->device);
388 old_device->device = NULL;
391 is_reenumerating = true;
393 darwin_deref_cached_device (old_device);
400 usbi_mutex_unlock(&darwin_cached_devices_lock);
401 if (is_reenumerating) {
405 for_each_context(ctx) {
406 usbi_dbg ("notifying context %p of device disconnect", ctx);
408 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
410 /* signal the core that this device has been disconnected. the core will tear down this device
411 when the reference count reaches 0 */
412 usbi_disconnect_device(dev);
413 libusb_unref_device(dev);
418 usbi_mutex_unlock(&active_contexts_lock);
421 static void darwin_hotplug_poll (void)
423 /* not sure if 1 ms will be too long/short but it should work ok */
424 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
426 /* since a kernel thread may notify the IOIterators used for
427 * hotplug notification we can't just clear the iterators.
428 * instead just wait until all IOService providers are quiet */
429 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
432 static void darwin_clear_iterator (io_iterator_t iter) {
435 while ((device = IOIteratorNext (iter)) != 0)
436 IOObjectRelease (device);
439 static void darwin_fail_startup(void) {
440 pthread_mutex_lock (&libusb_darwin_at_mutex);
441 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
442 pthread_cond_signal (&libusb_darwin_at_cond);
443 pthread_mutex_unlock (&libusb_darwin_at_mutex);
447 static void *darwin_event_thread_main (void *arg0) {
449 struct libusb_context *ctx = (struct libusb_context *)arg0;
450 CFRunLoopRef runloop;
451 CFRunLoopSourceRef libusb_shutdown_cfsource;
452 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
454 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
455 /* Set this thread's name, so it can be seen in the debugger
456 and crash reports. */
457 pthread_setname_np ("org.libusb.device-hotplug");
460 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
461 /* Tell the Objective-C garbage collector about this thread.
462 This is required because, unlike NSThreads, pthreads are
463 not automatically registered. Although we don't use
464 Objective-C, we use CoreFoundation, which does.
465 Garbage collection support was entirely removed in 10.12,
466 so don't bother there. */
467 objc_registerThreadWithCollector();
470 /* hotplug (device arrival/removal) sources */
471 CFRunLoopSourceRef libusb_notification_cfsource;
472 io_notification_port_t libusb_notification_port;
473 io_iterator_t libusb_rem_device_iterator;
474 io_iterator_t libusb_add_device_iterator;
476 usbi_dbg ("creating hotplug event source");
478 runloop = CFRunLoopGetCurrent ();
481 /* add the shutdown cfsource to the run loop */
482 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
483 libusb_shutdown_cfsourcectx.info = runloop;
484 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
485 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
486 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
488 /* add the notification port to the run loop */
489 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
490 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
491 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
493 /* create notifications for removed devices */
494 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
495 IOServiceMatching(darwin_device_class),
496 darwin_devices_detached,
497 ctx, &libusb_rem_device_iterator);
499 if (kresult != kIOReturnSuccess) {
500 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
501 CFRelease (libusb_shutdown_cfsource);
503 darwin_fail_startup ();
506 /* create notifications for attached devices */
507 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
508 IOServiceMatching(darwin_device_class),
509 darwin_devices_attached,
510 ctx, &libusb_add_device_iterator);
512 if (kresult != kIOReturnSuccess) {
513 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
514 CFRelease (libusb_shutdown_cfsource);
516 darwin_fail_startup ();
520 darwin_clear_iterator (libusb_rem_device_iterator);
521 darwin_clear_iterator (libusb_add_device_iterator);
523 usbi_dbg ("darwin event thread ready to receive events");
525 /* signal the main thread that the hotplug runloop has been created. */
526 pthread_mutex_lock (&libusb_darwin_at_mutex);
527 libusb_darwin_acfl = runloop;
528 libusb_darwin_acfls = libusb_shutdown_cfsource;
529 pthread_cond_signal (&libusb_darwin_at_cond);
530 pthread_mutex_unlock (&libusb_darwin_at_mutex);
532 /* run the runloop */
535 usbi_dbg ("darwin event thread exiting");
537 /* signal the main thread that the hotplug runloop has finished. */
538 pthread_mutex_lock (&libusb_darwin_at_mutex);
539 libusb_darwin_acfls = NULL;
540 libusb_darwin_acfl = NULL;
541 pthread_cond_signal (&libusb_darwin_at_cond);
542 pthread_mutex_unlock (&libusb_darwin_at_mutex);
544 /* remove the notification cfsource */
545 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
547 /* remove the shutdown cfsource */
548 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
550 /* delete notification port */
551 IONotificationPortDestroy (libusb_notification_port);
553 /* delete iterators */
554 IOObjectRelease (libusb_rem_device_iterator);
555 IOObjectRelease (libusb_add_device_iterator);
557 CFRelease (libusb_shutdown_cfsource);
563 /* cleanup function to destroy cached devices */
564 static void darwin_cleanup_devices(void) {
565 struct darwin_cached_device *dev, *next;
567 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
568 darwin_deref_cached_device(dev);
571 darwin_cached_devices.prev = darwin_cached_devices.next = NULL;
574 static int darwin_init(struct libusb_context *ctx) {
578 pthread_mutex_lock (&libusb_darwin_init_mutex);
580 first_init = (1 == ++init_count);
584 assert (NULL == darwin_cached_devices.next);
585 list_init (&darwin_cached_devices);
587 #if !defined(HAVE_CLOCK_GETTIME)
588 /* create the clocks that will be used if clock_gettime() is not available */
589 host_name_port_t host_self;
591 host_self = mach_host_self();
592 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
593 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
594 mach_port_deallocate(mach_task_self(), host_self);
598 rc = darwin_scan_devices (ctx);
599 if (LIBUSB_SUCCESS != rc)
603 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
605 usbi_err (ctx, "could not create event thread, error %d", rc);
606 rc = LIBUSB_ERROR_OTHER;
610 pthread_mutex_lock (&libusb_darwin_at_mutex);
611 while (!libusb_darwin_acfl)
612 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
613 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
614 libusb_darwin_acfl = NULL;
615 rc = LIBUSB_ERROR_OTHER;
617 pthread_mutex_unlock (&libusb_darwin_at_mutex);
620 pthread_join (libusb_darwin_at, NULL);
624 if (LIBUSB_SUCCESS != rc) {
626 darwin_cleanup_devices ();
627 #if !defined(HAVE_CLOCK_GETTIME)
628 mach_port_deallocate(mach_task_self(), clock_realtime);
629 mach_port_deallocate(mach_task_self(), clock_monotonic);
635 pthread_mutex_unlock (&libusb_darwin_init_mutex);
640 static void darwin_exit (struct libusb_context *ctx) {
643 pthread_mutex_lock (&libusb_darwin_init_mutex);
645 if (0 == --init_count) {
646 /* stop the event runloop and wait for the thread to terminate. */
647 pthread_mutex_lock (&libusb_darwin_at_mutex);
648 CFRunLoopSourceSignal (libusb_darwin_acfls);
649 CFRunLoopWakeUp (libusb_darwin_acfl);
650 while (libusb_darwin_acfl)
651 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
652 pthread_mutex_unlock (&libusb_darwin_at_mutex);
653 pthread_join (libusb_darwin_at, NULL);
655 darwin_cleanup_devices ();
657 #if !defined(HAVE_CLOCK_GETTIME)
658 mach_port_deallocate(mach_task_self(), clock_realtime);
659 mach_port_deallocate(mach_task_self(), clock_monotonic);
663 pthread_mutex_unlock (&libusb_darwin_init_mutex);
666 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
667 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
669 IOUSBConfigurationDescriptorPtr desc;
672 /* is there a simpler way to determine the index? */
673 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
674 if (kresult != kIOReturnSuccess)
675 return darwin_to_libusb (kresult);
677 for (i = 0 ; i < numConfig ; i++) {
678 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
680 if (desc->bConfigurationValue == config_value)
684 /* configuration not found */
685 return LIBUSB_ERROR_NOT_FOUND;
688 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
689 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
692 if (0 == priv->active_config)
693 return LIBUSB_ERROR_NOT_FOUND;
695 config_index = get_configuration_index (dev, priv->active_config);
696 if (config_index < 0)
699 assert(config_index >= 0 && config_index <= UINT8_MAX);
700 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
703 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
704 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
705 IOUSBConfigurationDescriptorPtr desc;
709 if (!priv || !priv->device)
710 return LIBUSB_ERROR_OTHER;
712 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
713 if (kresult == kIOReturnSuccess) {
714 /* copy descriptor */
715 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
716 len = libusb_le16_to_cpu(desc->wTotalLength);
718 memmove (buffer, desc, len);
721 ret = darwin_to_libusb (kresult);
722 if (ret != LIBUSB_SUCCESS)
728 /* check whether the os has configured the device */
729 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
730 usb_device_t **darwin_device = dev->device;
732 IOUSBConfigurationDescriptorPtr configDesc;
733 IOUSBFindInterfaceRequest request;
735 io_iterator_t interface_iterator;
736 io_service_t firstInterface;
738 if (dev->dev_descriptor.bNumConfigurations < 1) {
739 usbi_err (ctx, "device has no configurations");
740 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
743 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
745 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
746 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
747 usbi_dbg ("ignoring configuration on root hub simulation");
748 dev->active_config = 0;
749 return LIBUSB_SUCCESS;
752 /* find the first configuration */
753 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
754 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
756 /* check if the device is already configured. there is probably a better way than iterating over the
757 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
758 might lock up on the device request) */
760 /* Setup the Interface Request */
761 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
762 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
763 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
764 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
766 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
767 if (kresult != kIOReturnSuccess)
768 return darwin_to_libusb (kresult);
771 firstInterface = IOIteratorNext(interface_iterator);
773 /* done with the interface iterator */
774 IOObjectRelease(interface_iterator);
776 if (firstInterface) {
777 IOObjectRelease (firstInterface);
779 /* device is configured */
780 if (dev->dev_descriptor.bNumConfigurations == 1)
781 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
782 dev->active_config = dev->first_config;
784 /* devices with more than one configuration should work with GetConfiguration */
785 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
788 dev->active_config = 0;
790 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
792 return LIBUSB_SUCCESS;
795 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
796 IOUSBDevRequestTO req;
798 assert(buffer_size <= UINT16_MAX);
800 memset (buffer, 0, buffer_size);
802 /* Set up request for descriptor/ */
803 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
804 req.bRequest = kUSBRqGetDescriptor;
805 req.wValue = (UInt16)(desc << 8);
806 req.wIndex = desc_index;
807 req.wLength = (UInt16)buffer_size;
809 req.noDataTimeout = 20;
810 req.completionTimeout = 100;
812 return (*device)->DeviceRequestTO (device, &req);
815 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
816 usb_device_t **device = dev->device;
818 long delay = 30000; // microseconds
819 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
821 IOReturn ret = 0, ret2;
823 UInt16 idProduct, idVendor;
825 dev->can_enumerate = 0;
827 (*device)->GetDeviceClass (device, &bDeviceClass);
828 (*device)->GetDeviceProduct (device, &idProduct);
829 (*device)->GetDeviceVendor (device, &idVendor);
831 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
832 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
833 * to follow the spec as closely as possible, try opening the device */
834 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
837 /**** retrieve device descriptor ****/
838 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
840 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
841 /* received an overrun error but we still received a device descriptor */
842 ret = kIOReturnSuccess;
844 if (kIOUSBVendorIDAppleComputer == idVendor) {
845 /* NTH: don't bother retrying or unsuspending Apple devices */
849 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
850 0 == dev->dev_descriptor.bcdUSB)) {
851 /* work around for incorrectly configured devices */
852 if (try_reconfigure && is_open) {
853 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
855 /* set the first configuration */
856 (*device)->SetConfiguration(device, 1);
858 /* don't try to reconfigure again */
862 ret = kIOUSBPipeStalled;
865 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
866 /* device may be suspended. unsuspend it and try again */
867 #if DeviceVersion >= 320
870 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
871 (void)(*device)->GetUSBDeviceInformation (device, &info);
873 /* note that the device was suspended */
874 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
879 /* try to unsuspend the device */
880 ret2 = (*device)->USBDeviceSuspend (device, 0);
881 if (kIOReturnSuccess != ret2) {
882 /* prevent log spew from poorly behaving devices. this indicates the
883 os actually had trouble communicating with the device */
884 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
892 if (kIOReturnSuccess != ret) {
893 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
894 /* sleep for a little while before trying again */
895 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
897 } while (kIOReturnSuccess != ret && retries--);
900 /* resuspend the device */
901 (void)(*device)->USBDeviceSuspend (device, 1);
904 (void) (*device)->USBDeviceClose (device);
906 if (ret != kIOReturnSuccess) {
907 /* a debug message was already printed out for this error */
908 if (LIBUSB_CLASS_HUB == bDeviceClass)
909 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
910 idVendor, idProduct, darwin_error_str (ret), ret);
912 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
913 idVendor, idProduct, darwin_error_str (ret), ret);
914 return darwin_to_libusb (ret);
917 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
918 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
919 /* not a valid device */
920 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
921 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
922 return LIBUSB_ERROR_NO_DEVICE;
925 usbi_dbg ("cached device descriptor:");
926 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
927 usbi_dbg (" bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
928 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
929 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
930 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
931 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
932 usbi_dbg (" idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
933 usbi_dbg (" idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
934 usbi_dbg (" bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
935 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
936 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
937 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
938 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
940 dev->can_enumerate = 1;
942 return LIBUSB_SUCCESS;
945 /* Returns 1 on success, 0 on failure. */
946 static bool get_device_port (io_service_t service, UInt8 *port) {
951 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
955 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
956 if (kIOReturnSuccess == kresult) {
957 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
958 IOObjectRelease (parent);
964 /* Returns 1 on success, 0 on failure. */
965 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
969 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
971 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
972 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
978 /* We ran out of parents */
982 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
983 UInt64 *old_session_id) {
984 struct darwin_cached_device *new_device;
985 UInt64 sessionID = 0, parent_sessionID = 0;
986 UInt32 locationID = 0;
987 enum libusb_error ret = LIBUSB_SUCCESS;
988 usb_device_t **device;
991 /* assuming sessionID != 0 normally (never seen it be 0) */
995 /* get some info from the io registry */
996 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
997 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
998 if (!get_device_port (service, &port)) {
999 usbi_dbg("could not get connected port number");
1002 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1004 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1005 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1008 usbi_mutex_lock(&darwin_cached_devices_lock);
1010 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1011 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1012 sessionID, locationID, new_device->session, new_device->location);
1013 if (new_device->location == locationID && new_device->in_reenumerate) {
1014 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1015 *old_session_id = new_device->session;
1019 if (new_device->session == sessionID) {
1020 usbi_dbg("using cached device for device");
1021 *cached_out = new_device;
1029 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1031 device = darwin_device_from_service (service);
1033 ret = LIBUSB_ERROR_NO_DEVICE;
1037 if (!(*old_session_id)) {
1038 new_device = calloc (1, sizeof (*new_device));
1040 ret = LIBUSB_ERROR_NO_MEM;
1044 /* add this device to the cached device list */
1045 list_add(&new_device->list, &darwin_cached_devices);
1047 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1049 /* keep a reference to this device */
1050 darwin_ref_cached_device(new_device);
1052 (*device)->GetLocationID (device, &new_device->location);
1053 new_device->port = port;
1054 new_device->parent_session = parent_sessionID;
1057 /* keep track of devices regardless of if we successfully enumerate them to
1058 prevent them from being enumerated multiple times */
1059 *cached_out = new_device;
1061 new_device->session = sessionID;
1062 new_device->device = device;
1064 /* cache the device descriptor */
1065 ret = darwin_cache_device_descriptor(new_device);
1069 if (new_device->can_enumerate) {
1070 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1071 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1072 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1073 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1077 usbi_mutex_unlock(&darwin_cached_devices_lock);
1082 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1083 UInt64 old_session_id) {
1084 struct darwin_device_priv *priv;
1085 struct libusb_device *dev = NULL;
1087 enum libusb_error ret = LIBUSB_SUCCESS;
1090 /* check current active configuration (and cache the first configuration value--
1091 which may be used by claim_interface) */
1092 ret = darwin_check_configuration (ctx, cached_device);
1096 if (0 != old_session_id) {
1097 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1098 ctx, old_session_id, cached_device->session);
1099 /* save the libusb device before the session id is updated */
1100 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1104 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1105 ctx, cached_device->session);
1107 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1109 return LIBUSB_ERROR_NO_MEM;
1112 priv = usbi_get_device_priv(dev);
1114 priv->dev = cached_device;
1115 darwin_ref_cached_device (priv->dev);
1116 dev->port_number = cached_device->port;
1117 dev->bus_number = cached_device->location >> 24;
1118 assert(cached_device->address <= UINT8_MAX);
1119 dev->device_address = (uint8_t)cached_device->address;
1121 priv = usbi_get_device_priv(dev);
1124 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1125 "mismatch between libusb and IOKit device descriptor sizes");
1126 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1127 usbi_localize_device_descriptor(&dev->device_descriptor);
1128 dev->session_data = cached_device->session;
1130 if (cached_device->parent_session > 0) {
1131 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1133 dev->parent_dev = NULL;
1136 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1139 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1140 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1141 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1142 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1143 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1145 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1146 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1149 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1152 ret = usbi_sanitize_device (dev);
1156 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1157 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1161 if (!cached_device->in_reenumerate && 0 == ret) {
1162 usbi_connect_device (dev);
1164 libusb_unref_device (dev);
1170 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1171 struct darwin_cached_device *cached_device;
1172 UInt64 old_session_id;
1173 io_iterator_t deviceIterator;
1174 io_service_t service;
1178 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1179 if (kresult != kIOReturnSuccess)
1180 return darwin_to_libusb (kresult);
1182 while ((service = IOIteratorNext (deviceIterator))) {
1183 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1184 if (ret < 0 || !cached_device->can_enumerate) {
1188 (void) process_new_device (ctx, cached_device, old_session_id);
1190 IOObjectRelease(service);
1193 IOObjectRelease(deviceIterator);
1195 return LIBUSB_SUCCESS;
1198 static int darwin_open (struct libusb_device_handle *dev_handle) {
1199 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1200 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1203 if (0 == dpriv->open_count) {
1204 /* try to open the device */
1205 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1206 if (kresult != kIOReturnSuccess) {
1207 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1209 if (kIOReturnExclusiveAccess != kresult) {
1210 return darwin_to_libusb (kresult);
1213 /* it is possible to perform some actions on a device that is not open so do not return an error */
1214 priv->is_open = false;
1216 priv->is_open = true;
1219 /* create async event source */
1220 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1221 if (kresult != kIOReturnSuccess) {
1222 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1224 if (priv->is_open) {
1225 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1228 priv->is_open = false;
1230 return darwin_to_libusb (kresult);
1233 CFRetain (libusb_darwin_acfl);
1235 /* add the cfSource to the aync run loop */
1236 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1239 /* device opened successfully */
1240 dpriv->open_count++;
1242 usbi_dbg ("device open for access");
1247 static void darwin_close (struct libusb_device_handle *dev_handle) {
1248 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1249 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1253 if (dpriv->open_count == 0) {
1254 /* something is probably very wrong if this is the case */
1255 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1259 dpriv->open_count--;
1261 /* make sure all interfaces are released */
1262 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1263 if (dev_handle->claimed_interfaces & (1U << i))
1264 libusb_release_interface (dev_handle, i);
1266 if (0 == dpriv->open_count) {
1267 /* delete the device's async event source */
1268 if (priv->cfSource) {
1269 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1270 CFRelease (priv->cfSource);
1271 priv->cfSource = NULL;
1272 CFRelease (libusb_darwin_acfl);
1275 if (priv->is_open) {
1276 /* close the device */
1277 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1278 if (kresult != kIOReturnSuccess) {
1279 /* Log the fact that we had a problem closing the file, however failing a
1280 * close isn't really an error, so return success anyway */
1281 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1287 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1288 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1290 *config = dpriv->active_config;
1292 return LIBUSB_SUCCESS;
1295 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1296 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1303 /* Setting configuration will invalidate the interface, so we need
1304 to reclaim it. First, dispose of existing interfaces, if any. */
1305 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1306 if (dev_handle->claimed_interfaces & (1U << i))
1307 darwin_release_interface (dev_handle, i);
1309 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1310 if (kresult != kIOReturnSuccess)
1311 return darwin_to_libusb (kresult);
1313 /* Reclaim any interfaces. */
1314 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1315 if (dev_handle->claimed_interfaces & (1U << i))
1316 darwin_claim_interface (dev_handle, i);
1318 dpriv->active_config = (UInt8)config;
1320 return LIBUSB_SUCCESS;
1323 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1324 IOUSBFindInterfaceRequest request;
1326 io_iterator_t interface_iterator;
1327 UInt8 bInterfaceNumber;
1330 *usbInterfacep = IO_OBJECT_NULL;
1332 /* Setup the Interface Request */
1333 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1334 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1335 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1336 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1338 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1339 if (kresult != kIOReturnSuccess)
1342 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1343 /* find the interface number */
1344 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1347 if (ret && bInterfaceNumber == ifc) {
1351 (void) IOObjectRelease (*usbInterfacep);
1354 /* done with the interface iterator */
1355 IOObjectRelease(interface_iterator);
1357 return kIOReturnSuccess;
1360 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1361 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1363 /* current interface */
1364 struct darwin_interface *cInterface = &priv->interfaces[iface];
1368 UInt8 numep, direction, number;
1369 UInt8 dont_care1, dont_care3;
1373 usbi_dbg ("building table of endpoints.");
1375 /* retrieve the total number of endpoints on this interface */
1376 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1377 if (kresult != kIOReturnSuccess) {
1378 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1379 return darwin_to_libusb (kresult);
1382 /* iterate through pipe references */
1383 for (UInt8 i = 1 ; i <= numep ; i++) {
1384 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1385 &dont_care2, &dont_care3);
1387 if (kresult != kIOReturnSuccess) {
1388 /* probably a buggy device. try to get the endpoint address from the descriptors */
1389 struct libusb_config_descriptor *config;
1390 const struct libusb_endpoint_descriptor *endpoint_desc;
1393 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1394 if (kresult != kIOReturnSuccess) {
1395 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1396 return darwin_to_libusb (kresult);
1399 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1400 if (LIBUSB_SUCCESS != rc) {
1404 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1406 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1408 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1411 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1412 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1415 cInterface->num_endpoints = numep;
1417 return LIBUSB_SUCCESS;
1420 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1421 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1422 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1423 io_service_t usbInterface = IO_OBJECT_NULL;
1425 enum libusb_error ret;
1426 IOCFPlugInInterface **plugInInterface = NULL;
1429 /* current interface */
1430 struct darwin_interface *cInterface = &priv->interfaces[iface];
1432 kresult = darwin_get_interface (dpriv->device, 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, (int) 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, 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, uint8_t 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, uint8_t iface, uint8_t 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 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1570 /* If a device only supports a default setting for the specified interface, then a STALL
1571 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1572 Mimick the behaviour in e.g. the Linux kernel: in such case, reset all endpoints,
1573 and hide errors.Current implementation resets the entire device, instead of single
1574 interface, due to historic reasons. */
1575 if (kresult != kIOReturnSuccess) {
1576 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1577 darwin_reset_device (dev_handle);
1580 /* update list of endpoints */
1581 ret = get_endpoints (dev_handle, iface);
1583 /* this should not happen */
1584 darwin_release_interface (dev_handle, iface);
1585 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1591 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1592 /* current interface */
1593 struct darwin_interface *cInterface;
1597 /* determine the interface/endpoint to use */
1598 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1599 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1601 return LIBUSB_ERROR_NOT_FOUND;
1604 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1605 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1606 if (kresult != kIOReturnSuccess)
1607 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1609 return darwin_to_libusb (kresult);
1612 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1613 unsigned long claimed_interfaces) {
1614 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1615 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1616 int open_count = dpriv->open_count;
1619 /* clear claimed interfaces temporarily */
1620 dev_handle->claimed_interfaces = 0;
1622 /* close and re-open the device */
1623 priv->is_open = false;
1624 dpriv->open_count = 1;
1626 /* clean up open interfaces */
1627 (void) darwin_close (dev_handle);
1629 /* re-open the device */
1630 ret = darwin_open (dev_handle);
1631 dpriv->open_count = open_count;
1632 if (LIBUSB_SUCCESS != ret) {
1633 /* could not restore configuration */
1634 return LIBUSB_ERROR_NOT_FOUND;
1637 if (dpriv->active_config != active_config) {
1638 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1640 ret = darwin_set_configuration (dev_handle, active_config);
1641 if (LIBUSB_SUCCESS != ret) {
1642 usbi_dbg ("darwin/restore_state: could not restore configuration");
1643 return LIBUSB_ERROR_NOT_FOUND;
1647 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1649 if (claimed_interfaces) {
1650 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1651 if (!(claimed_interfaces & (1U << iface))) {
1655 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1657 ret = darwin_claim_interface (dev_handle, iface);
1658 if (LIBUSB_SUCCESS != ret) {
1659 usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
1660 return LIBUSB_ERROR_NOT_FOUND;
1663 dev_handle->claimed_interfaces |= 1U << iface;
1667 usbi_dbg ("darwin/restore_state: device state restored");
1669 return LIBUSB_SUCCESS;
1672 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1673 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1674 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1675 int8_t active_config = dpriv->active_config;
1676 IOUSBDeviceDescriptor descriptor;
1677 IOUSBConfigurationDescriptorPtr cached_configuration;
1678 IOUSBConfigurationDescriptor *cached_configurations;
1682 if (dpriv->in_reenumerate) {
1683 /* ack, two (or more) threads are trying to reset the device! abort! */
1684 return LIBUSB_ERROR_NOT_FOUND;
1687 dpriv->in_reenumerate = true;
1689 /* store copies of descriptors so they can be compared after the reset */
1690 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1691 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1693 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1694 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1695 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1698 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1699 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1700 if (kresult != kIOReturnSuccess) {
1701 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1702 dpriv->in_reenumerate = false;
1703 return darwin_to_libusb (kresult);
1706 usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1708 while (dpriv->in_reenumerate) {
1709 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1710 nanosleep (&delay, NULL);
1713 /* compare descriptors */
1714 usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1716 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1717 /* device descriptor changed. need to return not found. */
1718 usbi_dbg ("darwin/reset_device: device descriptor changed");
1719 return LIBUSB_ERROR_NOT_FOUND;
1722 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1723 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1724 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1725 usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1726 return LIBUSB_ERROR_NOT_FOUND;
1730 usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1732 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1735 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1736 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1737 io_service_t usbInterface;
1741 kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1742 if (kresult != kIOReturnSuccess) {
1743 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1745 return darwin_to_libusb (kresult);
1748 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1749 IOObjectRelease (usbInterface);
1761 static void darwin_destroy_device(struct libusb_device *dev) {
1762 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1765 /* need to hold the lock in case this is the last reference to the device */
1766 usbi_mutex_lock(&darwin_cached_devices_lock);
1767 darwin_deref_cached_device (dpriv->dev);
1769 usbi_mutex_unlock(&darwin_cached_devices_lock);
1773 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1774 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1777 uint8_t transferType;
1779 uint16_t maxPacketSize;
1781 struct darwin_interface *cInterface;
1782 #if InterfaceVersion >= 550
1783 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1785 /* None of the values below are used in libusb for bulk transfers */
1786 uint8_t direction, number, interval;
1789 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1790 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1792 return LIBUSB_ERROR_NOT_FOUND;
1795 #if InterfaceVersion >= 550
1796 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1798 transferType = pipeProperties.bTransferType;
1799 maxPacketSize = pipeProperties.wMaxPacketSize;
1801 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1802 &transferType, &maxPacketSize, &interval);
1806 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1807 darwin_error_str(ret), ret);
1808 return darwin_to_libusb (ret);
1811 if (0 != (transfer->length % maxPacketSize)) {
1812 /* do not need a zero packet */
1813 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1816 /* submit the request */
1817 /* timeouts are unavailable on interrupt endpoints */
1818 if (transferType == kUSBInterrupt) {
1819 if (IS_XFERIN(transfer))
1820 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1821 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1823 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1824 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1826 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1828 if (IS_XFERIN(transfer))
1829 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1830 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1831 darwin_async_io_callback, itransfer);
1833 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1834 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1835 darwin_async_io_callback, itransfer);
1839 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1840 darwin_error_str(ret), ret);
1842 return darwin_to_libusb (ret);
1845 #if InterfaceVersion >= 550
1846 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1847 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1848 struct darwin_interface *cInterface;
1852 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1853 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1855 return LIBUSB_ERROR_NOT_FOUND;
1858 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1860 if (IS_XFERIN(transfer))
1861 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1862 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1863 transfer->timeout, darwin_async_io_callback, itransfer);
1865 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1866 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1867 transfer->timeout, darwin_async_io_callback, itransfer);
1870 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1871 darwin_error_str(ret), ret);
1873 return darwin_to_libusb (ret);
1877 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1878 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1879 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1882 uint8_t direction, number, interval, pipeRef, transferType;
1883 uint16_t maxPacketSize;
1885 AbsoluteTime atTime;
1888 struct darwin_interface *cInterface;
1890 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1891 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1892 free(tpriv->isoc_framelist);
1893 tpriv->isoc_framelist = NULL;
1896 if (!tpriv->isoc_framelist) {
1897 tpriv->num_iso_packets = transfer->num_iso_packets;
1898 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1899 if (!tpriv->isoc_framelist)
1900 return LIBUSB_ERROR_NO_MEM;
1903 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1904 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1905 unsigned int length = transfer->iso_packet_desc[i].length;
1906 assert(length <= UINT16_MAX);
1907 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1910 /* determine the interface/endpoint to use */
1911 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1912 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1914 return LIBUSB_ERROR_NOT_FOUND;
1917 /* determine the properties of this endpoint and the speed of the device */
1918 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1919 &transferType, &maxPacketSize, &interval);
1921 /* Last but not least we need the bus frame number */
1922 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1923 if (kresult != kIOReturnSuccess) {
1924 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1925 free(tpriv->isoc_framelist);
1926 tpriv->isoc_framelist = NULL;
1928 return darwin_to_libusb (kresult);
1931 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1932 &transferType, &maxPacketSize, &interval);
1934 /* schedule for a frame a little in the future */
1937 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1938 frame = cInterface->frames[transfer->endpoint];
1940 /* submit the request */
1941 if (IS_XFERIN(transfer))
1942 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1943 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1946 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1947 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1950 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1952 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1954 /* High/super speed */
1955 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1957 if (kresult != kIOReturnSuccess) {
1958 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1959 darwin_error_str(kresult));
1960 free (tpriv->isoc_framelist);
1961 tpriv->isoc_framelist = NULL;
1964 return darwin_to_libusb (kresult);
1967 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1968 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1969 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1970 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1971 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1975 memset(&tpriv->req, 0, sizeof(tpriv->req));
1977 /* IOUSBDeviceInterface expects the request in cpu endianness */
1978 tpriv->req.bmRequestType = setup->bmRequestType;
1979 tpriv->req.bRequest = setup->bRequest;
1980 /* these values should be in bus order from libusb_fill_control_setup */
1981 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1982 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1983 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1984 /* data is stored after the libusb control block */
1985 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1986 tpriv->req.completionTimeout = transfer->timeout;
1987 tpriv->req.noDataTimeout = transfer->timeout;
1989 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1991 /* all transfers in libusb-1.0 are async */
1993 if (transfer->endpoint) {
1994 struct darwin_interface *cInterface;
1997 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1998 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2000 return LIBUSB_ERROR_NOT_FOUND;
2003 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2005 /* control request on endpoint 0 */
2006 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2008 if (kresult != kIOReturnSuccess)
2009 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2011 return darwin_to_libusb (kresult);
2014 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2015 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2017 switch (transfer->type) {
2018 case LIBUSB_TRANSFER_TYPE_CONTROL:
2019 return submit_control_transfer(itransfer);
2020 case LIBUSB_TRANSFER_TYPE_BULK:
2021 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2022 return submit_bulk_transfer(itransfer);
2023 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2024 return submit_iso_transfer(itransfer);
2025 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2026 #if InterfaceVersion >= 550
2027 return submit_stream_transfer(itransfer);
2029 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2030 return LIBUSB_ERROR_NOT_SUPPORTED;
2033 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2034 return LIBUSB_ERROR_INVALID_PARAM;
2038 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2039 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2040 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2043 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2046 return LIBUSB_ERROR_NO_DEVICE;
2048 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2050 return darwin_to_libusb (kresult);
2053 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2054 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2055 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2056 struct darwin_interface *cInterface;
2057 uint8_t pipeRef, iface;
2060 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2061 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2063 return LIBUSB_ERROR_NOT_FOUND;
2067 return LIBUSB_ERROR_NO_DEVICE;
2069 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2071 /* abort transactions */
2072 #if InterfaceVersion >= 550
2073 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2074 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2077 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2079 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2081 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2082 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2084 return darwin_to_libusb (kresult);
2087 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2088 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2090 switch (transfer->type) {
2091 case LIBUSB_TRANSFER_TYPE_CONTROL:
2092 return cancel_control_transfer(itransfer);
2093 case LIBUSB_TRANSFER_TYPE_BULK:
2094 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2095 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2096 return darwin_abort_transfers (itransfer);
2098 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2099 return LIBUSB_ERROR_INVALID_PARAM;
2103 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2104 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2105 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2106 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2108 usbi_dbg ("an async io operation has completed");
2110 /* if requested write a zero packet */
2111 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2112 struct darwin_interface *cInterface;
2115 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2117 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2120 tpriv->result = result;
2121 tpriv->size = (UInt32) (uintptr_t) arg0;
2123 /* signal the core that this transfer is complete */
2124 usbi_signal_transfer_completion(itransfer);
2127 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2128 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2129 result = kIOUSBTransactionTimeout;
2132 case kIOReturnUnderrun:
2133 case kIOReturnSuccess:
2134 return LIBUSB_TRANSFER_COMPLETED;
2135 case kIOReturnAborted:
2136 return LIBUSB_TRANSFER_CANCELLED;
2137 case kIOUSBPipeStalled:
2138 usbi_dbg ("transfer error: pipe is stalled");
2139 return LIBUSB_TRANSFER_STALL;
2140 case kIOReturnOverrun:
2141 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2142 return LIBUSB_TRANSFER_OVERFLOW;
2143 case kIOUSBTransactionTimeout:
2144 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2145 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2146 return LIBUSB_TRANSFER_TIMED_OUT;
2148 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2149 return LIBUSB_TRANSFER_ERROR;
2153 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2154 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2155 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2156 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2157 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2158 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2160 if (transfer->type > max_transfer_type) {
2161 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2162 return LIBUSB_ERROR_INVALID_PARAM;
2165 if (NULL == tpriv) {
2166 usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
2167 return LIBUSB_ERROR_INVALID_PARAM;
2170 usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2172 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2173 if (is_isoc && tpriv->isoc_framelist) {
2174 /* copy isochronous results back */
2176 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2177 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2178 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2179 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2181 } else if (!is_isoc) {
2182 itransfer->transferred += tpriv->size;
2186 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2187 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2190 #if !defined(HAVE_CLOCK_GETTIME)
2191 void usbi_get_monotonic_time(struct timespec *tp) {
2192 mach_timespec_t sys_time;
2194 /* use system boot time as reference for the monotonic clock */
2195 clock_get_time (clock_monotonic, &sys_time);
2197 tp->tv_sec = sys_time.tv_sec;
2198 tp->tv_nsec = sys_time.tv_nsec;
2201 void usbi_get_real_time(struct timespec *tp) {
2202 mach_timespec_t sys_time;
2204 /* CLOCK_REALTIME represents time since the epoch */
2205 clock_get_time (clock_realtime, &sys_time);
2207 tp->tv_sec = sys_time.tv_sec;
2208 tp->tv_nsec = sys_time.tv_nsec;
2212 #if InterfaceVersion >= 550
2213 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2214 int num_endpoints) {
2215 struct darwin_interface *cInterface;
2216 UInt32 supportsStreams;
2220 /* find the minimum number of supported streams on the endpoint list */
2221 for (i = 0 ; i < num_endpoints ; ++i) {
2222 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2226 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2227 if (num_streams > supportsStreams)
2228 num_streams = supportsStreams;
2231 /* it is an error if any endpoint in endpoints does not support streams */
2232 if (0 == num_streams)
2233 return LIBUSB_ERROR_INVALID_PARAM;
2235 /* create the streams */
2236 for (i = 0 ; i < num_endpoints ; ++i) {
2237 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2239 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2240 if (kIOReturnSuccess != rc)
2241 return darwin_to_libusb(rc);
2244 assert(num_streams <= INT_MAX);
2245 return (int)num_streams;
2248 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2249 struct darwin_interface *cInterface;
2250 UInt32 supportsStreams;
2254 for (int i = 0 ; i < num_endpoints ; ++i) {
2255 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2258 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2259 if (0 == supportsStreams)
2260 return LIBUSB_ERROR_INVALID_PARAM;
2262 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2263 if (kIOReturnSuccess != rc)
2264 return darwin_to_libusb(rc);
2267 return LIBUSB_SUCCESS;
2271 const struct usbi_os_backend usbi_backend = {
2274 .init = darwin_init,
2275 .exit = darwin_exit,
2276 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2277 .get_config_descriptor = darwin_get_config_descriptor,
2278 .hotplug_poll = darwin_hotplug_poll,
2280 .open = darwin_open,
2281 .close = darwin_close,
2282 .get_configuration = darwin_get_configuration,
2283 .set_configuration = darwin_set_configuration,
2284 .claim_interface = darwin_claim_interface,
2285 .release_interface = darwin_release_interface,
2287 .set_interface_altsetting = darwin_set_interface_altsetting,
2288 .clear_halt = darwin_clear_halt,
2289 .reset_device = darwin_reset_device,
2291 #if InterfaceVersion >= 550
2292 .alloc_streams = darwin_alloc_streams,
2293 .free_streams = darwin_free_streams,
2296 .kernel_driver_active = darwin_kernel_driver_active,
2298 .destroy_device = darwin_destroy_device,
2300 .submit_transfer = darwin_submit_transfer,
2301 .cancel_transfer = darwin_cancel_transfer,
2303 .handle_transfer_completion = darwin_handle_transfer_completion,
2305 .device_priv_size = sizeof(struct darwin_device_priv),
2306 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2307 .transfer_priv_size = sizeof(struct darwin_transfer_priv),