1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
2 /*
3 * darwin backend for libusb 1.0
4 * Copyright © 2008-2021 Nathan Hjelm <hjelmn@cs.unm.edu>
5 * Copyright © 2019-2021 Google LLC. All rights reserved.
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #include <config.h>
23 #include <assert.h>
24 #include <time.h>
25 #include <ctype.h>
26 #include <pthread.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/sysctl.h>
34
35 #include <mach/clock.h>
36 #include <mach/clock_types.h>
37 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
39
40 /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector
41 * function. Its use is also conditionalized to only older deployment targets. */
42 #define OBJC_SILENCE_GC_DEPRECATIONS 1
43
44 /* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate
45 * does not return error status on macOS. */
46 #define DARWIN_REENUMERATE_TIMEOUT_US (10 * USEC_PER_SEC)
47
48 #include <AvailabilityMacros.h>
49 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
50 #include <objc/objc-auto.h>
51 #endif
52
53 #include "darwin_usb.h"
54
55 static int init_count = 0;
56
57 /* Both kIOMasterPortDefault or kIOMainPortDefault are synonyms for 0. */
58 static const mach_port_t darwin_default_master_port = 0;
59
60 /* async event thread */
61 static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
62 static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
63
64 #if !defined(HAVE_CLOCK_GETTIME)
65 static clock_serv_t clock_realtime;
66 static clock_serv_t clock_monotonic;
67 #endif
68
69 #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1)
70
71 static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
72 static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
73
74 static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
75 static struct list_head darwin_cached_devices;
76 static const char *darwin_device_class = "IOUSBDevice";
77
78 #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev)
79
80 /* async event thread */
81 static pthread_t libusb_darwin_at;
82
83 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
84 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
85 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
86 static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bool capture);
87 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint);
88 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
89 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface);
90 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
91
92 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx);
93 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
94 UInt64 old_session_id);
95
96 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
97 UInt64 *old_session_id);
98
99 #if defined(ENABLE_LOGGING)
darwin_error_str(IOReturn result)100 static const char *darwin_error_str (IOReturn result) {
101 static char string_buffer[50];
102 switch (result) {
103 case kIOReturnSuccess:
104 return "no error";
105 case kIOReturnNotOpen:
106 return "device not opened for exclusive access";
107 case kIOReturnNoDevice:
108 return "no connection to an IOService";
109 case kIOUSBNoAsyncPortErr:
110 return "no async port has been opened for interface";
111 case kIOReturnExclusiveAccess:
112 return "another process has device opened for exclusive access";
113 case kIOUSBPipeStalled:
114 #if defined(kUSBHostReturnPipeStalled)
115 case kUSBHostReturnPipeStalled:
116 #endif
117 return "pipe is stalled";
118 case kIOReturnError:
119 return "could not establish a connection to the Darwin kernel";
120 case kIOUSBTransactionTimeout:
121 return "transaction timed out";
122 case kIOReturnBadArgument:
123 return "invalid argument";
124 case kIOReturnAborted:
125 return "transaction aborted";
126 case kIOReturnNotResponding:
127 return "device not responding";
128 case kIOReturnOverrun:
129 return "data overrun";
130 case kIOReturnCannotWire:
131 return "physical memory can not be wired down";
132 case kIOReturnNoResources:
133 return "out of resources";
134 case kIOUSBHighSpeedSplitError:
135 return "high speed split error";
136 case kIOUSBUnknownPipeErr:
137 return "pipe ref not recognized";
138 default:
139 snprintf(string_buffer, sizeof(string_buffer), "unknown error (0x%x)", result);
140 return string_buffer;
141 }
142 }
143 #endif
144
darwin_to_libusb(IOReturn result)145 static enum libusb_error darwin_to_libusb (IOReturn result) {
146 switch (result) {
147 case kIOReturnUnderrun:
148 case kIOReturnSuccess:
149 return LIBUSB_SUCCESS;
150 case kIOReturnNotOpen:
151 case kIOReturnNoDevice:
152 return LIBUSB_ERROR_NO_DEVICE;
153 case kIOReturnExclusiveAccess:
154 return LIBUSB_ERROR_ACCESS;
155 case kIOUSBPipeStalled:
156 #if defined(kUSBHostReturnPipeStalled)
157 case kUSBHostReturnPipeStalled:
158 #endif
159 return LIBUSB_ERROR_PIPE;
160 case kIOReturnBadArgument:
161 return LIBUSB_ERROR_INVALID_PARAM;
162 case kIOUSBTransactionTimeout:
163 return LIBUSB_ERROR_TIMEOUT;
164 case kIOUSBUnknownPipeErr:
165 return LIBUSB_ERROR_NOT_FOUND;
166 case kIOReturnNotResponding:
167 case kIOReturnAborted:
168 case kIOReturnError:
169 case kIOUSBNoAsyncPortErr:
170 default:
171 return LIBUSB_ERROR_OTHER;
172 }
173 }
174
175 /* this function must be called with the darwin_cached_devices_lock held */
darwin_deref_cached_device(struct darwin_cached_device * cached_dev)176 static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
177 cached_dev->refcount--;
178 /* free the device and remove it from the cache */
179 if (0 == cached_dev->refcount) {
180 list_del(&cached_dev->list);
181
182 if (cached_dev->device) {
183 (*(cached_dev->device))->Release(cached_dev->device);
184 cached_dev->device = NULL;
185 }
186 IOObjectRelease (cached_dev->service);
187 free (cached_dev);
188 }
189 }
190
darwin_ref_cached_device(struct darwin_cached_device * cached_dev)191 static void darwin_ref_cached_device(struct darwin_cached_device *cached_dev) {
192 cached_dev->refcount++;
193 }
194
ep_to_pipeRef(struct libusb_device_handle * dev_handle,uint8_t ep,uint8_t * pipep,uint8_t * ifcp,struct darwin_interface ** interface_out)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 = usbi_get_device_handle_priv(dev_handle);
197
198 /* current interface */
199 struct darwin_interface *cInterface;
200
201 uint8_t i, iface;
202
203 struct libusb_context *ctx = HANDLE_CTX(dev_handle);
204
205 usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
206
207 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
208 cInterface = &priv->interfaces[iface];
209
210 if (dev_handle->claimed_interfaces & (1U << iface)) {
211 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
212 if (cInterface->endpoint_addrs[i] == ep) {
213 *pipep = i + 1;
214
215 if (ifcp)
216 *ifcp = iface;
217
218 if (interface_out)
219 *interface_out = cInterface;
220
221 usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
222 return LIBUSB_SUCCESS;
223 }
224 }
225 }
226 }
227
228 /* No pipe found with the correct endpoint address */
229 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
230
231 return LIBUSB_ERROR_NOT_FOUND;
232 }
233
usb_setup_device_iterator(io_iterator_t * deviceIterator,UInt32 location)234 static IOReturn usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
235 CFMutableDictionaryRef matchingDict = IOServiceMatching(darwin_device_class);
236
237 if (!matchingDict)
238 return kIOReturnError;
239
240 if (location) {
241 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
242 &kCFTypeDictionaryKeyCallBacks,
243 &kCFTypeDictionaryValueCallBacks);
244
245 /* there are no unsigned CFNumber types so treat the value as signed. the OS seems to do this
246 internally (CFNumberType of locationID is kCFNumberSInt32Type) */
247 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
248
249 if (propertyMatchDict && locationCF) {
250 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
251 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
252 }
253 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
254
255 /* release our references as per the Create Rule */
256 if (propertyMatchDict)
257 CFRelease (propertyMatchDict);
258 if (locationCF)
259 CFRelease (locationCF);
260 }
261
262 return IOServiceGetMatchingServices(darwin_default_master_port, matchingDict, deviceIterator);
263 }
264
265 /* Returns 1 on success, 0 on failure. */
get_ioregistry_value_number(io_service_t service,CFStringRef property,CFNumberType type,void * p)266 static bool get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
267 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
268 Boolean success = 0;
269
270 if (cfNumber) {
271 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
272 success = CFNumberGetValue(cfNumber, type, p);
273 }
274
275 CFRelease (cfNumber);
276 }
277
278 return (success != 0);
279 }
280
281 /* Returns 1 on success, 0 on failure. */
get_ioregistry_value_data(io_service_t service,CFStringRef property,ssize_t size,void * p)282 static bool get_ioregistry_value_data (io_service_t service, CFStringRef property, ssize_t size, void *p) {
283 CFTypeRef cfData = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
284 bool success = false;
285
286 if (cfData) {
287 if (CFGetTypeID (cfData) == CFDataGetTypeID ()) {
288 CFIndex length = CFDataGetLength (cfData);
289 if (length < size) {
290 size = length;
291 }
292
293 CFDataGetBytes (cfData, CFRangeMake(0, size), p);
294 success = true;
295 }
296
297 CFRelease (cfData);
298 }
299
300 return success;
301 }
302
darwin_device_from_service(struct libusb_context * ctx,io_service_t service)303 static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
304 {
305 io_cf_plugin_ref_t *plugInInterface = NULL;
306 usb_device_t **device;
307 IOReturn kresult;
308 SInt32 score;
309 const int max_retries = 5;
310
311 /* The IOCreatePlugInInterfaceForService function might consistently return
312 an "out of resources" error with certain USB devices the first time we run
313 it. The reason is still unclear, but retrying fixes the problem */
314 for (int count = 0; count < max_retries; count++) {
315 kresult = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID,
316 kIOCFPlugInInterfaceID, &plugInInterface,
317 &score);
318 if (kIOReturnSuccess == kresult && plugInInterface) {
319 break;
320 }
321
322 usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
323
324 /* sleep for a little while before trying again */
325 nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
326 }
327
328 if (kIOReturnSuccess != kresult || !plugInInterface) {
329 usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
330 return NULL;
331 }
332
333 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
334 (LPVOID)&device);
335 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
336 (*plugInInterface)->Release (plugInInterface);
337
338 return device;
339 }
340
darwin_devices_attached(void * ptr,io_iterator_t add_devices)341 static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
342 UNUSED(ptr);
343 struct darwin_cached_device *cached_device;
344 UInt64 old_session_id;
345 struct libusb_context *ctx;
346 io_service_t service;
347 int ret;
348
349 usbi_mutex_lock(&active_contexts_lock);
350
351 while ((service = IOIteratorNext(add_devices))) {
352 ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
353 if (ret < 0 || !cached_device->can_enumerate) {
354 continue;
355 }
356
357 /* add this device to each active context's device list */
358 for_each_context(ctx) {
359 process_new_device (ctx, cached_device, old_session_id);
360 }
361
362 if (cached_device->in_reenumerate) {
363 usbi_dbg (NULL, "cached device in reset state. reset complete...");
364 cached_device->in_reenumerate = false;
365 }
366
367 IOObjectRelease(service);
368 }
369
370 usbi_mutex_unlock(&active_contexts_lock);
371 }
372
darwin_devices_detached(void * ptr,io_iterator_t rem_devices)373 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
374 UNUSED(ptr);
375 struct libusb_device *dev = NULL;
376 struct libusb_context *ctx;
377 struct darwin_cached_device *old_device;
378
379 io_service_t device;
380 UInt64 session, locationID;
381 int ret;
382
383 usbi_mutex_lock(&active_contexts_lock);
384
385 while ((device = IOIteratorNext (rem_devices)) != 0) {
386 bool is_reenumerating = false;
387
388 /* get the location from the i/o registry */
389 ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session);
390 (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
391 IOObjectRelease (device);
392 if (!ret)
393 continue;
394
395 /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
396 otherwise no cached device will ever get freed */
397 usbi_mutex_lock(&darwin_cached_devices_lock);
398 list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
399 if (old_device->session == session) {
400 if (old_device->in_reenumerate) {
401 /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
402 * will deref if needed. */
403 usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
404 session, locationID);
405
406 /* the device object is no longer usable so go ahead and release it */
407 if (old_device->device) {
408 (*(old_device->device))->Release(old_device->device);
409 old_device->device = NULL;
410 }
411
412 is_reenumerating = true;
413 } else {
414 darwin_deref_cached_device (old_device);
415 }
416
417 break;
418 }
419 }
420
421 usbi_mutex_unlock(&darwin_cached_devices_lock);
422 if (is_reenumerating) {
423 continue;
424 }
425
426 for_each_context(ctx) {
427 usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
428
429 dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
430 if (dev) {
431 /* signal the core that this device has been disconnected. the core will tear down this device
432 when the reference count reaches 0 */
433 usbi_disconnect_device(dev);
434 libusb_unref_device(dev);
435 }
436 }
437 }
438
439 usbi_mutex_unlock(&active_contexts_lock);
440 }
441
darwin_hotplug_poll(void)442 static void darwin_hotplug_poll (void)
443 {
444 /* not sure if 1 ms will be too long/short but it should work ok */
445 mach_timespec_t timeout = {.tv_sec = 0, .tv_nsec = 1000000ul};
446
447 /* since a kernel thread may notify the IOIterators used for
448 * hotplug notification we can't just clear the iterators.
449 * instead just wait until all IOService providers are quiet */
450 (void) IOKitWaitQuiet (darwin_default_master_port, &timeout);
451 }
452
darwin_clear_iterator(io_iterator_t iter)453 static void darwin_clear_iterator (io_iterator_t iter) {
454 io_service_t device;
455
456 while ((device = IOIteratorNext (iter)) != 0)
457 IOObjectRelease (device);
458 }
459
darwin_fail_startup(void)460 static void darwin_fail_startup(void) {
461 pthread_mutex_lock (&libusb_darwin_at_mutex);
462 libusb_darwin_acfl = LIBUSB_DARWIN_STARTUP_FAILURE;
463 pthread_cond_signal (&libusb_darwin_at_cond);
464 pthread_mutex_unlock (&libusb_darwin_at_mutex);
465 pthread_exit (NULL);
466 }
467
darwin_event_thread_main(void * arg0)468 static void *darwin_event_thread_main (void *arg0) {
469 IOReturn kresult;
470 struct libusb_context *ctx = (struct libusb_context *)arg0;
471 CFRunLoopRef runloop;
472 CFRunLoopSourceRef libusb_shutdown_cfsource;
473 CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
474
475 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
476 /* Set this thread's name, so it can be seen in the debugger
477 and crash reports. */
478 pthread_setname_np ("org.libusb.device-hotplug");
479 #endif
480
481 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200
482 /* Tell the Objective-C garbage collector about this thread.
483 This is required because, unlike NSThreads, pthreads are
484 not automatically registered. Although we don't use
485 Objective-C, we use CoreFoundation, which does.
486 Garbage collection support was entirely removed in 10.12,
487 so don't bother there. */
488 objc_registerThreadWithCollector();
489 #endif
490
491 /* hotplug (device arrival/removal) sources */
492 CFRunLoopSourceRef libusb_notification_cfsource;
493 io_notification_port_t libusb_notification_port;
494 io_iterator_t libusb_rem_device_iterator;
495 io_iterator_t libusb_add_device_iterator;
496
497 /* ctx must only be used for logging during thread startup */
498 usbi_dbg (ctx, "creating hotplug event source");
499
500 runloop = CFRunLoopGetCurrent ();
501 CFRetain (runloop);
502
503 /* add the shutdown cfsource to the run loop */
504 memset(&libusb_shutdown_cfsourcectx, 0, sizeof(libusb_shutdown_cfsourcectx));
505 libusb_shutdown_cfsourcectx.info = runloop;
506 libusb_shutdown_cfsourcectx.perform = (void (*)(void *))CFRunLoopStop;
507 libusb_shutdown_cfsource = CFRunLoopSourceCreate(NULL, 0, &libusb_shutdown_cfsourcectx);
508 CFRunLoopAddSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
509
510 /* add the notification port to the run loop */
511 libusb_notification_port = IONotificationPortCreate (darwin_default_master_port);
512 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
513 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
514
515 /* create notifications for removed devices */
516 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
517 IOServiceMatching(darwin_device_class),
518 darwin_devices_detached,
519 NULL, &libusb_rem_device_iterator);
520
521 if (kresult != kIOReturnSuccess) {
522 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
523 CFRelease (libusb_shutdown_cfsource);
524 CFRelease (runloop);
525 darwin_fail_startup ();
526 }
527
528 /* create notifications for attached devices */
529 kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
530 IOServiceMatching(darwin_device_class),
531 darwin_devices_attached,
532 NULL, &libusb_add_device_iterator);
533
534 if (kresult != kIOReturnSuccess) {
535 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
536 CFRelease (libusb_shutdown_cfsource);
537 CFRelease (runloop);
538 darwin_fail_startup ();
539 }
540
541 /* arm notifiers */
542 darwin_clear_iterator (libusb_rem_device_iterator);
543 darwin_clear_iterator (libusb_add_device_iterator);
544
545 usbi_dbg (ctx, "darwin event thread ready to receive events");
546
547 /* signal the main thread that the hotplug runloop has been created. */
548 pthread_mutex_lock (&libusb_darwin_at_mutex);
549 libusb_darwin_acfl = runloop;
550 libusb_darwin_acfls = libusb_shutdown_cfsource;
551 pthread_cond_signal (&libusb_darwin_at_cond);
552 pthread_mutex_unlock (&libusb_darwin_at_mutex);
553
554 /* run the runloop */
555 CFRunLoopRun();
556
557 usbi_dbg (NULL, "darwin event thread exiting");
558
559 /* signal the main thread that the hotplug runloop has finished. */
560 pthread_mutex_lock (&libusb_darwin_at_mutex);
561 libusb_darwin_acfls = NULL;
562 libusb_darwin_acfl = NULL;
563 pthread_cond_signal (&libusb_darwin_at_cond);
564 pthread_mutex_unlock (&libusb_darwin_at_mutex);
565
566 /* remove the notification cfsource */
567 CFRunLoopRemoveSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
568
569 /* remove the shutdown cfsource */
570 CFRunLoopRemoveSource(runloop, libusb_shutdown_cfsource, kCFRunLoopDefaultMode);
571
572 /* delete notification port */
573 IONotificationPortDestroy (libusb_notification_port);
574
575 /* delete iterators */
576 IOObjectRelease (libusb_rem_device_iterator);
577 IOObjectRelease (libusb_add_device_iterator);
578
579 CFRelease (libusb_shutdown_cfsource);
580 CFRelease (runloop);
581
582 pthread_exit (NULL);
583 }
584
585 /* cleanup function to destroy cached devices */
darwin_cleanup_devices(void)586 static void darwin_cleanup_devices(void) {
587 struct darwin_cached_device *dev, *next;
588
589 list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
590 darwin_deref_cached_device(dev);
591 }
592 }
593
darwin_init(struct libusb_context * ctx)594 static int darwin_init(struct libusb_context *ctx) {
595 bool first_init;
596 int rc;
597
598 first_init = (1 == ++init_count);
599
600 do {
601 if (first_init) {
602 if (NULL == darwin_cached_devices.next) {
603 list_init (&darwin_cached_devices);
604 }
605 assert(list_empty(&darwin_cached_devices));
606 #if !defined(HAVE_CLOCK_GETTIME)
607 /* create the clocks that will be used if clock_gettime() is not available */
608 host_name_port_t host_self;
609
610 host_self = mach_host_self();
611 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
612 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
613 mach_port_deallocate(mach_task_self(), host_self);
614 #endif
615 }
616
617 rc = darwin_scan_devices (ctx);
618 if (LIBUSB_SUCCESS != rc)
619 break;
620
621 if (first_init) {
622 rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
623 if (0 != rc) {
624 usbi_err (ctx, "could not create event thread, error %d", rc);
625 rc = LIBUSB_ERROR_OTHER;
626 break;
627 }
628
629 pthread_mutex_lock (&libusb_darwin_at_mutex);
630 while (!libusb_darwin_acfl)
631 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
632 if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
633 libusb_darwin_acfl = NULL;
634 rc = LIBUSB_ERROR_OTHER;
635 }
636 pthread_mutex_unlock (&libusb_darwin_at_mutex);
637
638 if (0 != rc)
639 pthread_join (libusb_darwin_at, NULL);
640 }
641 } while (0);
642
643 if (LIBUSB_SUCCESS != rc) {
644 if (first_init) {
645 darwin_cleanup_devices ();
646 #if !defined(HAVE_CLOCK_GETTIME)
647 mach_port_deallocate(mach_task_self(), clock_realtime);
648 mach_port_deallocate(mach_task_self(), clock_monotonic);
649 #endif
650 }
651 --init_count;
652 }
653
654 return rc;
655 }
656
darwin_exit(struct libusb_context * ctx)657 static void darwin_exit (struct libusb_context *ctx) {
658 UNUSED(ctx);
659
660 if (0 == --init_count) {
661 /* stop the event runloop and wait for the thread to terminate. */
662 pthread_mutex_lock (&libusb_darwin_at_mutex);
663 CFRunLoopSourceSignal (libusb_darwin_acfls);
664 CFRunLoopWakeUp (libusb_darwin_acfl);
665 while (libusb_darwin_acfl)
666 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
667 pthread_mutex_unlock (&libusb_darwin_at_mutex);
668 pthread_join (libusb_darwin_at, NULL);
669
670 darwin_cleanup_devices ();
671
672 #if !defined(HAVE_CLOCK_GETTIME)
673 mach_port_deallocate(mach_task_self(), clock_realtime);
674 mach_port_deallocate(mach_task_self(), clock_monotonic);
675 #endif
676 }
677 }
678
get_configuration_index(struct libusb_device * dev,UInt8 config_value)679 static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
680 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
681 UInt8 i, numConfig;
682 IOUSBConfigurationDescriptorPtr desc;
683 IOReturn kresult;
684
685 /* is there a simpler way to determine the index? */
686 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
687 if (kresult != kIOReturnSuccess)
688 return darwin_to_libusb (kresult);
689
690 for (i = 0 ; i < numConfig ; i++) {
691 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
692
693 if (desc->bConfigurationValue == config_value)
694 return i;
695 }
696
697 /* configuration not found */
698 return LIBUSB_ERROR_NOT_FOUND;
699 }
700
darwin_get_active_config_descriptor(struct libusb_device * dev,void * buffer,size_t len)701 static int darwin_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len) {
702 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
703 int config_index;
704
705 if (0 == priv->active_config)
706 return LIBUSB_ERROR_NOT_FOUND;
707
708 config_index = get_configuration_index (dev, priv->active_config);
709 if (config_index < 0)
710 return config_index;
711
712 assert(config_index >= 0 && config_index <= UINT8_MAX);
713 return darwin_get_config_descriptor (dev, (UInt8)config_index, buffer, len);
714 }
715
darwin_get_config_descriptor(struct libusb_device * dev,uint8_t config_index,void * buffer,size_t len)716 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len) {
717 struct darwin_cached_device *priv = DARWIN_CACHED_DEVICE(dev);
718 IOUSBConfigurationDescriptorPtr desc;
719 IOReturn kresult;
720 int ret;
721
722 if (!priv || !priv->device)
723 return LIBUSB_ERROR_OTHER;
724
725 kresult = (*priv->device)->GetConfigurationDescriptorPtr (priv->device, config_index, &desc);
726 if (kresult == kIOReturnSuccess) {
727 /* copy descriptor */
728 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
729 len = libusb_le16_to_cpu(desc->wTotalLength);
730
731 memmove (buffer, desc, len);
732 }
733
734 ret = darwin_to_libusb (kresult);
735 if (ret != LIBUSB_SUCCESS)
736 return ret;
737
738 return (int) len;
739 }
740
741 /* check whether the os has configured the device */
darwin_check_configuration(struct libusb_context * ctx,struct darwin_cached_device * dev)742 static enum libusb_error darwin_check_configuration (struct libusb_context *ctx, struct darwin_cached_device *dev) {
743 usb_device_t **darwin_device = dev->device;
744
745 IOUSBConfigurationDescriptorPtr configDesc;
746 IOUSBFindInterfaceRequest request;
747 IOReturn kresult;
748 io_iterator_t interface_iterator;
749 io_service_t firstInterface;
750
751 if (dev->dev_descriptor.bNumConfigurations < 1) {
752 usbi_err (ctx, "device has no configurations");
753 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
754 }
755
756 /* checking the configuration of a root hub simulation takes ~1 s in 10.11. the device is
757 not usable anyway */
758 if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
759 0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
760 usbi_dbg (ctx, "ignoring configuration on root hub simulation");
761 dev->active_config = 0;
762 return LIBUSB_SUCCESS;
763 }
764
765 /* find the first configuration */
766 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
767 dev->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
768
769 /* check if the device is already configured. there is probably a better way than iterating over the
770 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
771 might lock up on the device request) */
772
773 /* Setup the Interface Request */
774 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
775 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
776 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
777 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
778
779 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
780 if (kresult != kIOReturnSuccess)
781 return darwin_to_libusb (kresult);
782
783 /* iterate once */
784 firstInterface = IOIteratorNext(interface_iterator);
785
786 /* done with the interface iterator */
787 IOObjectRelease(interface_iterator);
788
789 if (firstInterface) {
790 IOObjectRelease (firstInterface);
791
792 /* device is configured */
793 if (dev->dev_descriptor.bNumConfigurations == 1)
794 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
795 dev->active_config = dev->first_config;
796 else
797 /* devices with more than one configuration should work with GetConfiguration */
798 (*darwin_device)->GetConfiguration (darwin_device, &dev->active_config);
799 } else
800 /* not configured */
801 dev->active_config = 0;
802
803 usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
804
805 return LIBUSB_SUCCESS;
806 }
807
darwin_request_descriptor(usb_device_t ** device,UInt8 desc,UInt8 desc_index,void * buffer,size_t buffer_size)808 static IOReturn darwin_request_descriptor (usb_device_t **device, UInt8 desc, UInt8 desc_index, void *buffer, size_t buffer_size) {
809 IOUSBDevRequestTO req;
810
811 assert(buffer_size <= UINT16_MAX);
812
813 memset (buffer, 0, buffer_size);
814
815 /* Set up request for descriptor/ */
816 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
817 req.bRequest = kUSBRqGetDescriptor;
818 req.wValue = (UInt16)(desc << 8);
819 req.wIndex = desc_index;
820 req.wLength = (UInt16)buffer_size;
821 req.pData = buffer;
822 req.noDataTimeout = 20;
823 req.completionTimeout = 100;
824
825 return (*device)->DeviceRequestTO (device, &req);
826 }
827
darwin_cache_device_descriptor(struct libusb_context * ctx,struct darwin_cached_device * dev)828 static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
829 usb_device_t **device = dev->device;
830 int retries = 1;
831 long delay = 30000; // microseconds
832 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
833 int is_open = 0;
834 IOReturn ret = 0, ret2;
835 UInt8 bDeviceClass;
836 UInt16 idProduct, idVendor;
837
838 dev->can_enumerate = 0;
839
840 (*device)->GetDeviceClass (device, &bDeviceClass);
841 (*device)->GetDeviceProduct (device, &idProduct);
842 (*device)->GetDeviceVendor (device, &idVendor);
843
844 /* According to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
845 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
846 * to follow the spec as closely as possible, try opening the device */
847 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
848
849 do {
850 /**** retrieve device descriptor ****/
851 ret = darwin_request_descriptor (device, kUSBDeviceDesc, 0, &dev->dev_descriptor, sizeof(dev->dev_descriptor));
852
853 if (kIOReturnOverrun == ret && kUSBDeviceDesc == dev->dev_descriptor.bDescriptorType)
854 /* received an overrun error but we still received a device descriptor */
855 ret = kIOReturnSuccess;
856
857 if (kIOUSBVendorIDAppleComputer == idVendor) {
858 /* NTH: don't bother retrying or unsuspending Apple devices */
859 break;
860 }
861
862 if (kIOReturnSuccess == ret && (0 == dev->dev_descriptor.bNumConfigurations ||
863 0 == dev->dev_descriptor.bcdUSB)) {
864 /* work around for incorrectly configured devices */
865 if (try_reconfigure && is_open) {
866 usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
867
868 /* set the first configuration */
869 (*device)->SetConfiguration(device, 1);
870
871 /* don't try to reconfigure again */
872 try_reconfigure = 0;
873 }
874
875 ret = kIOUSBPipeStalled;
876 }
877
878 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
879 /* device may be suspended. unsuspend it and try again */
880 #if DeviceVersion >= 320
881 UInt32 info = 0;
882
883 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
884 (void)(*device)->GetUSBDeviceInformation (device, &info);
885
886 /* note that the device was suspended */
887 if (info & (1U << kUSBInformationDeviceIsSuspendedBit) || 0 == info)
888 try_unsuspend = 1;
889 #endif
890
891 if (try_unsuspend) {
892 /* try to unsuspend the device */
893 ret2 = (*device)->USBDeviceSuspend (device, 0);
894 if (kIOReturnSuccess != ret2) {
895 /* prevent log spew from poorly behaving devices. this indicates the
896 os actually had trouble communicating with the device */
897 usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
898 } else
899 unsuspended = 1;
900
901 try_unsuspend = 0;
902 }
903 }
904
905 if (kIOReturnSuccess != ret) {
906 usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
907 /* sleep for a little while before trying again */
908 nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
909 }
910 } while (kIOReturnSuccess != ret && retries--);
911
912 if (unsuspended)
913 /* resuspend the device */
914 (void)(*device)->USBDeviceSuspend (device, 1);
915
916 if (is_open)
917 (void) (*device)->USBDeviceClose (device);
918
919 if (ret != kIOReturnSuccess) {
920 /* a debug message was already printed out for this error */
921 if (LIBUSB_CLASS_HUB == bDeviceClass)
922 usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
923 idVendor, idProduct, darwin_error_str (ret), ret);
924 else
925 usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
926 idVendor, idProduct, darwin_error_str (ret), ret);
927 return darwin_to_libusb (ret);
928 }
929
930 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
931 if (libusb_le16_to_cpu (dev->dev_descriptor.idProduct) != idProduct) {
932 /* not a valid device */
933 usbi_warn (NULL, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
934 idProduct, libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
935 return LIBUSB_ERROR_NO_DEVICE;
936 }
937
938 usbi_dbg (ctx, "cached device descriptor:");
939 usbi_dbg (ctx, " bDescriptorType: 0x%02x", dev->dev_descriptor.bDescriptorType);
940 usbi_dbg (ctx, " bcdUSB: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
941 usbi_dbg (ctx, " bDeviceClass: 0x%02x", dev->dev_descriptor.bDeviceClass);
942 usbi_dbg (ctx, " bDeviceSubClass: 0x%02x", dev->dev_descriptor.bDeviceSubClass);
943 usbi_dbg (ctx, " bDeviceProtocol: 0x%02x", dev->dev_descriptor.bDeviceProtocol);
944 usbi_dbg (ctx, " bMaxPacketSize0: 0x%02x", dev->dev_descriptor.bMaxPacketSize0);
945 usbi_dbg (ctx, " idVendor: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
946 usbi_dbg (ctx, " idProduct: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
947 usbi_dbg (ctx, " bcdDevice: 0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
948 usbi_dbg (ctx, " iManufacturer: 0x%02x", dev->dev_descriptor.iManufacturer);
949 usbi_dbg (ctx, " iProduct: 0x%02x", dev->dev_descriptor.iProduct);
950 usbi_dbg (ctx, " iSerialNumber: 0x%02x", dev->dev_descriptor.iSerialNumber);
951 usbi_dbg (ctx, " bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
952
953 dev->can_enumerate = 1;
954
955 return LIBUSB_SUCCESS;
956 }
957
958 /* Returns 1 on success, 0 on failure. */
get_device_port(io_service_t service,UInt8 * port)959 static bool get_device_port (io_service_t service, UInt8 *port) {
960 IOReturn kresult;
961 io_service_t parent;
962 bool ret = false;
963
964 if (get_ioregistry_value_number (service, CFSTR("PortNum"), kCFNumberSInt8Type, port)) {
965 return true;
966 }
967
968 kresult = IORegistryEntryGetParentEntry (service, kIOServicePlane, &parent);
969 if (kIOReturnSuccess == kresult) {
970 ret = get_ioregistry_value_data (parent, CFSTR("port"), 1, port);
971 IOObjectRelease (parent);
972 }
973
974 return ret;
975 }
976
977 /* Returns 1 on success, 0 on failure. */
get_device_parent_sessionID(io_service_t service,UInt64 * parent_sessionID)978 static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) {
979 IOReturn kresult;
980 io_service_t parent;
981
982 /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */
983 parent = service;
984 while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) {
985 if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) {
986 /* Success */
987 return true;
988 }
989 }
990
991 /* We ran out of parents */
992 return false;
993 }
994
darwin_get_cached_device(struct libusb_context * ctx,io_service_t service,struct darwin_cached_device ** cached_out,UInt64 * old_session_id)995 static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
996 UInt64 *old_session_id) {
997 struct darwin_cached_device *new_device;
998 UInt64 sessionID = 0, parent_sessionID = 0;
999 UInt32 locationID = 0;
1000 enum libusb_error ret = LIBUSB_SUCCESS;
1001 usb_device_t **device;
1002 UInt8 port = 0;
1003
1004 /* assuming sessionID != 0 normally (never seen it be 0) */
1005 *old_session_id = 0;
1006 *cached_out = NULL;
1007
1008 /* get some info from the io registry */
1009 (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
1010 (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
1011 if (!get_device_port (service, &port)) {
1012 usbi_dbg(ctx, "could not get connected port number");
1013 }
1014
1015 usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
1016
1017 if (get_device_parent_sessionID(service, &parent_sessionID)) {
1018 usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
1019 }
1020
1021 usbi_mutex_lock(&darwin_cached_devices_lock);
1022 do {
1023 list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
1024 usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
1025 sessionID, locationID, new_device->session, new_device->location);
1026 if (new_device->location == locationID && new_device->in_reenumerate) {
1027 usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
1028 *old_session_id = new_device->session;
1029 break;
1030 }
1031
1032 if (new_device->session == sessionID) {
1033 usbi_dbg(ctx, "using cached device for device");
1034 *cached_out = new_device;
1035 break;
1036 }
1037 }
1038
1039 if (*cached_out)
1040 break;
1041
1042 usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
1043
1044 device = darwin_device_from_service (ctx, service);
1045 if (!device) {
1046 ret = LIBUSB_ERROR_NO_DEVICE;
1047 break;
1048 }
1049
1050 if (!(*old_session_id)) {
1051 new_device = calloc (1, sizeof (*new_device));
1052 if (!new_device) {
1053 ret = LIBUSB_ERROR_NO_MEM;
1054 break;
1055 }
1056
1057 /* add this device to the cached device list */
1058 list_add(&new_device->list, &darwin_cached_devices);
1059
1060 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&new_device->address);
1061
1062 /* keep a reference to this device */
1063 darwin_ref_cached_device(new_device);
1064
1065 (*device)->GetLocationID (device, &new_device->location);
1066 new_device->port = port;
1067 new_device->parent_session = parent_sessionID;
1068 } else {
1069 /* release the ref to old device's service */
1070 IOObjectRelease (new_device->service);
1071 }
1072
1073 /* keep track of devices regardless of if we successfully enumerate them to
1074 prevent them from being enumerated multiple times */
1075 *cached_out = new_device;
1076
1077 new_device->session = sessionID;
1078 new_device->device = device;
1079 new_device->service = service;
1080
1081 /* retain the service */
1082 IOObjectRetain (service);
1083
1084 /* cache the device descriptor */
1085 ret = darwin_cache_device_descriptor(ctx, new_device);
1086 if (ret)
1087 break;
1088
1089 if (new_device->can_enumerate) {
1090 snprintf(new_device->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", new_device->address,
1091 libusb_le16_to_cpu (new_device->dev_descriptor.idVendor),
1092 libusb_le16_to_cpu (new_device->dev_descriptor.idProduct),
1093 new_device->dev_descriptor.bDeviceClass, new_device->dev_descriptor.bDeviceSubClass);
1094 }
1095 } while (0);
1096
1097 usbi_mutex_unlock(&darwin_cached_devices_lock);
1098
1099 return ret;
1100 }
1101
process_new_device(struct libusb_context * ctx,struct darwin_cached_device * cached_device,UInt64 old_session_id)1102 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
1103 UInt64 old_session_id) {
1104 struct darwin_device_priv *priv;
1105 struct libusb_device *dev = NULL;
1106 UInt8 devSpeed;
1107 enum libusb_error ret = LIBUSB_SUCCESS;
1108
1109 do {
1110 /* check current active configuration (and cache the first configuration value--
1111 which may be used by claim_interface) */
1112 ret = darwin_check_configuration (ctx, cached_device);
1113 if (ret)
1114 break;
1115
1116 if (0 != old_session_id) {
1117 usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
1118 ctx, old_session_id, cached_device->session);
1119 /* save the libusb device before the session id is updated */
1120 dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
1121 }
1122
1123 if (!dev) {
1124 usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
1125 ctx, cached_device->session);
1126
1127 dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
1128 if (!dev) {
1129 return LIBUSB_ERROR_NO_MEM;
1130 }
1131
1132 priv = usbi_get_device_priv(dev);
1133
1134 priv->dev = cached_device;
1135 darwin_ref_cached_device (priv->dev);
1136 dev->port_number = cached_device->port;
1137 /* the location ID encodes the path to the device. the top byte of the location ID contains the bus number
1138 (numbered from 0). the remaining bytes can be used to construct the device tree for that bus. */
1139 dev->bus_number = cached_device->location >> 24;
1140 assert(cached_device->address <= UINT8_MAX);
1141 dev->device_address = (uint8_t)cached_device->address;
1142 } else {
1143 priv = usbi_get_device_priv(dev);
1144 }
1145
1146 static_assert(sizeof(dev->device_descriptor) == sizeof(cached_device->dev_descriptor),
1147 "mismatch between libusb and IOKit device descriptor sizes");
1148 memcpy(&dev->device_descriptor, &cached_device->dev_descriptor, LIBUSB_DT_DEVICE_SIZE);
1149 usbi_localize_device_descriptor(&dev->device_descriptor);
1150 dev->session_data = cached_device->session;
1151
1152 if (NULL != dev->parent_dev) {
1153 libusb_unref_device(dev->parent_dev);
1154 dev->parent_dev = NULL;
1155 }
1156
1157 if (cached_device->parent_session > 0) {
1158 dev->parent_dev = usbi_get_device_by_session_id (ctx, (unsigned long) cached_device->parent_session);
1159 }
1160
1161 (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
1162
1163 switch (devSpeed) {
1164 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
1165 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
1166 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
1167 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1168 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
1169 #endif
1170 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
1171 case kUSBDeviceSpeedSuperPlus: dev->speed = LIBUSB_SPEED_SUPER_PLUS; break;
1172 #endif
1173 default:
1174 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
1175 }
1176
1177 ret = usbi_sanitize_device (dev);
1178 if (ret < 0)
1179 break;
1180
1181 usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
1182 dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
1183
1184 } while (0);
1185
1186 if (!cached_device->in_reenumerate && 0 == ret) {
1187 usbi_connect_device (dev);
1188 } else {
1189 libusb_unref_device (dev);
1190 }
1191
1192 return ret;
1193 }
1194
darwin_scan_devices(struct libusb_context * ctx)1195 static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
1196 struct darwin_cached_device *cached_device;
1197 UInt64 old_session_id;
1198 io_iterator_t deviceIterator;
1199 io_service_t service;
1200 IOReturn kresult;
1201 int ret;
1202
1203 kresult = usb_setup_device_iterator (&deviceIterator, 0);
1204 if (kresult != kIOReturnSuccess)
1205 return darwin_to_libusb (kresult);
1206
1207 while ((service = IOIteratorNext (deviceIterator))) {
1208 ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
1209 if (ret < 0 || !cached_device->can_enumerate) {
1210 continue;
1211 }
1212
1213 (void) process_new_device (ctx, cached_device, old_session_id);
1214
1215 IOObjectRelease(service);
1216 }
1217
1218 IOObjectRelease(deviceIterator);
1219
1220 return LIBUSB_SUCCESS;
1221 }
1222
darwin_open(struct libusb_device_handle * dev_handle)1223 static int darwin_open (struct libusb_device_handle *dev_handle) {
1224 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1225 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1226 IOReturn kresult;
1227
1228 if (0 == dpriv->open_count) {
1229 /* try to open the device */
1230 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
1231 if (kresult != kIOReturnSuccess) {
1232 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
1233
1234 if (kIOReturnExclusiveAccess != kresult) {
1235 return darwin_to_libusb (kresult);
1236 }
1237
1238 /* it is possible to perform some actions on a device that is not open so do not return an error */
1239 priv->is_open = false;
1240 } else {
1241 priv->is_open = true;
1242 }
1243
1244 /* create async event source */
1245 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
1246 if (kresult != kIOReturnSuccess) {
1247 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
1248
1249 if (priv->is_open) {
1250 (*(dpriv->device))->USBDeviceClose (dpriv->device);
1251 }
1252
1253 priv->is_open = false;
1254
1255 return darwin_to_libusb (kresult);
1256 }
1257
1258 CFRetain (libusb_darwin_acfl);
1259
1260 /* add the cfSource to the async run loop */
1261 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
1262 }
1263
1264 /* device opened successfully */
1265 dpriv->open_count++;
1266
1267 usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
1268
1269 return 0;
1270 }
1271
darwin_close(struct libusb_device_handle * dev_handle)1272 static void darwin_close (struct libusb_device_handle *dev_handle) {
1273 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1274 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1275 IOReturn kresult;
1276 int i;
1277
1278 if (dpriv->open_count == 0) {
1279 /* something is probably very wrong if this is the case */
1280 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!");
1281 return;
1282 }
1283
1284 dpriv->open_count--;
1285 if (NULL == dpriv->device) {
1286 usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService");
1287 return;
1288 }
1289
1290 /* make sure all interfaces are released */
1291 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1292 if (dev_handle->claimed_interfaces & (1U << i))
1293 libusb_release_interface (dev_handle, i);
1294
1295 if (0 == dpriv->open_count) {
1296 /* delete the device's async event source */
1297 if (priv->cfSource) {
1298 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
1299 CFRelease (priv->cfSource);
1300 priv->cfSource = NULL;
1301 CFRelease (libusb_darwin_acfl);
1302 }
1303
1304 if (priv->is_open) {
1305 /* close the device */
1306 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
1307 if (kresult != kIOReturnSuccess) {
1308 /* Log the fact that we had a problem closing the file, however failing a
1309 * close isn't really an error, so return success anyway */
1310 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
1311 }
1312 }
1313 }
1314 }
1315
darwin_get_configuration(struct libusb_device_handle * dev_handle,uint8_t * config)1316 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config) {
1317 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1318
1319 *config = dpriv->active_config;
1320
1321 return LIBUSB_SUCCESS;
1322 }
1323
darwin_set_configuration(struct libusb_device_handle * dev_handle,int config)1324 static enum libusb_error darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
1325 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1326 IOReturn kresult;
1327 uint8_t i;
1328
1329 if (config == -1)
1330 config = 0;
1331
1332 /* Setting configuration will invalidate the interface, so we need
1333 to reclaim it. First, dispose of existing interfaces, if any. */
1334 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1335 if (dev_handle->claimed_interfaces & (1U << i))
1336 darwin_release_interface (dev_handle, i);
1337
1338 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, (UInt8)config);
1339 if (kresult != kIOReturnSuccess)
1340 return darwin_to_libusb (kresult);
1341
1342 /* Reclaim any interfaces. */
1343 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1344 if (dev_handle->claimed_interfaces & (1U << i))
1345 darwin_claim_interface (dev_handle, i);
1346
1347 dpriv->active_config = (UInt8)config;
1348
1349 return LIBUSB_SUCCESS;
1350 }
1351
darwin_get_interface(usb_device_t ** darwin_device,uint8_t ifc,io_service_t * usbInterfacep)1352 static IOReturn darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1353 IOUSBFindInterfaceRequest request;
1354 IOReturn kresult;
1355 io_iterator_t interface_iterator;
1356 UInt8 bInterfaceNumber;
1357 bool ret;
1358
1359 *usbInterfacep = IO_OBJECT_NULL;
1360
1361 /* Setup the Interface Request */
1362 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1363 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1364 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1365 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1366
1367 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1368 if (kresult != kIOReturnSuccess)
1369 return kresult;
1370
1371 while ((*usbInterfacep = IOIteratorNext(interface_iterator))) {
1372 /* find the interface number */
1373 ret = get_ioregistry_value_number (*usbInterfacep, CFSTR("bInterfaceNumber"), kCFNumberSInt8Type,
1374 &bInterfaceNumber);
1375
1376 if (ret && bInterfaceNumber == ifc) {
1377 break;
1378 }
1379
1380 (void) IOObjectRelease (*usbInterfacep);
1381 }
1382
1383 /* done with the interface iterator */
1384 IOObjectRelease(interface_iterator);
1385
1386 return kIOReturnSuccess;
1387 }
1388
get_endpoints(struct libusb_device_handle * dev_handle,uint8_t iface)1389 static enum libusb_error get_endpoints (struct libusb_device_handle *dev_handle, uint8_t iface) {
1390 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1391
1392 /* current interface */
1393 struct darwin_interface *cInterface = &priv->interfaces[iface];
1394 #if InterfaceVersion >= 550
1395 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1396 #else
1397 UInt8 dont_care1, dont_care3;
1398 UInt16 dont_care2;
1399 #endif
1400
1401 IOReturn kresult;
1402
1403 UInt8 numep, direction, number;
1404 int rc;
1405 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1406
1407
1408 usbi_dbg (ctx, "building table of endpoints.");
1409
1410 /* retrieve the total number of endpoints on this interface */
1411 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1412 if (kresult != kIOReturnSuccess) {
1413 usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1414 return darwin_to_libusb (kresult);
1415 }
1416
1417 /* iterate through pipe references */
1418 for (UInt8 i = 1 ; i <= numep ; i++) {
1419 #if InterfaceVersion >= 550
1420 kresult = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, i, &pipeProperties);
1421 number = pipeProperties.bEndpointNumber;
1422 direction = pipeProperties.bDirection;
1423 #else
1424 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1425 &dont_care2, &dont_care3);
1426 #endif
1427 if (kresult != kIOReturnSuccess) {
1428 /* probably a buggy device. try to get the endpoint address from the descriptors */
1429 struct libusb_config_descriptor *config;
1430 const struct libusb_endpoint_descriptor *endpoint_desc;
1431 UInt8 alt_setting;
1432
1433 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
1434 if (kresult != kIOReturnSuccess) {
1435 usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
1436 return darwin_to_libusb (kresult);
1437 }
1438
1439 rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
1440 if (LIBUSB_SUCCESS != rc) {
1441 return rc;
1442 }
1443
1444 if (iface >= config->bNumInterfaces) {
1445 usbi_err (HANDLE_CTX (dev_handle), "interface %d out of range for device", iface);
1446 return LIBUSB_ERROR_NOT_FOUND;
1447 }
1448 endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
1449
1450 cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
1451 } else {
1452 cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1453 }
1454
1455 usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
1456 cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
1457 }
1458
1459 cInterface->num_endpoints = numep;
1460
1461 return LIBUSB_SUCCESS;
1462 }
1463
darwin_claim_interface(struct libusb_device_handle * dev_handle,uint8_t iface)1464 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1465 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1466 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1467 io_service_t usbInterface = IO_OBJECT_NULL;
1468 IOReturn kresult;
1469 enum libusb_error ret;
1470 IOCFPlugInInterface **plugInInterface = NULL;
1471 SInt32 score;
1472
1473 /* current interface */
1474 struct darwin_interface *cInterface = &priv->interfaces[iface];
1475
1476 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1477
1478 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1479 if (kresult != kIOReturnSuccess)
1480 return darwin_to_libusb (kresult);
1481
1482 /* make sure we have an interface */
1483 if (!usbInterface && dpriv->first_config != 0) {
1484 usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
1485
1486 /* set the configuration */
1487 ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
1488 if (ret != LIBUSB_SUCCESS) {
1489 usbi_err (ctx, "could not set configuration");
1490 return ret;
1491 }
1492
1493 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1494 if (kresult != kIOReturnSuccess) {
1495 usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
1496 return darwin_to_libusb (kresult);
1497 }
1498 }
1499
1500 if (!usbInterface) {
1501 usbi_info (ctx, "interface not found");
1502 return LIBUSB_ERROR_NOT_FOUND;
1503 }
1504
1505 /* get an interface to the device's interface */
1506 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1507 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1508
1509 /* ignore release error */
1510 (void)IOObjectRelease (usbInterface);
1511
1512 if (kresult != kIOReturnSuccess) {
1513 usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1514 return darwin_to_libusb (kresult);
1515 }
1516
1517 if (!plugInInterface) {
1518 usbi_err (ctx, "plugin interface not found");
1519 return LIBUSB_ERROR_NOT_FOUND;
1520 }
1521
1522 /* Do the actual claim */
1523 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1524 CFUUIDGetUUIDBytes(InterfaceInterfaceID),
1525 (LPVOID)&cInterface->interface);
1526 /* We no longer need the intermediate plug-in */
1527 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1528 (*plugInInterface)->Release (plugInInterface);
1529 if (kresult != kIOReturnSuccess || !cInterface->interface) {
1530 usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
1531 return darwin_to_libusb (kresult);
1532 }
1533
1534 /* claim the interface */
1535 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1536 if (kresult != kIOReturnSuccess) {
1537 usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
1538 return darwin_to_libusb (kresult);
1539 }
1540
1541 /* update list of endpoints */
1542 ret = get_endpoints (dev_handle, iface);
1543 if (ret) {
1544 /* this should not happen */
1545 darwin_release_interface (dev_handle, iface);
1546 usbi_err (ctx, "could not build endpoint table");
1547 return ret;
1548 }
1549
1550 cInterface->cfSource = NULL;
1551
1552 /* create async event source */
1553 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1554 if (kresult != kIOReturnSuccess) {
1555 usbi_err (ctx, "could not create async event source");
1556
1557 /* can't continue without an async event source */
1558 (void)darwin_release_interface (dev_handle, iface);
1559
1560 return darwin_to_libusb (kresult);
1561 }
1562
1563 /* add the cfSource to the async thread's run loop */
1564 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1565
1566 usbi_dbg (ctx, "interface opened");
1567
1568 return LIBUSB_SUCCESS;
1569 }
1570
darwin_release_interface(struct libusb_device_handle * dev_handle,uint8_t iface)1571 static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
1572 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1573 IOReturn kresult;
1574
1575 /* current interface */
1576 struct darwin_interface *cInterface = &priv->interfaces[iface];
1577
1578 /* Check to see if an interface is open */
1579 if (!cInterface->interface)
1580 return LIBUSB_SUCCESS;
1581
1582 /* clean up endpoint data */
1583 cInterface->num_endpoints = 0;
1584
1585 /* delete the interface's async event source */
1586 if (cInterface->cfSource) {
1587 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1588 CFRelease (cInterface->cfSource);
1589 cInterface->cfSource = NULL;
1590 }
1591
1592 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1593 if (kresult != kIOReturnSuccess)
1594 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1595
1596 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1597 if (kresult != kIOReturnSuccess)
1598 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1599
1600 cInterface->interface = (usb_interface_t **) IO_OBJECT_NULL;
1601
1602 return darwin_to_libusb (kresult);
1603 }
1604
check_alt_setting_and_clear_halt(struct libusb_device_handle * dev_handle,uint8_t altsetting,struct darwin_interface * cInterface)1605 static int check_alt_setting_and_clear_halt(struct libusb_device_handle *dev_handle, uint8_t altsetting, struct darwin_interface *cInterface) {
1606 enum libusb_error ret;
1607 IOReturn kresult;
1608 uint8_t current_alt_setting;
1609
1610 kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, ¤t_alt_setting);
1611 if (kresult == kIOReturnSuccess && altsetting != current_alt_setting) {
1612 return LIBUSB_ERROR_PIPE;
1613 }
1614
1615 for (int i = 0 ; i < cInterface->num_endpoints ; i++) {
1616 ret = darwin_clear_halt(dev_handle, cInterface->endpoint_addrs[i]);
1617 if (LIBUSB_SUCCESS != ret) {
1618 usbi_warn(HANDLE_CTX (dev_handle), "error clearing pipe halt for endpoint %d", i);
1619 if (LIBUSB_ERROR_NOT_FOUND == ret) {
1620 /* may need to re-open the interface */
1621 return ret;
1622 }
1623 }
1624 }
1625
1626 return LIBUSB_SUCCESS;
1627 }
1628
darwin_set_interface_altsetting(struct libusb_device_handle * dev_handle,uint8_t iface,uint8_t altsetting)1629 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting) {
1630 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1631 IOReturn kresult;
1632 enum libusb_error ret;
1633
1634 /* current interface */
1635 struct darwin_interface *cInterface = &priv->interfaces[iface];
1636
1637 if (!cInterface->interface)
1638 return LIBUSB_ERROR_NO_DEVICE;
1639
1640 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1641 if (kresult == kIOReturnSuccess) {
1642 /* update the list of endpoints */
1643 ret = get_endpoints (dev_handle, iface);
1644 if (ret) {
1645 /* this should not happen */
1646 darwin_release_interface (dev_handle, iface);
1647 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1648 }
1649 return ret;
1650 }
1651
1652 usbi_warn (HANDLE_CTX (dev_handle), "SetAlternateInterface: %s", darwin_error_str(kresult));
1653
1654 ret = darwin_to_libusb(kresult);
1655 if (ret != LIBUSB_ERROR_PIPE) {
1656 return ret;
1657 }
1658
1659 /* If a device only supports a default setting for the specified interface, then a STALL
1660 (kIOUSBPipeStalled) may be returned. Ref: USB 2.0 specs 9.4.10.
1661 Mimic the behaviour in e.g. the Linux kernel: in such case, reset all endpoints
1662 of the interface (as would have been done per 9.1.1.5) and return success. */
1663
1664 ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1665 if (LIBUSB_ERROR_NOT_FOUND == ret) {
1666 /* For some reason we need to reclaim the interface after the pipe error with some versions of macOS */
1667 ret = darwin_claim_interface (dev_handle, iface);
1668 if (LIBUSB_SUCCESS != ret) {
1669 darwin_release_interface (dev_handle, iface);
1670 usbi_err (HANDLE_CTX (dev_handle), "could not reclaim interface: %s", darwin_error_str(kresult));
1671 }
1672 ret = check_alt_setting_and_clear_halt(dev_handle, altsetting, cInterface);
1673 }
1674
1675 return ret;
1676 }
1677
darwin_clear_halt(struct libusb_device_handle * dev_handle,unsigned char endpoint)1678 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1679 /* current interface */
1680 struct darwin_interface *cInterface;
1681 IOReturn kresult;
1682 uint8_t pipeRef;
1683
1684 /* determine the interface/endpoint to use */
1685 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, NULL, &cInterface) != 0) {
1686 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1687
1688 return LIBUSB_ERROR_NOT_FOUND;
1689 }
1690
1691 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1692 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1693 if (kresult != kIOReturnSuccess)
1694 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1695
1696 return darwin_to_libusb (kresult);
1697 }
1698
darwin_restore_state(struct libusb_device_handle * dev_handle,int8_t active_config,unsigned long claimed_interfaces)1699 static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config,
1700 unsigned long claimed_interfaces) {
1701 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1702 struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle);
1703 int open_count = dpriv->open_count;
1704 int ret;
1705
1706 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1707
1708 /* clear claimed interfaces temporarily */
1709 dev_handle->claimed_interfaces = 0;
1710
1711 /* close and re-open the device */
1712 priv->is_open = false;
1713 dpriv->open_count = 1;
1714
1715 /* clean up open interfaces */
1716 (void) darwin_close (dev_handle);
1717
1718 /* re-open the device */
1719 ret = darwin_open (dev_handle);
1720 dpriv->open_count = open_count;
1721 if (LIBUSB_SUCCESS != ret) {
1722 /* could not restore configuration */
1723 return LIBUSB_ERROR_NOT_FOUND;
1724 }
1725
1726 if (dpriv->active_config != active_config) {
1727 usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
1728
1729 ret = darwin_set_configuration (dev_handle, active_config);
1730 if (LIBUSB_SUCCESS != ret) {
1731 usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
1732 return LIBUSB_ERROR_NOT_FOUND;
1733 }
1734 }
1735
1736 usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
1737
1738 if (claimed_interfaces) {
1739 for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
1740 if (!(claimed_interfaces & (1U << iface))) {
1741 continue;
1742 }
1743
1744 usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
1745
1746 ret = darwin_claim_interface (dev_handle, iface);
1747 if (LIBUSB_SUCCESS != ret) {
1748 usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
1749 return LIBUSB_ERROR_NOT_FOUND;
1750 }
1751
1752 dev_handle->claimed_interfaces |= 1U << iface;
1753 }
1754 }
1755
1756 usbi_dbg (ctx, "darwin/restore_state: device state restored");
1757
1758 return LIBUSB_SUCCESS;
1759 }
1760
darwin_reenumerate_device(struct libusb_device_handle * dev_handle,bool capture)1761 static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) {
1762 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1763 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1764 int8_t active_config = dpriv->active_config;
1765 UInt32 options = 0;
1766 IOUSBDeviceDescriptor descriptor;
1767 IOUSBConfigurationDescriptorPtr cached_configuration;
1768 IOUSBConfigurationDescriptor *cached_configurations;
1769 IOReturn kresult;
1770 UInt8 i;
1771
1772 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
1773
1774 if (dpriv->in_reenumerate) {
1775 /* ack, two (or more) threads are trying to reset the device! abort! */
1776 return LIBUSB_ERROR_NOT_FOUND;
1777 }
1778
1779 dpriv->in_reenumerate = true;
1780
1781 /* store copies of descriptors so they can be compared after the reset */
1782 memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
1783 cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
1784
1785 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1786 (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1787 memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
1788 }
1789
1790 /* if we need to release capture */
1791 if (HAS_CAPTURE_DEVICE()) {
1792 if (capture) {
1793 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
1794 options |= kUSBReEnumerateCaptureDeviceMask;
1795 #endif
1796 }
1797 } else {
1798 capture = false;
1799 }
1800
1801 /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
1802 kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
1803 if (kresult != kIOReturnSuccess) {
1804 usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
1805 dpriv->in_reenumerate = false;
1806 return darwin_to_libusb (kresult);
1807 }
1808
1809 /* capture mode does not re-enumerate but it does require re-open */
1810 if (capture) {
1811 usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
1812 dpriv->in_reenumerate = false;
1813 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1814 }
1815
1816 usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
1817
1818 struct timespec start;
1819 usbi_get_monotonic_time(&start);
1820
1821 while (dpriv->in_reenumerate) {
1822 struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
1823 nanosleep (&delay, NULL);
1824
1825 struct timespec now;
1826 usbi_get_monotonic_time(&now);
1827 unsigned long elapsed_us = (now.tv_sec - start.tv_sec) * USEC_PER_SEC +
1828 (now.tv_nsec - start.tv_nsec) / 1000;
1829
1830 if (elapsed_us >= DARWIN_REENUMERATE_TIMEOUT_US) {
1831 usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
1832 dpriv->in_reenumerate = false;
1833 return LIBUSB_ERROR_TIMEOUT;
1834 }
1835 }
1836
1837 /* compare descriptors */
1838 usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
1839
1840 if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
1841 /* device descriptor changed. need to return not found. */
1842 usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
1843 return LIBUSB_ERROR_NOT_FOUND;
1844 }
1845
1846 for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
1847 (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
1848 if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1849 usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1850 return LIBUSB_ERROR_NOT_FOUND;
1851 }
1852 }
1853
1854 usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
1855
1856 return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1857 }
1858
darwin_reset_device(struct libusb_device_handle * dev_handle)1859 static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
1860 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1861 IOReturn kresult;
1862 enum libusb_error ret;
1863
1864 #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX == 1
1865 if (dpriv->capture_count > 0) {
1866 /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
1867 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1868 ret = darwin_to_libusb (kresult);
1869 } else {
1870 ret = darwin_reenumerate_device (dev_handle, false);
1871 }
1872 #else
1873 /* ResetDevice() is missing on non-macOS platforms */
1874 ret = darwin_reenumerate_device (dev_handle, false);
1875 if ((ret == LIBUSB_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND) && dpriv->capture_count > 0) {
1876 int capture_count;
1877 int8_t active_config = dpriv->active_config;
1878 unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
1879
1880 /* save old capture_count */
1881 capture_count = dpriv->capture_count;
1882 /* reset capture count */
1883 dpriv->capture_count = 0;
1884 /* attempt to detach kernel driver again as it is now re-attached */
1885 ret = darwin_detach_kernel_driver (dev_handle, 0);
1886 if (ret != LIBUSB_SUCCESS) {
1887 return ret;
1888 }
1889 /* restore capture_count */
1890 dpriv->capture_count = capture_count;
1891 /* restore configuration */
1892 ret = darwin_restore_state (dev_handle, active_config, claimed_interfaces);
1893 }
1894 #endif
1895 return ret;
1896 }
1897
usb_find_interface_matching_location(const io_name_t class_name,UInt8 interface_number,UInt32 location)1898 static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
1899 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name);
1900 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0,
1901 &kCFTypeDictionaryKeyCallBacks,
1902 &kCFTypeDictionaryValueCallBacks);
1903 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
1904 CFTypeRef interfaceCF = CFNumberCreate (NULL, kCFNumberSInt8Type, &interface_number);
1905
1906 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
1907 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
1908 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBHostMatchingPropertyInterfaceNumber), interfaceCF);
1909
1910 CFRelease (interfaceCF);
1911 CFRelease (locationCF);
1912 CFRelease (propertyMatchDict);
1913
1914 return IOServiceGetMatchingService (darwin_default_master_port, matchingDict);
1915 }
1916
darwin_kernel_driver_active(struct libusb_device_handle * dev_handle,uint8_t interface)1917 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, uint8_t interface) {
1918 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1919 io_service_t usb_interface, child = IO_OBJECT_NULL;
1920
1921 /* locate the IO registry entry for this interface */
1922 usb_interface = usb_find_interface_matching_location (kIOUSBHostInterfaceClassName, interface, dpriv->location);
1923 if (0 == usb_interface) {
1924 /* check for the legacy class entry */
1925 usb_interface = usb_find_interface_matching_location (kIOUSBInterfaceClassName, interface, dpriv->location);
1926 if (0 == usb_interface) {
1927 return LIBUSB_ERROR_NOT_FOUND;
1928 }
1929 }
1930
1931 /* if the IO object has a child entry in the IO Registry it has a kernel driver attached */
1932 (void) IORegistryEntryGetChildEntry (usb_interface, kIOServicePlane, &child);
1933 IOObjectRelease (usb_interface);
1934 if (IO_OBJECT_NULL != child) {
1935 IOObjectRelease (child);
1936 return 1;
1937 }
1938
1939 /* no driver */
1940 return 0;
1941 }
1942
darwin_destroy_device(struct libusb_device * dev)1943 static void darwin_destroy_device(struct libusb_device *dev) {
1944 struct darwin_device_priv *dpriv = usbi_get_device_priv(dev);
1945
1946 if (dpriv->dev) {
1947 /* need to hold the lock in case this is the last reference to the device */
1948 usbi_mutex_lock(&darwin_cached_devices_lock);
1949 darwin_deref_cached_device (dpriv->dev);
1950 dpriv->dev = NULL;
1951 usbi_mutex_unlock(&darwin_cached_devices_lock);
1952 }
1953 }
1954
submit_bulk_transfer(struct usbi_transfer * itransfer)1955 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1956 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1957
1958 IOReturn ret;
1959 uint8_t transferType;
1960 uint8_t pipeRef;
1961 uint16_t maxPacketSize;
1962
1963 struct darwin_interface *cInterface;
1964 #if InterfaceVersion >= 550
1965 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
1966 #else
1967 /* None of the values below are used in libusb for bulk transfers */
1968 uint8_t direction, number, interval;
1969 #endif
1970
1971 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
1972 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1973
1974 return LIBUSB_ERROR_NOT_FOUND;
1975 }
1976
1977 #if InterfaceVersion >= 550
1978 ret = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
1979
1980 transferType = pipeProperties.bTransferType;
1981 maxPacketSize = pipeProperties.wMaxPacketSize;
1982 #else
1983 ret = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1984 &transferType, &maxPacketSize, &interval);
1985 #endif
1986
1987 if (ret) {
1988 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1989 darwin_error_str(ret), ret);
1990 return darwin_to_libusb (ret);
1991 }
1992
1993 if (0 != (transfer->length % maxPacketSize)) {
1994 /* do not need a zero packet */
1995 transfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET;
1996 }
1997
1998 /* submit the request */
1999 /* timeouts are unavailable on interrupt endpoints */
2000 if (transferType == kUSBInterrupt) {
2001 if (IS_XFERIN(transfer))
2002 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
2003 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
2004 else
2005 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
2006 (UInt32)transfer->length, darwin_async_io_callback, itransfer);
2007 } else {
2008 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2009
2010 if (IS_XFERIN(transfer))
2011 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
2012 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
2013 darwin_async_io_callback, itransfer);
2014 else
2015 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
2016 (UInt32)transfer->length, transfer->timeout, transfer->timeout,
2017 darwin_async_io_callback, itransfer);
2018 }
2019
2020 if (ret)
2021 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
2022 darwin_error_str(ret), ret);
2023
2024 return darwin_to_libusb (ret);
2025 }
2026
2027 #if InterfaceVersion >= 550
submit_stream_transfer(struct usbi_transfer * itransfer)2028 static int submit_stream_transfer(struct usbi_transfer *itransfer) {
2029 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2030 struct darwin_interface *cInterface;
2031 uint8_t pipeRef;
2032 IOReturn ret;
2033
2034 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2035 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2036
2037 return LIBUSB_ERROR_NOT_FOUND;
2038 }
2039
2040 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2041
2042 if (IS_XFERIN(transfer))
2043 ret = (*(cInterface->interface))->ReadStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2044 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2045 transfer->timeout, darwin_async_io_callback, itransfer);
2046 else
2047 ret = (*(cInterface->interface))->WriteStreamsPipeAsyncTO(cInterface->interface, pipeRef, itransfer->stream_id,
2048 transfer->buffer, (UInt32)transfer->length, transfer->timeout,
2049 transfer->timeout, darwin_async_io_callback, itransfer);
2050
2051 if (ret)
2052 usbi_err (TRANSFER_CTX (transfer), "bulk stream transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
2053 darwin_error_str(ret), ret);
2054
2055 return darwin_to_libusb (ret);
2056 }
2057 #endif
2058
submit_iso_transfer(struct usbi_transfer * itransfer)2059 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
2060 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2061 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2062
2063 IOReturn kresult;
2064 uint8_t pipeRef, interval;
2065 UInt64 frame;
2066 AbsoluteTime atTime;
2067 int i;
2068 #if InterfaceVersion >= 550
2069 IOUSBEndpointProperties pipeProperties = {.bVersion = kUSBEndpointPropertiesVersion3};
2070 #else
2071 /* None of the values below are used in libusb for iso transfers */
2072 uint8_t direction, number, transferType;
2073 uint16_t maxPacketSize;
2074 #endif
2075
2076 struct darwin_interface *cInterface;
2077
2078 /* construct an array of IOUSBIsocFrames, reuse the old one if the sizes are the same */
2079 if (tpriv->num_iso_packets != transfer->num_iso_packets) {
2080 free(tpriv->isoc_framelist);
2081 tpriv->isoc_framelist = NULL;
2082 }
2083
2084 if (!tpriv->isoc_framelist) {
2085 tpriv->num_iso_packets = transfer->num_iso_packets;
2086 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc ((size_t)transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
2087 if (!tpriv->isoc_framelist)
2088 return LIBUSB_ERROR_NO_MEM;
2089 }
2090
2091 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
2092 for (i = 0 ; i < transfer->num_iso_packets ; i++) {
2093 unsigned int length = transfer->iso_packet_desc[i].length;
2094 assert(length <= UINT16_MAX);
2095 tpriv->isoc_framelist[i].frReqCount = (UInt16)length;
2096 }
2097
2098 /* determine the interface/endpoint to use */
2099 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2100 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2101
2102 return LIBUSB_ERROR_NOT_FOUND;
2103 }
2104
2105 /* determine the properties of this endpoint and the speed of the device */
2106 #if InterfaceVersion >= 550
2107 kresult = (*(cInterface->interface))->GetPipePropertiesV3 (cInterface->interface, pipeRef, &pipeProperties);
2108 interval = pipeProperties.bInterval;
2109 #else
2110 kresult = (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
2111 &transferType, &maxPacketSize, &interval);
2112 #endif
2113 if (kresult != kIOReturnSuccess) {
2114 usbi_err (TRANSFER_CTX (transfer), "failed to get pipe properties: %d", kresult);
2115 free(tpriv->isoc_framelist);
2116 tpriv->isoc_framelist = NULL;
2117
2118 return darwin_to_libusb (kresult);
2119 }
2120
2121 /* Last but not least we need the bus frame number */
2122 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
2123 if (kresult != kIOReturnSuccess) {
2124 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
2125 free(tpriv->isoc_framelist);
2126 tpriv->isoc_framelist = NULL;
2127
2128 return darwin_to_libusb (kresult);
2129 }
2130
2131 /* schedule for a frame a little in the future */
2132 frame += 4;
2133
2134 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
2135 frame = cInterface->frames[transfer->endpoint];
2136
2137 /* submit the request */
2138 if (IS_XFERIN(transfer))
2139 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2140 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2141 itransfer);
2142 else
2143 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
2144 (UInt32)transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
2145 itransfer);
2146
2147 if (LIBUSB_SPEED_FULL == transfer->dev_handle->dev->speed)
2148 /* Full speed */
2149 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1));
2150 else
2151 /* High/super speed */
2152 cInterface->frames[transfer->endpoint] = frame + (UInt32)transfer->num_iso_packets * (1U << (interval - 1)) / 8;
2153
2154 if (kresult != kIOReturnSuccess) {
2155 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
2156 darwin_error_str(kresult));
2157 free (tpriv->isoc_framelist);
2158 tpriv->isoc_framelist = NULL;
2159 }
2160
2161 return darwin_to_libusb (kresult);
2162 }
2163
submit_control_transfer(struct usbi_transfer * itransfer)2164 static int submit_control_transfer(struct usbi_transfer *itransfer) {
2165 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2166 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
2167 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2168 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2169
2170 IOReturn kresult;
2171
2172 memset(&tpriv->req, 0, sizeof(tpriv->req));
2173
2174 /* IOUSBDeviceInterface expects the request in cpu endianness */
2175 tpriv->req.bmRequestType = setup->bmRequestType;
2176 tpriv->req.bRequest = setup->bRequest;
2177 /* these values should be in bus order from libusb_fill_control_setup */
2178 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
2179 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
2180 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
2181 /* data is stored after the libusb control block */
2182 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
2183 tpriv->req.completionTimeout = transfer->timeout;
2184 tpriv->req.noDataTimeout = transfer->timeout;
2185
2186 itransfer->timeout_flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
2187
2188 /* all transfers in libusb-1.0 are async */
2189
2190 if (transfer->endpoint) {
2191 struct darwin_interface *cInterface;
2192 uint8_t pipeRef;
2193
2194 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface) != 0) {
2195 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
2196
2197 return LIBUSB_ERROR_NOT_FOUND;
2198 }
2199
2200 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
2201 } else
2202 /* control request on endpoint 0 */
2203 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
2204
2205 if (kresult != kIOReturnSuccess)
2206 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
2207
2208 return darwin_to_libusb (kresult);
2209 }
2210
darwin_submit_transfer(struct usbi_transfer * itransfer)2211 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
2212 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2213
2214 switch (transfer->type) {
2215 case LIBUSB_TRANSFER_TYPE_CONTROL:
2216 return submit_control_transfer(itransfer);
2217 case LIBUSB_TRANSFER_TYPE_BULK:
2218 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2219 return submit_bulk_transfer(itransfer);
2220 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2221 return submit_iso_transfer(itransfer);
2222 case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
2223 #if InterfaceVersion >= 550
2224 return submit_stream_transfer(itransfer);
2225 #else
2226 usbi_err (TRANSFER_CTX(transfer), "IOUSBFamily version does not support bulk stream transfers");
2227 return LIBUSB_ERROR_NOT_SUPPORTED;
2228 #endif
2229 default:
2230 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2231 return LIBUSB_ERROR_INVALID_PARAM;
2232 }
2233 }
2234
cancel_control_transfer(struct usbi_transfer * itransfer)2235 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
2236 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2237 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2238 IOReturn kresult;
2239
2240 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
2241
2242 if (!dpriv->device)
2243 return LIBUSB_ERROR_NO_DEVICE;
2244
2245 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
2246
2247 return darwin_to_libusb (kresult);
2248 }
2249
darwin_abort_transfers(struct usbi_transfer * itransfer)2250 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
2251 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2252 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(transfer->dev_handle->dev);
2253 struct darwin_interface *cInterface;
2254 uint8_t pipeRef, iface;
2255 IOReturn kresult;
2256
2257 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2258
2259 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
2260 usbi_err (ctx, "endpoint not found on any open interface");
2261
2262 return LIBUSB_ERROR_NOT_FOUND;
2263 }
2264
2265 if (!dpriv->device)
2266 return LIBUSB_ERROR_NO_DEVICE;
2267
2268 usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
2269
2270 /* abort transactions */
2271 #if InterfaceVersion >= 550
2272 if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
2273 (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
2274 else
2275 #endif
2276 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
2277
2278 usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
2279
2280 /* newer versions of darwin support clearing additional bits on the device's endpoint */
2281 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
2282
2283 return darwin_to_libusb (kresult);
2284 }
2285
darwin_cancel_transfer(struct usbi_transfer * itransfer)2286 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
2287 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2288
2289 switch (transfer->type) {
2290 case LIBUSB_TRANSFER_TYPE_CONTROL:
2291 return cancel_control_transfer(itransfer);
2292 case LIBUSB_TRANSFER_TYPE_BULK:
2293 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2294 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2295 return darwin_abort_transfers (itransfer);
2296 default:
2297 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
2298 return LIBUSB_ERROR_INVALID_PARAM;
2299 }
2300 }
2301
darwin_async_io_callback(void * refcon,IOReturn result,void * arg0)2302 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
2303 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
2304 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2305 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2306
2307 usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
2308
2309 /* if requested write a zero packet */
2310 if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
2311 struct darwin_interface *cInterface;
2312 uint8_t pipeRef;
2313
2314 (void) ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, NULL, &cInterface);
2315
2316 (*(cInterface->interface))->WritePipe (cInterface->interface, pipeRef, transfer->buffer, 0);
2317 }
2318
2319 tpriv->result = result;
2320 tpriv->size = (UInt32) (uintptr_t) arg0;
2321
2322 /* signal the core that this transfer is complete */
2323 usbi_signal_transfer_completion(itransfer);
2324 }
2325
darwin_transfer_status(struct usbi_transfer * itransfer,IOReturn result)2326 static enum libusb_transfer_status darwin_transfer_status (struct usbi_transfer *itransfer, IOReturn result) {
2327 if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
2328 result = kIOUSBTransactionTimeout;
2329
2330 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2331
2332 switch (result) {
2333 case kIOReturnUnderrun:
2334 case kIOReturnSuccess:
2335 return LIBUSB_TRANSFER_COMPLETED;
2336 case kIOReturnAborted:
2337 return LIBUSB_TRANSFER_CANCELLED;
2338 case kIOUSBPipeStalled:
2339 usbi_dbg (ctx, "transfer error: pipe is stalled");
2340 return LIBUSB_TRANSFER_STALL;
2341 case kIOReturnOverrun:
2342 usbi_warn (ctx, "transfer error: data overrun");
2343 return LIBUSB_TRANSFER_OVERFLOW;
2344 case kIOUSBTransactionTimeout:
2345 usbi_warn (ctx, "transfer error: timed out");
2346 itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2347 return LIBUSB_TRANSFER_TIMED_OUT;
2348 default:
2349 usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
2350 return LIBUSB_TRANSFER_ERROR;
2351 }
2352 }
2353
darwin_handle_transfer_completion(struct usbi_transfer * itransfer)2354 static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
2355 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
2356 struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
2357 const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
2358 const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
2359 bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
2360 struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
2361
2362 if (transfer->type > max_transfer_type) {
2363 usbi_err (ctx, "unknown endpoint type %d", transfer->type);
2364 return LIBUSB_ERROR_INVALID_PARAM;
2365 }
2366
2367 if (NULL == tpriv) {
2368 usbi_err (ctx, "malformed request is missing transfer priv");
2369 return LIBUSB_ERROR_INVALID_PARAM;
2370 }
2371
2372 usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
2373
2374 if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
2375 if (is_isoc && tpriv->isoc_framelist) {
2376 /* copy isochronous results back */
2377
2378 for (int i = 0; i < transfer->num_iso_packets ; i++) {
2379 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
2380 lib_desc->status = darwin_transfer_status (itransfer, tpriv->isoc_framelist[i].frStatus);
2381 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
2382 }
2383 } else if (!is_isoc) {
2384 itransfer->transferred += tpriv->size;
2385 }
2386 }
2387
2388 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
2389 return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
2390 }
2391
2392 #if !defined(HAVE_CLOCK_GETTIME)
usbi_get_monotonic_time(struct timespec * tp)2393 void usbi_get_monotonic_time(struct timespec *tp) {
2394 mach_timespec_t sys_time;
2395
2396 /* use system boot time as reference for the monotonic clock */
2397 clock_get_time (clock_monotonic, &sys_time);
2398
2399 tp->tv_sec = sys_time.tv_sec;
2400 tp->tv_nsec = sys_time.tv_nsec;
2401 }
2402
usbi_get_real_time(struct timespec * tp)2403 void usbi_get_real_time(struct timespec *tp) {
2404 mach_timespec_t sys_time;
2405
2406 /* CLOCK_REALTIME represents time since the epoch */
2407 clock_get_time (clock_realtime, &sys_time);
2408
2409 tp->tv_sec = sys_time.tv_sec;
2410 tp->tv_nsec = sys_time.tv_nsec;
2411 }
2412 #endif
2413
2414 #if InterfaceVersion >= 550
darwin_alloc_streams(struct libusb_device_handle * dev_handle,uint32_t num_streams,unsigned char * endpoints,int num_endpoints)2415 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
2416 int num_endpoints) {
2417 struct darwin_interface *cInterface;
2418 UInt32 supportsStreams;
2419 uint8_t pipeRef;
2420 int rc, i;
2421
2422 /* find the minimum number of supported streams on the endpoint list */
2423 for (i = 0 ; i < num_endpoints ; ++i) {
2424 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface))) {
2425 return rc;
2426 }
2427
2428 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2429 if (num_streams > supportsStreams)
2430 num_streams = supportsStreams;
2431 }
2432
2433 /* it is an error if any endpoint in endpoints does not support streams */
2434 if (0 == num_streams)
2435 return LIBUSB_ERROR_INVALID_PARAM;
2436
2437 /* create the streams */
2438 for (i = 0 ; i < num_endpoints ; ++i) {
2439 (void) ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface);
2440
2441 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, num_streams);
2442 if (kIOReturnSuccess != rc)
2443 return darwin_to_libusb(rc);
2444 }
2445
2446 assert(num_streams <= INT_MAX);
2447 return (int)num_streams;
2448 }
2449
darwin_free_streams(struct libusb_device_handle * dev_handle,unsigned char * endpoints,int num_endpoints)2450 static int darwin_free_streams (struct libusb_device_handle *dev_handle, unsigned char *endpoints, int num_endpoints) {
2451 struct darwin_interface *cInterface;
2452 UInt32 supportsStreams;
2453 uint8_t pipeRef;
2454 int rc;
2455
2456 for (int i = 0 ; i < num_endpoints ; ++i) {
2457 if (0 != (rc = ep_to_pipeRef (dev_handle, endpoints[i], &pipeRef, NULL, &cInterface)))
2458 return rc;
2459
2460 (*(cInterface->interface))->SupportsStreams (cInterface->interface, pipeRef, &supportsStreams);
2461 if (0 == supportsStreams)
2462 return LIBUSB_ERROR_INVALID_PARAM;
2463
2464 rc = (*(cInterface->interface))->CreateStreams (cInterface->interface, pipeRef, 0);
2465 if (kIOReturnSuccess != rc)
2466 return darwin_to_libusb(rc);
2467 }
2468
2469 return LIBUSB_SUCCESS;
2470 }
2471 #endif
2472
2473 #if InterfaceVersion >= 700
2474
2475 /* macOS APIs for getting entitlement values */
2476
2477 #if !defined(TARGET_OS_OSX) || TARGET_OS_OSX == 1
2478 #include <Security/Security.h>
2479 #else
2480 typedef struct __SecTask *SecTaskRef;
2481 extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator);
2482 extern CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef task, CFStringRef entitlement, CFErrorRef *error);
2483 #endif
2484
darwin_has_capture_entitlements(void)2485 static bool darwin_has_capture_entitlements (void) {
2486 SecTaskRef task;
2487 CFTypeRef value;
2488 bool entitled;
2489
2490 task = SecTaskCreateFromSelf (kCFAllocatorDefault);
2491 if (task == NULL) {
2492 return false;
2493 }
2494 value = SecTaskCopyValueForEntitlement(task, CFSTR("com.apple.vm.device-access"), NULL);
2495 CFRelease (task);
2496 entitled = value && (CFGetTypeID (value) == CFBooleanGetTypeID ()) && CFBooleanGetValue (value);
2497 if (value) {
2498 CFRelease (value);
2499 }
2500 return entitled;
2501 }
2502
darwin_reload_device(struct libusb_device_handle * dev_handle)2503 static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
2504 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2505 enum libusb_error err;
2506
2507 usbi_mutex_lock(&darwin_cached_devices_lock);
2508 (*(dpriv->device))->Release(dpriv->device);
2509 dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
2510 if (!dpriv->device) {
2511 err = LIBUSB_ERROR_NO_DEVICE;
2512 } else {
2513 err = LIBUSB_SUCCESS;
2514 }
2515 usbi_mutex_unlock(&darwin_cached_devices_lock);
2516
2517 return err;
2518 }
2519
2520 /* On macOS, we capture an entire device at once, not individual interfaces. */
2521
darwin_detach_kernel_driver(struct libusb_device_handle * dev_handle,uint8_t interface)2522 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2523 UNUSED(interface);
2524 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2525 IOReturn kresult;
2526 enum libusb_error err;
2527 struct libusb_context *ctx = HANDLE_CTX (dev_handle);
2528
2529 if (HAS_CAPTURE_DEVICE()) {
2530 } else {
2531 return LIBUSB_ERROR_NOT_SUPPORTED;
2532 }
2533
2534 if (dpriv->capture_count == 0) {
2535 usbi_dbg (ctx, "attempting to detach kernel driver from device");
2536
2537 if (darwin_has_capture_entitlements ()) {
2538 /* request authorization */
2539 kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
2540 if (kresult != kIOReturnSuccess) {
2541 usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
2542 return darwin_to_libusb (kresult);
2543 }
2544
2545 /* we need start() to be called again for authorization status to refresh */
2546 err = darwin_reload_device (dev_handle);
2547 if (err != LIBUSB_SUCCESS) {
2548 return err;
2549 }
2550 } else {
2551 usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
2552 if (0 != geteuid()) {
2553 usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
2554 return LIBUSB_ERROR_ACCESS;
2555 }
2556 }
2557
2558 /* reset device to release existing drivers */
2559 err = darwin_reenumerate_device (dev_handle, true);
2560 if (err != LIBUSB_SUCCESS) {
2561 return err;
2562 }
2563 }
2564 dpriv->capture_count++;
2565 return LIBUSB_SUCCESS;
2566 }
2567
2568
darwin_attach_kernel_driver(struct libusb_device_handle * dev_handle,uint8_t interface)2569 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface) {
2570 UNUSED(interface);
2571 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2572
2573 if (HAS_CAPTURE_DEVICE()) {
2574 } else {
2575 return LIBUSB_ERROR_NOT_SUPPORTED;
2576 }
2577
2578 dpriv->capture_count--;
2579 if (dpriv->capture_count > 0) {
2580 return LIBUSB_SUCCESS;
2581 }
2582
2583 usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
2584
2585 /* reset device to attach kernel drivers */
2586 return darwin_reenumerate_device (dev_handle, false);
2587 }
2588
darwin_capture_claim_interface(struct libusb_device_handle * dev_handle,uint8_t iface)2589 static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2590 enum libusb_error ret;
2591 if (dev_handle->auto_detach_kernel_driver && darwin_kernel_driver_active(dev_handle, iface)) {
2592 ret = darwin_detach_kernel_driver (dev_handle, iface);
2593 if (ret != LIBUSB_SUCCESS) {
2594 usbi_info (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret);
2595 }
2596 }
2597
2598 return darwin_claim_interface (dev_handle, iface);
2599 }
2600
darwin_capture_release_interface(struct libusb_device_handle * dev_handle,uint8_t iface)2601 static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) {
2602 enum libusb_error ret;
2603 struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
2604
2605 ret = darwin_release_interface (dev_handle, iface);
2606 if (ret != LIBUSB_SUCCESS) {
2607 return ret;
2608 }
2609
2610 if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) {
2611 ret = darwin_attach_kernel_driver (dev_handle, iface);
2612 if (LIBUSB_SUCCESS != ret) {
2613 usbi_info (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret);
2614 }
2615 /* ignore the error as the interface was successfully released */
2616 }
2617
2618 return LIBUSB_SUCCESS;
2619 }
2620
2621 #endif
2622
2623 const struct usbi_os_backend usbi_backend = {
2624 .name = "Darwin",
2625 .caps = USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
2626 .init = darwin_init,
2627 .exit = darwin_exit,
2628 .get_active_config_descriptor = darwin_get_active_config_descriptor,
2629 .get_config_descriptor = darwin_get_config_descriptor,
2630 .hotplug_poll = darwin_hotplug_poll,
2631
2632 .open = darwin_open,
2633 .close = darwin_close,
2634 .get_configuration = darwin_get_configuration,
2635 .set_configuration = darwin_set_configuration,
2636
2637 .set_interface_altsetting = darwin_set_interface_altsetting,
2638 .clear_halt = darwin_clear_halt,
2639 .reset_device = darwin_reset_device,
2640
2641 #if InterfaceVersion >= 550
2642 .alloc_streams = darwin_alloc_streams,
2643 .free_streams = darwin_free_streams,
2644 #endif
2645
2646 .kernel_driver_active = darwin_kernel_driver_active,
2647
2648 #if InterfaceVersion >= 700
2649 .detach_kernel_driver = darwin_detach_kernel_driver,
2650 .attach_kernel_driver = darwin_attach_kernel_driver,
2651 .claim_interface = darwin_capture_claim_interface,
2652 .release_interface = darwin_capture_release_interface,
2653 #else
2654 .claim_interface = darwin_claim_interface,
2655 .release_interface = darwin_release_interface,
2656 #endif
2657
2658 .destroy_device = darwin_destroy_device,
2659
2660 .submit_transfer = darwin_submit_transfer,
2661 .cancel_transfer = darwin_cancel_transfer,
2662
2663 .handle_transfer_completion = darwin_handle_transfer_completion,
2664
2665 .device_priv_size = sizeof(struct darwin_device_priv),
2666 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
2667 .transfer_priv_size = sizeof(struct darwin_transfer_priv),
2668 };
2669