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 (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 (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1645 if (!(claimed_interfaces & (1U << iface))) {
1649 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1651 ret = darwin_claim_interface (dev_handle, iface);
1652 if (LIBUSB_SUCCESS != ret) {
1653 usbi_dbg ("darwin/restore_state: could not claim interface %u", 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, uint8_t interface) {
1730 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1731 io_service_t usbInterface;
1735 kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1736 if (kresult != kIOReturnSuccess) {
1737 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1739 return darwin_to_libusb (kresult);
1742 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1743 IOObjectRelease (usbInterface);
1755 static void darwin_destroy_device(struct libusb_device *dev) {
1756 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1759 /* need to hold the lock in case this is the last reference to the device */
1760 usbi_mutex_lock(&darwin_cached_devices_lock);
1761 darwin_deref_cached_device (dpriv->dev);
1763 usbi_mutex_unlock(&darwin_cached_devices_lock);
1767 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1768 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1771 uint8_t transferType;
1773 uint16_t maxPacketSize;
1775 struct darwin_interface *cInterface;
1776 #if InterfaceVersion >= 550
1777 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1779 /* None of the values below are used in libusb for bulk transfers */
1780 uint8_t direction, number, interval;
1783 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1784 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1786 return LIBUSB_ERROR_NOT_FOUND;
1789 #if InterfaceVersion >= 550
1790 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1792 transferType = pipeProperties.bTransferType;
1793 maxPacketSize = pipeProperties.wMaxPacketSize;
1795 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1796 &transferType, &maxPacketSize, &interval);
1800 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1801 darwin_error_str(ret), ret);
1802 return darwin_to_libusb (ret);
1805 if (0 != (transfer->length % maxPacketSize)) {
1806 /* do not need a zero packet */
1807 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1810 /* submit the request */
1811 /* timeouts are unavailable on interrupt endpoints */
1812 if (transferType == kUSBInterrupt) {
1813 if (IS_XFERIN(transfer))
1814 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1815 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1817 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1818 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1820 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1822 if (IS_XFERIN(transfer))
1823 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1824 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1825 darwin_async_io_callback, itransfer);
1827 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1828 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1829 darwin_async_io_callback, itransfer);
1833 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1834 darwin_error_str(ret), ret);
1836 return darwin_to_libusb (ret);
1839 #if InterfaceVersion >= 550
1840 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1841 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1842 struct darwin_interface *cInterface;
1846 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1847 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1849 return LIBUSB_ERROR_NOT_FOUND;
1852 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1854 if (IS_XFERIN(transfer))
1855 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1856 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1857 transfer->timeout, darwin_async_io_callback, itransfer);
1859 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1860 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1861 transfer->timeout, darwin_async_io_callback, itransfer);
1864 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1865 darwin_error_str(ret), ret);
1867 return darwin_to_libusb (ret);
1871 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1872 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1873 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1876 uint8_t direction, number, interval, pipeRef, transferType;
1877 uint16_t maxPacketSize;
1879 AbsoluteTime atTime;
1882 struct darwin_interface *cInterface;
1884 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1885 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1886 free(tpriv->isoc_framelist);
1887 tpriv->isoc_framelist = NULL;
1890 if (!tpriv->isoc_framelist) {
1891 tpriv->num_iso_packets = transfer->num_iso_packets;
1892 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1893 if (!tpriv->isoc_framelist)
1894 return LIBUSB_ERROR_NO_MEM;
1897 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1898 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1899 unsigned int length = transfer->iso_packet_desc[i].length;
1900 assert(length <= UINT16_MAX);
1901 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1904 /* determine the interface/endpoint to use */
1905 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1906 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1908 return LIBUSB_ERROR_NOT_FOUND;
1911 /* determine the properties of this endpoint and the speed of the device */
1912 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1913 &transferType, &maxPacketSize, &interval);
1915 /* Last but not least we need the bus frame number */
1916 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1917 if (kresult != kIOReturnSuccess) {
1918 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1919 free(tpriv->isoc_framelist);
1920 tpriv->isoc_framelist = NULL;
1922 return darwin_to_libusb (kresult);
1925 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1926 &transferType, &maxPacketSize, &interval);
1928 /* schedule for a frame a little in the future */
1931 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1932 frame = cInterface->frames[transfer->endpoint];
1934 /* submit the request */
1935 if (IS_XFERIN(transfer))
1936 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1937 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1940 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1941 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1944 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1946 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1948 /* High/super speed */
1949 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1951 if (kresult != kIOReturnSuccess) {
1952 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1953 darwin_error_str(kresult));
1954 free (tpriv->isoc_framelist);
1955 tpriv->isoc_framelist = NULL;
1958 return darwin_to_libusb (kresult);
1961 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1962 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1963 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1964 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1965 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1969 memset(&tpriv->req, 0, sizeof(tpriv->req));
1971 /* IOUSBDeviceInterface expects the request in cpu endianness */
1972 tpriv->req.bmRequestType = setup->bmRequestType;
1973 tpriv->req.bRequest = setup->bRequest;
1974 /* these values should be in bus order from libusb_fill_control_setup */
1975 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1976 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1977 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1978 /* data is stored after the libusb control block */
1979 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1980 tpriv->req.completionTimeout = transfer->timeout;
1981 tpriv->req.noDataTimeout = transfer->timeout;
1983 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1985 /* all transfers in libusb-1.0 are async */
1987 if (transfer->endpoint) {
1988 struct darwin_interface *cInterface;
1991 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1992 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1994 return LIBUSB_ERROR_NOT_FOUND;
1997 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1999 /* control request on endpoint 0 */
2000 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2002 if (kresult != kIOReturnSuccess)
2003 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2005 return darwin_to_libusb (kresult);
2008 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2009 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2011 switch (transfer->type) {
2012 case LIBUSB_TRANSFER_TYPE_CONTROL:
2013 return submit_control_transfer(itransfer);
2014 case LIBUSB_TRANSFER_TYPE_BULK:
2015 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2016 return submit_bulk_transfer(itransfer);
2017 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2018 return submit_iso_transfer(itransfer);
2019 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2020 #if InterfaceVersion >= 550
2021 return submit_stream_transfer(itransfer);
2023 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2024 return LIBUSB_ERROR_NOT_SUPPORTED;
2027 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2028 return LIBUSB_ERROR_INVALID_PARAM;
2032 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2033 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2034 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2037 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2040 return LIBUSB_ERROR_NO_DEVICE;
2042 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2044 return darwin_to_libusb (kresult);
2047 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2048 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2049 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2050 struct darwin_interface *cInterface;
2051 uint8_t pipeRef, iface;
2054 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2055 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2057 return LIBUSB_ERROR_NOT_FOUND;
2061 return LIBUSB_ERROR_NO_DEVICE;
2063 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2065 /* abort transactions */
2066 #if InterfaceVersion >= 550
2067 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2068 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2071 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2073 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2075 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2076 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2078 return darwin_to_libusb (kresult);
2081 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2082 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2084 switch (transfer->type) {
2085 case LIBUSB_TRANSFER_TYPE_CONTROL:
2086 return cancel_control_transfer(itransfer);
2087 case LIBUSB_TRANSFER_TYPE_BULK:
2088 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2089 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2090 return darwin_abort_transfers (itransfer);
2092 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2093 return LIBUSB_ERROR_INVALID_PARAM;
2097 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2098 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2099 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2100 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2102 usbi_dbg ("an async io operation has completed");
2104 /* if requested write a zero packet */
2105 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2106 struct darwin_interface *cInterface;
2109 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2111 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2114 tpriv->result = result;
2115 tpriv->size = (UInt32) (uintptr_t) arg0;
2117 /* signal the core that this transfer is complete */
2118 usbi_signal_transfer_completion(itransfer);
2121 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2122 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2123 result = kIOUSBTransactionTimeout;
2126 case kIOReturnUnderrun:
2127 case kIOReturnSuccess:
2128 return LIBUSB_TRANSFER_COMPLETED;
2129 case kIOReturnAborted:
2130 return LIBUSB_TRANSFER_CANCELLED;
2131 case kIOUSBPipeStalled:
2132 usbi_dbg ("transfer error: pipe is stalled");
2133 return LIBUSB_TRANSFER_STALL;
2134 case kIOReturnOverrun:
2135 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2136 return LIBUSB_TRANSFER_OVERFLOW;
2137 case kIOUSBTransactionTimeout:
2138 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2139 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2140 return LIBUSB_TRANSFER_TIMED_OUT;
2142 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2143 return LIBUSB_TRANSFER_ERROR;
2147 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2148 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2149 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2150 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2151 const char *transfer_types[max_transfer_type + 1] = {"control", "isoc", "bulk", "interrupt", "bulk-stream"};
2152 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2154 if (transfer->type > max_transfer_type) {
2155 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2156 return LIBUSB_ERROR_INVALID_PARAM;
2159 if (NULL == tpriv) {
2160 usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
2161 return LIBUSB_ERROR_INVALID_PARAM;
2164 usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2166 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2167 if (is_isoc && tpriv->isoc_framelist) {
2168 /* copy isochronous results back */
2170 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2171 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2172 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2173 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2175 } else if (!is_isoc) {
2176 itransfer->transferred += tpriv->size;
2180 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2181 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2184 #if !defined(HAVE_CLOCK_GETTIME)
2185 void usbi_get_monotonic_time(struct timespec *tp) {
2186 mach_timespec_t sys_time;
2188 /* use system boot time as reference for the monotonic clock */
2189 clock_get_time (clock_monotonic, &sys_time);
2191 tp->tv_sec = sys_time.tv_sec;
2192 tp->tv_nsec = sys_time.tv_nsec;
2195 void usbi_get_real_time(struct timespec *tp) {
2196 mach_timespec_t sys_time;
2198 /* CLOCK_REALTIME represents time since the epoch */
2199 clock_get_time (clock_realtime, &sys_time);
2201 tp->tv_sec = sys_time.tv_sec;
2202 tp->tv_nsec = sys_time.tv_nsec;
2206 #if InterfaceVersion >= 550
2207 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2208 int num_endpoints) {
2209 struct darwin_interface *cInterface;
2210 UInt32 supportsStreams;
2214 /* find the minimum number of supported streams on the endpoint list */
2215 for (i = 0 ; i < num_endpoints ; ++i) {
2216 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2220 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2221 if (num_streams > supportsStreams)
2222 num_streams = supportsStreams;
2225 /* it is an error if any endpoint in endpoints does not support streams */
2226 if (0 == num_streams)
2227 return LIBUSB_ERROR_INVALID_PARAM;
2229 /* create the streams */
2230 for (i = 0 ; i < num_endpoints ; ++i) {
2231 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2233 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2234 if (kIOReturnSuccess != rc)
2235 return darwin_to_libusb(rc);
2238 assert(num_streams <= INT_MAX);
2239 return (int)num_streams;
2242 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2243 struct darwin_interface *cInterface;
2244 UInt32 supportsStreams;
2248 for (int i = 0 ; i < num_endpoints ; ++i) {
2249 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2252 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2253 if (0 == supportsStreams)
2254 return LIBUSB_ERROR_INVALID_PARAM;
2256 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2257 if (kIOReturnSuccess != rc)
2258 return darwin_to_libusb(rc);
2261 return LIBUSB_SUCCESS;
2265 const struct usbi_os_backend usbi_backend = {
2268 .init = darwin_init,
2269 .exit = darwin_exit,
2270 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2271 .get_config_descriptor = darwin_get_config_descriptor,
2272 .hotplug_poll = darwin_hotplug_poll,
2274 .open = darwin_open,
2275 .close = darwin_close,
2276 .get_configuration = darwin_get_configuration,
2277 .set_configuration = darwin_set_configuration,
2278 .claim_interface = darwin_claim_interface,
2279 .release_interface = darwin_release_interface,
2281 .set_interface_altsetting = darwin_set_interface_altsetting,
2282 .clear_halt = darwin_clear_halt,
2283 .reset_device = darwin_reset_device,
2285 #if InterfaceVersion >= 550
2286 .alloc_streams = darwin_alloc_streams,
2287 .free_streams = darwin_free_streams,
2290 .kernel_driver_active = darwin_kernel_driver_active,
2292 .destroy_device = darwin_destroy_device,
2294 .submit_transfer = darwin_submit_transfer,
2295 .cancel_transfer = darwin_cancel_transfer,
2297 .handle_transfer_completion = darwin_handle_transfer_completion,
2299 .device_priv_size = sizeof(struct darwin_device_priv),
2300 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2301 .transfer_priv_size = sizeof(struct darwin_transfer_priv),