OS X: Use kCFNumberSInt32Type when reading device location from the IO registry
[libusbx.git] / libusb / os / darwin_usb.c
blob47d796177d23a8b3b6505e28525bed73d3c94d86
1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
2 /*
3 * darwin backend for libusbx 1.0
4 * Copyright © 2008-2012 Nathan Hjelm <hjelmn@users.sourceforge.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "config.h"
22 #include <ctype.h>
23 #include <dirent.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <pthread.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/ioctl.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <libkern/OSAtomic.h>
36 #include <mach/clock.h>
37 #include <mach/clock_types.h>
38 #include <mach/mach_host.h>
39 #include <mach/mach_port.h>
41 #include <AvailabilityMacros.h>
42 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
43 #include <objc/objc-auto.h>
44 #endif
46 #include <IOKit/IOCFBundle.h>
47 #include <IOKit/usb/IOUSBLib.h>
48 #include <IOKit/IOCFPlugIn.h>
50 #include "darwin_usb.h"
52 /* async event thread */
53 static pthread_mutex_t libusb_darwin_at_mutex;
54 static pthread_cond_t libusb_darwin_at_cond;
56 static clock_serv_t clock_realtime;
57 static clock_serv_t clock_monotonic;
59 static CFRunLoopRef libusb_darwin_acfl = NULL; /* async cf loop */
60 static volatile int32_t initCount = 0;
62 /* async event thread */
63 static pthread_t libusb_darwin_at;
65 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian);
66 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface);
67 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface);
68 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
69 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
71 #ifdef ENABLE_LOGGING
72 static const char *darwin_error_str (int result) {
73 switch (result) {
74 case kIOReturnSuccess:
75 return "no error";
76 case kIOReturnNotOpen:
77 return "device not opened for exclusive access";
78 case kIOReturnNoDevice:
79 return "no connection to an IOService";
80 case kIOUSBNoAsyncPortErr:
81 return "no async port has been opened for interface";
82 case kIOReturnExclusiveAccess:
83 return "another process has device opened for exclusive access";
84 case kIOUSBPipeStalled:
85 return "pipe is stalled";
86 case kIOReturnError:
87 return "could not establish a connection to the Darwin kernel";
88 case kIOUSBTransactionTimeout:
89 return "transaction timed out";
90 case kIOReturnBadArgument:
91 return "invalid argument";
92 case kIOReturnAborted:
93 return "transaction aborted";
94 case kIOReturnNotResponding:
95 return "device not responding";
96 case kIOReturnOverrun:
97 return "data overrun";
98 case kIOReturnCannotWire:
99 return "physical memory can not be wired down";
100 default:
101 return "unknown error";
104 #endif
106 static int darwin_to_libusb (int result) {
107 switch (result) {
108 case kIOReturnUnderrun:
109 case kIOReturnSuccess:
110 return LIBUSB_SUCCESS;
111 case kIOReturnNotOpen:
112 case kIOReturnNoDevice:
113 return LIBUSB_ERROR_NO_DEVICE;
114 case kIOReturnExclusiveAccess:
115 return LIBUSB_ERROR_ACCESS;
116 case kIOUSBPipeStalled:
117 return LIBUSB_ERROR_PIPE;
118 case kIOReturnBadArgument:
119 return LIBUSB_ERROR_INVALID_PARAM;
120 case kIOUSBTransactionTimeout:
121 return LIBUSB_ERROR_TIMEOUT;
122 case kIOReturnNotResponding:
123 case kIOReturnAborted:
124 case kIOReturnError:
125 case kIOUSBNoAsyncPortErr:
126 default:
127 return LIBUSB_ERROR_OTHER;
132 static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp) {
133 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
135 /* current interface */
136 struct darwin_interface *cInterface;
138 int8_t i, iface;
140 usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
142 for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
143 cInterface = &priv->interfaces[iface];
145 if (dev_handle->claimed_interfaces & (1 << iface)) {
146 for (i = 0 ; i < cInterface->num_endpoints ; i++) {
147 if (cInterface->endpoint_addrs[i] == ep) {
148 *pipep = i + 1;
149 *ifcp = iface;
150 usbi_dbg ("pipe %d on interface %d matches", *pipep, *ifcp);
151 return 0;
157 /* No pipe found with the correct endpoint address */
158 usbi_warn (HANDLE_CTX(dev_handle), "no pipeRef found with endpoint address 0x%02x.", ep);
160 return -1;
163 static int usb_setup_device_iterator (io_iterator_t *deviceIterator, UInt32 location) {
164 CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
166 if (!matchingDict)
167 return kIOReturnError;
169 if (location) {
170 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
171 &kCFTypeDictionaryKeyCallBacks,
172 &kCFTypeDictionaryValueCallBacks);
174 if (propertyMatchDict) {
175 /* there are no unsigned CFNumber types so treat the value as signed. the os seems to do this
176 internally (CFNumberType of locationID is 3) */
177 CFTypeRef locationCF = CFNumberCreate (NULL, kCFNumberSInt32Type, &location);
179 CFDictionarySetValue (propertyMatchDict, CFSTR(kUSBDevicePropertyLocationID), locationCF);
180 /* release our reference to the CFNumber (CFDictionarySetValue retains it) */
181 CFRelease (locationCF);
183 CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
184 /* release out reference to the CFMutableDictionaryRef (CFDictionarySetValue retains it) */
185 CFRelease (propertyMatchDict);
187 /* else we can still proceed as long as the caller accounts for the possibility of other devices in the iterator */
190 return IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, deviceIterator);
193 static int get_ioregistry_value_number (io_service_t service, CFStringRef property, CFNumberType type, void *p) {
194 CFTypeRef cfNumber = IORegistryEntryCreateCFProperty (service, property, kCFAllocatorDefault, 0);
195 int ret = 0;
197 if (cfNumber) {
198 if (CFGetTypeID(cfNumber) == CFNumberGetTypeID()) {
199 ret = CFNumberGetValue(cfNumber, type, p);
202 CFRelease (cfNumber);
205 return ret;
208 static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp, UInt8 *portp, UInt32 *parent_locationp) {
209 io_cf_plugin_ref_t *plugInInterface = NULL;
210 usb_device_t **device;
211 io_service_t usbDevice, parent;
212 kern_return_t result;
213 SInt32 score;
215 if (!IOIteratorIsValid (deviceIterator))
216 return NULL;
219 while ((usbDevice = IOIteratorNext(deviceIterator))) {
220 result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
221 kIOCFPlugInInterfaceID, &plugInInterface,
222 &score);
224 /* we are done with the usb_device_t */
225 (void)IOObjectRelease(usbDevice);
227 if (portp) {
228 *portp = 0;
229 (void) get_ioregistry_value_number (usbDevice, CFSTR("PortNum"), kCFNumberSInt8Type, portp);
232 if (parent_locationp) {
233 *parent_locationp = 0;
235 result = IORegistryEntryGetParentEntry (usbDevice, kIOUSBPlane, &parent);
237 if (kIOReturnSuccess == result) {
238 (void) get_ioregistry_value_number (parent, CFSTR("locationID"), kCFNumberLongType, parent_locationp);
242 if (kIOReturnSuccess == result && plugInInterface)
243 break;
245 usbi_dbg ("libusb/darwin.c usb_get_next_device: could not set up plugin for service: %s\n", darwin_error_str (result));
248 if (!usbDevice)
249 return NULL;
251 (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
252 (LPVOID)&device);
253 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
254 (*plugInInterface)->Release (plugInInterface);
256 /* get the location from the device */
257 if (locationp)
258 (*(device))->GetLocationID(device, locationp);
260 return device;
263 static kern_return_t darwin_get_device (uint32_t dev_location, usb_device_t ***darwin_device) {
264 kern_return_t kresult;
265 UInt32 location;
266 io_iterator_t deviceIterator;
268 kresult = usb_setup_device_iterator (&deviceIterator, dev_location);
269 if (kresult)
270 return kresult;
272 /* This port of libusb uses locations to keep track of devices. */
273 while ((*darwin_device = usb_get_next_device (deviceIterator, &location, NULL, NULL)) != NULL) {
274 if (location == dev_location)
275 break;
277 (**darwin_device)->Release(*darwin_device);
280 IOObjectRelease (deviceIterator);
282 if (!(*darwin_device))
283 return kIOReturnNoDevice;
285 return kIOReturnSuccess;
290 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
291 struct libusb_context *ctx = (struct libusb_context *)ptr;
292 struct libusb_device_handle *handle;
293 struct darwin_device_priv *dpriv;
294 struct darwin_device_handle_priv *priv;
296 io_service_t device;
297 UInt32 location;
298 bool locationValid;
299 CFTypeRef locationCF;
300 UInt32 message;
302 usbi_dbg ("a device has been detached");
304 while ((device = IOIteratorNext (rem_devices)) != 0) {
305 /* get the location from the i/o registry */
306 locationCF = IORegistryEntryCreateCFProperty (device, CFSTR(kUSBDevicePropertyLocationID), kCFAllocatorDefault, 0);
308 IOObjectRelease (device);
310 if (!locationCF)
311 continue;
313 locationValid = CFGetTypeID(locationCF) == CFNumberGetTypeID() &&
314 CFNumberGetValue(locationCF, kCFNumberSInt32Type, &location);
316 CFRelease (locationCF);
318 if (!locationValid)
319 continue;
321 usbi_mutex_lock(&ctx->open_devs_lock);
322 list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
323 dpriv = (struct darwin_device_priv *)handle->dev->os_priv;
325 /* the device may have been opened several times. write to each handle's event descriptor */
326 if (dpriv->location == location && handle->os_priv) {
327 priv = (struct darwin_device_handle_priv *)handle->os_priv;
329 message = MESSAGE_DEVICE_GONE;
330 write (priv->fds[1], &message, sizeof (message));
334 usbi_mutex_unlock(&ctx->open_devs_lock);
338 static void darwin_clear_iterator (io_iterator_t iter) {
339 io_service_t device;
341 while ((device = IOIteratorNext (iter)) != 0)
342 IOObjectRelease (device);
345 static void *event_thread_main (void *arg0) {
346 IOReturn kresult;
347 struct libusb_context *ctx = (struct libusb_context *)arg0;
348 CFRunLoopRef runloop;
350 /* Set this thread's name, so it can be seen in the debugger
351 and crash reports. */
352 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
353 pthread_setname_np ("org.libusb.device-detach");
354 #endif
356 /* Tell the Objective-C garbage collector about this thread.
357 This is required because, unlike NSThreads, pthreads are
358 not automatically registered. Although we don't use
359 Objective-C, we use CoreFoundation, which does. */
360 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
361 objc_registerThreadWithCollector();
362 #endif
364 /* hotplug (device removal) source */
365 CFRunLoopSourceRef libusb_notification_cfsource;
366 io_notification_port_t libusb_notification_port;
367 io_iterator_t libusb_rem_device_iterator;
369 usbi_dbg ("creating hotplug event source");
371 runloop = CFRunLoopGetCurrent ();
372 CFRetain (runloop);
374 /* add the notification port to the run loop */
375 libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
376 libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
377 CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
379 /* create notifications for removed devices */
380 kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
381 IOServiceMatching(kIOUSBDeviceClassName),
382 (IOServiceMatchingCallback)darwin_devices_detached,
383 (void *)ctx, &libusb_rem_device_iterator);
385 if (kresult != kIOReturnSuccess) {
386 usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
388 pthread_exit (NULL);
391 /* arm notifiers */
392 darwin_clear_iterator (libusb_rem_device_iterator);
394 usbi_dbg ("thread ready to receive events");
396 /* signal the main thread that the async runloop has been created. */
397 pthread_mutex_lock (&libusb_darwin_at_mutex);
398 libusb_darwin_acfl = runloop;
399 pthread_cond_signal (&libusb_darwin_at_cond);
400 pthread_mutex_unlock (&libusb_darwin_at_mutex);
402 /* run the runloop */
403 CFRunLoopRun();
405 usbi_dbg ("thread exiting");
407 /* delete notification port */
408 IONotificationPortDestroy (libusb_notification_port);
409 IOObjectRelease (libusb_rem_device_iterator);
411 CFRelease (runloop);
413 libusb_darwin_acfl = NULL;
415 pthread_exit (NULL);
418 static int darwin_init(struct libusb_context *ctx) {
419 host_name_port_t host_self;
421 if (OSAtomicIncrement32Barrier(&initCount) == 1) {
422 /* create the clocks that will be used */
424 host_self = mach_host_self();
425 host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
426 host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
427 mach_port_deallocate(mach_task_self(), host_self);
429 pthread_mutex_init (&libusb_darwin_at_mutex, NULL);
430 pthread_cond_init (&libusb_darwin_at_cond, NULL);
432 pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx);
434 pthread_mutex_lock (&libusb_darwin_at_mutex);
435 while (!libusb_darwin_acfl)
436 pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
437 pthread_mutex_unlock (&libusb_darwin_at_mutex);
440 return 0;
443 static void darwin_exit (void) {
444 if (OSAtomicDecrement32Barrier(&initCount) == 0) {
445 mach_port_deallocate(mach_task_self(), clock_realtime);
446 mach_port_deallocate(mach_task_self(), clock_monotonic);
448 /* stop the async runloop and wait for the thread to terminate. */
449 CFRunLoopStop (libusb_darwin_acfl);
450 pthread_join (libusb_darwin_at, NULL);
454 static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
455 struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
457 /* return cached copy */
458 memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
460 *host_endian = 0;
462 return 0;
465 static int get_configuration_index (struct libusb_device *dev, int config_value) {
466 struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
467 UInt8 i, numConfig;
468 IOUSBConfigurationDescriptorPtr desc;
469 IOReturn kresult;
471 /* is there a simpler way to determine the index? */
472 kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
473 if (kresult != kIOReturnSuccess)
474 return darwin_to_libusb (kresult);
476 for (i = 0 ; i < numConfig ; i++) {
477 (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
479 if (desc->bConfigurationValue == config_value)
480 return i;
483 /* configuration not found */
484 return LIBUSB_ERROR_OTHER;
487 static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) {
488 struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
489 int config_index;
491 if (0 == priv->active_config)
492 return LIBUSB_ERROR_INVALID_PARAM;
494 config_index = get_configuration_index (dev, priv->active_config);
495 if (config_index < 0)
496 return config_index;
498 return darwin_get_config_descriptor (dev, config_index, buffer, len, host_endian);
501 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) {
502 struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
503 IOUSBConfigurationDescriptorPtr desc;
504 IOReturn kresult;
505 usb_device_t **device = NULL;
507 if (!priv)
508 return LIBUSB_ERROR_OTHER;
510 if (!priv->device) {
511 kresult = darwin_get_device (priv->location, &device);
512 if (kresult || !device) {
513 usbi_err (DEVICE_CTX (dev), "could not find device: %s", darwin_error_str (kresult));
515 return darwin_to_libusb (kresult);
518 /* don't have to open the device to get a config descriptor */
519 } else
520 device = priv->device;
522 kresult = (*device)->GetConfigurationDescriptorPtr (device, config_index, &desc);
523 if (kresult == kIOReturnSuccess) {
524 /* copy descriptor */
525 if (libusb_le16_to_cpu(desc->wTotalLength) < len)
526 len = libusb_le16_to_cpu(desc->wTotalLength);
528 memmove (buffer, desc, len);
530 /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */
531 *host_endian = 0;
534 if (!priv->device)
535 (*device)->Release (device);
537 return darwin_to_libusb (kresult);
540 /* check whether the os has configured the device */
541 static int darwin_check_configuration (struct libusb_context *ctx, struct libusb_device *dev, usb_device_t **darwin_device) {
542 struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
544 IOUSBConfigurationDescriptorPtr configDesc;
545 IOUSBFindInterfaceRequest request;
546 kern_return_t kresult;
547 io_iterator_t interface_iterator;
548 io_service_t firstInterface;
550 if (priv->dev_descriptor.bNumConfigurations < 1) {
551 usbi_err (ctx, "device has no configurations");
552 return LIBUSB_ERROR_OTHER; /* no configurations at this speed so we can't use it */
555 /* find the first configuration */
556 kresult = (*darwin_device)->GetConfigurationDescriptorPtr (darwin_device, 0, &configDesc);
557 priv->first_config = (kIOReturnSuccess == kresult) ? configDesc->bConfigurationValue : 1;
559 /* check if the device is already configured. there is probably a better way than iterating over the
560 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
561 might lock up on the device request) */
563 /* Setup the Interface Request */
564 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
565 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
566 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
567 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
569 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
570 if (kresult)
571 return darwin_to_libusb (kresult);
573 /* iterate once */
574 firstInterface = IOIteratorNext(interface_iterator);
576 /* done with the interface iterator */
577 IOObjectRelease(interface_iterator);
579 if (firstInterface) {
580 IOObjectRelease (firstInterface);
582 /* device is configured */
583 if (priv->dev_descriptor.bNumConfigurations == 1)
584 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
585 priv->active_config = priv->first_config;
586 else
587 /* devices with more than one configuration should work with GetConfiguration */
588 (*darwin_device)->GetConfiguration (darwin_device, &priv->active_config);
589 } else
590 /* not configured */
591 priv->active_config = 0;
593 usbi_dbg ("active config: %u, first config: %u", priv->active_config, priv->first_config);
595 return 0;
598 static int darwin_cache_device_descriptor (struct libusb_context *ctx, struct libusb_device *dev, usb_device_t **device) {
599 struct darwin_device_priv *priv;
600 int retries = 2, delay = 30000;
601 int unsuspended = 0, try_unsuspend = 1, try_reconfigure = 1;
602 int is_open = 0;
603 int ret = 0, ret2;
604 IOUSBDevRequest req;
605 UInt8 bDeviceClass;
606 UInt16 idProduct, idVendor;
608 (*device)->GetDeviceClass (device, &bDeviceClass);
609 (*device)->GetDeviceProduct (device, &idProduct);
610 (*device)->GetDeviceVendor (device, &idVendor);
612 priv = (struct darwin_device_priv *)dev->os_priv;
614 /* try to open the device (we can usually continue even if this fails) */
615 is_open = ((*device)->USBDeviceOpenSeize(device) == kIOReturnSuccess);
617 /**** retrieve device descriptor ****/
618 do {
619 /* Set up request for device descriptor */
620 memset (&(priv->dev_descriptor), 0, sizeof(IOUSBDeviceDescriptor));
621 req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
622 req.bRequest = kUSBRqGetDescriptor;
623 req.wValue = kUSBDeviceDesc << 8;
624 req.wIndex = 0;
625 req.wLength = sizeof(priv->dev_descriptor);
626 req.pData = &(priv->dev_descriptor);
628 /* according to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
629 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request. Still,
630 * to follow the spec as closely as possible, try opening the device */
632 ret = (*(device))->DeviceRequest (device, &req);
634 if (kIOReturnOverrun == ret && kUSBDeviceDesc == priv->dev_descriptor.bDescriptorType)
635 /* received an overrun error but we still received a device descriptor */
636 ret = kIOReturnSuccess;
638 if (kIOUSBVendorIDAppleComputer == idVendor) {
639 /* NTH: don't bother retrying or unsuspending Apple devices */
640 break;
643 if (kIOReturnSuccess == ret && (0 == priv->dev_descriptor.bNumConfigurations ||
644 0 == priv->dev_descriptor.bcdUSB)) {
645 /* work around for incorrectly configured devices */
646 if (try_reconfigure && is_open) {
647 usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
649 /* set the first configuration */
650 (*device)->SetConfiguration(device, 1);
652 /* don't try to reconfigure again */
653 try_reconfigure = 0;
656 ret = kIOUSBPipeStalled;
659 if (kIOReturnSuccess != ret && is_open && try_unsuspend) {
660 /* device may be suspended. unsuspend it and try again */
661 #if DeviceVersion >= 320
662 UInt32 info;
664 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
665 (void)(*device)->GetUSBDeviceInformation (device, &info);
667 try_unsuspend = info & (1 << kUSBInformationDeviceIsSuspendedBit);
668 #endif
670 if (try_unsuspend) {
671 /* resume the device */
672 ret2 = (*device)->USBDeviceSuspend (device, 0);
673 if (kIOReturnSuccess != ret2) {
674 /* prevent log spew from poorly behaving devices. this indicates the
675 os actually had trouble communicating with the device */
676 usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
677 } else
678 unsuspended = 1;
680 try_unsuspend = 0;
684 if (kIOReturnSuccess != ret) {
685 usbi_dbg("kernel responded with code: 0x%08x. sleeping for %d ms before trying again", ret, delay/1000);
686 /* sleep for a little while before trying again */
687 usleep (delay);
689 } while (kIOReturnSuccess != ret && retries--);
691 if (unsuspended)
692 /* resuspend the device */
693 (void)(*device)->USBDeviceSuspend (device, 1);
695 if (is_open)
696 (void) (*device)->USBDeviceClose (device);
698 if (ret != kIOReturnSuccess) {
699 /* a debug message was already printed out for this error */
700 if (LIBUSB_CLASS_HUB == bDeviceClass)
701 usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s. skipping device", idVendor, idProduct, darwin_error_str (ret));
702 else
703 usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s. skipping device", idVendor, idProduct, darwin_error_str (ret));
705 return -1;
708 usbi_dbg ("device descriptor:");
709 usbi_dbg (" bDescriptorType: 0x%02x", priv->dev_descriptor.bDescriptorType);
710 usbi_dbg (" bcdUSB: 0x%04x", priv->dev_descriptor.bcdUSB);
711 usbi_dbg (" bDeviceClass: 0x%02x", priv->dev_descriptor.bDeviceClass);
712 usbi_dbg (" bDeviceSubClass: 0x%02x", priv->dev_descriptor.bDeviceSubClass);
713 usbi_dbg (" bDeviceProtocol: 0x%02x", priv->dev_descriptor.bDeviceProtocol);
714 usbi_dbg (" bMaxPacketSize0: 0x%02x", priv->dev_descriptor.bMaxPacketSize0);
715 usbi_dbg (" idVendor: 0x%04x", priv->dev_descriptor.idVendor);
716 usbi_dbg (" idProduct: 0x%04x", priv->dev_descriptor.idProduct);
717 usbi_dbg (" bcdDevice: 0x%04x", priv->dev_descriptor.bcdDevice);
718 usbi_dbg (" iManufacturer: 0x%02x", priv->dev_descriptor.iManufacturer);
719 usbi_dbg (" iProduct: 0x%02x", priv->dev_descriptor.iProduct);
720 usbi_dbg (" iSerialNumber: 0x%02x", priv->dev_descriptor.iSerialNumber);
721 usbi_dbg (" bNumConfigurations: 0x%02x", priv->dev_descriptor.bNumConfigurations);
723 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
724 if (libusb_le16_to_cpu (priv->dev_descriptor.idProduct) != idProduct) {
725 /* not a valid device */
726 usbi_warn (ctx, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
727 idProduct, libusb_le16_to_cpu (priv->dev_descriptor.idProduct));
728 return -1;
731 return 0;
734 static int process_new_device (struct libusb_context *ctx, usb_device_t **device, UInt32 locationID,
735 UInt32 parent_location, UInt8 port, struct discovered_devs **_discdevs,
736 struct libusb_device **last_dev) {
737 struct darwin_device_priv *priv;
738 struct libusb_device *dev, *parent = NULL;
739 struct discovered_devs *discdevs;
740 UInt16 address;
741 UInt8 devSpeed;
742 int ret = 0, need_unref = 0;
744 do {
745 dev = usbi_get_device_by_session_id(ctx, locationID);
746 if (!dev) {
747 usbi_dbg ("allocating new device for location 0x%08x", locationID);
748 dev = usbi_alloc_device(ctx, locationID);
749 need_unref = 1;
750 } else
751 usbi_dbg ("using existing device for location 0x%08x", locationID);
753 if (!dev) {
754 ret = LIBUSB_ERROR_NO_MEM;
755 break;
758 priv = (struct darwin_device_priv *)dev->os_priv;
760 (*device)->GetDeviceAddress (device, (USBDeviceAddress *)&address);
762 ret = darwin_cache_device_descriptor (ctx, dev, device);
763 if (ret < 0)
764 break;
766 /* check current active configuration (and cache the first configuration value-- which may be used by claim_interface) */
767 ret = darwin_check_configuration (ctx, dev, device);
768 if (ret < 0)
769 break;
771 /* the device iterator provides devices in increasing order of location. given this property
772 * we can use the last device to find the parent. */
773 for (parent = *last_dev ; parent ; parent = parent->parent_dev) {
774 struct darwin_device_priv *parent_priv = (struct darwin_device_priv *) parent->os_priv;
776 if (parent_priv->location == parent_location) {
777 break;
781 dev->parent_dev = parent;
783 dev->port_number = port;
784 dev->bus_number = locationID >> 24;
785 dev->device_address = address;
787 (*device)->GetDeviceSpeed (device, &devSpeed);
789 switch (devSpeed) {
790 case kUSBDeviceSpeedLow: dev->speed = LIBUSB_SPEED_LOW; break;
791 case kUSBDeviceSpeedFull: dev->speed = LIBUSB_SPEED_FULL; break;
792 case kUSBDeviceSpeedHigh: dev->speed = LIBUSB_SPEED_HIGH; break;
793 #if DeviceVersion >= 500
794 case kUSBDeviceSpeedSuper: dev->speed = LIBUSB_SPEED_SUPER; break;
795 #endif
796 default:
797 usbi_warn (ctx, "Got unknown device speed %d", devSpeed);
800 /* save our location, we'll need this later */
801 priv->location = locationID;
802 snprintf(priv->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", address, priv->dev_descriptor.idVendor, priv->dev_descriptor.idProduct,
803 priv->dev_descriptor.bDeviceClass, priv->dev_descriptor.bDeviceSubClass);
805 ret = usbi_sanitize_device (dev);
806 if (ret < 0)
807 break;
809 /* append the device to the list of discovered devices */
810 discdevs = discovered_devs_append(*_discdevs, dev);
811 if (!discdevs) {
812 ret = LIBUSB_ERROR_NO_MEM;
813 break;
816 *_discdevs = discdevs;
817 *last_dev = dev;
819 usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
820 dev->port_number, priv->sys_path, (void *) parent);
821 } while (0);
823 if (need_unref)
824 libusb_unref_device(dev);
826 return ret;
829 static int darwin_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) {
830 io_iterator_t deviceIterator;
831 usb_device_t **device;
832 kern_return_t kresult;
833 UInt32 location, parent_location;
834 UInt8 port;
835 struct libusb_device *last_dev = NULL;
837 kresult = usb_setup_device_iterator (&deviceIterator, 0);
838 if (kresult != kIOReturnSuccess)
839 return darwin_to_libusb (kresult);
841 while ((device = usb_get_next_device (deviceIterator, &location, &port, &parent_location)) != NULL) {
842 (void) process_new_device (ctx, device, location, parent_location, port, _discdevs, &last_dev);
844 (*(device))->Release(device);
847 IOObjectRelease(deviceIterator);
849 return 0;
852 static int darwin_open (struct libusb_device_handle *dev_handle) {
853 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
854 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
855 usb_device_t **darwin_device;
856 IOReturn kresult;
858 if (0 == dpriv->open_count) {
859 kresult = darwin_get_device (dpriv->location, &darwin_device);
860 if (kresult) {
861 usbi_err (HANDLE_CTX (dev_handle), "could not find device: %s", darwin_error_str (kresult));
862 return darwin_to_libusb (kresult);
865 dpriv->device = darwin_device;
867 /* try to open the device */
868 kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
870 if (kresult != kIOReturnSuccess) {
871 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceOpen: %s", darwin_error_str(kresult));
873 switch (kresult) {
874 case kIOReturnExclusiveAccess:
875 /* it is possible to perform some actions on a device that is not open so do not return an error */
876 priv->is_open = 0;
878 break;
879 default:
880 (*(dpriv->device))->Release (dpriv->device);
881 dpriv->device = NULL;
882 return darwin_to_libusb (kresult);
884 } else {
885 /* create async event source */
886 kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
887 if (kresult != kIOReturnSuccess) {
888 usbi_err (HANDLE_CTX (dev_handle), "CreateDeviceAsyncEventSource: %s", darwin_error_str(kresult));
890 (*(dpriv->device))->USBDeviceClose (dpriv->device);
891 (*(dpriv->device))->Release (dpriv->device);
893 dpriv->device = NULL;
894 return darwin_to_libusb (kresult);
897 priv->is_open = 1;
899 CFRetain (libusb_darwin_acfl);
901 /* add the cfSource to the aync run loop */
902 CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
906 /* device opened successfully */
907 dpriv->open_count++;
909 /* create a file descriptor for notifications */
910 pipe (priv->fds);
912 /* set the pipe to be non-blocking */
913 fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
915 usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
917 usbi_dbg ("device open for access");
919 return 0;
922 static void darwin_close (struct libusb_device_handle *dev_handle) {
923 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
924 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
925 IOReturn kresult;
926 int i;
928 if (dpriv->open_count == 0) {
929 /* something is probably very wrong if this is the case */
930 usbi_err (HANDLE_CTX (dev_handle), "Close called on a device that was not open!\n");
931 return;
934 dpriv->open_count--;
936 /* make sure all interfaces are released */
937 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
938 if (dev_handle->claimed_interfaces & (1 << i))
939 libusb_release_interface (dev_handle, i);
941 if (0 == dpriv->open_count) {
942 if (priv->is_open) {
943 /* delete the device's async event source */
944 if (priv->cfSource) {
945 CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
946 CFRelease (priv->cfSource);
949 /* close the device */
950 kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
951 if (kresult) {
952 /* Log the fact that we had a problem closing the file, however failing a
953 * close isn't really an error, so return success anyway */
954 usbi_warn (HANDLE_CTX (dev_handle), "USBDeviceClose: %s", darwin_error_str(kresult));
958 kresult = (*(dpriv->device))->Release(dpriv->device);
959 if (kresult) {
960 /* Log the fact that we had a problem closing the file, however failing a
961 * close isn't really an error, so return success anyway */
962 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
965 dpriv->device = NULL;
968 /* file descriptors are maintained per-instance */
969 usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
970 close (priv->fds[1]);
971 close (priv->fds[0]);
973 priv->fds[0] = priv->fds[1] = -1;
976 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
977 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
979 *config = (int) dpriv->active_config;
981 return 0;
984 static int darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
985 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
986 IOReturn kresult;
987 int i;
989 /* Setting configuration will invalidate the interface, so we need
990 to reclaim it. First, dispose of existing interfaces, if any. */
991 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
992 if (dev_handle->claimed_interfaces & (1 << i))
993 darwin_release_interface (dev_handle, i);
995 kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, config);
996 if (kresult != kIOReturnSuccess)
997 return darwin_to_libusb (kresult);
999 /* Reclaim any interfaces. */
1000 for (i = 0 ; i < USB_MAXINTERFACES ; i++)
1001 if (dev_handle->claimed_interfaces & (1 << i))
1002 darwin_claim_interface (dev_handle, i);
1004 dpriv->active_config = config;
1006 return 0;
1009 static int darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
1010 IOUSBFindInterfaceRequest request;
1011 uint8_t current_interface;
1012 kern_return_t kresult;
1013 io_iterator_t interface_iterator;
1015 *usbInterfacep = IO_OBJECT_NULL;
1017 /* Setup the Interface Request */
1018 request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
1019 request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
1020 request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
1021 request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
1023 kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
1024 if (kresult)
1025 return kresult;
1027 for ( current_interface = 0 ; current_interface <= ifc ; current_interface++ ) {
1028 *usbInterfacep = IOIteratorNext(interface_iterator);
1029 if (current_interface != ifc)
1030 (void) IOObjectRelease (*usbInterfacep);
1033 /* done with the interface iterator */
1034 IOObjectRelease(interface_iterator);
1036 return 0;
1039 static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
1040 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1042 /* current interface */
1043 struct darwin_interface *cInterface = &priv->interfaces[iface];
1045 kern_return_t kresult;
1047 u_int8_t numep, direction, number;
1048 u_int8_t dont_care1, dont_care3;
1049 u_int16_t dont_care2;
1050 int i;
1052 usbi_dbg ("building table of endpoints.");
1054 /* retrieve the total number of endpoints on this interface */
1055 kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
1056 if (kresult) {
1057 usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
1058 return darwin_to_libusb (kresult);
1061 /* iterate through pipe references */
1062 for (i = 1 ; i <= numep ; i++) {
1063 kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
1064 &dont_care2, &dont_care3);
1066 if (kresult != kIOReturnSuccess) {
1067 usbi_err (HANDLE_CTX (dev_handle), "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult));
1069 return darwin_to_libusb (kresult);
1072 usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
1074 cInterface->endpoint_addrs[i - 1] = ((direction << 7 & LIBUSB_ENDPOINT_DIR_MASK) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
1077 cInterface->num_endpoints = numep;
1079 return 0;
1082 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
1083 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
1084 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1085 io_service_t usbInterface = IO_OBJECT_NULL;
1086 IOReturn kresult;
1087 IOCFPlugInInterface **plugInInterface = NULL;
1088 SInt32 score;
1090 /* current interface */
1091 struct darwin_interface *cInterface = &priv->interfaces[iface];
1093 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1094 if (kresult != kIOReturnSuccess)
1095 return darwin_to_libusb (kresult);
1097 /* make sure we have an interface */
1098 if (!usbInterface && dpriv->first_config != 0) {
1099 usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
1101 /* set the configuration */
1102 kresult = darwin_set_configuration (dev_handle, dpriv->first_config);
1103 if (kresult != LIBUSB_SUCCESS) {
1104 usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
1105 return kresult;
1108 kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
1109 if (kresult) {
1110 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1111 return darwin_to_libusb (kresult);
1115 if (!usbInterface) {
1116 usbi_err (HANDLE_CTX (dev_handle), "interface not found");
1117 return LIBUSB_ERROR_NOT_FOUND;
1120 /* get an interface to the device's interface */
1121 kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
1122 kIOCFPlugInInterfaceID, &plugInInterface, &score);
1124 /* ignore release error */
1125 (void)IOObjectRelease (usbInterface);
1127 if (kresult) {
1128 usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
1129 return darwin_to_libusb (kresult);
1132 if (!plugInInterface) {
1133 usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
1134 return LIBUSB_ERROR_NOT_FOUND;
1137 /* Do the actual claim */
1138 kresult = (*plugInInterface)->QueryInterface(plugInInterface,
1139 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
1140 (LPVOID)&cInterface->interface);
1141 /* We no longer need the intermediate plug-in */
1142 /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
1143 (*plugInInterface)->Release (plugInInterface);
1144 if (kresult || !cInterface->interface) {
1145 usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
1146 return darwin_to_libusb (kresult);
1149 /* claim the interface */
1150 kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
1151 if (kresult) {
1152 usbi_err (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
1153 return darwin_to_libusb (kresult);
1156 /* update list of endpoints */
1157 kresult = get_endpoints (dev_handle, iface);
1158 if (kresult) {
1159 /* this should not happen */
1160 darwin_release_interface (dev_handle, iface);
1161 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1162 return kresult;
1165 cInterface->cfSource = NULL;
1167 /* create async event source */
1168 kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
1169 if (kresult != kIOReturnSuccess) {
1170 usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
1172 /* can't continue without an async event source */
1173 (void)darwin_release_interface (dev_handle, iface);
1175 return darwin_to_libusb (kresult);
1178 /* add the cfSource to the async thread's run loop */
1179 CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1181 usbi_dbg ("interface opened");
1183 return 0;
1186 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
1187 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1188 IOReturn kresult;
1190 /* current interface */
1191 struct darwin_interface *cInterface = &priv->interfaces[iface];
1193 /* Check to see if an interface is open */
1194 if (!cInterface->interface)
1195 return LIBUSB_SUCCESS;
1197 /* clean up endpoint data */
1198 cInterface->num_endpoints = 0;
1200 /* delete the interface's async event source */
1201 if (cInterface->cfSource) {
1202 CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
1203 CFRelease (cInterface->cfSource);
1206 kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
1207 if (kresult)
1208 usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult));
1210 kresult = (*(cInterface->interface))->Release(cInterface->interface);
1211 if (kresult != kIOReturnSuccess)
1212 usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult));
1214 cInterface->interface = IO_OBJECT_NULL;
1216 return darwin_to_libusb (kresult);
1219 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
1220 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1221 IOReturn kresult;
1223 /* current interface */
1224 struct darwin_interface *cInterface = &priv->interfaces[iface];
1226 if (!cInterface->interface)
1227 return LIBUSB_ERROR_NO_DEVICE;
1229 kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
1230 if (kresult != kIOReturnSuccess)
1231 darwin_reset_device (dev_handle);
1233 /* update list of endpoints */
1234 kresult = get_endpoints (dev_handle, iface);
1235 if (kresult) {
1236 /* this should not happen */
1237 darwin_release_interface (dev_handle, iface);
1238 usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
1239 return kresult;
1242 return darwin_to_libusb (kresult);
1245 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
1246 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
1248 /* current interface */
1249 struct darwin_interface *cInterface;
1250 uint8_t pipeRef, iface;
1251 IOReturn kresult;
1253 /* determine the interface/endpoint to use */
1254 if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, &iface) != 0) {
1255 usbi_err (HANDLE_CTX (dev_handle), "endpoint not found on any open interface");
1257 return LIBUSB_ERROR_NOT_FOUND;
1260 cInterface = &priv->interfaces[iface];
1262 #if (InterfaceVersion < 190)
1263 kresult = (*(cInterface->interface))->ClearPipeStall(cInterface->interface, pipeRef);
1264 #else
1265 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1266 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1267 #endif
1268 if (kresult)
1269 usbi_warn (HANDLE_CTX (dev_handle), "ClearPipeStall: %s", darwin_error_str (kresult));
1271 return darwin_to_libusb (kresult);
1274 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
1275 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
1276 IOReturn kresult;
1278 kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
1279 if (kresult)
1280 usbi_err (HANDLE_CTX (dev_handle), "ResetDevice: %s", darwin_error_str (kresult));
1282 return darwin_to_libusb (kresult);
1285 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
1286 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
1287 io_service_t usbInterface;
1288 CFTypeRef driver;
1289 IOReturn kresult;
1291 kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1292 if (kresult) {
1293 usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
1295 return darwin_to_libusb (kresult);
1298 driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1299 IOObjectRelease (usbInterface);
1301 if (driver) {
1302 CFRelease (driver);
1304 return 1;
1307 /* no driver */
1308 return 0;
1311 /* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */
1312 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
1313 (void)dev_handle;
1314 (void)interface;
1315 return LIBUSB_ERROR_NOT_SUPPORTED;
1318 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
1319 (void)dev_handle;
1320 (void)interface;
1321 return LIBUSB_ERROR_NOT_SUPPORTED;
1324 static void darwin_destroy_device(struct libusb_device *dev) {
1325 (void)dev;
1328 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1329 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1330 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1332 IOReturn ret;
1333 uint8_t transferType;
1334 /* None of the values below are used in libusbx for bulk transfers */
1335 uint8_t direction, number, interval, pipeRef, iface;
1336 uint16_t maxPacketSize;
1338 struct darwin_interface *cInterface;
1340 if (IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)
1341 return LIBUSB_ERROR_NOT_SUPPORTED;
1343 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1344 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1346 return LIBUSB_ERROR_NOT_FOUND;
1349 cInterface = &priv->interfaces[iface];
1351 (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1352 &transferType, &maxPacketSize, &interval);
1354 /* submit the request */
1355 /* timeouts are unavailable on interrupt endpoints */
1356 if (transferType == kUSBInterrupt) {
1357 if (IS_XFERIN(transfer))
1358 ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1359 transfer->length, darwin_async_io_callback, itransfer);
1360 else
1361 ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1362 transfer->length, darwin_async_io_callback, itransfer);
1363 } else {
1364 itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1366 if (IS_XFERIN(transfer))
1367 ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1368 transfer->length, transfer->timeout, transfer->timeout,
1369 darwin_async_io_callback, (void *)itransfer);
1370 else
1371 ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1372 transfer->length, transfer->timeout, transfer->timeout,
1373 darwin_async_io_callback, (void *)itransfer);
1376 if (ret)
1377 usbi_err (TRANSFER_CTX (transfer), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", IS_XFERIN(transfer) ? "In" : "Out",
1378 darwin_error_str(ret), ret);
1380 return darwin_to_libusb (ret);
1383 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1384 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1385 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1386 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1388 IOReturn kresult;
1389 uint8_t pipeRef, iface;
1390 UInt64 frame;
1391 AbsoluteTime atTime;
1392 int i;
1394 struct darwin_interface *cInterface;
1396 /* construct an array of IOUSBIsocFrames, reuse the old one if possible */
1397 if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) {
1398 free(tpriv->isoc_framelist);
1399 tpriv->isoc_framelist = NULL;
1402 if (!tpriv->isoc_framelist) {
1403 tpriv->num_iso_packets = transfer->num_iso_packets;
1404 tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1405 if (!tpriv->isoc_framelist)
1406 return LIBUSB_ERROR_NO_MEM;
1409 /* copy the frame list from the libusbx descriptor (the structures differ only is member order) */
1410 for (i = 0 ; i < transfer->num_iso_packets ; i++)
1411 tpriv->isoc_framelist[i].frReqCount = transfer->iso_packet_desc[i].length;
1413 /* determine the interface/endpoint to use */
1414 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1415 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1417 return LIBUSB_ERROR_NOT_FOUND;
1420 cInterface = &priv->interfaces[iface];
1422 /* Last but not least we need the bus frame number */
1423 kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1424 if (kresult) {
1425 usbi_err (TRANSFER_CTX (transfer), "failed to get bus frame number: %d", kresult);
1426 free(tpriv->isoc_framelist);
1427 tpriv->isoc_framelist = NULL;
1429 return darwin_to_libusb (kresult);
1432 /* schedule for a frame a little in the future */
1433 frame += 4;
1435 if (cInterface->frames[transfer->endpoint] && frame < cInterface->frames[transfer->endpoint])
1436 frame = cInterface->frames[transfer->endpoint];
1438 /* submit the request */
1439 if (IS_XFERIN(transfer))
1440 kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1441 transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1442 itransfer);
1443 else
1444 kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1445 transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1446 itransfer);
1448 cInterface->frames[transfer->endpoint] = frame + transfer->num_iso_packets / 8;
1450 if (kresult != kIOReturnSuccess) {
1451 usbi_err (TRANSFER_CTX (transfer), "isochronous transfer failed (dir: %s): %s", IS_XFERIN(transfer) ? "In" : "Out",
1452 darwin_error_str(kresult));
1453 free (tpriv->isoc_framelist);
1454 tpriv->isoc_framelist = NULL;
1457 return darwin_to_libusb (kresult);
1460 static int submit_control_transfer(struct usbi_transfer *itransfer) {
1461 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1462 struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1463 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
1464 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1465 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1467 IOReturn kresult;
1469 bzero(&tpriv->req, sizeof(tpriv->req));
1471 /* IOUSBDeviceInterface expects the request in cpu endianess */
1472 tpriv->req.bmRequestType = setup->bmRequestType;
1473 tpriv->req.bRequest = setup->bRequest;
1474 /* these values should be in bus order from libusb_fill_control_setup */
1475 tpriv->req.wValue = OSSwapLittleToHostInt16 (setup->wValue);
1476 tpriv->req.wIndex = OSSwapLittleToHostInt16 (setup->wIndex);
1477 tpriv->req.wLength = OSSwapLittleToHostInt16 (setup->wLength);
1478 /* data is stored after the libusbx control block */
1479 tpriv->req.pData = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1480 tpriv->req.completionTimeout = transfer->timeout;
1481 tpriv->req.noDataTimeout = transfer->timeout;
1483 itransfer->flags |= USBI_TRANSFER_OS_HANDLES_TIMEOUT;
1485 /* all transfers in libusb-1.0 are async */
1487 if (transfer->endpoint) {
1488 struct darwin_interface *cInterface;
1489 uint8_t pipeRef, iface;
1491 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1492 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1494 return LIBUSB_ERROR_NOT_FOUND;
1497 cInterface = &priv->interfaces[iface];
1499 kresult = (*(cInterface->interface))->ControlRequestAsyncTO (cInterface->interface, pipeRef, &(tpriv->req), darwin_async_io_callback, itransfer);
1500 } else
1501 /* control request on endpoint 0 */
1502 kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1504 if (kresult != kIOReturnSuccess)
1505 usbi_err (TRANSFER_CTX (transfer), "control request failed: %s", darwin_error_str(kresult));
1507 return darwin_to_libusb (kresult);
1510 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1511 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1513 switch (transfer->type) {
1514 case LIBUSB_TRANSFER_TYPE_CONTROL:
1515 return submit_control_transfer(itransfer);
1516 case LIBUSB_TRANSFER_TYPE_BULK:
1517 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1518 return submit_bulk_transfer(itransfer);
1519 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1520 return submit_iso_transfer(itransfer);
1521 default:
1522 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1523 return LIBUSB_ERROR_INVALID_PARAM;
1527 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
1528 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1529 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
1530 IOReturn kresult;
1532 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions control pipe");
1534 if (!dpriv->device)
1535 return LIBUSB_ERROR_NO_DEVICE;
1537 kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
1539 return darwin_to_libusb (kresult);
1542 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
1543 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1544 struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
1545 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1546 struct darwin_interface *cInterface;
1547 uint8_t pipeRef, iface;
1548 IOReturn kresult;
1550 if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1551 usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
1553 return LIBUSB_ERROR_NOT_FOUND;
1556 cInterface = &priv->interfaces[iface];
1558 if (!dpriv->device)
1559 return LIBUSB_ERROR_NO_DEVICE;
1561 usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
1563 /* abort transactions */
1564 (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
1566 usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
1568 /* clear the data toggle bit */
1569 #if (InterfaceVersion < 190)
1570 kresult = (*(cInterface->interface))->ClearPipeStall(cInterface->interface, pipeRef);
1571 #else
1572 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1573 kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1574 #endif
1576 return darwin_to_libusb (kresult);
1579 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
1580 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1582 switch (transfer->type) {
1583 case LIBUSB_TRANSFER_TYPE_CONTROL:
1584 return cancel_control_transfer(itransfer);
1585 case LIBUSB_TRANSFER_TYPE_BULK:
1586 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1587 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1588 return darwin_abort_transfers (itransfer);
1589 default:
1590 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1591 return LIBUSB_ERROR_INVALID_PARAM;
1595 static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) {
1596 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1597 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1599 if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && tpriv->isoc_framelist) {
1600 free (tpriv->isoc_framelist);
1601 tpriv->isoc_framelist = NULL;
1605 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
1606 struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
1607 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1608 struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1609 UInt32 message, size;
1611 usbi_dbg ("an async io operation has completed");
1613 /* The size should never be larger than 4 GB - Also see libusb bug #117 */
1614 if ((intptr_t) arg0 > UINT32_MAX)
1615 usbi_err (ITRANSFER_CTX (itransfer),
1616 "async size truncation detected - please report this error");
1617 size = (UInt32) (intptr_t) arg0;
1619 /* send a completion message to the device's file descriptor */
1620 message = MESSAGE_ASYNC_IO_COMPLETE;
1621 write (priv->fds[1], &message, sizeof (message));
1622 write (priv->fds[1], &itransfer, sizeof (itransfer));
1623 write (priv->fds[1], &result, sizeof (IOReturn));
1624 write (priv->fds[1], &size, sizeof (size));
1627 static int darwin_transfer_status (struct usbi_transfer *itransfer, kern_return_t result) {
1628 if (itransfer->flags & USBI_TRANSFER_TIMED_OUT)
1629 result = kIOUSBTransactionTimeout;
1631 switch (result) {
1632 case kIOReturnUnderrun:
1633 case kIOReturnSuccess:
1634 return LIBUSB_TRANSFER_COMPLETED;
1635 case kIOReturnAborted:
1636 return LIBUSB_TRANSFER_CANCELLED;
1637 case kIOUSBPipeStalled:
1638 usbi_dbg ("transfer error: pipe is stalled");
1639 return LIBUSB_TRANSFER_STALL;
1640 case kIOReturnOverrun:
1641 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
1642 return LIBUSB_TRANSFER_OVERFLOW;
1643 case kIOUSBTransactionTimeout:
1644 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
1645 itransfer->flags |= USBI_TRANSFER_TIMED_OUT;
1646 return LIBUSB_TRANSFER_TIMED_OUT;
1647 default:
1648 usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
1649 return LIBUSB_TRANSFER_ERROR;
1653 static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
1654 struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1655 struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1656 int isIsoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
1657 int isBulk = LIBUSB_TRANSFER_TYPE_BULK == transfer->type;
1658 int isControl = LIBUSB_TRANSFER_TYPE_CONTROL == transfer->type;
1659 int isInterrupt = LIBUSB_TRANSFER_TYPE_INTERRUPT == transfer->type;
1660 int i;
1662 if (!isIsoc && !isBulk && !isControl && !isInterrupt) {
1663 usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
1664 return;
1667 usbi_dbg ("handling %s completion with kernel status %d",
1668 isControl ? "control" : isBulk ? "bulk" : isIsoc ? "isoc" : "interrupt", result);
1670 if (kIOReturnSuccess == result || kIOReturnUnderrun == result) {
1671 if (isIsoc && tpriv->isoc_framelist) {
1672 /* copy isochronous results back */
1674 for (i = 0; i < transfer->num_iso_packets ; i++) {
1675 struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
1676 lib_desc->status = darwin_to_libusb (tpriv->isoc_framelist[i].frStatus);
1677 lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
1679 } else if (!isIsoc)
1680 itransfer->transferred += io_size;
1683 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
1684 usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, result));
1687 static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) {
1688 struct usbi_transfer *itransfer;
1689 UInt32 io_size;
1690 IOReturn kresult;
1691 POLL_NFDS_TYPE i = 0;
1692 ssize_t ret;
1693 UInt32 message;
1695 usbi_mutex_lock(&ctx->open_devs_lock);
1696 for (i = 0; i < nfds && num_ready > 0; i++) {
1697 struct pollfd *pollfd = &fds[i];
1698 struct libusb_device_handle *handle;
1699 struct darwin_device_handle_priv *hpriv = NULL;
1701 usbi_dbg ("checking fd %i with revents = %x", fds[i], pollfd->revents);
1703 if (!pollfd->revents)
1704 continue;
1706 num_ready--;
1707 list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
1708 hpriv = (struct darwin_device_handle_priv *)handle->os_priv;
1709 if (hpriv->fds[0] == pollfd->fd)
1710 break;
1712 if (!hpriv)
1713 continue;
1715 if (!(pollfd->revents & POLLERR)) {
1716 ret = read (hpriv->fds[0], &message, sizeof (message));
1717 if (ret < (ssize_t)sizeof (message))
1718 continue;
1719 } else
1720 /* could not poll the device-- response is to delete the device (this seems a little heavy-handed) */
1721 message = MESSAGE_DEVICE_GONE;
1723 switch (message) {
1724 case MESSAGE_DEVICE_GONE:
1725 /* remove the device's async port from the runloop */
1726 if (hpriv->cfSource) {
1727 if (libusb_darwin_acfl)
1728 CFRunLoopRemoveSource (libusb_darwin_acfl, hpriv->cfSource, kCFRunLoopDefaultMode);
1729 CFRelease (hpriv->cfSource);
1730 hpriv->cfSource = NULL;
1733 usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fds[0]);
1734 usbi_handle_disconnect(handle);
1736 /* done with this device */
1737 continue;
1738 case MESSAGE_ASYNC_IO_COMPLETE:
1739 read (hpriv->fds[0], &itransfer, sizeof (itransfer));
1740 read (hpriv->fds[0], &kresult, sizeof (IOReturn));
1741 read (hpriv->fds[0], &io_size, sizeof (UInt32));
1743 darwin_handle_callback (itransfer, kresult, io_size);
1744 break;
1745 default:
1746 usbi_warn (ctx, "unknown message received from device pipe");
1750 usbi_mutex_unlock(&ctx->open_devs_lock);
1752 return 0;
1755 static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
1756 mach_timespec_t sys_time;
1757 clock_serv_t clock_ref;
1759 switch (clk_id) {
1760 case USBI_CLOCK_REALTIME:
1761 /* CLOCK_REALTIME represents time since the epoch */
1762 clock_ref = clock_realtime;
1763 break;
1764 case USBI_CLOCK_MONOTONIC:
1765 /* use system boot time as reference for the monotonic clock */
1766 clock_ref = clock_monotonic;
1767 break;
1768 default:
1769 return LIBUSB_ERROR_INVALID_PARAM;
1772 clock_get_time (clock_ref, &sys_time);
1774 tp->tv_sec = sys_time.tv_sec;
1775 tp->tv_nsec = sys_time.tv_nsec;
1777 return 0;
1780 const struct usbi_os_backend darwin_backend = {
1781 .name = "Darwin",
1782 .init = darwin_init,
1783 .exit = darwin_exit,
1784 .get_device_list = darwin_get_device_list,
1785 .get_device_descriptor = darwin_get_device_descriptor,
1786 .get_active_config_descriptor = darwin_get_active_config_descriptor,
1787 .get_config_descriptor = darwin_get_config_descriptor,
1789 .open = darwin_open,
1790 .close = darwin_close,
1791 .get_configuration = darwin_get_configuration,
1792 .set_configuration = darwin_set_configuration,
1793 .claim_interface = darwin_claim_interface,
1794 .release_interface = darwin_release_interface,
1796 .set_interface_altsetting = darwin_set_interface_altsetting,
1797 .clear_halt = darwin_clear_halt,
1798 .reset_device = darwin_reset_device,
1800 .kernel_driver_active = darwin_kernel_driver_active,
1801 .detach_kernel_driver = darwin_detach_kernel_driver,
1802 .attach_kernel_driver = darwin_attach_kernel_driver,
1804 .destroy_device = darwin_destroy_device,
1806 .submit_transfer = darwin_submit_transfer,
1807 .cancel_transfer = darwin_cancel_transfer,
1808 .clear_transfer_priv = darwin_clear_transfer_priv,
1810 .handle_events = op_handle_events,
1812 .clock_gettime = darwin_clock_gettime,
1814 .device_priv_size = sizeof(struct darwin_device_priv),
1815 .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
1816 .transfer_priv_size = sizeof(struct darwin_transfer_priv),
1817 .add_iso_packet_size = 0,