1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2019 Nathan Hjelm <hjelmn@users.sourceforge.net>
5 * Copyright © 2019 Google LLC. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <sys/types.h>
34 #include <sys/sysctl.h>
36 #include <mach/clock.h>
37 #include <mach/clock_types.h>
38 #include <mach/mach_host.h>
39 #include <mach/mach_port.h>
41 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
42 * function. Its use is also conditionalized to only older deployment targets. */
43 #define OBJC_SILENCE_GC_DEPRECATIONS 1
45 #include <AvailabilityMacros.h>
46 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
47 #include <objc/objc-auto.h>
50 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
51 /* Apple deprecated the darwin atomics in 10.12 in favor of C11 atomics */
52 #include <stdatomic.h>
53 #define libusb_darwin_atomic_fetch_add(x, y) atomic_fetch_add(x, y)
55 _Atomic int32_t initCount = ATOMIC_VAR_INIT(0);
57 /* use darwin atomics if the target is older than 10.12 */
58 #include <libkern/OSAtomic.h>
60 /* OSAtomicAdd32Barrier returns the new value */
61 #define libusb_darwin_atomic_fetch_add(x, y) (OSAtomicAdd32Barrier(y, x) - y)
63 static volatile int32_t initCount = 0;
67 /* On 10.12 and later, use newly available clock_*() functions */
68 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
69 #define OSX_USE_CLOCK_GETTIME 1
71 #define OSX_USE_CLOCK_GETTIME 0
74 #include "darwin_usb.h"
76 /* async event thread */
77 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
78 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
80 #if !OSX_USE_CLOCK_GETTIME
81 static clock_serv_t clock_realtime;
82 static clock_serv_t clock_monotonic;
85 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
86 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
88 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
89 static struct list_head darwin_cached_devices = {&darwin_cached_devices, &darwin_cached_devices};
90 static const char *darwin_device_class = kIOUSBDeviceClassName;
92 #define DARWIN_CACHED_DEVICE(a) ((struct darwin_cached_device *) (((struct darwin_device_priv *)((a)->os_priv))->dev))
94 /* async event thread */
95 static pthread_t libusb_darwin_at;
97 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian);
98 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface);
99 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface);
100 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
101 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
103 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
104 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
105 UInt64 old_session_id);
107 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
108 UInt64 *old_session_id);
110 #if defined(ENABLE_LOGGING)
111 static const char *darwin_error_str (IOReturn result) {
112 static char string_buffer[50];
114 case kIOReturnSuccess:
116 case kIOReturnNotOpen:
117 return "device not opened for exclusive access";
118 case kIOReturnNoDevice:
119 return "no connection to an IOService";
120 case kIOUSBNoAsyncPortErr:
121 return "no async port has been opened for interface";
122 case kIOReturnExclusiveAccess:
123 return "another process has device opened for exclusive access";
124 case kIOUSBPipeStalled:
125 return "pipe is stalled";
127 return "could not establish a connection to the Darwin kernel";
128 case kIOUSBTransactionTimeout:
129 return "transaction timed out";
130 case kIOReturnBadArgument:
131 return "invalid argument";
132 case kIOReturnAborted:
133 return "transaction aborted";
134 case kIOReturnNotResponding:
135 return "device not responding";
136 case kIOReturnOverrun:
137 return "data overrun";
138 case kIOReturnCannotWire:
139 return "physical memory can not be wired down";
140 case kIOReturnNoResources:
141 return "out of resources";
142 case kIOUSBHighSpeedSplitError:
143 return "high speed split error";
145 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
146 return string_buffer;
151 static enum libusb_error darwin_to_libusb (IOReturn result) {
153 case kIOReturnUnderrun:
154 case kIOReturnSuccess:
155 return LIBUSB_SUCCESS;
156 case kIOReturnNotOpen:
157 case kIOReturnNoDevice:
158 return LIBUSB_ERROR_NO_DEVICE;
159 case kIOReturnExclusiveAccess:
160 return LIBUSB_ERROR_ACCESS;
161 case kIOUSBPipeStalled:
162 return LIBUSB_ERROR_PIPE;
163 case kIOReturnBadArgument:
164 return LIBUSB_ERROR_INVALID_PARAM;
165 case kIOUSBTransactionTimeout:
166 return LIBUSB_ERROR_TIMEOUT;
167 case kIOReturnNotResponding:
168 case kIOReturnAborted:
170 case kIOUSBNoAsyncPortErr:
172 return LIBUSB_ERROR_OTHER;
176 /* this function must be called with the darwin_cached_devices_lock held */
177 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
178 cached_dev->refcount--;
179 /* free the device and remove it from the cache */
180 if (0 == cached_dev->refcount) {
181 list_del(&cached_dev->list);
183 if (cached_dev->device) {
184 (*(cached_dev->device))->Release(cached_dev->device);
185 cached_dev->device = NULL;
191 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
192 cached_dev->refcount++;
195 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) {
196 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
198 /* current interface */
199 struct darwin_interface *cInterface;
203 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
205 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
206 cInterface = &priv->interfaces[iface];
208 if (dev_handle->claimed_interfaces & (1U << iface)) {
209 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
210 if (cInterface->endpoint_addrs[i] == ep) {
217 *interface_out = cInterface;
219 usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
220 return LIBUSB_SUCCESS;
226 /* No pipe found with the correct endpoint address */
227 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
229 return LIBUSB_ERROR_NOT_FOUND;
232 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
233 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
236 return kIOReturnError;
239 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
240 &kCFTypeDictionaryKeyCallBacks,
241 &kCFTypeDictionaryValueCallBacks);
243 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
244 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
245 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
247 if (propertyMatchDict && locationCF) {
248 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
249 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
251 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
253 /* release our references as per the Create Rule */
254 if (propertyMatchDict)
255 CFRelease (propertyMatchDict);
257 CFRelease (locationCF);
260 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
263 /* Returns 1 on success, 0 on failure. */
264 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
265 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
269 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
270 success = CFNumberGetValue(cfNumber, type, p);
273 CFRelease (cfNumber);
276 return (success != 0);
279 /* Returns 1 on success, 0 on failure. */
280 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
281 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
282 bool success = false;
285 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
286 CFIndex length = CFDataGetLength (cfData);
291 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
301 static usb_device_t **darwin_device_from_service (io_service_t service)
303 io_cf_plugin_ref_t *plugInInterface = NULL;
304 usb_device_t **device;
307 const int max_retries = 5;
309 /* The IOCreatePlugInInterfaceForService function might consistently return
310 an "out of resources" error with certain USB devices the first time we run
311 it. The reason is still unclear, but retrying fixes the problem */
312 for (int count = 0; count < max_retries; count++) {
313 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
314 kIOCFPlugInInterfaceID, &plugInInterface,
316 if (kIOReturnSuccess == kresult && plugInInterface) {
320 usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
322 /* sleep for a little while before trying again */
323 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
326 if (kIOReturnSuccess != kresult || !plugInInterface) {
327 usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
331 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
333 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
334 (*plugInInterface)->Release (plugInInterface);
339 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
341 struct darwin_cached_device *cached_device;
342 UInt64 old_session_id;
343 struct libusb_context *ctx;
344 io_service_t service;
347 usbi_mutex_lock(&active_contexts_lock);
349 while ((service = IOIteratorNext(add_devices))) {
350 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
351 if (ret < 0 || !cached_device->can_enumerate) {
355 /* add this device to each active context's device list */
356 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
357 process_new_device (ctx, cached_device, old_session_id);
360 if (cached_device->in_reenumerate) {
361 usbi_dbg ("cached device in reset state. reset complete...");
362 cached_device->in_reenumerate = false;
365 IOObjectRelease(service);
368 usbi_mutex_unlock(&active_contexts_lock);
371 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
373 struct libusb_device *dev = NULL;
374 struct libusb_context *ctx;
375 struct darwin_cached_device *old_device;
381 usbi_mutex_lock(&active_contexts_lock);
383 while ((device = IOIteratorNext (rem_devices)) != 0) {
384 bool is_reenumerating = false;
386 /* get the location from the i/o registry */
387 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
388 IOObjectRelease (device);
392 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
393 otherwise no cached device will ever get freed */
394 usbi_mutex_lock(&darwin_cached_devices_lock);
395 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
396 if (old_device->session == session) {
397 if (old_device->in_reenumerate) {
398 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
399 * will deref if needed. */
400 usbi_dbg ("detected device detatched due to re-enumeration");
402 /* the device object is no longer usable so go ahead and release it */
403 if (old_device->device) {
404 (*(old_device->device))->Release(old_device->device);
405 old_device->device = NULL;
408 is_reenumerating = true;
410 darwin_deref_cached_device (old_device);
417 usbi_mutex_unlock(&darwin_cached_devices_lock);
418 if (is_reenumerating) {
422 list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
423 usbi_dbg ("notifying context %p of device disconnect", ctx);
425 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
427 /* signal the core that this device has been disconnected. the core will tear down this device
428 when the reference count reaches 0 */
429 usbi_disconnect_device(dev);
430 libusb_unref_device(dev);
435 usbi_mutex_unlock(&active_contexts_lock);
438 static void darwin_hotplug_poll (void)
440 /* not sure if 1 ms will be too long/short but it should work ok */
441 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
443 /* since a kernel thread may notify the IOIterators used for
444 * hotplug notification we can't just clear the iterators.
445 * instead just wait until all IOService providers are quiet */
446 (void) IOKitWaitQuiet (kIOMasterPortDefault, &timeout);
449 static void darwin_clear_iterator (io_iterator_t iter) {
452 while ((device = IOIteratorNext (iter)) != 0)
453 IOObjectRelease (device);
456 static void *darwin_event_thread_main (void *arg0) {
458 struct libusb_context *ctx = (struct libusb_context *)arg0;
459 CFRunLoopRef runloop;
461 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
462 /* Set this thread's name, so it can be seen in the debugger
463 and crash reports. */
464 pthread_setname_np ("org.libusb.device-hotplug");
467 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
468 /* Tell the Objective-C garbage collector about this thread.
469 This is required because, unlike NSThreads, pthreads are
470 not automatically registered. Although we don't use
471 Objective-C, we use CoreFoundation, which does.
472 Garbage collection support was entirely removed in 10.12,
473 so don't bother there. */
474 objc_registerThreadWithCollector();
477 /* hotplug (device arrival/removal) sources */
478 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
479 CFRunLoopSourceRef libusb_notification_cfsource;
480 io_notification_port_t libusb_notification_port;
481 io_iterator_t libusb_rem_device_iterator;
482 io_iterator_t libusb_add_device_iterator;
484 usbi_dbg ("creating hotplug event source");
486 runloop = CFRunLoopGetCurrent ();
489 /* add the shutdown cfsource to the run loop */
490 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
491 libusb_shutdown_cfsourcectx.info = runloop;
492 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
493 libusb_darwin_acfls = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
494 CFRunLoopAddSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode);
496 /* add the notification port to the run loop */
497 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
498 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
499 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
501 /* create notifications for removed devices */
502 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
503 IOServiceMatching(darwin_device_class),
504 darwin_devices_detached,
505 ctx, &libusb_rem_device_iterator);
507 if (kresult != kIOReturnSuccess) {
508 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
513 /* create notifications for attached devices */
514 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
515 IOServiceMatching(darwin_device_class),
516 darwin_devices_attached,
517 ctx, &libusb_add_device_iterator);
519 if (kresult != kIOReturnSuccess) {
520 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
526 darwin_clear_iterator (libusb_rem_device_iterator);
527 darwin_clear_iterator (libusb_add_device_iterator);
529 usbi_dbg ("darwin event thread ready to receive events");
531 /* signal the main thread that the hotplug runloop has been created. */
532 pthread_mutex_lock (&libusb_darwin_at_mutex);
533 libusb_darwin_acfl = runloop;
534 pthread_cond_signal (&libusb_darwin_at_cond);
535 pthread_mutex_unlock (&libusb_darwin_at_mutex);
537 /* run the runloop */
540 usbi_dbg ("darwin event thread exiting");
542 /* remove the notification cfsource */
543 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
545 /* remove the shutdown cfsource */
546 CFRunLoopRemoveSource(runloop, libusb_darwin_acfls, kCFRunLoopDefaultMode);
548 /* delete notification port */
549 IONotificationPortDestroy (libusb_notification_port);
551 /* delete iterators */
552 IOObjectRelease (libusb_rem_device_iterator);
553 IOObjectRelease (libusb_add_device_iterator);
555 CFRelease (libusb_darwin_acfls);
558 libusb_darwin_acfls = NULL;
559 libusb_darwin_acfl = NULL;
564 /* cleanup function to destroy cached devices */
565 static void __attribute__((destructor)) _darwin_finalize(void) {
566 struct darwin_cached_device *dev, *next;
568 usbi_mutex_lock(&darwin_cached_devices_lock);
569 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
570 darwin_deref_cached_device(dev);
572 usbi_mutex_unlock(&darwin_cached_devices_lock);
575 static int darwin_init(struct libusb_context *ctx) {
578 rc = darwin_scan_devices (ctx);
579 if (LIBUSB_SUCCESS != rc) {
583 if (libusb_darwin_atomic_fetch_add (&initCount, 1) == 0) {
584 #if !OSX_USE_CLOCK_GETTIME
585 /* create the clocks that will be used if clock_gettime() is not available */
586 host_name_port_t host_self;
588 host_self = mach_host_self();
589 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
590 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
591 mach_port_deallocate(mach_task_self(), host_self);
594 pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
596 pthread_mutex_lock (&libusb_darwin_at_mutex);
597 while (!libusb_darwin_acfl)
598 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
599 pthread_mutex_unlock (&libusb_darwin_at_mutex);
605 static void darwin_exit (struct libusb_context *ctx) {
607 if (libusb_darwin_atomic_fetch_add (&initCount, -1) == 1) {
608 #if !OSX_USE_CLOCK_GETTIME
609 mach_port_deallocate(mach_task_self(), clock_realtime);
610 mach_port_deallocate(mach_task_self(), clock_monotonic);
613 /* stop the event runloop and wait for the thread to terminate. */
614 CFRunLoopSourceSignal(libusb_darwin_acfls);
615 CFRunLoopWakeUp (libusb_darwin_acfl);
616 pthread_join (libusb_darwin_at, NULL);
620 static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
621 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
623 /* return cached copy */
624 memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
628 return LIBUSB_SUCCESS;
631 static int get_configuration_index (struct libusb_device *dev, int config_value) {
632 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
634 IOUSBConfigurationDescriptorPtr desc;
637 /* is there a simpler way to determine the index? */
638 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
639 if (kresult != kIOReturnSuccess)
640 return darwin_to_libusb (kresult);
642 for (i = 0 ; i < numConfig ; i++) {
643 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
645 if (desc->bConfigurationValue == config_value)
649 /* configuration not found */
650 return LIBUSB_ERROR_NOT_FOUND;
653 static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) {
654 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
657 if (0 == priv->active_config)
658 return LIBUSB_ERROR_NOT_FOUND;
660 config_index = get_configuration_index (dev, priv->active_config);
661 if (config_index < 0)
664 assert(config_index >= 0 && config_index <= UINT8_MAX);
665 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len, host_endian);
668 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) {
669 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
670 IOUSBConfigurationDescriptorPtr desc;
674 if (!priv || !priv->device)
675 return LIBUSB_ERROR_OTHER;
677 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
678 if (kresult == kIOReturnSuccess) {
679 /* copy descriptor */
680 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
681 len = libusb_le16_to_cpu(desc->wTotalLength);
683 memmove (buffer, desc, len);
685 /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */
689 ret = darwin_to_libusb (kresult);
690 if (ret != LIBUSB_SUCCESS)
696 /* check whether the os has configured the device */
697 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
698 usb_device_t **darwin_device = dev->device;
700 IOUSBConfigurationDescriptorPtr configDesc;
701 IOUSBFindInterfaceRequest request;
703 io_iterator_t interface_iterator;
704 io_service_t firstInterface;
706 if (dev->dev_descriptor.bNumConfigurations < 1) {
707 usbi_err (ctx, "device has no configurations");
708 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
711 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
713 if (0x05ac == dev->dev_descriptor.idVendor && 0x8005 == dev->dev_descriptor.idProduct) {
714 usbi_dbg ("ignoring configuration on root hub simulation");
715 dev->active_config = 0;
716 return LIBUSB_SUCCESS;
719 /* find the first configuration */
720 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
721 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
723 /* check if the device is already configured. there is probably a better way than iterating over the
724 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
725 might lock up on the device request) */
727 /* Setup the Interface Request */
728 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
729 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
730 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
731 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
733 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
734 if (kresult != kIOReturnSuccess)
735 return darwin_to_libusb (kresult);
738 firstInterface = IOIteratorNext(interface_iterator);
740 /* done with the interface iterator */
741 IOObjectRelease(interface_iterator);
743 if (firstInterface) {
744 IOObjectRelease (firstInterface);
746 /* device is configured */
747 if (dev->dev_descriptor.bNumConfigurations == 1)
748 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
749 dev->active_config = dev->first_config;
751 /* devices with more than one configuration should work with GetConfiguration */
752 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
755 dev->active_config = 0;
757 usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
759 return LIBUSB_SUCCESS;
762 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
763 IOUSBDevRequestTO req;
765 assert(buffer_size <= UINT16_MAX);
767 memset (buffer, 0, buffer_size);
769 /* Set up request for descriptor/ */
770 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
771 req.bRequest = kUSBRqGetDescriptor;
772 req.wValue = (UInt16)(desc << 8);
773 req.wIndex = desc_index;
774 req.wLength = (UInt16)buffer_size;
776 req.noDataTimeout = 20;
777 req.completionTimeout = 100;
779 return (*device)->DeviceRequestTO (device, &req);
782 static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
783 usb_device_t **device = dev->device;
785 long delay = 30000; // microseconds
786 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
788 IOReturn ret = 0, ret2;
790 UInt16 idProduct, idVendor;
792 dev->can_enumerate = 0;
794 (*device)->GetDeviceClass (device, &bDeviceClass);
795 (*device)->GetDeviceProduct (device, &idProduct);
796 (*device)->GetDeviceVendor (device, &idVendor);
798 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
799 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
800 * to follow the spec as closely as possible, try opening the device */
801 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
804 /**** retrieve device descriptor ****/
805 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
807 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
808 /* received an overrun error but we still received a device descriptor */
809 ret = kIOReturnSuccess;
811 if (kIOUSBVendorIDAppleComputer == idVendor) {
812 /* NTH: don't bother retrying or unsuspending Apple devices */
816 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
817 0 == dev->dev_descriptor.bcdUSB)) {
818 /* work around for incorrectly configured devices */
819 if (try_reconfigure && is_open) {
820 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
822 /* set the first configuration */
823 (*device)->SetConfiguration(device, 1);
825 /* don't try to reconfigure again */
829 ret = kIOUSBPipeStalled;
832 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
833 /* device may be suspended. unsuspend it and try again */
834 #if DeviceVersion >= 320
837 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
838 (void)(*device)->GetUSBDeviceInformation (device, &info);
840 /* note that the device was suspended */
841 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
846 /* try to unsuspend the device */
847 ret2 = (*device)->USBDeviceSuspend (device, 0);
848 if (kIOReturnSuccess != ret2) {
849 /* prevent log spew from poorly behaving devices. this indicates the
850 os actually had trouble communicating with the device */
851 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
859 if (kIOReturnSuccess != ret) {
860 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
861 /* sleep for a little while before trying again */
862 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
864 } while (kIOReturnSuccess != ret && retries--);
867 /* resuspend the device */
868 (void)(*device)->USBDeviceSuspend (device, 1);
871 (void) (*device)->USBDeviceClose (device);
873 if (ret != kIOReturnSuccess) {
874 /* a debug message was already printed out for this error */
875 if (LIBUSB_CLASS_HUB == bDeviceClass)
876 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
877 idVendor, idProduct, darwin_error_str (ret), ret);
879 usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
880 idVendor, idProduct, darwin_error_str (ret), ret);
881 return darwin_to_libusb (ret);
884 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
885 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
886 /* not a valid device */
887 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
888 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
889 return LIBUSB_ERROR_NO_DEVICE;
892 usbi_dbg ("cached device descriptor:");
893 usbi_dbg (" bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
894 usbi_dbg (" bcdUSB: 0x%04x", dev->dev_descriptor.bcdUSB);
895 usbi_dbg (" bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
896 usbi_dbg (" bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
897 usbi_dbg (" bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
898 usbi_dbg (" bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
899 usbi_dbg (" idVendor: 0x%04x", dev->dev_descriptor.idVendor);
900 usbi_dbg (" idProduct: 0x%04x", dev->dev_descriptor.idProduct);
901 usbi_dbg (" bcdDevice: 0x%04x", dev->dev_descriptor.bcdDevice);
902 usbi_dbg (" iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
903 usbi_dbg (" iProduct: 0x%02x", dev->dev_descriptor.iProduct);
904 usbi_dbg (" iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
905 usbi_dbg (" bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
907 dev->can_enumerate = 1;
909 return LIBUSB_SUCCESS;
912 /* Returns 1 on success, 0 on failure. */
913 static bool get_device_port (io_service_t service, UInt8 *port) {
918 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
922 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
923 if (kIOReturnSuccess == kresult) {
924 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
925 IOObjectRelease (parent);
931 /* Returns 1 on success, 0 on failure. */
932 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
936 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
938 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
939 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
945 /* We ran out of parents */
949 static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
950 UInt64 *old_session_id) {
951 struct darwin_cached_device *new_device;
952 UInt64 sessionID = 0, parent_sessionID = 0;
953 UInt32 locationID = 0;
954 enum libusb_error ret = LIBUSB_SUCCESS;
955 usb_device_t **device;
958 /* assuming sessionID != 0 normally (never seen it be 0) */
962 /* get some info from the io registry */
963 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
964 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
965 if (!get_device_port (service, &port)) {
966 usbi_dbg("could not get connected port number");
969 usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
971 if (get_device_parent_sessionID(service, &parent_sessionID)) {
972 usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
975 usbi_mutex_lock(&darwin_cached_devices_lock);
977 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
978 usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
979 sessionID, locationID, new_device->session, new_device->location);
980 if (new_device->location == locationID && new_device->in_reenumerate) {
981 usbi_dbg ("found cached device with matching location that is being re-enumerated");
982 *old_session_id = new_device->session;
986 if (new_device->session == sessionID) {
987 usbi_dbg("using cached device for device");
988 *cached_out = new_device;
996 usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
998 device = darwin_device_from_service (service);
1000 ret = LIBUSB_ERROR_NO_DEVICE;
1004 if (!(*old_session_id)) {
1005 new_device = calloc (1, sizeof (*new_device));
1007 ret = LIBUSB_ERROR_NO_MEM;
1011 /* add this device to the cached device list */
1012 list_add(&new_device->list, &darwin_cached_devices);
1014 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1016 /* keep a reference to this device */
1017 darwin_ref_cached_device(new_device);
1019 (*device)->GetLocationID (device, &new_device->location);
1020 new_device->port = port;
1021 new_device->parent_session = parent_sessionID;
1024 /* keep track of devices regardless of if we successfully enumerate them to
1025 prevent them from being enumerated multiple times */
1026 *cached_out = new_device;
1028 new_device->session = sessionID;
1029 new_device->device = device;
1031 /* cache the device descriptor */
1032 ret = darwin_cache_device_descriptor(new_device);
1036 if (new_device->can_enumerate) {
1037 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1038 new_device->dev_descriptor.idVendor, new_device->dev_descriptor.idProduct,
1039 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1043 usbi_mutex_unlock(&darwin_cached_devices_lock);
1048 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1049 UInt64 old_session_id) {
1050 struct darwin_device_priv *priv;
1051 struct libusb_device *dev = NULL;
1053 enum libusb_error ret = LIBUSB_SUCCESS;
1056 /* check current active configuration (and cache the first configuration value--
1057 which may be used by claim_interface) */
1058 ret = darwin_check_configuration (ctx, cached_device);
1062 if (0 != old_session_id) {
1063 usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1064 ctx, old_session_id, cached_device->session);
1065 /* save the libusb device before the session id is updated */
1066 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1070 usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
1071 ctx, cached_device->session);
1073 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1075 return LIBUSB_ERROR_NO_MEM;
1078 priv = (struct darwin_device_priv *)dev->os_priv;
1080 priv->dev = cached_device;
1081 darwin_ref_cached_device (priv->dev);
1082 dev->port_number = cached_device->port;
1083 dev->bus_number = cached_device->location >> 24;
1084 assert(cached_device->address <= UINT8_MAX);
1085 dev->device_address = (uint8_t)cached_device->address;
1087 priv = (struct darwin_device_priv *)dev->os_priv;
1090 if (cached_device->parent_session > 0) {
1091 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1093 dev->parent_dev = NULL;
1096 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1099 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1100 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1101 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1102 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
1103 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1105 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1106 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1109 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1112 ret = usbi_sanitize_device (dev);
1116 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
1117 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1121 if (!cached_device->in_reenumerate && 0 == ret) {
1122 usbi_connect_device (dev);
1124 libusb_unref_device (dev);
1130 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1131 struct darwin_cached_device *cached_device;
1132 UInt64 old_session_id;
1133 io_iterator_t deviceIterator;
1134 io_service_t service;
1138 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1139 if (kresult != kIOReturnSuccess)
1140 return darwin_to_libusb (kresult);
1142 while ((service = IOIteratorNext (deviceIterator))) {
1143 ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
1144 if (ret < 0 || !cached_device->can_enumerate) {
1148 (void) process_new_device (ctx, cached_device, old_session_id);
1150 IOObjectRelease(service);
1153 IOObjectRelease(deviceIterator);
1155 return LIBUSB_SUCCESS;
1158 static int darwin_open (struct libusb_device_handle *dev_handle) {
1159 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1160 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1163 if (0 == dpriv->open_count) {
1164 /* try to open the device */
1165 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1166 if (kresult != kIOReturnSuccess) {
1167 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1169 if (kIOReturnExclusiveAccess != kresult) {
1170 return darwin_to_libusb (kresult);
1173 /* it is possible to perform some actions on a device that is not open so do not return an error */
1174 priv->is_open = false;
1176 priv->is_open = true;
1179 /* create async event source */
1180 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1181 if (kresult != kIOReturnSuccess) {
1182 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1184 if (priv->is_open) {
1185 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1188 priv->is_open = false;
1190 return darwin_to_libusb (kresult);
1193 CFRetain (libusb_darwin_acfl);
1195 /* add the cfSource to the aync run loop */
1196 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1199 /* device opened successfully */
1200 dpriv->open_count++;
1202 usbi_dbg ("device open for access");
1207 static void darwin_close (struct libusb_device_handle *dev_handle) {
1208 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1209 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1213 if (dpriv->open_count == 0) {
1214 /* something is probably very wrong if this is the case */
1215 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1219 dpriv->open_count--;
1221 /* make sure all interfaces are released */
1222 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1223 if (dev_handle->claimed_interfaces & (1U << i))
1224 libusb_release_interface (dev_handle, i);
1226 if (0 == dpriv->open_count) {
1227 /* delete the device's async event source */
1228 if (priv->cfSource) {
1229 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1230 CFRelease (priv->cfSource);
1231 priv->cfSource = NULL;
1232 CFRelease (libusb_darwin_acfl);
1235 if (priv->is_open) {
1236 /* close the device */
1237 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1238 if (kresult != kIOReturnSuccess) {
1239 /* Log the fact that we had a problem closing the file, however failing a
1240 * close isn't really an error, so return success anyway */
1241 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1247 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
1248 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1250 *config = (int) dpriv->active_config;
1252 return LIBUSB_SUCCESS;
1255 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1256 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1260 assert(config >= 0 && config <= UINT8_MAX);
1262 /* Setting configuration will invalidate the interface, so we need
1263 to reclaim it. First, dispose of existing interfaces, if any. */
1264 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1265 if (dev_handle->claimed_interfaces & (1U << i))
1266 darwin_release_interface (dev_handle, i);
1268 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1269 if (kresult != kIOReturnSuccess)
1270 return darwin_to_libusb (kresult);
1272 /* Reclaim any interfaces. */
1273 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1274 if (dev_handle->claimed_interfaces & (1U << i))
1275 darwin_claim_interface (dev_handle, i);
1277 dpriv->active_config = (UInt8)config;
1279 return LIBUSB_SUCCESS;
1282 static IOReturn darwin_get_interface (usb_device_t **darwin_device, int ifc, io_service_t *usbInterfacep) {
1283 IOUSBFindInterfaceRequest request;
1285 io_iterator_t interface_iterator;
1286 UInt8 bInterfaceNumber;
1289 *usbInterfacep = IO_OBJECT_NULL;
1291 /* Setup the Interface Request */
1292 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1293 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1294 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1295 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1297 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1298 if (kresult != kIOReturnSuccess)
1301 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1302 /* find the interface number */
1303 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1306 if (ret && bInterfaceNumber == ifc) {
1310 (void) IOObjectRelease (*usbInterfacep);
1313 /* done with the interface iterator */
1314 IOObjectRelease(interface_iterator);
1316 return kIOReturnSuccess;
1319 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1320 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1322 /* current interface */
1323 struct darwin_interface *cInterface = &priv->interfaces[iface];
1327 UInt8 numep, direction, number;
1328 UInt8 dont_care1, dont_care3;
1332 usbi_dbg ("building table of endpoints.");
1334 /* retrieve the total number of endpoints on this interface */
1335 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1336 if (kresult != kIOReturnSuccess) {
1337 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1338 return darwin_to_libusb (kresult);
1341 /* iterate through pipe references */
1342 for (UInt8 i = 1 ; i <= numep ; i++) {
1343 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1344 &dont_care2, &dont_care3);
1346 if (kresult != kIOReturnSuccess) {
1347 /* probably a buggy device. try to get the endpoint address from the descriptors */
1348 struct libusb_config_descriptor *config;
1349 const struct libusb_endpoint_descriptor *endpoint_desc;
1352 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1353 if (kresult != kIOReturnSuccess) {
1354 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1355 return darwin_to_libusb (kresult);
1358 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1359 if (LIBUSB_SUCCESS != rc) {
1363 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1365 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1367 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1370 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1371 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1374 cInterface->num_endpoints = numep;
1376 return LIBUSB_SUCCESS;
1379 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
1380 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1381 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1382 io_service_t usbInterface = IO_OBJECT_NULL;
1384 enum libusb_error ret;
1385 IOCFPlugInInterface **plugInInterface = NULL;
1388 assert(iface >= 0 && iface <= UINT8_MAX);
1390 /* current interface */
1391 struct darwin_interface *cInterface = &priv->interfaces[iface];
1393 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1394 if (kresult != kIOReturnSuccess)
1395 return darwin_to_libusb (kresult);
1397 /* make sure we have an interface */
1398 if (!usbInterface && dpriv->first_config != 0) {
1399 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1401 /* set the configuration */
1402 ret = darwin_set_configuration (dev_handle, dpriv->first_config);
1403 if (ret != LIBUSB_SUCCESS) {
1404 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1408 kresult = darwin_get_interface (dpriv->device, (uint8_t)iface, &usbInterface);
1409 if (kresult != kIOReturnSuccess) {
1410 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1411 return darwin_to_libusb (kresult);
1415 if (!usbInterface) {
1416 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1417 return LIBUSB_ERROR_NOT_FOUND;
1420 /* get an interface to the device's interface */
1421 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1422 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1424 /* ignore release error */
1425 (void)IOObjectRelease (usbInterface);
1427 if (kresult != kIOReturnSuccess) {
1428 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1429 return darwin_to_libusb (kresult);
1432 if (!plugInInterface) {
1433 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1434 return LIBUSB_ERROR_NOT_FOUND;
1437 /* Do the actual claim */
1438 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1439 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1440 (LPVOID)&cInterface->interface);
1441 /* We no longer need the intermediate plug-in */
1442 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1443 (*plugInInterface)->Release (plugInInterface);
1444 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1445 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1446 return darwin_to_libusb (kresult);
1449 /* claim the interface */
1450 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1451 if (kresult != kIOReturnSuccess) {
1452 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1453 return darwin_to_libusb (kresult);
1456 /* update list of endpoints */
1457 ret = get_endpoints (dev_handle, iface);
1459 /* this should not happen */
1460 darwin_release_interface (dev_handle, iface);
1461 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1465 cInterface->cfSource = NULL;
1467 /* create async event source */
1468 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1469 if (kresult != kIOReturnSuccess) {
1470 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1472 /* can't continue without an async event source */
1473 (void)darwin_release_interface (dev_handle, iface);
1475 return darwin_to_libusb (kresult);
1478 /* add the cfSource to the async thread's run loop */
1479 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1481 usbi_dbg ("interface opened");
1483 return LIBUSB_SUCCESS;
1486 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
1487 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1490 /* current interface */
1491 struct darwin_interface *cInterface = &priv->interfaces[iface];
1493 /* Check to see if an interface is open */
1494 if (!cInterface->interface)
1495 return LIBUSB_SUCCESS;
1497 /* clean up endpoint data */
1498 cInterface->num_endpoints = 0;
1500 /* delete the interface's async event source */
1501 if (cInterface->cfSource) {
1502 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1503 CFRelease (cInterface->cfSource);
1506 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1507 if (kresult != kIOReturnSuccess)
1508 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1510 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1511 if (kresult != kIOReturnSuccess)
1512 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1514 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1516 return darwin_to_libusb (kresult);
1519 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
1520 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1522 enum libusb_error ret;
1524 /* current interface */
1525 struct darwin_interface *cInterface = &priv->interfaces[iface];
1527 if (!cInterface->interface)
1528 return LIBUSB_ERROR_NO_DEVICE;
1530 assert(altsetting >= 0 && altsetting <= UINT8_MAX);
1531 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, (UInt8)altsetting);
1532 if (kresult != kIOReturnSuccess)
1533 darwin_reset_device (dev_handle);
1535 /* update list of endpoints */
1536 ret = get_endpoints (dev_handle, iface);
1538 /* this should not happen */
1539 darwin_release_interface (dev_handle, iface);
1540 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1544 return darwin_to_libusb (kresult);
1547 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1548 /* current interface */
1549 struct darwin_interface *cInterface;
1553 /* determine the interface/endpoint to use */
1554 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1555 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1557 return LIBUSB_ERROR_NOT_FOUND;
1560 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1561 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1562 if (kresult != kIOReturnSuccess)
1563 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1565 return darwin_to_libusb (kresult);
1568 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1569 unsigned long claimed_interfaces) {
1570 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1571 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1572 int open_count = dpriv->open_count;
1575 /* clear claimed interfaces temporarily */
1576 dev_handle->claimed_interfaces = 0;
1578 /* close and re-open the device */
1579 priv->is_open = false;
1580 dpriv->open_count = 1;
1582 /* clean up open interfaces */
1583 (void) darwin_close (dev_handle);
1585 /* re-open the device */
1586 ret = darwin_open (dev_handle);
1587 dpriv->open_count = open_count;
1588 if (LIBUSB_SUCCESS != ret) {
1589 /* could not restore configuration */
1590 return LIBUSB_ERROR_NOT_FOUND;
1593 if (dpriv->active_config != active_config) {
1594 usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
1596 ret = darwin_set_configuration (dev_handle, active_config);
1597 if (LIBUSB_SUCCESS != ret) {
1598 usbi_dbg ("darwin/restore_state: could not restore configuration");
1599 return LIBUSB_ERROR_NOT_FOUND;
1603 usbi_dbg ("darwin/restore_state: reclaiming interfaces");
1605 if (claimed_interfaces) {
1606 for (int iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1607 if (!(claimed_interfaces & (1U << iface))) {
1611 usbi_dbg ("darwin/restore_state: re-claiming interface %d", iface);
1613 ret = darwin_claim_interface (dev_handle, iface);
1614 if (LIBUSB_SUCCESS != ret) {
1615 usbi_dbg ("darwin/restore_state: could not claim interface %d", iface);
1616 return LIBUSB_ERROR_NOT_FOUND;
1619 dev_handle->claimed_interfaces |= 1U << iface;
1623 usbi_dbg ("darwin/restore_state: device state restored");
1625 return LIBUSB_SUCCESS;
1628 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1629 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1630 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1631 int8_t active_config = dpriv->active_config;
1632 IOUSBDeviceDescriptor descriptor;
1633 IOUSBConfigurationDescriptorPtr cached_configuration;
1634 IOUSBConfigurationDescriptor *cached_configurations;
1638 if (dpriv->in_reenumerate) {
1639 /* ack, two (or more) threads are trying to reset the device! abort! */
1640 return LIBUSB_ERROR_NOT_FOUND;
1643 dpriv->in_reenumerate = true;
1645 /* store copies of descriptors so they can be compared after the reset */
1646 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1647 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1649 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1650 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1651 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1654 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1655 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, 0);
1656 if (kresult != kIOReturnSuccess) {
1657 usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1658 dpriv->in_reenumerate = false;
1659 return darwin_to_libusb (kresult);
1662 usbi_dbg ("darwin/reset_device: waiting for re-enumeration to complete...");
1664 while (dpriv->in_reenumerate) {
1665 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1666 nanosleep (&delay, NULL);
1669 /* compare descriptors */
1670 usbi_dbg ("darwin/reset_device: checking whether descriptors changed");
1672 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1673 /* device descriptor changed. need to return not found. */
1674 usbi_dbg ("darwin/reset_device: device descriptor changed");
1675 return LIBUSB_ERROR_NOT_FOUND;
1678 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1679 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1680 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1681 usbi_dbg ("darwin/reset_device: configuration descriptor %d changed", i);
1682 return LIBUSB_ERROR_NOT_FOUND;
1686 usbi_dbg ("darwin/reset_device: device reset complete. restoring state...");
1688 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1691 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
1692 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1693 io_service_t usbInterface;
1697 assert(interface >= 0 && interface <= UINT8_MAX);
1698 kresult = darwin_get_interface (dpriv->device, (uint8_t)interface, &usbInterface);
1699 if (kresult != kIOReturnSuccess) {
1700 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1702 return darwin_to_libusb (kresult);
1705 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1706 IOObjectRelease (usbInterface);
1718 static void darwin_destroy_device(struct libusb_device *dev) {
1719 struct darwin_device_priv *dpriv = (struct darwin_device_priv *) dev->os_priv;
1722 /* need to hold the lock in case this is the last reference to the device */
1723 usbi_mutex_lock(&darwin_cached_devices_lock);
1724 darwin_deref_cached_device (dpriv->dev);
1726 usbi_mutex_unlock(&darwin_cached_devices_lock);
1730 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1731 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1734 uint8_t transferType;
1735 /* None of the values below are used in libusbx for bulk transfers */
1736 uint8_t direction, number, interval, pipeRef;
1737 uint16_t maxPacketSize;
1739 struct darwin_interface *cInterface;
1741 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1742 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1744 return LIBUSB_ERROR_NOT_FOUND;
1747 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1748 &transferType, &maxPacketSize, &interval);
1751 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1752 darwin_error_str(ret), ret);
1753 return darwin_to_libusb (ret);
1756 if (0 != (transfer->length % maxPacketSize)) {
1757 /* do not need a zero packet */
1758 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1761 /* submit the request */
1762 /* timeouts are unavailable on interrupt endpoints */
1763 if (transferType == kUSBInterrupt) {
1764 if (IS_XFERIN(transfer))
1765 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1766 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1768 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1769 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
1771 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1773 if (IS_XFERIN(transfer))
1774 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1775 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1776 darwin_async_io_callback, itransfer);
1778 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1779 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
1780 darwin_async_io_callback, itransfer);
1784 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1785 darwin_error_str(ret), ret);
1787 return darwin_to_libusb (ret);
1790 #if InterfaceVersion >= 550
1791 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
1792 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1793 struct darwin_interface *cInterface;
1797 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1798 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1800 return LIBUSB_ERROR_NOT_FOUND;
1803 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1805 if (IS_XFERIN(transfer))
1806 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1807 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1808 transfer->timeout, darwin_async_io_callback, itransfer);
1810 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
1811 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
1812 transfer->timeout, darwin_async_io_callback, itransfer);
1815 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1816 darwin_error_str(ret), ret);
1818 return darwin_to_libusb (ret);
1822 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1823 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1824 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1827 uint8_t direction, number, interval, pipeRef, transferType;
1828 uint16_t maxPacketSize;
1830 AbsoluteTime atTime;
1833 struct darwin_interface *cInterface;
1835 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
1836 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
1837 free(tpriv->isoc_framelist);
1838 tpriv->isoc_framelist = NULL;
1841 if (!tpriv->isoc_framelist) {
1842 tpriv->num_iso_packets = transfer->num_iso_packets;
1843 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1844 if (!tpriv->isoc_framelist)
1845 return LIBUSB_ERROR_NO_MEM;
1848 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1849 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
1850 unsigned int length = transfer->iso_packet_desc[i].length;
1851 assert(length <= UINT16_MAX);
1852 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
1855 /* determine the interface/endpoint to use */
1856 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1857 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1859 return LIBUSB_ERROR_NOT_FOUND;
1862 /* determine the properties of this endpoint and the speed of the device */
1863 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1864 &transferType, &maxPacketSize, &interval);
1866 /* Last but not least we need the bus frame number */
1867 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1868 if (kresult != kIOReturnSuccess) {
1869 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1870 free(tpriv->isoc_framelist);
1871 tpriv->isoc_framelist = NULL;
1873 return darwin_to_libusb (kresult);
1876 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1877 &transferType, &maxPacketSize, &interval);
1879 /* schedule for a frame a little in the future */
1882 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1883 frame = cInterface->frames[transfer->endpoint];
1885 /* submit the request */
1886 if (IS_XFERIN(transfer))
1887 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1888 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1891 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1892 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1895 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
1897 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
1899 /* High/super speed */
1900 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
1902 if (kresult != kIOReturnSuccess) {
1903 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1904 darwin_error_str(kresult));
1905 free (tpriv->isoc_framelist);
1906 tpriv->isoc_framelist = NULL;
1909 return darwin_to_libusb (kresult);
1912 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1913 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1914 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1915 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1916 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1920 memset(&tpriv->req, 0, sizeof(tpriv->req));
1922 /* IOUSBDeviceInterface expects the request in cpu endianness */
1923 tpriv->req.bmRequestType = setup->bmRequestType;
1924 tpriv->req.bRequest = setup->bRequest;
1925 /* these values should be in bus order from libusb_fill_control_setup */
1926 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1927 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1928 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1929 /* data is stored after the libusb control block */
1930 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1931 tpriv->req.completionTimeout = transfer->timeout;
1932 tpriv->req.noDataTimeout = transfer->timeout;
1934 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1936 /* all transfers in libusb-1.0 are async */
1938 if (transfer->endpoint) {
1939 struct darwin_interface *cInterface;
1942 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1943 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1945 return LIBUSB_ERROR_NOT_FOUND;
1948 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1950 /* control request on endpoint 0 */
1951 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1953 if (kresult != kIOReturnSuccess)
1954 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
1956 return darwin_to_libusb (kresult);
1959 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1960 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1962 switch (transfer->type) {
1963 case LIBUSB_TRANSFER_TYPE_CONTROL:
1964 return submit_control_transfer(itransfer);
1965 case LIBUSB_TRANSFER_TYPE_BULK:
1966 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1967 return submit_bulk_transfer(itransfer);
1968 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1969 return submit_iso_transfer(itransfer);
1970 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
1971 #if InterfaceVersion >= 550
1972 return submit_stream_transfer(itransfer);
1974 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
1975 return LIBUSB_ERROR_NOT_SUPPORTED;
1978 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1979 return LIBUSB_ERROR_INVALID_PARAM;
1983 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
1984 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1985 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
1988 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
1991 return LIBUSB_ERROR_NO_DEVICE;
1993 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
1995 return darwin_to_libusb (kresult);
1998 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
1999 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2000 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2001 struct darwin_interface *cInterface;
2002 uint8_t pipeRef, iface;
2005 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2006 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2008 return LIBUSB_ERROR_NOT_FOUND;
2012 return LIBUSB_ERROR_NO_DEVICE;
2014 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2016 /* abort transactions */
2017 #if InterfaceVersion >= 550
2018 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2019 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2022 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2024 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
2026 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2027 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2029 return darwin_to_libusb (kresult);
2032 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2033 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2035 switch (transfer->type) {
2036 case LIBUSB_TRANSFER_TYPE_CONTROL:
2037 return cancel_control_transfer(itransfer);
2038 case LIBUSB_TRANSFER_TYPE_BULK:
2039 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2040 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2041 return darwin_abort_transfers (itransfer);
2043 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2044 return LIBUSB_ERROR_INVALID_PARAM;
2048 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2049 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2050 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2051 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
2053 usbi_dbg ("an async io operation has completed");
2055 /* if requested write a zero packet */
2056 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2057 struct darwin_interface *cInterface;
2060 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2062 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2065 tpriv->result = result;
2066 tpriv->size = (UInt32) (uintptr_t) arg0;
2068 /* signal the core that this transfer is complete */
2069 usbi_signal_transfer_completion(itransfer);
2072 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2073 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2074 result = kIOUSBTransactionTimeout;
2077 case kIOReturnUnderrun:
2078 case kIOReturnSuccess:
2079 return LIBUSB_TRANSFER_COMPLETED;
2080 case kIOReturnAborted:
2081 return LIBUSB_TRANSFER_CANCELLED;
2082 case kIOUSBPipeStalled:
2083 usbi_dbg ("transfer error: pipe is stalled");
2084 return LIBUSB_TRANSFER_STALL;
2085 case kIOReturnOverrun:
2086 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
2087 return LIBUSB_TRANSFER_OVERFLOW;
2088 case kIOUSBTransactionTimeout:
2089 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
2090 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2091 return LIBUSB_TRANSFER_TIMED_OUT;
2093 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2094 return LIBUSB_TRANSFER_ERROR;
2098 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2099 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2100 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
2101 bool isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2102 bool isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
2103 bool isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
2104 bool isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
2107 if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
2108 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2109 return LIBUSB_ERROR_INVALID_PARAM;
2112 usbi_dbg ("handling %s completion with kernel status %d",
2113 isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", tpriv->result);
2115 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result) {
2116 if (isIsoc && tpriv->isoc_framelist) {
2117 /* copy isochronous results back */
2119 for (i = 0; i < transfer->num_iso_packets ; i++) {
2120 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2121 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2122 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2125 itransfer->transferred += tpriv->size;
2128 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2129 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2132 static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
2133 #if !OSX_USE_CLOCK_GETTIME
2134 mach_timespec_t sys_time;
2135 clock_serv_t clock_ref;
2138 case USBI_CLOCK_REALTIME:
2139 /* CLOCK_REALTIME represents time since the epoch */
2140 clock_ref = clock_realtime;
2142 case USBI_CLOCK_MONOTONIC:
2143 /* use system boot time as reference for the monotonic clock */
2144 clock_ref = clock_monotonic;
2147 return LIBUSB_ERROR_INVALID_PARAM;
2150 clock_get_time (clock_ref, &sys_time);
2152 tp->tv_sec = sys_time.tv_sec;
2153 tp->tv_nsec = sys_time.tv_nsec;
2155 return LIBUSB_SUCCESS;
2158 case USBI_CLOCK_MONOTONIC:
2159 return clock_gettime(CLOCK_MONOTONIC, tp);
2160 case USBI_CLOCK_REALTIME:
2161 return clock_gettime(CLOCK_REALTIME, tp);
2163 return LIBUSB_ERROR_INVALID_PARAM;
2168 #if InterfaceVersion >= 550
2169 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2170 int num_endpoints) {
2171 struct darwin_interface *cInterface;
2172 UInt32 supportsStreams;
2176 /* find the mimimum number of supported streams on the endpoint list */
2177 for (i = 0 ; i < num_endpoints ; ++i) {
2178 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2182 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2183 if (num_streams > supportsStreams)
2184 num_streams = supportsStreams;
2187 /* it is an error if any endpoint in endpoints does not support streams */
2188 if (0 == num_streams)
2189 return LIBUSB_ERROR_INVALID_PARAM;
2191 /* create the streams */
2192 for (i = 0 ; i < num_endpoints ; ++i) {
2193 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2195 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2196 if (kIOReturnSuccess != rc)
2197 return darwin_to_libusb(rc);
2200 assert(num_streams <= INT_MAX);
2201 return (int)num_streams;
2204 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2205 struct darwin_interface *cInterface;
2206 UInt32 supportsStreams;
2210 for (int i = 0 ; i < num_endpoints ; ++i) {
2211 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2214 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2215 if (0 == supportsStreams)
2216 return LIBUSB_ERROR_INVALID_PARAM;
2218 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2219 if (kIOReturnSuccess != rc)
2220 return darwin_to_libusb(rc);
2223 return LIBUSB_SUCCESS;
2227 const struct usbi_os_backend usbi_backend = {
2230 .init = darwin_init,
2231 .exit = darwin_exit,
2232 .get_device_descriptor = darwin_get_device_descriptor,
2233 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2234 .get_config_descriptor = darwin_get_config_descriptor,
2235 .hotplug_poll = darwin_hotplug_poll,
2237 .open = darwin_open,
2238 .close = darwin_close,
2239 .get_configuration = darwin_get_configuration,
2240 .set_configuration = darwin_set_configuration,
2241 .claim_interface = darwin_claim_interface,
2242 .release_interface = darwin_release_interface,
2244 .set_interface_altsetting = darwin_set_interface_altsetting,
2245 .clear_halt = darwin_clear_halt,
2246 .reset_device = darwin_reset_device,
2248 #if InterfaceVersion >= 550
2249 .alloc_streams = darwin_alloc_streams,
2250 .free_streams = darwin_free_streams,
2253 .kernel_driver_active = darwin_kernel_driver_active,
2255 .destroy_device = darwin_destroy_device,
2257 .submit_transfer = darwin_submit_transfer,
2258 .cancel_transfer = darwin_cancel_transfer,
2260 .handle_transfer_completion = darwin_handle_transfer_completion,
2262 .clock_gettime = darwin_clock_gettime,
2264 .device_priv_size = sizeof(struct darwin_device_priv),
2265 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2266 .transfer_priv_size = sizeof(struct darwin_transfer_priv),