1 /* -*- Mode: C; indent-tabs-mode:nil -*- */
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
30 #include <sys/ioctl.h>
32 #include <sys/types.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>
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
);
72 static const char *darwin_error_str (int result
) {
74 case kIOReturnSuccess
:
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";
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";
101 return "unknown error";
106 static int darwin_to_libusb (int 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
:
125 case kIOUSBNoAsyncPortErr
:
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
;
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
) {
150 usbi_dbg ("pipe %d on interface %d matches", *pipep
, *ifcp
);
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
);
163 static int usb_setup_device_iterator (io_iterator_t
*deviceIterator
, UInt32 location
) {
164 CFMutableDictionaryRef matchingDict
= IOServiceMatching(kIOUSBDeviceClassName
);
167 return kIOReturnError
;
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);
198 if (CFGetTypeID(cfNumber
) == CFNumberGetTypeID()) {
199 ret
= CFNumberGetValue(cfNumber
, type
, p
);
202 CFRelease (cfNumber
);
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
;
215 if (!IOIteratorIsValid (deviceIterator
))
219 while ((usbDevice
= IOIteratorNext(deviceIterator
))) {
220 result
= IOCreatePlugInInterfaceForService(usbDevice
, kIOUSBDeviceUserClientTypeID
,
221 kIOCFPlugInInterfaceID
, &plugInInterface
,
224 /* we are done with the usb_device_t */
225 (void)IOObjectRelease(usbDevice
);
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
)
245 usbi_dbg ("libusb/darwin.c usb_get_next_device: could not set up plugin for service: %s\n", darwin_error_str (result
));
251 (void)(*plugInInterface
)->QueryInterface(plugInInterface
, CFUUIDGetUUIDBytes(DeviceInterfaceID
),
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 */
258 (*(device
))->GetLocationID(device
, locationp
);
263 static kern_return_t
darwin_get_device (uint32_t dev_location
, usb_device_t
***darwin_device
) {
264 kern_return_t kresult
;
266 io_iterator_t deviceIterator
;
268 kresult
= usb_setup_device_iterator (&deviceIterator
, dev_location
);
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
)
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
;
299 CFTypeRef locationCF
;
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
);
313 locationValid
= CFGetTypeID(locationCF
) == CFNumberGetTypeID() &&
314 CFNumberGetValue(locationCF
, kCFNumberSInt32Type
, &location
);
316 CFRelease (locationCF
);
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
) {
341 while ((device
= IOIteratorNext (iter
)) != 0)
342 IOObjectRelease (device
);
345 static void *event_thread_main (void *arg0
) {
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");
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();
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 ();
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
));
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 */
405 usbi_dbg ("thread exiting");
407 /* delete notification port */
408 IONotificationPortDestroy (libusb_notification_port
);
409 IOObjectRelease (libusb_rem_device_iterator
);
413 libusb_darwin_acfl
= 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
);
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
);
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
;
468 IOUSBConfigurationDescriptorPtr desc
;
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
)
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
;
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)
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
;
505 usb_device_t
**device
= NULL
;
508 return LIBUSB_ERROR_OTHER
;
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 */
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 */
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
);
571 return darwin_to_libusb (kresult
);
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
;
587 /* devices with more than one configuration should work with GetConfiguration */
588 (*darwin_device
)->GetConfiguration (darwin_device
, &priv
->active_config
);
591 priv
->active_config
= 0;
593 usbi_dbg ("active config: %u, first config: %u", priv
->active_config
, priv
->first_config
);
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;
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 ****/
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;
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 */
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 */
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
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
);
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
));
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 */
689 } while (kIOReturnSuccess
!= ret
&& retries
--);
692 /* resuspend the device */
693 (void)(*device
)->USBDeviceSuspend (device
, 1);
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
));
703 usbi_warn (ctx
, "could not retrieve device descriptor %.4x:%.4x: %s. skipping device", idVendor
, idProduct
, darwin_error_str (ret
));
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
));
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
;
742 int ret
= 0, need_unref
= 0;
745 dev
= usbi_get_device_by_session_id(ctx
, locationID
);
747 usbi_dbg ("allocating new device for location 0x%08x", locationID
);
748 dev
= usbi_alloc_device(ctx
, locationID
);
751 usbi_dbg ("using existing device for location 0x%08x", locationID
);
754 ret
= LIBUSB_ERROR_NO_MEM
;
758 priv
= (struct darwin_device_priv
*)dev
->os_priv
;
760 (*device
)->GetDeviceAddress (device
, (USBDeviceAddress
*)&address
);
762 ret
= darwin_cache_device_descriptor (ctx
, dev
, device
);
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
);
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
) {
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
);
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;
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
);
809 /* append the device to the list of discovered devices */
810 discdevs
= discovered_devs_append(*_discdevs
, dev
);
812 ret
= LIBUSB_ERROR_NO_MEM
;
816 *_discdevs
= discdevs
;
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
);
824 libusb_unref_device(dev
);
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
;
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
);
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
;
858 if (0 == dpriv
->open_count
) {
859 kresult
= darwin_get_device (dpriv
->location
, &darwin_device
);
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
));
874 case kIOReturnExclusiveAccess
:
875 /* it is possible to perform some actions on a device that is not open so do not return an error */
880 (*(dpriv
->device
))->Release (dpriv
->device
);
881 dpriv
->device
= NULL
;
882 return darwin_to_libusb (kresult
);
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
);
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 */
909 /* create a file descriptor for notifications */
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");
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
;
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");
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
) {
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
);
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
);
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
;
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
;
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
;
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
);
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
);
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
;
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
);
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
;
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
;
1087 IOCFPlugInInterface
**plugInInterface
= NULL
;
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");
1108 kresult
= darwin_get_interface (dpriv
->device
, iface
, &usbInterface
);
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
);
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
);
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
);
1159 /* this should not happen */
1160 darwin_release_interface (dev_handle
, iface
);
1161 usbi_err (HANDLE_CTX (dev_handle
), "could not build endpoint table");
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");
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
;
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
);
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
;
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
);
1236 /* this should not happen */
1237 darwin_release_interface (dev_handle
, iface
);
1238 usbi_err (HANDLE_CTX (dev_handle
), "could not build endpoint table");
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
;
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
);
1265 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1266 kresult
= (*(cInterface
->interface
))->ClearPipeStallBothEnds(cInterface
->interface
, pipeRef
);
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
;
1278 kresult
= (*(dpriv
->device
))->ResetDevice (dpriv
->device
);
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
;
1291 kresult
= darwin_get_interface (dpriv
->device
, interface
, &usbInterface
);
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
);
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
) {
1315 return LIBUSB_ERROR_NOT_SUPPORTED
;
1318 static int darwin_detach_kernel_driver (struct libusb_device_handle
*dev_handle
, int interface
) {
1321 return LIBUSB_ERROR_NOT_SUPPORTED
;
1324 static void darwin_destroy_device(struct libusb_device
*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
;
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
);
1361 ret
= (*(cInterface
->interface
))->WritePipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1362 transfer
->length
, darwin_async_io_callback
, itransfer
);
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
);
1371 ret
= (*(cInterface
->interface
))->WritePipeAsyncTO(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1372 transfer
->length
, transfer
->timeout
, transfer
->timeout
,
1373 darwin_async_io_callback
, (void *)itransfer
);
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
;
1389 uint8_t pipeRef
, iface
;
1391 AbsoluteTime atTime
;
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
);
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 */
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
,
1444 kresult
= (*(cInterface
->interface
))->WriteIsochPipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
, frame
,
1445 transfer
->num_iso_packets
, tpriv
->isoc_framelist
, darwin_async_io_callback
,
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
);
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
);
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
);
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
;
1532 usbi_warn (ITRANSFER_CTX (itransfer
), "aborting all transactions control pipe");
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
;
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
];
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
);
1572 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1573 kresult
= (*(cInterface
->interface
))->ClearPipeStallBothEnds(cInterface
->interface
, pipeRef
);
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
);
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
;
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
;
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
;
1662 if (!isIsoc
&& !isBulk
&& !isControl
&& !isInterrupt
) {
1663 usbi_err (TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
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
;
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
;
1691 POLL_NFDS_TYPE i
= 0;
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
)
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
)
1715 if (!(pollfd
->revents
& POLLERR
)) {
1716 ret
= read (hpriv
->fds
[0], &message
, sizeof (message
));
1717 if (ret
< (ssize_t
)sizeof (message
))
1720 /* could not poll the device-- response is to delete the device (this seems a little heavy-handed) */
1721 message
= MESSAGE_DEVICE_GONE
;
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 */
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
);
1746 usbi_warn (ctx
, "unknown message received from device pipe");
1750 usbi_mutex_unlock(&ctx
->open_devs_lock
);
1755 static int darwin_clock_gettime(int clk_id
, struct timespec
*tp
) {
1756 mach_timespec_t sys_time
;
1757 clock_serv_t clock_ref
;
1760 case USBI_CLOCK_REALTIME
:
1761 /* CLOCK_REALTIME represents time since the epoch */
1762 clock_ref
= clock_realtime
;
1764 case USBI_CLOCK_MONOTONIC
:
1765 /* use system boot time as reference for the monotonic clock */
1766 clock_ref
= clock_monotonic
;
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
;
1780 const struct usbi_os_backend darwin_backend
= {
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,