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
31 #include <sys/types.h>
34 #include <sys/sysctl.h>
36 #include <mach/clock.h>
37 #include <mach/clock_types.h>
38 #include <mach/mach_host.h>
39 #include <mach/mach_port.h>
41 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
42 * function. Its use is also conditionalized to only older deployment targets. */
43 #define OBJC_SILENCE_GC_DEPRECATIONS 1
45 #include <AvailabilityMacros.h>
46 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
47 #include <objc/objc-auto.h>
50 #include "darwin_usb.h"
52 static pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
53 static int init_count = 0;
55 /* async event thread */
56 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
57 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
59 #if !defined(HAVE_CLOCK_GETTIME)
60 static clock_serv_t clock_realtime;
61 static clock_serv_t clock_monotonic;
64 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
66 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
67 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
69 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
70 static struct list_head darwin_cached_devices;
71 static const char *darwin_device_class = "IOUSBDevice";
73 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
75 /* async event thread */
76 static pthread_t libusb_darwin_at;
78 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
79 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
80 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
81 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
82 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
84 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
85 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
86 UInt64 old_session_id);
88 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
89 UInt64 *old_session_id);
91 #if defined(ENABLE_LOGGING)
92 static const char *darwin_error_str (IOReturn result) {
93 static char string_buffer[50];
95 case kIOReturnSuccess:
97 case kIOReturnNotOpen:
98 return "device not opened for exclusive access";
99 case kIOReturnNoDevice:
100 return "no connection to an IOService";
101 case kIOUSBNoAsyncPortErr:
102 return "no async port has been opened for interface";
103 case kIOReturnExclusiveAccess:
104 return "another process has device opened for exclusive access";
105 case kIOUSBPipeStalled:
106 return "pipe is stalled";
108 return "could not establish a connection to the Darwin kernel";
109 case kIOUSBTransactionTimeout:
110 return "transaction timed out";
111 case kIOReturnBadArgument:
112 return "invalid argument";
113 case kIOReturnAborted:
114 return "transaction aborted";
115 case kIOReturnNotResponding:
116 return "device not responding";
117 case kIOReturnOverrun:
118 return "data overrun";
119 case kIOReturnCannotWire:
120 return "physical memory can not be wired down";
121 case kIOReturnNoResources:
122 return "out of resources";
123 case kIOUSBHighSpeedSplitError:
124 return "high speed split error";
125 case kIOUSBUnknownPipeErr:
126 return "pipe ref not recognized";
128 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
129 return string_buffer;
134 static enum libusb_error darwin_to_libusb (IOReturn result) {
136 case kIOReturnUnderrun:
137 case kIOReturnSuccess:
138 return LIBUSB_SUCCESS;
139 case kIOReturnNotOpen:
140 case kIOReturnNoDevice:
141 return LIBUSB_ERROR_NO_DEVICE;
142 case kIOReturnExclusiveAccess:
143 return LIBUSB_ERROR_ACCESS;
144 case kIOUSBPipeStalled:
145 return LIBUSB_ERROR_PIPE;
146 case kIOReturnBadArgument:
147 return LIBUSB_ERROR_INVALID_PARAM;
148 case kIOUSBTransactionTimeout:
149 return LIBUSB_ERROR_TIMEOUT;
150 case kIOReturnNotResponding:
151 case kIOReturnAborted:
153 case kIOUSBNoAsyncPortErr:
154 case kIOUSBUnknownPipeErr:
156 return LIBUSB_ERROR_OTHER;
160 /* this function must be called with the darwin_cached_devices_lock held */
161 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
162 cached_dev->refcount--;
163 /* free the device and remove it from the cache */
164 if (0 == cached_dev->refcount) {
165 list_del(&cached_dev->list);
167 if (cached_dev->device) {
168 (*(cached_dev->device))->Release(cached_dev->device);
169 cached_dev->device = NULL;
175 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
176 cached_dev->refcount++;
179 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) {
180 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
182 /* current interface */
183 struct darwin_interface *cInterface;
187 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
189 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
190 cInterface = &priv->interfaces[iface];
192 if (dev_handle->claimed_interfaces & (1U << iface)) {
193 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
194 if (cInterface->endpoint_addrs[i] == ep) {
201 *interface_out = cInterface;
203 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
204 return LIBUSB_SUCCESS;
210 /* No pipe found with the correct endpoint address */
211 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
213 return LIBUSB_ERROR_NOT_FOUND;
216 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
217 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
220 return kIOReturnError;
223 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
224 &kCFTypeDictionaryKeyCallBacks,
225 &kCFTypeDictionaryValueCallBacks);
227 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
228 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
229 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
231 if (propertyMatchDict && locationCF) {
232 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
233 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
235 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
237 /* release our references as per the Create Rule */
238 if (propertyMatchDict)
239 CFRelease (propertyMatchDict);
241 CFRelease (locationCF);
244 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
247 /* Returns 1 on success, 0 on failure. */
248 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
249 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
253 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
254 success = CFNumberGetValue(cfNumber, type, p);
257 CFRelease (cfNumber);
260 return (success != 0);
263 /* Returns 1 on success, 0 on failure. */
264 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
265 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
266 bool success = false;
269 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
270 CFIndex length = CFDataGetLength (cfData);
275 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
285 static usb_device_t **darwin_device_from_service (io_service_t service)
287 io_cf_plugin_ref_t *plugInInterface = NULL;
288 usb_device_t **device;
291 const int max_retries = 5;
293 /* The IOCreatePlugInInterfaceForService function might consistently return
294 an "out of resources" error with certain USB devices the first time we run
295 it. The reason is still unclear, but retrying fixes the problem */
296 for (int count = 0; count < max_retries; count++) {
297 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
298 kIOCFPlugInInterfaceID, &plugInInterface,
300 if (kIOReturnSuccess == kresult && plugInInterface) {
304 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
306 /* sleep for a little while before trying again */
307 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
310 if (kIOReturnSuccess != kresult || !plugInInterface) {
311 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
315 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
317 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
318 (*plugInInterface)->Release (plugInInterface);
323 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
325 struct darwin_cached_device *cached_device;
326 UInt64 old_session_id;
327 struct libusb_context *ctx;
328 io_service_t service;
331 usbi_mutex_lock(&active_contexts_lock);
333 while ((service = IOIteratorNext(add_devices))) {
334 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
335 if (ret < 0 || !cached_device->can_enumerate) {
339 /* add this device to each active context's device list */
340 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
341 process_new_device (ctx, cached_device, old_session_id);
344 if (cached_device->in_reenumerate) {
345 usbi_dbg ("cached device in reset state. reset complete...");
346 cached_device->in_reenumerate = false;
349 IOObjectRelease(service);
352 usbi_mutex_unlock(&active_contexts_lock);
355 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
357 struct libusb_device *dev = NULL;
358 struct libusb_context *ctx;
359 struct darwin_cached_device *old_device;
365 usbi_mutex_lock(&active_contexts_lock);
367 while ((device = IOIteratorNext (rem_devices)) != 0) {
368 bool is_reenumerating = false;
370 /* get the location from the i/o registry */
371 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
372 IOObjectRelease (device);
376 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
377 otherwise no cached device will ever get freed */
378 usbi_mutex_lock(&darwin_cached_devices_lock);
379 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
380 if (old_device->session == session) {
381 if (old_device->in_reenumerate) {
382 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
383 * will deref if needed. */
384 usbi_dbg ("detected device detatched due to re-enumeration");
386 /* the device object is no longer usable so go ahead and release it */
387 if (old_device->device) {
388 (*(old_device->device))->Release(old_device->device);
389 old_device->device = NULL;
392 is_reenumerating = true;
394 darwin_deref_cached_device (old_device);
401 usbi_mutex_unlock(&darwin_cached_devices_lock);
402 if (is_reenumerating) {
406 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
407 usbi_dbg ("notifying context %p of device disconnect", ctx);
409 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
411 /* signal the core that this device has been disconnected. the core will tear down this device
412 when the reference count reaches 0 */
413 usbi_disconnect_device(dev);
414 libusb_unref_device(dev);
419 usbi_mutex_unlock(&active_contexts_lock);
422 static void darwin_hotplug_poll (void)
424 /* not sure if 1 ms will be too long/short but it should work ok */
425 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
427 /* since a kernel thread may notify the IOIterators used for
428 * hotplug notification we can't just clear the iterators.
429 * instead just wait until all IOService providers are quiet */
430 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
433 static void darwin_clear_iterator (io_iterator_t iter) {
436 while ((device = IOIteratorNext (iter)) != 0)
437 IOObjectRelease (device);
440 static void darwin_fail_startup(void) {
441 pthread_mutex_lock (&libusb_darwin_at_mutex);
442 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
443 pthread_cond_signal (&libusb_darwin_at_cond);
444 pthread_mutex_unlock (&libusb_darwin_at_mutex);
448 static void *darwin_event_thread_main (void *arg0) {
450 struct libusb_context *ctx = (struct libusb_context *)arg0;
451 CFRunLoopRef runloop;
452 CFRunLoopSourceRef libusb_shutdown_cfsource;
453 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
455 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
456 /* Set this thread's name, so it can be seen in the debugger
457 and crash reports. */
458 pthread_setname_np ("org.libusb.device-hotplug");
461 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
462 /* Tell the Objective-C garbage collector about this thread.
463 This is required because, unlike NSThreads, pthreads are
464 not automatically registered. Although we don't use
465 Objective-C, we use CoreFoundation, which does.
466 Garbage collection support was entirely removed in 10.12,
467 so don't bother there. */
468 objc_registerThreadWithCollector();
471 /* hotplug (device arrival/removal) sources */
472 CFRunLoopSourceRef libusb_notification_cfsource;
473 io_notification_port_t libusb_notification_port;
474 io_iterator_t libusb_rem_device_iterator;
475 io_iterator_t libusb_add_device_iterator;
477 usbi_dbg ("creating hotplug event source");
479 runloop = CFRunLoopGetCurrent ();
482 /* add the shutdown cfsource to the run loop */
483 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
484 libusb_shutdown_cfsourcectx.info = runloop;
485 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
486 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
487 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
489 /* add the notification port to the run loop */
490 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
491 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
492 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
494 /* create notifications for removed devices */
495 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
496 IOServiceMatching(darwin_device_class),
497 darwin_devices_detached,
498 ctx, &libusb_rem_device_iterator);
500 if (kresult != kIOReturnSuccess) {
501 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
502 CFRelease (libusb_shutdown_cfsource);
504 darwin_fail_startup ();
507 /* create notifications for attached devices */
508 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
509 IOServiceMatching(darwin_device_class),
510 darwin_devices_attached,
511 ctx, &libusb_add_device_iterator);
513 if (kresult != kIOReturnSuccess) {
514 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
515 CFRelease (libusb_shutdown_cfsource);
517 darwin_fail_startup ();
521 darwin_clear_iterator (libusb_rem_device_iterator);
522 darwin_clear_iterator (libusb_add_device_iterator);
524 usbi_dbg ("darwin event thread ready to receive events");
526 /* signal the main thread that the hotplug runloop has been created. */
527 pthread_mutex_lock (&libusb_darwin_at_mutex);
528 libusb_darwin_acfl = runloop;
529 libusb_darwin_acfls = libusb_shutdown_cfsource;
530 pthread_cond_signal (&libusb_darwin_at_cond);
531 pthread_mutex_unlock (&libusb_darwin_at_mutex);
533 /* run the runloop */
536 usbi_dbg ("darwin event thread exiting");
538 /* signal the main thread that the hotplug runloop has finished. */
539 pthread_mutex_lock (&libusb_darwin_at_mutex);
540 libusb_darwin_acfls = NULL;
541 libusb_darwin_acfl = NULL;
542 pthread_cond_signal (&libusb_darwin_at_cond);
543 pthread_mutex_unlock (&libusb_darwin_at_mutex);
545 /* remove the notification cfsource */
546 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
548 /* remove the shutdown cfsource */
549 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
551 /* delete notification port */
552 IONotificationPortDestroy (libusb_notification_port);
554 /* delete iterators */
555 IOObjectRelease (libusb_rem_device_iterator);
556 IOObjectRelease (libusb_add_device_iterator);
558 CFRelease (libusb_shutdown_cfsource);
564 /* cleanup function to destroy cached devices */
565 static void darwin_cleanup_devices(void) {
566 struct darwin_cached_device *dev, *next;
568 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
569 darwin_deref_cached_device(dev);
572 darwin_cached_devices.prev = darwin_cached_devices.next = NULL;
575 static int darwin_init(struct libusb_context *ctx) {
579 pthread_mutex_lock (&libusb_darwin_init_mutex);
581 first_init = (1 == ++init_count);
585 assert (NULL == darwin_cached_devices.next);
586 list_init (&darwin_cached_devices);
588 #if !defined(HAVE_CLOCK_GETTIME)
589 /* create the clocks that will be used if clock_gettime() is not available */
590 host_name_port_t host_self;
592 host_self = mach_host_self();
593 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
594 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
595 mach_port_deallocate(mach_task_self(), host_self);
599 rc = darwin_scan_devices (ctx);
600 if (LIBUSB_SUCCESS != rc)
604 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
606 usbi_err (ctx, "could not create event thread, error %d", rc);
607 rc = LIBUSB_ERROR_OTHER;
611 pthread_mutex_lock (&libusb_darwin_at_mutex);
612 while (!libusb_darwin_acfl)
613 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
614 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
615 libusb_darwin_acfl = NULL;
616 rc = LIBUSB_ERROR_OTHER;
618 pthread_mutex_unlock (&libusb_darwin_at_mutex);
621 pthread_join (libusb_darwin_at, NULL);
625 if (LIBUSB_SUCCESS != rc) {
627 darwin_cleanup_devices ();
628 #if !defined(HAVE_CLOCK_GETTIME)
629 mach_port_deallocate(mach_task_self(), clock_realtime);
630 mach_port_deallocate(mach_task_self(), clock_monotonic);
636 pthread_mutex_unlock (&libusb_darwin_init_mutex);
641 static void darwin_exit (struct libusb_context *ctx) {
644 pthread_mutex_lock (&libusb_darwin_init_mutex);
646 if (0 == --init_count) {
647 /* stop the event runloop and wait for the thread to terminate. */
648 pthread_mutex_lock (&libusb_darwin_at_mutex);
649 CFRunLoopSourceSignal (libusb_darwin_acfls);
650 CFRunLoopWakeUp (libusb_darwin_acfl);
651 while (libusb_darwin_acfl)
652 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
653 pthread_mutex_unlock (&libusb_darwin_at_mutex);
654 pthread_join (libusb_darwin_at, NULL);
656 darwin_cleanup_devices ();
658 #if !defined(HAVE_CLOCK_GETTIME)
659 mach_port_deallocate(mach_task_self(), clock_realtime);
660 mach_port_deallocate(mach_task_self(), clock_monotonic);
664 pthread_mutex_unlock (&libusb_darwin_init_mutex);
667 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
668 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
670 IOUSBConfigurationDescriptorPtr desc;
673 /* is there a simpler way to determine the index? */
674 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
675 if (kresult != kIOReturnSuccess)
676 return darwin_to_libusb (kresult);
678 for (i = 0 ; i < numConfig ; i++) {
679 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
681 if (desc->bConfigurationValue == config_value)
685 /* configuration not found */
686 return LIBUSB_ERROR_NOT_FOUND;
689 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
690 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
693 if (0 == priv->active_config)
694 return LIBUSB_ERROR_NOT_FOUND;
696 config_index = get_configuration_index (dev, priv->active_config);
697 if (config_index < 0)
700 assert(config_index >= 0 && config_index <= UINT8_MAX);
701 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
704 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
705 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
706 IOUSBConfigurationDescriptorPtr desc;
710 if (!priv || !priv->device)
711 return LIBUSB_ERROR_OTHER;
713 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
714 if (kresult == kIOReturnSuccess) {
715 /* copy descriptor */
716 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
717 len = libusb_le16_to_cpu(desc->wTotalLength);
719 memmove (buffer, desc, len);
722 ret = darwin_to_libusb (kresult);
723 if (ret != LIBUSB_SUCCESS)
729 /* check whether the os has configured the device */
730 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
731 usb_device_t **darwin_device = dev->device;
733 IOUSBConfigurationDescriptorPtr configDesc;
734 IOUSBFindInterfaceRequest request;
736 io_iterator_t interface_iterator;
737 io_service_t firstInterface;
739 if (dev->dev_descriptor.bNumConfigurations < 1) {
740 usbi_err (ctx, "device has no configurations");
741 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
744 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
746 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
747 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
748 usbi_dbg ("ignoring configuration on root hub simulation");
749 dev->active_config = 0;
750 return LIBUSB_SUCCESS;
753 /* find the first configuration */
754 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
755 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
757 /* check if the device is already configured. there is probably a better way than iterating over the
758 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
759 might lock up on the device request) */
761 /* Setup the Interface Request */
762 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
763 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
764 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
765 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
767 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
768 if (kresult != kIOReturnSuccess)
769 return darwin_to_libusb (kresult);
772 firstInterface = IOIteratorNext(interface_iterator);
774 /* done with the interface iterator */
775 IOObjectRelease(interface_iterator);
777 if (firstInterface) {
778 IOObjectRelease (firstInterface);
780 /* device is configured */
781 if (dev->dev_descriptor.bNumConfigurations == 1)
782 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
783 dev->active_config = dev->first_config;
785 /* devices with more than one configuration should work with GetConfiguration */
786 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
789 dev->active_config = 0;
791 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
793 return LIBUSB_SUCCESS;
796 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
797 IOUSBDevRequestTO req;
799 assert(buffer_size <= UINT16_MAX);
801 memset (buffer, 0, buffer_size);
803 /* Set up request for descriptor/ */
804 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
805 req.bRequest = kUSBRqGetDescriptor;
806 req.wValue = (UInt16)(desc << 8);
807 req.wIndex = desc_index;
808 req.wLength = (UInt16)buffer_size;
810 req.noDataTimeout = 20;
811 req.completionTimeout = 100;
813 return (*device)->DeviceRequestTO (device, &req);
816 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
817 usb_device_t **device = dev->device;
819 long delay = 30000; // microseconds
820 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
822 IOReturn ret = 0, ret2;
824 UInt16 idProduct, idVendor;
826 dev->can_enumerate = 0;
828 (*device)->GetDeviceClass (device, &bDeviceClass);
829 (*device)->GetDeviceProduct (device, &idProduct);
830 (*device)->GetDeviceVendor (device, &idVendor);
832 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
833 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
834 * to follow the spec as closely as possible, try opening the device */
835 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
838 /**** retrieve device descriptor ****/
839 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
841 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
842 /* received an overrun error but we still received a device descriptor */
843 ret = kIOReturnSuccess;
845 if (kIOUSBVendorIDAppleComputer == idVendor) {
846 /* NTH: don't bother retrying or unsuspending Apple devices */
850 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
851 0 == dev->dev_descriptor.bcdUSB)) {
852 /* work around for incorrectly configured devices */
853 if (try_reconfigure && is_open) {
854 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
856 /* set the first configuration */
857 (*device)->SetConfiguration(device, 1);
859 /* don't try to reconfigure again */
863 ret = kIOUSBPipeStalled;
866 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
867 /* device may be suspended. unsuspend it and try again */
868 #if DeviceVersion >= 320
871 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
872 (void)(*device)->GetUSBDeviceInformation (device, &info);
874 /* note that the device was suspended */
875 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
880 /* try to unsuspend the device */
881 ret2 = (*device)->USBDeviceSuspend (device, 0);
882 if (kIOReturnSuccess != ret2) {
883 /* prevent log spew from poorly behaving devices. this indicates the
884 os actually had trouble communicating with the device */
885 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
893 if (kIOReturnSuccess != ret) {
894 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
895 /* sleep for a little while before trying again */
896 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
898 } while (kIOReturnSuccess != ret && retries--);
901 /* resuspend the device */
902 (void)(*device)->USBDeviceSuspend (device, 1);
905 (void) (*device)->USBDeviceClose (device);
907 if (ret != kIOReturnSuccess) {
908 /* a debug message was already printed out for this error */
909 if (LIBUSB_CLASS_HUB == bDeviceClass)
910 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
911 idVendor, idProduct, darwin_error_str (ret), ret);
913 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
914 idVendor, idProduct, darwin_error_str (ret), ret);
915 return darwin_to_libusb (ret);
918 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
919 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
920 /* not a valid device */
921 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
922 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
923 return LIBUSB_ERROR_NO_DEVICE;
926 usbi_dbg ("cached device descriptor:");
927 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
928 usbi_dbg (" bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
929 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
930 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
931 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
932 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
933 usbi_dbg (" idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
934 usbi_dbg (" idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
935 usbi_dbg (" bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
936 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
937 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
938 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
939 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
941 dev->can_enumerate = 1;
943 return LIBUSB_SUCCESS;
946 /* Returns 1 on success, 0 on failure. */
947 static bool get_device_port (io_service_t service, UInt8 *port) {
952 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
956 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
957 if (kIOReturnSuccess == kresult) {
958 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
959 IOObjectRelease (parent);
965 /* Returns 1 on success, 0 on failure. */
966 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
970 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
972 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
973 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
979 /* We ran out of parents */
983 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
984 UInt64 *old_session_id) {
985 struct darwin_cached_device *new_device;
986 UInt64 sessionID = 0, parent_sessionID = 0;
987 UInt32 locationID = 0;
988 enum libusb_error ret = LIBUSB_SUCCESS;
989 usb_device_t **device;
992 /* assuming sessionID != 0 normally (never seen it be 0) */
996 /* get some info from the io registry */
997 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
998 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
999 if (!get_device_port (service, &port)) {
1000 usbi_dbg("could not get connected port number");
1003 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
1005 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1006 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
1009 usbi_mutex_lock(&darwin_cached_devices_lock);
1011 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1012 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1013 sessionID, locationID, new_device->session, new_device->location);
1014 if (new_device->location == locationID && new_device->in_reenumerate) {
1015 usbi_dbg ("found cached device with matching location that is being re-enumerated");
1016 *old_session_id = new_device->session;
1020 if (new_device->session == sessionID) {
1021 usbi_dbg("using cached device for device");
1022 *cached_out = new_device;
1030 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
1032 device = darwin_device_from_service (service);
1034 ret = LIBUSB_ERROR_NO_DEVICE;
1038 if (!(*old_session_id)) {
1039 new_device = calloc (1, sizeof (*new_device));
1041 ret = LIBUSB_ERROR_NO_MEM;
1045 /* add this device to the cached device list */
1046 list_add(&new_device->list, &darwin_cached_devices);
1048 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1050 /* keep a reference to this device */
1051 darwin_ref_cached_device(new_device);
1053 (*device)->GetLocationID (device, &new_device->location);
1054 new_device->port = port;
1055 new_device->parent_session = parent_sessionID;
1058 /* keep track of devices regardless of if we successfully enumerate them to
1059 prevent them from being enumerated multiple times */
1060 *cached_out = new_device;
1062 new_device->session = sessionID;
1063 new_device->device = device;
1065 /* cache the device descriptor */
1066 ret = darwin_cache_device_descriptor(new_device);
1070 if (new_device->can_enumerate) {
1071 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1072 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1073 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1074 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1078 usbi_mutex_unlock(&darwin_cached_devices_lock);
1083 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1084 UInt64 old_session_id) {
1085 struct darwin_device_priv *priv;
1086 struct libusb_device *dev = NULL;
1088 enum libusb_error ret = LIBUSB_SUCCESS;
1091 /* check current active configuration (and cache the first configuration value--
1092 which may be used by claim_interface) */
1093 ret = darwin_check_configuration (ctx, cached_device);
1097 if (0 != old_session_id) {
1098 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1099 ctx, old_session_id, cached_device->session);
1100 /* save the libusb device before the session id is updated */
1101 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1105 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1106 ctx, cached_device->session);
1108 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1110 return LIBUSB_ERROR_NO_MEM;
1113 priv = usbi_get_device_priv(dev);
1115 priv->dev = cached_device;
1116 darwin_ref_cached_device (priv->dev);
1117 dev->port_number = cached_device->port;
1118 dev->bus_number = cached_device->location >> 24;
1119 assert(cached_device->address <= UINT8_MAX);
1120 dev->device_address = (uint8_t)cached_device->address;
1122 priv = usbi_get_device_priv(dev);
1125 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1126 "mismatch between libusb and IOKit device descriptor sizes");
1127 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1128 usbi_localize_device_descriptor(&dev->device_descriptor);
1129 dev->session_data = cached_device->session;
1131 if (cached_device->parent_session > 0) {
1132 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1134 dev->parent_dev = NULL;
1137 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1140 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1141 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1142 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1143 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1144 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1146 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1147 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1150 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1153 ret = usbi_sanitize_device (dev);
1157 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1158 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1162 if (!cached_device->in_reenumerate && 0 == ret) {
1163 usbi_connect_device (dev);
1165 libusb_unref_device (dev);
1171 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1172 struct darwin_cached_device *cached_device;
1173 UInt64 old_session_id;
1174 io_iterator_t deviceIterator;
1175 io_service_t service;
1179 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1180 if (kresult != kIOReturnSuccess)
1181 return darwin_to_libusb (kresult);
1183 while ((service = IOIteratorNext (deviceIterator))) {
1184 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1185 if (ret < 0 || !cached_device->can_enumerate) {
1189 (void) process_new_device (ctx, cached_device, old_session_id);
1191 IOObjectRelease(service);
1194 IOObjectRelease(deviceIterator);
1196 return LIBUSB_SUCCESS;
1199 static int darwin_open (struct libusb_device_handle *dev_handle) {
1200 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1201 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1204 if (0 == dpriv->open_count) {
1205 /* try to open the device */
1206 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1207 if (kresult != kIOReturnSuccess) {
1208 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1210 if (kIOReturnExclusiveAccess != kresult) {
1211 return darwin_to_libusb (kresult);
1214 /* it is possible to perform some actions on a device that is not open so do not return an error */
1215 priv->is_open = false;
1217 priv->is_open = true;
1220 /* create async event source */
1221 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1222 if (kresult != kIOReturnSuccess) {
1223 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1225 if (priv->is_open) {
1226 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1229 priv->is_open = false;
1231 return darwin_to_libusb (kresult);
1234 CFRetain (libusb_darwin_acfl);
1236 /* add the cfSource to the aync run loop */
1237 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1240 /* device opened successfully */
1241 dpriv->open_count++;
1243 usbi_dbg ("device open for access");
1248 static void darwin_close (struct libusb_device_handle *dev_handle) {
1249 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1250 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1254 if (dpriv->open_count == 0) {
1255 /* something is probably very wrong if this is the case */
1256 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1260 dpriv->open_count--;
1262 /* make sure all interfaces are released */
1263 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1264 if (dev_handle->claimed_interfaces & (1U << i))
1265 libusb_release_interface (dev_handle, i);
1267 if (0 == dpriv->open_count) {
1268 /* delete the device's async event source */
1269 if (priv->cfSource) {
1270 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1271 CFRelease (priv->cfSource);
1272 priv->cfSource = NULL;
1273 CFRelease (libusb_darwin_acfl);
1276 if (priv->is_open) {
1277 /* close the device */
1278 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1279 if (kresult != kIOReturnSuccess) {
1280 /* Log the fact that we had a problem closing the file, however failing a
1281 * close isn't really an error, so return success anyway */
1282 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1288 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1289 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1291 *config = dpriv->active_config;
1293 return LIBUSB_SUCCESS;
1296 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1297 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1304 /* Setting configuration will invalidate the interface, so we need
1305 to reclaim it. First, dispose of existing interfaces, if any. */
1306 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1307 if (dev_handle->claimed_interfaces & (1U << i))
1308 darwin_release_interface (dev_handle, i);
1310 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1311 if (kresult != kIOReturnSuccess)
1312 return darwin_to_libusb (kresult);
1314 /* Reclaim any interfaces. */
1315 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1316 if (dev_handle->claimed_interfaces & (1U << i))
1317 darwin_claim_interface (dev_handle, i);
1319 dpriv->active_config = (UInt8)config;
1321 return LIBUSB_SUCCESS;
1324 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1325 IOUSBFindInterfaceRequest request;
1327 io_iterator_t interface_iterator;
1328 UInt8 bInterfaceNumber;
1331 *usbInterfacep = IO_OBJECT_NULL;
1333 /* Setup the Interface Request */
1334 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1335 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1336 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1337 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1339 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1340 if (kresult != kIOReturnSuccess)
1343 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1344 /* find the interface number */
1345 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1348 if (ret && bInterfaceNumber == ifc) {
1352 (void) IOObjectRelease (*usbInterfacep);
1355 /* done with the interface iterator */
1356 IOObjectRelease(interface_iterator);
1358 return kIOReturnSuccess;
1361 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1362 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1364 /* current interface */
1365 struct darwin_interface *cInterface = &priv->interfaces[iface];
1369 UInt8 numep, direction, number;
1370 UInt8 dont_care1, dont_care3;
1374 usbi_dbg ("building table of endpoints.");
1376 /* retrieve the total number of endpoints on this interface */
1377 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1378 if (kresult != kIOReturnSuccess) {
1379 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1380 return darwin_to_libusb (kresult);
1383 /* iterate through pipe references */
1384 for (UInt8 i = 1 ; i <= numep ; i++) {
1385 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1386 &dont_care2, &dont_care3);
1388 if (kresult != kIOReturnSuccess) {
1389 /* probably a buggy device. try to get the endpoint address from the descriptors */
1390 struct libusb_config_descriptor *config;
1391 const struct libusb_endpoint_descriptor *endpoint_desc;
1394 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1395 if (kresult != kIOReturnSuccess) {
1396 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1397 return darwin_to_libusb (kresult);
1400 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1401 if (LIBUSB_SUCCESS != rc) {
1405 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1407 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1409 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1412 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1413 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1416 cInterface->num_endpoints = numep;
1418 return LIBUSB_SUCCESS;
1421 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1422 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1423 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1424 io_service_t usbInterface = IO_OBJECT_NULL;
1426 enum libusb_error ret;
1427 IOCFPlugInInterface **plugInInterface = NULL;
1430 /* current interface */
1431 struct darwin_interface *cInterface = &priv->interfaces[iface];
1433 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1434 if (kresult != kIOReturnSuccess)
1435 return darwin_to_libusb (kresult);
1437 /* make sure we have an interface */
1438 if (!usbInterface && dpriv->first_config != 0) {
1439 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1441 /* set the configuration */
1442 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1443 if (ret != LIBUSB_SUCCESS) {
1444 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1448 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1449 if (kresult != kIOReturnSuccess) {
1450 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1451 return darwin_to_libusb (kresult);
1455 if (!usbInterface) {
1456 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1457 return LIBUSB_ERROR_NOT_FOUND;
1460 /* get an interface to the device's interface */
1461 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1462 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1464 /* ignore release error */
1465 (void)IOObjectRelease (usbInterface);
1467 if (kresult != kIOReturnSuccess) {
1468 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1469 return darwin_to_libusb (kresult);
1472 if (!plugInInterface) {
1473 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1474 return LIBUSB_ERROR_NOT_FOUND;
1477 /* Do the actual claim */
1478 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1479 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1480 (LPVOID)&cInterface->interface);
1481 /* We no longer need the intermediate plug-in */
1482 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1483 (*plugInInterface)->Release (plugInInterface);
1484 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1485 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1486 return darwin_to_libusb (kresult);
1489 /* claim the interface */
1490 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1491 if (kresult != kIOReturnSuccess) {
1492 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1493 return darwin_to_libusb (kresult);
1496 /* update list of endpoints */
1497 ret = get_endpoints (dev_handle, iface);
1499 /* this should not happen */
1500 darwin_release_interface (dev_handle, iface);
1501 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1505 cInterface->cfSource = NULL;
1507 /* create async event source */
1508 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1509 if (kresult != kIOReturnSuccess) {
1510 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1512 /* can't continue without an async event source */
1513 (void)darwin_release_interface (dev_handle, iface);
1515 return darwin_to_libusb (kresult);
1518 /* add the cfSource to the async thread's run loop */
1519 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1521 usbi_dbg ("interface opened");
1523 return LIBUSB_SUCCESS;
1526 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1527 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1530 /* current interface */
1531 struct darwin_interface *cInterface = &priv->interfaces[iface];
1533 /* Check to see if an interface is open */
1534 if (!cInterface->interface)
1535 return LIBUSB_SUCCESS;
1537 /* clean up endpoint data */
1538 cInterface->num_endpoints = 0;
1540 /* delete the interface's async event source */
1541 if (cInterface->cfSource) {
1542 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1543 CFRelease (cInterface->cfSource);
1546 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1547 if (kresult != kIOReturnSuccess)
1548 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1550 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1551 if (kresult != kIOReturnSuccess)
1552 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1554 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1556 return darwin_to_libusb (kresult);
1559 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1560 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1562 enum libusb_error ret;
1564 /* current interface */
1565 struct darwin_interface *cInterface = &priv->interfaces[iface];
1567 if (!cInterface->interface)
1568 return LIBUSB_ERROR_NO_DEVICE;
1570 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1571 if (kresult != kIOReturnSuccess)
1572 darwin_reset_device (dev_handle);
1574 /* update list of endpoints */
1575 ret = get_endpoints (dev_handle, iface);
1577 /* this should not happen */
1578 darwin_release_interface (dev_handle, iface);
1579 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1583 return darwin_to_libusb (kresult);
1586 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1587 /* current interface */
1588 struct darwin_interface *cInterface;
1592 /* determine the interface/endpoint to use */
1593 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1594 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1596 return LIBUSB_ERROR_NOT_FOUND;
1599 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1600 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1601 if (kresult != kIOReturnSuccess)
1602 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1604 return darwin_to_libusb (kresult);
1607 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1608 unsigned long claimed_interfaces) {
1609 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1610 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1611 int open_count = dpriv->open_count;
1614 /* clear claimed interfaces temporarily */
1615 dev_handle->claimed_interfaces = 0;
1617 /* close and re-open the device */
1618 priv->is_open = false;
1619 dpriv->open_count = 1;
1621 /* clean up open interfaces */
1622 (void) darwin_close (dev_handle);
1624 /* re-open the device */
1625 ret = darwin_open (dev_handle);
1626 dpriv->open_count = open_count;
1627 if (LIBUSB_SUCCESS != ret) {
1628 /* could not restore configuration */
1629 return LIBUSB_ERROR_NOT_FOUND;
1632 if (dpriv->active_config != active_config) {
1633 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1635 ret = darwin_set_configuration (dev_handle, active_config);
1636 if (LIBUSB_SUCCESS != ret) {
1637 usbi_dbg ("darwin/restore_state: could not restore configuration");
1638 return LIBUSB_ERROR_NOT_FOUND;
1642 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1644 if (claimed_interfaces) {
1645 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1646 if (!(claimed_interfaces & (1U << iface))) {
1650 usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
1652 ret = darwin_claim_interface (dev_handle, iface);
1653 if (LIBUSB_SUCCESS != ret) {
1654 usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
1655 return LIBUSB_ERROR_NOT_FOUND;
1658 dev_handle->claimed_interfaces |= 1U << iface;
1662 usbi_dbg ("darwin/restore_state: device state restored");
1664 return LIBUSB_SUCCESS;
1667 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1668 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1669 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1670 int8_t active_config = dpriv->active_config;
1671 IOUSBDeviceDescriptor descriptor;
1672 IOUSBConfigurationDescriptorPtr cached_configuration;
1673 IOUSBConfigurationDescriptor *cached_configurations;
1677 if (dpriv->in_reenumerate) {
1678 /* ack, two (or more) threads are trying to reset the device! abort! */
1679 return LIBUSB_ERROR_NOT_FOUND;
1682 dpriv->in_reenumerate = true;
1684 /* store copies of descriptors so they can be compared after the reset */
1685 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1686 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1688 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1689 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1690 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1693 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1694 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1695 if (kresult != kIOReturnSuccess) {
1696 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1697 dpriv->in_reenumerate = false;
1698 return darwin_to_libusb (kresult);
1701 usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1703 while (dpriv->in_reenumerate) {
1704 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1705 nanosleep (&delay, NULL);
1708 /* compare descriptors */
1709 usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1711 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1712 /* device descriptor changed. need to return not found. */
1713 usbi_dbg ("darwin/reset_device: device descriptor changed");
1714 return LIBUSB_ERROR_NOT_FOUND;
1717 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1718 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1719 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1720 usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1721 return LIBUSB_ERROR_NOT_FOUND;
1725 usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1727 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1730 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1731 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1732 io_service_t usbInterface;
1736 kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1737 if (kresult != kIOReturnSuccess) {
1738 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1740 return darwin_to_libusb (kresult);
1743 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1744 IOObjectRelease (usbInterface);
1756 static void darwin_destroy_device(struct libusb_device *dev) {
1757 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1760 /* need to hold the lock in case this is the last reference to the device */
1761 usbi_mutex_lock(&darwin_cached_devices_lock);
1762 darwin_deref_cached_device (dpriv->dev);
1764 usbi_mutex_unlock(&darwin_cached_devices_lock);
1768 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1769 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1772 uint8_t transferType;
1774 uint16_t maxPacketSize;
1776 struct darwin_interface *cInterface;
1777 #if InterfaceVersion >= 550
1778 IOUSBEndpointProperties pipeProperties;
1780 /* None of the values below are used in libusb for bulk transfers */
1781 uint8_t direction, number, interval;
1784 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1785 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1787 return LIBUSB_ERROR_NOT_FOUND;
1790 #if InterfaceVersion >= 550
1791 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1793 transferType = pipeProperties.bTransferType;
1794 maxPacketSize = pipeProperties.wMaxPacketSize;
1796 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1797 &transferType, &maxPacketSize, &interval);
1801 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1802 darwin_error_str(ret), ret);
1803 return darwin_to_libusb (ret);
1806 if (0 != (transfer->length % maxPacketSize)) {
1807 /* do not need a zero packet */
1808 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1811 /* submit the request */
1812 /* timeouts are unavailable on interrupt endpoints */
1813 if (transferType == kUSBInterrupt) {
1814 if (IS_XFERIN(transfer))
1815 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1816 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1818 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1819 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1821 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1823 if (IS_XFERIN(transfer))
1824 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1825 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1826 darwin_async_io_callback, itransfer);
1828 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1829 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1830 darwin_async_io_callback, itransfer);
1834 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1835 darwin_error_str(ret), ret);
1837 return darwin_to_libusb (ret);
1840 #if InterfaceVersion >= 550
1841 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1842 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1843 struct darwin_interface *cInterface;
1847 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1848 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1850 return LIBUSB_ERROR_NOT_FOUND;
1853 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1855 if (IS_XFERIN(transfer))
1856 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1857 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1858 transfer->timeout, darwin_async_io_callback, itransfer);
1860 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1861 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1862 transfer->timeout, darwin_async_io_callback, itransfer);
1865 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1866 darwin_error_str(ret), ret);
1868 return darwin_to_libusb (ret);
1872 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1873 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1874 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1877 uint8_t direction, number, interval, pipeRef, transferType;
1878 uint16_t maxPacketSize;
1880 AbsoluteTime atTime;
1883 struct darwin_interface *cInterface;
1885 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1886 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1887 free(tpriv->isoc_framelist);
1888 tpriv->isoc_framelist = NULL;
1891 if (!tpriv->isoc_framelist) {
1892 tpriv->num_iso_packets = transfer->num_iso_packets;
1893 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1894 if (!tpriv->isoc_framelist)
1895 return LIBUSB_ERROR_NO_MEM;
1898 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1899 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1900 unsigned int length = transfer->iso_packet_desc[i].length;
1901 assert(length <= UINT16_MAX);
1902 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1905 /* determine the interface/endpoint to use */
1906 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1907 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1909 return LIBUSB_ERROR_NOT_FOUND;
1912 /* determine the properties of this endpoint and the speed of the device */
1913 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1914 &transferType, &maxPacketSize, &interval);
1916 /* Last but not least we need the bus frame number */
1917 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1918 if (kresult != kIOReturnSuccess) {
1919 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1920 free(tpriv->isoc_framelist);
1921 tpriv->isoc_framelist = NULL;
1923 return darwin_to_libusb (kresult);
1926 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1927 &transferType, &maxPacketSize, &interval);
1929 /* schedule for a frame a little in the future */
1932 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1933 frame = cInterface->frames[transfer->endpoint];
1935 /* submit the request */
1936 if (IS_XFERIN(transfer))
1937 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1938 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1941 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1942 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1945 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1947 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1949 /* High/super speed */
1950 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1952 if (kresult != kIOReturnSuccess) {
1953 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1954 darwin_error_str(kresult));
1955 free (tpriv->isoc_framelist);
1956 tpriv->isoc_framelist = NULL;
1959 return darwin_to_libusb (kresult);
1962 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1963 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1964 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1965 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1966 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
1970 memset(&tpriv->req, 0, sizeof(tpriv->req));
1972 /* IOUSBDeviceInterface expects the request in cpu endianness */
1973 tpriv->req.bmRequestType = setup->bmRequestType;
1974 tpriv->req.bRequest = setup->bRequest;
1975 /* these values should be in bus order from libusb_fill_control_setup */
1976 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1977 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1978 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1979 /* data is stored after the libusb control block */
1980 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1981 tpriv->req.completionTimeout = transfer->timeout;
1982 tpriv->req.noDataTimeout = transfer->timeout;
1984 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1986 /* all transfers in libusb-1.0 are async */
1988 if (transfer->endpoint) {
1989 struct darwin_interface *cInterface;
1992 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1993 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1995 return LIBUSB_ERROR_NOT_FOUND;
1998 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2000 /* control request on endpoint 0 */
2001 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2003 if (kresult != kIOReturnSuccess)
2004 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2006 return darwin_to_libusb (kresult);
2009 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2010 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2012 switch (transfer->type) {
2013 case LIBUSB_TRANSFER_TYPE_CONTROL:
2014 return submit_control_transfer(itransfer);
2015 case LIBUSB_TRANSFER_TYPE_BULK:
2016 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2017 return submit_bulk_transfer(itransfer);
2018 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2019 return submit_iso_transfer(itransfer);
2020 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2021 #if InterfaceVersion >= 550
2022 return submit_stream_transfer(itransfer);
2024 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2025 return LIBUSB_ERROR_NOT_SUPPORTED;
2028 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2029 return LIBUSB_ERROR_INVALID_PARAM;
2033 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2034 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2035 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2038 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2041 return LIBUSB_ERROR_NO_DEVICE;
2043 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2045 return darwin_to_libusb (kresult);
2048 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2049 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2050 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2051 struct darwin_interface *cInterface;
2052 uint8_t pipeRef, iface;
2055 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2056 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2058 return LIBUSB_ERROR_NOT_FOUND;
2062 return LIBUSB_ERROR_NO_DEVICE;
2064 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2066 /* abort transactions */
2067 #if InterfaceVersion >= 550
2068 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2069 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2072 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2074 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2076 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2077 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2079 return darwin_to_libusb (kresult);
2082 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2083 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2085 switch (transfer->type) {
2086 case LIBUSB_TRANSFER_TYPE_CONTROL:
2087 return cancel_control_transfer(itransfer);
2088 case LIBUSB_TRANSFER_TYPE_BULK:
2089 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2090 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2091 return darwin_abort_transfers (itransfer);
2093 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2094 return LIBUSB_ERROR_INVALID_PARAM;
2098 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2099 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2100 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2101 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2103 usbi_dbg ("an async io operation has completed");
2105 /* if requested write a zero packet */
2106 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2107 struct darwin_interface *cInterface;
2110 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2112 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2115 tpriv->result = result;
2116 tpriv->size = (UInt32) (uintptr_t) arg0;
2118 /* signal the core that this transfer is complete */
2119 usbi_signal_transfer_completion(itransfer);
2122 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2123 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2124 result = kIOUSBTransactionTimeout;
2127 case kIOReturnUnderrun:
2128 case kIOReturnSuccess:
2129 return LIBUSB_TRANSFER_COMPLETED;
2130 case kIOReturnAborted:
2131 return LIBUSB_TRANSFER_CANCELLED;
2132 case kIOUSBPipeStalled:
2133 usbi_dbg ("transfer error: pipe is stalled");
2134 return LIBUSB_TRANSFER_STALL;
2135 case kIOReturnOverrun:
2136 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2137 return LIBUSB_TRANSFER_OVERFLOW;
2138 case kIOUSBTransactionTimeout:
2139 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2140 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2141 return LIBUSB_TRANSFER_TIMED_OUT;
2143 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2144 return LIBUSB_TRANSFER_ERROR;
2148 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2149 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2150 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2151 bool isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2152 bool isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
2153 bool isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
2154 bool isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
2157 if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
2158 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2159 return LIBUSB_ERROR_INVALID_PARAM;
2162 usbi_dbg ("handling %s completion with kernel status %d",
2163 isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
2165 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2166 if (isIsoc && tpriv->isoc_framelist) {
2167 /* copy isochronous results back */
2169 for (i = 0; i < transfer->num_iso_packets ; i++) {
2170 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2171 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2172 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2175 itransfer->transferred += tpriv->size;
2178 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2179 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2182 #if !defined(HAVE_CLOCK_GETTIME)
2183 int usbi_clock_gettime(int clk_id, struct timespec *tp) {
2184 mach_timespec_t sys_time;
2185 clock_serv_t clock_ref;
2188 case USBI_CLOCK_REALTIME:
2189 /* CLOCK_REALTIME represents time since the epoch */
2190 clock_ref = clock_realtime;
2192 case USBI_CLOCK_MONOTONIC:
2193 /* use system boot time as reference for the monotonic clock */
2194 clock_ref = clock_monotonic;
2201 clock_get_time (clock_ref, &sys_time);
2203 tp->tv_sec = sys_time.tv_sec;
2204 tp->tv_nsec = sys_time.tv_nsec;
2210 #if InterfaceVersion >= 550
2211 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2212 int num_endpoints) {
2213 struct darwin_interface *cInterface;
2214 UInt32 supportsStreams;
2218 /* find the mimimum number of supported streams on the endpoint list */
2219 for (i = 0 ; i < num_endpoints ; ++i) {
2220 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2224 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2225 if (num_streams > supportsStreams)
2226 num_streams = supportsStreams;
2229 /* it is an error if any endpoint in endpoints does not support streams */
2230 if (0 == num_streams)
2231 return LIBUSB_ERROR_INVALID_PARAM;
2233 /* create the streams */
2234 for (i = 0 ; i < num_endpoints ; ++i) {
2235 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2237 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2238 if (kIOReturnSuccess != rc)
2239 return darwin_to_libusb(rc);
2242 assert(num_streams <= INT_MAX);
2243 return (int)num_streams;
2246 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2247 struct darwin_interface *cInterface;
2248 UInt32 supportsStreams;
2252 for (int i = 0 ; i < num_endpoints ; ++i) {
2253 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2256 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2257 if (0 == supportsStreams)
2258 return LIBUSB_ERROR_INVALID_PARAM;
2260 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2261 if (kIOReturnSuccess != rc)
2262 return darwin_to_libusb(rc);
2265 return LIBUSB_SUCCESS;
2269 const struct usbi_os_backend usbi_backend = {
2272 .init = darwin_init,
2273 .exit = darwin_exit,
2274 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2275 .get_config_descriptor = darwin_get_config_descriptor,
2276 .hotplug_poll = darwin_hotplug_poll,
2278 .open = darwin_open,
2279 .close = darwin_close,
2280 .get_configuration = darwin_get_configuration,
2281 .set_configuration = darwin_set_configuration,
2282 .claim_interface = darwin_claim_interface,
2283 .release_interface = darwin_release_interface,
2285 .set_interface_altsetting = darwin_set_interface_altsetting,
2286 .clear_halt = darwin_clear_halt,
2287 .reset_device = darwin_reset_device,
2289 #if InterfaceVersion >= 550
2290 .alloc_streams = darwin_alloc_streams,
2291 .free_streams = darwin_free_streams,
2294 .kernel_driver_active = darwin_kernel_driver_active,
2296 .destroy_device = darwin_destroy_device,
2298 .submit_transfer = darwin_submit_transfer,
2299 .cancel_transfer = darwin_cancel_transfer,
2301 .handle_transfer_completion = darwin_handle_transfer_completion,
2303 .device_priv_size = sizeof(struct darwin_device_priv),
2304 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2305 .transfer_priv_size = sizeof(struct darwin_transfer_priv),