2 * darwin backend for libusb 1.0
3 * Copyright (C) 2008-2010 Nathan Hjelm <hjelmn@users.sourceforge.net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <sys/ioctl.h>
31 #include <sys/types.h>
34 #include <mach/clock.h>
35 #include <mach/clock_types.h>
36 #include <mach/mach_host.h>
38 #include <mach/mach_port.h>
39 #include <IOKit/IOCFBundle.h>
40 #include <IOKit/usb/IOUSBLib.h>
41 #include <IOKit/IOCFPlugIn.h>
43 #include "darwin_usb.h"
45 static mach_port_t libusb_darwin_mp
= 0; /* master port */
46 static CFRunLoopRef libusb_darwin_acfl
= NULL
; /* async cf loop */
47 static int initCount
= 0;
49 /* async event thread */
50 static pthread_t libusb_darwin_at
;
52 static int darwin_get_config_descriptor(struct libusb_device
*dev
, uint8_t config_index
, unsigned char *buffer
, size_t len
, int *host_endian
);
53 static int darwin_claim_interface(struct libusb_device_handle
*dev_handle
, int iface
);
54 static int darwin_release_interface(struct libusb_device_handle
*dev_handle
, int iface
);
55 static int darwin_reset_device(struct libusb_device_handle
*dev_handle
);
56 static void darwin_async_io_callback (void *refcon
, IOReturn result
, void *arg0
);
58 static const char *darwin_error_str (int result
) {
60 case kIOReturnSuccess
:
62 case kIOReturnNotOpen
:
63 return "device not opened for exclusive access";
64 case kIOReturnNoDevice
:
65 return "no connection to an IOService";
66 case kIOUSBNoAsyncPortErr
:
67 return "no async port has been opened for interface";
68 case kIOReturnExclusiveAccess
:
69 return "another process has device opened for exclusive access";
70 case kIOUSBPipeStalled
:
71 return "pipe is stalled";
73 return "could not establish a connection to the Darwin kernel";
74 case kIOUSBTransactionTimeout
:
75 return "transaction timed out";
76 case kIOReturnBadArgument
:
77 return "invalid argument";
78 case kIOReturnAborted
:
79 return "transaction aborted";
80 case kIOReturnNotResponding
:
81 return "device not responding";
82 case kIOReturnOverrun
:
83 return "data overrun";
84 case kIOReturnCannotWire
:
85 return "physical memory can not be wired down";
87 return "unknown error";
91 static int darwin_to_libusb (int result
) {
93 case kIOReturnUnderrun
:
94 case kIOReturnSuccess
:
95 return LIBUSB_SUCCESS
;
96 case kIOReturnNotOpen
:
97 case kIOReturnNoDevice
:
98 return LIBUSB_ERROR_NO_DEVICE
;
99 case kIOReturnExclusiveAccess
:
100 return LIBUSB_ERROR_ACCESS
;
101 case kIOUSBPipeStalled
:
102 return LIBUSB_ERROR_PIPE
;
103 case kIOReturnBadArgument
:
104 return LIBUSB_ERROR_INVALID_PARAM
;
105 case kIOUSBTransactionTimeout
:
106 return LIBUSB_ERROR_TIMEOUT
;
107 case kIOReturnNotResponding
:
108 case kIOReturnAborted
:
110 case kIOUSBNoAsyncPortErr
:
112 return LIBUSB_ERROR_OTHER
;
117 static int ep_to_pipeRef(struct libusb_device_handle
*dev_handle
, uint8_t ep
, uint8_t *pipep
, uint8_t *ifcp
) {
118 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
120 /* current interface */
121 struct __darwin_interface
*cInterface
;
125 usbi_info (HANDLE_CTX(dev_handle
), "converting ep address 0x%02x to pipeRef and interface", ep
);
127 for (iface
= 0 ; iface
< USB_MAXINTERFACES
; iface
++) {
128 cInterface
= &priv
->interfaces
[iface
];
130 if (dev_handle
->claimed_interfaces
& (1 << iface
)) {
131 for (i
= 0 ; i
< cInterface
->num_endpoints
; i
++) {
132 if (cInterface
->endpoint_addrs
[i
] == ep
) {
135 usbi_info (HANDLE_CTX(dev_handle
), "pipe %d on interface %d matches", *pipep
, *ifcp
);
142 /* No pipe found with the correct endpoint address */
143 usbi_warn (HANDLE_CTX(dev_handle
), "no pipeRef found with endpoint address 0x%02x.", ep
);
148 static int usb_setup_device_iterator (io_iterator_t
*deviceIterator
) {
149 return IOServiceGetMatchingServices(libusb_darwin_mp
, IOServiceMatching(kIOUSBDeviceClassName
), deviceIterator
);
152 static usb_device_t
**usb_get_next_device (io_iterator_t deviceIterator
, UInt32
*locationp
) {
153 io_cf_plugin_ref_t
*plugInInterface
= NULL
;
154 usb_device_t
**device
;
155 io_service_t usbDevice
;
159 if (!IOIteratorIsValid (deviceIterator
))
163 while ((usbDevice
= IOIteratorNext(deviceIterator
))) {
164 result
= IOCreatePlugInInterfaceForService(usbDevice
, kIOUSBDeviceUserClientTypeID
,
165 kIOCFPlugInInterfaceID
, &plugInInterface
,
167 if (kIOReturnSuccess
== result
&& plugInInterface
)
170 usbi_dbg ("libusb/darwin.c usb_get_next_device: could not set up plugin for service: %s\n", darwin_error_str (result
));
176 (void)IOObjectRelease(usbDevice
);
177 (void)(*plugInInterface
)->QueryInterface(plugInInterface
, CFUUIDGetUUIDBytes(DeviceInterfaceID
),
180 (*plugInInterface
)->Stop(plugInInterface
);
181 IODestroyPlugInInterface (plugInInterface
);
183 /* get the location from the device */
185 (*(device
))->GetLocationID(device
, locationp
);
190 static kern_return_t
darwin_get_device (uint32_t dev_location
, usb_device_t
***darwin_device
) {
191 kern_return_t kresult
;
193 io_iterator_t deviceIterator
;
195 kresult
= usb_setup_device_iterator (&deviceIterator
);
199 /* This port of libusb uses locations to keep track of devices. */
200 while ((*darwin_device
= usb_get_next_device (deviceIterator
, &location
)) != NULL
) {
201 if (location
== dev_location
)
204 (**darwin_device
)->Release(*darwin_device
);
207 IOObjectRelease (deviceIterator
);
209 if (!(*darwin_device
))
210 return kIOReturnNoDevice
;
212 return kIOReturnSuccess
;
217 static void darwin_devices_detached (void *ptr
, io_iterator_t rem_devices
) {
218 struct libusb_context
*ctx
= (struct libusb_context
*)ptr
;
219 struct libusb_device_handle
*handle
;
220 struct darwin_device_priv
*dpriv
;
221 struct darwin_device_handle_priv
*priv
;
225 CFTypeRef locationCF
;
228 usbi_info (ctx
, "a device has been detached");
230 while ((device
= IOIteratorNext (rem_devices
)) != 0) {
231 /* get the location from the i/o registry */
232 locationCF
= IORegistryEntryCreateCFProperty (device
, CFSTR(kUSBDevicePropertyLocationID
), kCFAllocatorDefault
, 0);
234 CFNumberGetValue(locationCF
, kCFNumberLongType
, &location
);
235 CFRelease (locationCF
);
236 IOObjectRelease (device
);
238 usbi_mutex_lock(&ctx
->open_devs_lock
);
239 list_for_each_entry(handle
, &ctx
->open_devs
, list
, struct libusb_device_handle
) {
240 dpriv
= (struct darwin_device_priv
*)handle
->dev
->os_priv
;
242 /* the device may have been opened several times. write to each handle's event descriptor */
243 if (dpriv
->location
== location
&& handle
->os_priv
) {
244 priv
= (struct darwin_device_handle_priv
*)handle
->os_priv
;
246 message
= MESSAGE_DEVICE_GONE
;
247 write (priv
->fds
[1], &message
, sizeof (message
));
251 usbi_mutex_unlock(&ctx
->open_devs_lock
);
255 static void darwin_clear_iterator (io_iterator_t iter
) {
258 while ((device
= IOIteratorNext (iter
)) != 0)
259 IOObjectRelease (device
);
262 static void *event_thread_main (void *arg0
) {
264 struct libusb_context
*ctx
= (struct libusb_context
*)arg0
;
266 /* hotplug (device removal) source */
267 CFRunLoopSourceRef libusb_notification_cfsource
;
268 io_notification_port_t libusb_notification_port
;
269 io_iterator_t libusb_rem_device_iterator
;
271 usbi_info (ctx
, "creating hotplug event source");
273 CFRetain (CFRunLoopGetCurrent ());
275 /* add the notification port to the run loop */
276 libusb_notification_port
= IONotificationPortCreate (libusb_darwin_mp
);
277 libusb_notification_cfsource
= IONotificationPortGetRunLoopSource (libusb_notification_port
);
278 CFRunLoopAddSource(CFRunLoopGetCurrent (), libusb_notification_cfsource
, kCFRunLoopDefaultMode
);
280 /* create notifications for removed devices */
281 kresult
= IOServiceAddMatchingNotification (libusb_notification_port
, kIOTerminatedNotification
,
282 IOServiceMatching(kIOUSBDeviceClassName
),
283 (IOServiceMatchingCallback
)darwin_devices_detached
,
284 (void *)ctx
, &libusb_rem_device_iterator
);
286 if (kresult
!= kIOReturnSuccess
) {
287 usbi_err (ctx
, "could not add hotplug event source: %s", darwin_error_str (kresult
));
289 pthread_exit ((void *)kresult
);
293 darwin_clear_iterator (libusb_rem_device_iterator
);
295 /* let the main thread know about the async runloop */
296 libusb_darwin_acfl
= CFRunLoopGetCurrent ();
298 usbi_info (ctx
, "thread ready to receive events");
300 /* run the runloop */
303 usbi_info (ctx
, "thread exiting");
305 /* delete notification port */
306 CFRunLoopSourceInvalidate (libusb_notification_cfsource
);
307 IONotificationPortDestroy (libusb_notification_port
);
309 CFRelease (CFRunLoopGetCurrent ());
311 libusb_darwin_acfl
= NULL
;
316 static int darwin_init(struct libusb_context
*ctx
) {
319 if (!(initCount
++)) {
320 /* Create the master port for talking to IOKit */
321 if (!libusb_darwin_mp
) {
322 kresult
= IOMasterPort (MACH_PORT_NULL
, &libusb_darwin_mp
);
324 if (kresult
!= kIOReturnSuccess
|| !libusb_darwin_mp
)
325 return darwin_to_libusb (kresult
);
328 pthread_create (&libusb_darwin_at
, NULL
, event_thread_main
, (void *)ctx
);
330 while (!libusb_darwin_acfl
)
337 static void darwin_exit (void) {
338 if (!(--initCount
)) {
341 /* stop the async runloop */
342 CFRunLoopStop (libusb_darwin_acfl
);
343 pthread_join (libusb_darwin_at
, &ret
);
345 if (libusb_darwin_mp
)
346 mach_port_deallocate(mach_task_self(), libusb_darwin_mp
);
348 libusb_darwin_mp
= 0;
352 static int darwin_get_device_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, int *host_endian
) {
353 struct darwin_device_priv
*priv
= (struct darwin_device_priv
*)dev
->os_priv
;
355 /* return cached copy */
356 memmove (buffer
, &(priv
->dev_descriptor
), DEVICE_DESC_LENGTH
);
363 static int get_configuration_index (struct libusb_device
*dev
, int config_value
) {
364 struct darwin_device_priv
*priv
= (struct darwin_device_priv
*)dev
->os_priv
;
366 IOUSBConfigurationDescriptorPtr desc
;
369 /* is there a simpler way to determine the index? */
370 kresult
= (*(priv
->device
))->GetNumberOfConfigurations (priv
->device
, &numConfig
);
371 if (kresult
!= kIOReturnSuccess
)
372 return darwin_to_libusb (kresult
);
374 for (i
= 0 ; i
< numConfig
; i
++) {
375 (*(priv
->device
))->GetConfigurationDescriptorPtr (priv
->device
, i
, &desc
);
377 if (desc
->bConfigurationValue
== config_value
)
381 /* configuration not found */
382 return LIBUSB_ERROR_OTHER
;
385 static int darwin_get_active_config_descriptor(struct libusb_device
*dev
, unsigned char *buffer
, size_t len
, int *host_endian
) {
386 struct darwin_device_priv
*priv
= (struct darwin_device_priv
*)dev
->os_priv
;
389 if (0 == priv
->active_config
)
390 return LIBUSB_ERROR_INVALID_PARAM
;
392 config_index
= get_configuration_index (dev
, priv
->active_config
);
393 if (config_index
< 0)
396 return darwin_get_config_descriptor (dev
, config_index
, buffer
, len
, host_endian
);
399 static int darwin_get_config_descriptor(struct libusb_device
*dev
, uint8_t config_index
, unsigned char *buffer
, size_t len
, int *host_endian
) {
400 struct darwin_device_priv
*priv
= (struct darwin_device_priv
*)dev
->os_priv
;
401 IOUSBConfigurationDescriptorPtr desc
;
403 usb_device_t
**device
= NULL
;
406 return LIBUSB_ERROR_OTHER
;
409 kresult
= darwin_get_device (priv
->location
, &device
);
410 if (kresult
|| !device
) {
411 usbi_err (DEVICE_CTX (dev
), "could not find device: %s", darwin_error_str (kresult
));
413 return darwin_to_libusb (kresult
);
416 /* don't have to open the device to get a config descriptor */
418 device
= priv
->device
;
420 kresult
= (*device
)->GetConfigurationDescriptorPtr (device
, config_index
, &desc
);
421 if (kresult
== kIOReturnSuccess
) {
422 /* copy descriptor */
423 if (libusb_le16_to_cpu(desc
->wTotalLength
) < len
)
424 len
= libusb_le16_to_cpu(desc
->wTotalLength
);
426 memmove (buffer
, desc
, len
);
428 /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */
433 (*device
)->Release (device
);
435 return darwin_to_libusb (kresult
);
438 /* check whether the os has configured the device */
439 static int darwin_check_configuration (struct libusb_context
*ctx
, struct libusb_device
*dev
, usb_device_t
**darwin_device
) {
440 struct darwin_device_priv
*priv
= (struct darwin_device_priv
*)dev
->os_priv
;
442 IOUSBConfigurationDescriptorPtr configDesc
;
443 IOUSBFindInterfaceRequest request
;
444 kern_return_t kresult
;
445 io_iterator_t interface_iterator
;
446 io_service_t firstInterface
;
448 if (priv
->dev_descriptor
.bNumConfigurations
< 1) {
449 usbi_err (ctx
, "device has no configurations");
450 return LIBUSB_ERROR_OTHER
; /* no configurations at this speed so we can't use it */
453 /* find the first configuration */
454 kresult
= (*darwin_device
)->GetConfigurationDescriptorPtr (darwin_device
, 0, &configDesc
);
455 priv
->first_config
= (kIOReturnSuccess
== kresult
) ? configDesc
->bConfigurationValue
: 1;
457 /* check if the device is already configured. there is probably a better way than iterating over the
458 to accomplish this (the trick is we need to avoid a call to GetConfigurations since buggy devices
459 might lock up on the device request) */
461 /* Setup the Interface Request */
462 request
.bInterfaceClass
= kIOUSBFindInterfaceDontCare
;
463 request
.bInterfaceSubClass
= kIOUSBFindInterfaceDontCare
;
464 request
.bInterfaceProtocol
= kIOUSBFindInterfaceDontCare
;
465 request
.bAlternateSetting
= kIOUSBFindInterfaceDontCare
;
467 kresult
= (*(darwin_device
))->CreateInterfaceIterator(darwin_device
, &request
, &interface_iterator
);
469 return darwin_to_libusb (kresult
);
472 firstInterface
= IOIteratorNext(interface_iterator
);
474 /* done with the interface iterator */
475 IOObjectRelease(interface_iterator
);
477 if (firstInterface
) {
478 IOObjectRelease (firstInterface
);
480 /* device is configured */
481 if (priv
->dev_descriptor
.bNumConfigurations
== 1)
482 /* to avoid problems with some devices get the configurations value from the configuration descriptor */
483 priv
->active_config
= priv
->first_config
;
485 /* devices with more than one configuration should work with GetConfiguration */
486 (*darwin_device
)->GetConfiguration (darwin_device
, &priv
->active_config
);
489 priv
->active_config
= 0;
491 usbi_info (ctx
, "active config: %u, first config: %u", priv
->active_config
, priv
->first_config
);
496 static int process_new_device (struct libusb_context
*ctx
, usb_device_t
**device
, UInt32 locationID
, struct discovered_devs
**_discdevs
) {
497 struct darwin_device_priv
*priv
;
498 struct libusb_device
*dev
;
499 struct discovered_devs
*discdevs
;
500 UInt16 address
, idVendor
, idProduct
;
501 UInt8 bDeviceClass
, bDeviceSubClass
;
503 int ret
= 0, need_unref
= 0;
506 dev
= usbi_get_device_by_session_id(ctx
, locationID
);
508 usbi_info (ctx
, "allocating new device for location 0x%08x", locationID
);
509 dev
= usbi_alloc_device(ctx
, locationID
);
512 usbi_info (ctx
, "using existing device for location 0x%08x", locationID
);
515 ret
= LIBUSB_ERROR_NO_MEM
;
519 priv
= (struct darwin_device_priv
*)dev
->os_priv
;
521 /* Set up request for device descriptor */
522 req
.bmRequestType
= USBmakebmRequestType(kUSBIn
, kUSBStandard
, kUSBDevice
);
523 req
.bRequest
= kUSBRqGetDescriptor
;
524 req
.wValue
= kUSBDeviceDesc
<< 8;
526 req
.wLength
= sizeof(IOUSBDeviceDescriptor
);
527 req
.pData
= &(priv
->dev_descriptor
);
529 (*(device
))->GetDeviceAddress (device
, (USBDeviceAddress
*)&address
);
530 (*(device
))->GetDeviceProduct (device
, &idProduct
);
531 (*(device
))->GetDeviceVendor (device
, &idVendor
);
532 (*(device
))->GetDeviceClass (device
, &bDeviceClass
);
533 (*(device
))->GetDeviceSubClass (device
, &bDeviceSubClass
);
535 /**** retrieve device descriptors ****/
536 /* according to Apple's documentation the device must be open for DeviceRequest but we may not be able to open some
537 * devices and Apple's USB Prober doesn't bother to open the device before issuing a descriptor request */
538 ret
= (*(device
))->DeviceRequest (device
, &req
);
539 if (ret
!= kIOReturnSuccess
) {
540 int try_unsuspend
= 1;
541 #if DeviceVersion >= 320
544 /* device may be suspended. unsuspend it and try again */
545 /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
546 (void)(*device
)->GetUSBDeviceInformation (device
, &info
);
548 try_unsuspend
= info
& (1 << kUSBInformationDeviceIsSuspendedBit
);
551 /* the device should be open before to device is unsuspended */
552 (void) (*device
)->USBDeviceOpenSeize(device
);
555 /* resume the device */
556 (void)(*device
)->USBDeviceSuspend (device
, 0);
558 ret
= (*(device
))->DeviceRequest (device
, &req
);
560 /* resuspend the device */
561 (void)(*device
)->USBDeviceSuspend (device
, 1);
564 (*device
)->USBDeviceClose (device
);
567 if (ret
!= kIOReturnSuccess
) {
568 usbi_warn (ctx
, "could not retrieve device descriptor: %s. skipping device", darwin_error_str (ret
));
573 /**** end: retrieve device descriptors ****/
575 /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
576 if (libusb_le16_to_cpu (priv
->dev_descriptor
.idProduct
) != idProduct
) {
577 /* not a valid device */
578 usbi_warn (ctx
, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
579 idProduct
, libusb_le16_to_cpu (priv
->dev_descriptor
.idProduct
));
584 dev
->bus_number
= locationID
>> 24;
585 dev
->device_address
= address
;
587 /* check current active configuration (and cache the first configuration value-- which may be used by claim_interface) */
588 ret
= darwin_check_configuration (ctx
, dev
, device
);
592 /* save our location, we'll need this later */
593 priv
->location
= locationID
;
594 snprintf(priv
->sys_path
, 20, "%03i-%04x-%04x-%02x-%02x", address
, idVendor
, idProduct
, bDeviceClass
, bDeviceSubClass
);
596 ret
= usbi_sanitize_device (dev
);
600 /* append the device to the list of discovered devices */
601 discdevs
= discovered_devs_append(*_discdevs
, dev
);
603 ret
= LIBUSB_ERROR_NO_MEM
;
607 *_discdevs
= discdevs
;
609 usbi_info (ctx
, "found device with address %d at %s", dev
->device_address
, priv
->sys_path
);
613 libusb_unref_device(dev
);
618 static int darwin_get_device_list(struct libusb_context
*ctx
, struct discovered_devs
**_discdevs
) {
619 io_iterator_t deviceIterator
;
620 usb_device_t
**device
;
621 kern_return_t kresult
;
624 if (!libusb_darwin_mp
)
625 return LIBUSB_ERROR_INVALID_PARAM
;
627 kresult
= usb_setup_device_iterator (&deviceIterator
);
628 if (kresult
!= kIOReturnSuccess
)
629 return darwin_to_libusb (kresult
);
631 while ((device
= usb_get_next_device (deviceIterator
, &location
)) != NULL
) {
632 (void) process_new_device (ctx
, device
, location
, _discdevs
);
634 (*(device
))->Release(device
);
637 IOObjectRelease(deviceIterator
);
642 static int darwin_open (struct libusb_device_handle
*dev_handle
) {
643 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
644 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
645 usb_device_t
**darwin_device
;
648 if (0 == dpriv
->open_count
) {
649 kresult
= darwin_get_device (dpriv
->location
, &darwin_device
);
651 usbi_err (HANDLE_CTX (dev_handle
), "could not find device: %s", darwin_error_str (kresult
));
652 return darwin_to_libusb (kresult
);
655 dpriv
->device
= darwin_device
;
657 /* try to open the device */
658 kresult
= (*(dpriv
->device
))->USBDeviceOpenSeize (dpriv
->device
);
660 if (kresult
!= kIOReturnSuccess
) {
661 usbi_err (HANDLE_CTX (dev_handle
), "USBDeviceOpen: %s", darwin_error_str(kresult
));
664 case kIOReturnExclusiveAccess
:
665 /* it is possible to perform some actions on a device that is not open so do not return an error */
670 (*(dpriv
->device
))->Release (dpriv
->device
);
671 dpriv
->device
= NULL
;
672 return darwin_to_libusb (kresult
);
677 /* create async event source */
678 kresult
= (*(dpriv
->device
))->CreateDeviceAsyncEventSource (dpriv
->device
, &priv
->cfSource
);
680 CFRetain (libusb_darwin_acfl
);
682 /* add the cfSource to the aync run loop */
683 CFRunLoopAddSource(libusb_darwin_acfl
, priv
->cfSource
, kCFRunLoopCommonModes
);
687 /* device opened successfully */
690 /* create a file descriptor for notifications */
693 /* set the pipe to be non-blocking */
694 fcntl (priv
->fds
[1], F_SETFD
, O_NONBLOCK
);
696 usbi_add_pollfd(HANDLE_CTX(dev_handle
), priv
->fds
[0], POLLIN
);
698 usbi_info (HANDLE_CTX (dev_handle
), "device open for access");
703 static void darwin_close (struct libusb_device_handle
*dev_handle
) {
704 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
705 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
709 if (dpriv
->open_count
== 0) {
710 /* something is probably very wrong if this is the case */
711 usbi_err (HANDLE_CTX (dev_handle
), "Close called on a device that was not open!\n");
717 /* make sure all interfaces are released */
718 for (i
= 0 ; i
< USB_MAXINTERFACES
; i
++)
719 if (dev_handle
->claimed_interfaces
& (1 << i
))
720 libusb_release_interface (dev_handle
, i
);
722 if (0 == dpriv
->open_count
) {
724 /* delete the device's async event source */
725 if (priv
->cfSource
) {
726 CFRunLoopRemoveSource (libusb_darwin_acfl
, priv
->cfSource
, kCFRunLoopDefaultMode
);
727 CFRelease (priv
->cfSource
);
730 /* close the device */
731 kresult
= (*(dpriv
->device
))->USBDeviceClose(dpriv
->device
);
733 /* Log the fact that we had a problem closing the file, however failing a
734 * close isn't really an error, so return success anyway */
735 usbi_err (HANDLE_CTX (dev_handle
), "USBDeviceClose: %s", darwin_error_str(kresult
));
739 kresult
= (*(dpriv
->device
))->Release(dpriv
->device
);
741 /* Log the fact that we had a problem closing the file, however failing a
742 * close isn't really an error, so return success anyway */
743 usbi_err (HANDLE_CTX (dev_handle
), "Release: %s", darwin_error_str(kresult
));
746 dpriv
->device
= NULL
;
749 /* file descriptors are maintained per-instance */
750 usbi_remove_pollfd (HANDLE_CTX (dev_handle
), priv
->fds
[0]);
751 close (priv
->fds
[1]);
752 close (priv
->fds
[0]);
754 priv
->fds
[0] = priv
->fds
[1] = -1;
757 static int darwin_get_configuration(struct libusb_device_handle
*dev_handle
, int *config
) {
758 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
760 *config
= (int) dpriv
->active_config
;
765 static int darwin_set_configuration(struct libusb_device_handle
*dev_handle
, int config
) {
766 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
770 /* Setting configuration will invalidate the interface, so we need
771 to reclaim it. First, dispose of existing interfaces, if any. */
772 for (i
= 0 ; i
< USB_MAXINTERFACES
; i
++)
773 if (dev_handle
->claimed_interfaces
& (1 << i
))
774 darwin_release_interface (dev_handle
, i
);
776 kresult
= (*(dpriv
->device
))->SetConfiguration (dpriv
->device
, config
);
777 if (kresult
!= kIOReturnSuccess
)
778 return darwin_to_libusb (kresult
);
780 /* Reclaim any interfaces. */
781 for (i
= 0 ; i
< USB_MAXINTERFACES
; i
++)
782 if (dev_handle
->claimed_interfaces
& (1 << i
))
783 darwin_claim_interface (dev_handle
, i
);
785 dpriv
->active_config
= config
;
790 static int darwin_get_interface (usb_device_t
**darwin_device
, uint8_t ifc
, io_service_t
*usbInterfacep
) {
791 IOUSBFindInterfaceRequest request
;
792 uint8_t current_interface
;
793 kern_return_t kresult
;
794 io_iterator_t interface_iterator
;
796 *usbInterfacep
= IO_OBJECT_NULL
;
798 /* Setup the Interface Request */
799 request
.bInterfaceClass
= kIOUSBFindInterfaceDontCare
;
800 request
.bInterfaceSubClass
= kIOUSBFindInterfaceDontCare
;
801 request
.bInterfaceProtocol
= kIOUSBFindInterfaceDontCare
;
802 request
.bAlternateSetting
= kIOUSBFindInterfaceDontCare
;
804 kresult
= (*(darwin_device
))->CreateInterfaceIterator(darwin_device
, &request
, &interface_iterator
);
808 for ( current_interface
= 0 ; current_interface
<= ifc
; current_interface
++ ) {
809 *usbInterfacep
= IOIteratorNext(interface_iterator
);
810 if (current_interface
!= ifc
)
811 (void) IOObjectRelease (*usbInterfacep
);
814 /* done with the interface iterator */
815 IOObjectRelease(interface_iterator
);
820 static int get_endpoints (struct libusb_device_handle
*dev_handle
, int iface
) {
821 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
823 /* current interface */
824 struct __darwin_interface
*cInterface
= &priv
->interfaces
[iface
];
826 kern_return_t kresult
;
828 u_int8_t numep
, direction
, number
;
829 u_int8_t dont_care1
, dont_care3
;
830 u_int16_t dont_care2
;
833 usbi_info (HANDLE_CTX (dev_handle
), "building table of endpoints.");
835 /* retrieve the total number of endpoints on this interface */
836 kresult
= (*(cInterface
->interface
))->GetNumEndpoints(cInterface
->interface
, &numep
);
838 usbi_err (HANDLE_CTX (dev_handle
), "can't get number of endpoints for interface: %s", darwin_error_str(kresult
));
839 return darwin_to_libusb (kresult
);
842 /* iterate through pipe references */
843 for (i
= 1 ; i
<= numep
; i
++) {
844 kresult
= (*(cInterface
->interface
))->GetPipeProperties(cInterface
->interface
, i
, &direction
, &number
, &dont_care1
,
845 &dont_care2
, &dont_care3
);
847 if (kresult
!= kIOReturnSuccess
) {
848 usbi_err (HANDLE_CTX (dev_handle
), "error getting pipe information for pipe %d: %s", i
, darwin_error_str(kresult
));
850 return darwin_to_libusb (kresult
);
853 usbi_info (HANDLE_CTX (dev_handle
), "interface: %i pipe %i: dir: %i number: %i", iface
, i
, direction
, number
);
855 cInterface
->endpoint_addrs
[i
- 1] = ((direction
<< 7 & LIBUSB_ENDPOINT_DIR_MASK
) | (number
& LIBUSB_ENDPOINT_ADDRESS_MASK
));
858 cInterface
->num_endpoints
= numep
;
863 static int darwin_claim_interface(struct libusb_device_handle
*dev_handle
, int iface
) {
864 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
865 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
866 io_service_t usbInterface
= IO_OBJECT_NULL
;
868 IOCFPlugInInterface
**plugInInterface
= NULL
;
871 /* current interface */
872 struct __darwin_interface
*cInterface
= &priv
->interfaces
[iface
];
874 kresult
= darwin_get_interface (dpriv
->device
, iface
, &usbInterface
);
875 if (kresult
!= kIOReturnSuccess
)
876 return darwin_to_libusb (kresult
);
878 /* make sure we have an interface */
879 if (!usbInterface
&& dpriv
->first_config
!= 0) {
880 usbi_info (HANDLE_CTX (dev_handle
), "no interface found; setting configuration: %d", dpriv
->first_config
);
882 /* set the configuration */
883 kresult
= darwin_set_configuration (dev_handle
, dpriv
->first_config
);
884 if (kresult
!= LIBUSB_SUCCESS
) {
885 usbi_err (HANDLE_CTX (dev_handle
), "could not set configuration");
889 kresult
= darwin_get_interface (dpriv
->device
, iface
, &usbInterface
);
891 usbi_err (HANDLE_CTX (dev_handle
), "darwin_get_interface: %s", darwin_error_str(kresult
));
892 return darwin_to_libusb (kresult
);
897 usbi_err (HANDLE_CTX (dev_handle
), "interface not found");
898 return LIBUSB_ERROR_NOT_FOUND
;
901 /* get an interface to the device's interface */
902 kresult
= IOCreatePlugInInterfaceForService (usbInterface
, kIOUSBInterfaceUserClientTypeID
,
903 kIOCFPlugInInterfaceID
, &plugInInterface
, &score
);
905 usbi_err (HANDLE_CTX (dev_handle
), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult
));
906 return darwin_to_libusb (kresult
);
909 if (!plugInInterface
) {
910 usbi_err (HANDLE_CTX (dev_handle
), "plugin interface not found");
911 return LIBUSB_ERROR_NOT_FOUND
;
914 /* ignore release error */
915 (void)IOObjectRelease (usbInterface
);
917 /* Do the actual claim */
918 kresult
= (*plugInInterface
)->QueryInterface(plugInInterface
,
919 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID
),
920 (LPVOID
)&cInterface
->interface
);
921 if (kresult
|| !cInterface
->interface
) {
922 usbi_err (HANDLE_CTX (dev_handle
), "QueryInterface: %s", darwin_error_str(kresult
));
923 return darwin_to_libusb (kresult
);
926 /* We no longer need the intermediate plug-in */
927 (*plugInInterface
)->Release(plugInInterface
);
929 /* claim the interface */
930 kresult
= (*(cInterface
->interface
))->USBInterfaceOpen(cInterface
->interface
);
932 usbi_err (HANDLE_CTX (dev_handle
), "USBInterfaceOpen: %s", darwin_error_str(kresult
));
933 return darwin_to_libusb (kresult
);
936 /* update list of endpoints */
937 kresult
= get_endpoints (dev_handle
, iface
);
939 /* this should not happen */
940 darwin_release_interface (dev_handle
, iface
);
941 usbi_err (HANDLE_CTX (dev_handle
), "could not build endpoint table");
945 cInterface
->cfSource
= NULL
;
947 /* create async event source */
948 kresult
= (*(cInterface
->interface
))->CreateInterfaceAsyncEventSource (cInterface
->interface
, &cInterface
->cfSource
);
949 if (kresult
!= kIOReturnSuccess
) {
950 usbi_err (HANDLE_CTX (dev_handle
), "could not create async event source");
952 /* can't continue without an async event source */
953 (void)darwin_release_interface (dev_handle
, iface
);
955 return darwin_to_libusb (kresult
);
958 /* add the cfSource to the async thread's run loop */
959 CFRunLoopAddSource(libusb_darwin_acfl
, cInterface
->cfSource
, kCFRunLoopDefaultMode
);
961 usbi_info (HANDLE_CTX (dev_handle
), "interface opened");
966 static int darwin_release_interface(struct libusb_device_handle
*dev_handle
, int iface
) {
967 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
970 /* current interface */
971 struct __darwin_interface
*cInterface
= &priv
->interfaces
[iface
];
973 /* Check to see if an interface is open */
974 if (!cInterface
->interface
)
975 return LIBUSB_SUCCESS
;
977 /* clean up endpoint data */
978 cInterface
->num_endpoints
= 0;
980 /* delete the interface's async event source */
981 if (cInterface
->cfSource
) {
982 CFRunLoopRemoveSource (libusb_darwin_acfl
, cInterface
->cfSource
, kCFRunLoopDefaultMode
);
983 CFRelease (cInterface
->cfSource
);
986 kresult
= (*(cInterface
->interface
))->USBInterfaceClose(cInterface
->interface
);
988 usbi_err (HANDLE_CTX (dev_handle
), "USBInterfaceClose: %s", darwin_error_str(kresult
));
990 kresult
= (*(cInterface
->interface
))->Release(cInterface
->interface
);
991 if (kresult
!= kIOReturnSuccess
)
992 usbi_err (HANDLE_CTX (dev_handle
), "Release: %s", darwin_error_str(kresult
));
994 cInterface
->interface
= IO_OBJECT_NULL
;
996 return darwin_to_libusb (kresult
);
999 static int darwin_set_interface_altsetting(struct libusb_device_handle
*dev_handle
, int iface
, int altsetting
) {
1000 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
1003 /* current interface */
1004 struct __darwin_interface
*cInterface
= &priv
->interfaces
[iface
];
1006 if (!cInterface
->interface
)
1007 return LIBUSB_ERROR_NO_DEVICE
;
1009 kresult
= (*(cInterface
->interface
))->SetAlternateInterface (cInterface
->interface
, altsetting
);
1010 if (kresult
!= kIOReturnSuccess
)
1011 darwin_reset_device (dev_handle
);
1013 /* update list of endpoints */
1014 kresult
= get_endpoints (dev_handle
, iface
);
1016 /* this should not happen */
1017 darwin_release_interface (dev_handle
, iface
);
1018 usbi_err (HANDLE_CTX (dev_handle
), "could not build endpoint table");
1022 return darwin_to_libusb (kresult
);
1025 static int darwin_clear_halt(struct libusb_device_handle
*dev_handle
, unsigned char endpoint
) {
1026 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)dev_handle
->os_priv
;
1028 /* current interface */
1029 struct __darwin_interface
*cInterface
;
1030 uint8_t pipeRef
, iface
;
1033 /* determine the interface/endpoint to use */
1034 if (ep_to_pipeRef (dev_handle
, endpoint
, &pipeRef
, &iface
) != 0) {
1035 usbi_err (HANDLE_CTX (dev_handle
), "endpoint not found on any open interface");
1037 return LIBUSB_ERROR_NOT_FOUND
;
1040 cInterface
= &priv
->interfaces
[iface
];
1042 #if (InterfaceVersion < 190)
1043 kresult
= (*(cInterface
->interface
))->ClearPipeStall(cInterface
->interface
, pipeRef
);
1045 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1046 kresult
= (*(cInterface
->interface
))->ClearPipeStallBothEnds(cInterface
->interface
, pipeRef
);
1049 usbi_err (HANDLE_CTX (dev_handle
), "ClearPipeStall: %s", darwin_error_str (kresult
));
1051 return darwin_to_libusb (kresult
);
1054 static int darwin_reset_device(struct libusb_device_handle
*dev_handle
) {
1055 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
1058 kresult
= (*(dpriv
->device
))->ResetDevice (dpriv
->device
);
1060 usbi_err (HANDLE_CTX (dev_handle
), "ResetDevice: %s", darwin_error_str (kresult
));
1062 return darwin_to_libusb (kresult
);
1065 static int darwin_kernel_driver_active(struct libusb_device_handle
*dev_handle
, int interface
) {
1066 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)dev_handle
->dev
->os_priv
;
1067 io_service_t usbInterface
;
1071 kresult
= darwin_get_interface (dpriv
->device
, interface
, &usbInterface
);
1073 usbi_err (HANDLE_CTX (dev_handle
), "darwin_get_interface: %s", darwin_error_str(kresult
));
1075 return darwin_to_libusb (kresult
);
1078 driver
= IORegistryEntryCreateCFProperty (usbInterface
, kIOBundleIdentifierKey
, kCFAllocatorDefault
, 0);
1079 IOObjectRelease (usbInterface
);
1091 /* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */
1092 static int darwin_attach_kernel_driver (struct libusb_device_handle
*dev_handle
, int interface
) {
1093 return LIBUSB_ERROR_NOT_SUPPORTED
;
1096 static int darwin_detach_kernel_driver (struct libusb_device_handle
*dev_handle
, int interface
) {
1097 return LIBUSB_ERROR_NOT_SUPPORTED
;
1100 static void darwin_destroy_device(struct libusb_device
*dev
) {
1103 static int submit_bulk_transfer(struct usbi_transfer
*itransfer
) {
1104 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1105 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)transfer
->dev_handle
->os_priv
;
1108 uint8_t is_read
; /* 0 = we're reading, 1 = we're writing */
1109 uint8_t transferType
;
1110 /* None of the values below are used in libusb for bulk transfers */
1111 uint8_t direction
, number
, interval
, pipeRef
, iface
;
1112 uint16_t maxPacketSize
;
1114 struct __darwin_interface
*cInterface
;
1116 /* are we reading or writing? */
1117 is_read
= transfer
->endpoint
& LIBUSB_ENDPOINT_IN
;
1119 if (ep_to_pipeRef (transfer
->dev_handle
, transfer
->endpoint
, &pipeRef
, &iface
) != 0) {
1120 usbi_err (TRANSFER_CTX (transfer
), "endpoint not found on any open interface");
1122 return LIBUSB_ERROR_NOT_FOUND
;
1125 cInterface
= &priv
->interfaces
[iface
];
1127 (*(cInterface
->interface
))->GetPipeProperties (cInterface
->interface
, pipeRef
, &direction
, &number
,
1128 &transferType
, &maxPacketSize
, &interval
);
1130 /* submit the request */
1131 /* timeouts are unavailable on interrupt endpoints */
1132 if (transferType
== kUSBInterrupt
) {
1134 ret
= (*(cInterface
->interface
))->ReadPipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1135 transfer
->length
, darwin_async_io_callback
, itransfer
);
1137 ret
= (*(cInterface
->interface
))->WritePipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1138 transfer
->length
, darwin_async_io_callback
, itransfer
);
1141 ret
= (*(cInterface
->interface
))->ReadPipeAsyncTO(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1142 transfer
->length
, transfer
->timeout
, transfer
->timeout
,
1143 darwin_async_io_callback
, (void *)itransfer
);
1145 ret
= (*(cInterface
->interface
))->WritePipeAsyncTO(cInterface
->interface
, pipeRef
, transfer
->buffer
,
1146 transfer
->length
, transfer
->timeout
, transfer
->timeout
,
1147 darwin_async_io_callback
, (void *)itransfer
);
1151 usbi_err (TRANSFER_CTX (transfer
), "bulk transfer failed (dir = %s): %s (code = 0x%08x)", is_read
? "In" : "Out",
1152 darwin_error_str(ret
), ret
);
1154 return darwin_to_libusb (ret
);
1157 static int submit_iso_transfer(struct usbi_transfer
*itransfer
) {
1158 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1159 struct darwin_transfer_priv
*tpriv
= usbi_transfer_get_os_priv(itransfer
);
1160 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)transfer
->dev_handle
->os_priv
;
1163 uint8_t is_read
; /* 0 = we're writing, 1 = we're reading */
1164 uint8_t pipeRef
, iface
;
1166 AbsoluteTime atTime
;
1169 struct __darwin_interface
*cInterface
;
1171 /* are we reading or writing? */
1172 is_read
= transfer
->endpoint
& LIBUSB_ENDPOINT_IN
;
1174 /* construct an array of IOUSBIsocFrames */
1175 tpriv
->isoc_framelist
= (IOUSBIsocFrame
*) calloc (transfer
->num_iso_packets
, sizeof(IOUSBIsocFrame
));
1176 if (!tpriv
->isoc_framelist
)
1177 return LIBUSB_ERROR_NO_MEM
;
1179 /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1180 for (i
= 0 ; i
< transfer
->num_iso_packets
; i
++)
1181 tpriv
->isoc_framelist
[i
].frReqCount
= transfer
->iso_packet_desc
[i
].length
;
1183 /* determine the interface/endpoint to use */
1184 if (ep_to_pipeRef (transfer
->dev_handle
, transfer
->endpoint
, &pipeRef
, &iface
) != 0) {
1185 usbi_err (TRANSFER_CTX (transfer
), "endpoint not found on any open interface");
1187 return LIBUSB_ERROR_NOT_FOUND
;
1190 cInterface
= &priv
->interfaces
[iface
];
1192 /* Last but not least we need the bus frame number */
1193 kresult
= (*(cInterface
->interface
))->GetBusFrameNumber(cInterface
->interface
, &frame
, &atTime
);
1195 usbi_err (TRANSFER_CTX (transfer
), "failed to get bus frame number: %d", kresult
);
1196 free(tpriv
->isoc_framelist
);
1197 tpriv
->isoc_framelist
= NULL
;
1199 return darwin_to_libusb (kresult
);
1202 /* schedule for a frame a little in the future */
1205 /* submit the request */
1207 kresult
= (*(cInterface
->interface
))->ReadIsochPipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
, frame
,
1208 transfer
->num_iso_packets
, tpriv
->isoc_framelist
, darwin_async_io_callback
,
1211 kresult
= (*(cInterface
->interface
))->WriteIsochPipeAsync(cInterface
->interface
, pipeRef
, transfer
->buffer
, frame
,
1212 transfer
->num_iso_packets
, tpriv
->isoc_framelist
, darwin_async_io_callback
,
1215 if (kresult
!= kIOReturnSuccess
) {
1216 usbi_err (TRANSFER_CTX (transfer
), "isochronous transfer failed (dir: %s): %s", is_read
? "In" : "Out",
1217 darwin_error_str(kresult
));
1218 free (tpriv
->isoc_framelist
);
1219 tpriv
->isoc_framelist
= NULL
;
1222 return darwin_to_libusb (kresult
);
1225 static int submit_control_transfer(struct usbi_transfer
*itransfer
) {
1226 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1227 struct libusb_control_setup
*setup
= (struct libusb_control_setup
*) transfer
->buffer
;
1228 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)transfer
->dev_handle
->dev
->os_priv
;
1229 struct darwin_transfer_priv
*tpriv
= usbi_transfer_get_os_priv(itransfer
);
1233 bzero(&tpriv
->req
, sizeof(tpriv
->req
));
1235 /* IOUSBDeviceInterface expects the request in cpu endianess */
1236 tpriv
->req
.bmRequestType
= setup
->bmRequestType
;
1237 tpriv
->req
.bRequest
= setup
->bRequest
;
1238 /* these values should be in bus order from libusb_fill_control_setup */
1239 tpriv
->req
.wValue
= OSSwapLittleToHostInt16 (setup
->wValue
);
1240 tpriv
->req
.wIndex
= OSSwapLittleToHostInt16 (setup
->wIndex
);
1241 tpriv
->req
.wLength
= OSSwapLittleToHostInt16 (setup
->wLength
);
1242 /* data is stored after the libusb control block */
1243 tpriv
->req
.pData
= transfer
->buffer
+ LIBUSB_CONTROL_SETUP_SIZE
;
1244 tpriv
->req
.completionTimeout
= transfer
->timeout
;
1245 tpriv
->req
.noDataTimeout
= transfer
->timeout
;
1247 /* all transfers in libusb-1.0 are async */
1248 kresult
= (*(dpriv
->device
))->DeviceRequestAsyncTO(dpriv
->device
, &(tpriv
->req
), darwin_async_io_callback
, itransfer
);
1250 if (kresult
!= kIOReturnSuccess
)
1251 usbi_err (TRANSFER_CTX (transfer
), "control request failed: %s", darwin_error_str(kresult
));
1253 return darwin_to_libusb (kresult
);
1256 static int darwin_submit_transfer(struct usbi_transfer
*itransfer
) {
1257 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1259 switch (transfer
->type
) {
1260 case LIBUSB_TRANSFER_TYPE_CONTROL
:
1261 return submit_control_transfer(itransfer
);
1262 case LIBUSB_TRANSFER_TYPE_BULK
:
1263 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
1264 return submit_bulk_transfer(itransfer
);
1265 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
1266 return submit_iso_transfer(itransfer
);
1268 usbi_err (TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1269 return LIBUSB_ERROR_INVALID_PARAM
;
1273 static int cancel_control_transfer(struct usbi_transfer
*itransfer
) {
1274 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1275 struct darwin_device_priv
*dpriv
= (struct darwin_device_priv
*)transfer
->dev_handle
->dev
->os_priv
;
1278 usbi_info (ITRANSFER_CTX (itransfer
), "WARNING: aborting all transactions control pipe");
1280 kresult
= (*(dpriv
->device
))->USBDeviceAbortPipeZero (dpriv
->device
);
1282 return darwin_to_libusb (kresult
);
1285 static int darwin_abort_transfers (struct usbi_transfer
*itransfer
) {
1286 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1287 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)transfer
->dev_handle
->os_priv
;
1288 struct __darwin_interface
*cInterface
;
1289 uint8_t pipeRef
, iface
;
1292 if (ep_to_pipeRef (transfer
->dev_handle
, transfer
->endpoint
, &pipeRef
, &iface
) != 0) {
1293 usbi_err (TRANSFER_CTX (transfer
), "endpoint not found on any open interface");
1295 return LIBUSB_ERROR_NOT_FOUND
;
1298 cInterface
= &priv
->interfaces
[iface
];
1300 usbi_info (ITRANSFER_CTX (itransfer
), "WARNING: aborting all transactions on interface %d pipe %d", iface
, pipeRef
);
1302 /* abort transactions */
1303 (*(cInterface
->interface
))->AbortPipe (cInterface
->interface
, pipeRef
);
1305 usbi_info (ITRANSFER_CTX (itransfer
), "calling clear pipe stall to clear the data toggle bit");
1307 /* clear the data toggle bit */
1308 #if (InterfaceVersion < 190)
1309 kresult
= (*(cInterface
->interface
))->ClearPipeStall(cInterface
->interface
, pipeRef
);
1311 /* newer versions of darwin support clearing additional bits on the device's endpoint */
1312 kresult
= (*(cInterface
->interface
))->ClearPipeStallBothEnds(cInterface
->interface
, pipeRef
);
1315 return darwin_to_libusb (kresult
);
1318 static int darwin_cancel_transfer(struct usbi_transfer
*itransfer
) {
1319 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1321 switch (transfer
->type
) {
1322 case LIBUSB_TRANSFER_TYPE_CONTROL
:
1323 return cancel_control_transfer(itransfer
);
1324 case LIBUSB_TRANSFER_TYPE_BULK
:
1325 case LIBUSB_TRANSFER_TYPE_INTERRUPT
:
1326 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
:
1327 return darwin_abort_transfers (itransfer
);
1329 usbi_err (TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1330 return LIBUSB_ERROR_INVALID_PARAM
;
1334 static void darwin_clear_transfer_priv (struct usbi_transfer
*itransfer
) {
1335 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1336 struct darwin_transfer_priv
*tpriv
= usbi_transfer_get_os_priv(itransfer
);
1338 if (transfer
->type
== LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
&& tpriv
->isoc_framelist
) {
1339 free (tpriv
->isoc_framelist
);
1340 tpriv
->isoc_framelist
= NULL
;
1344 static void darwin_async_io_callback (void *refcon
, IOReturn result
, void *arg0
) {
1345 struct usbi_transfer
*itransfer
= (struct usbi_transfer
*)refcon
;
1346 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1347 struct darwin_device_handle_priv
*priv
= (struct darwin_device_handle_priv
*)transfer
->dev_handle
->os_priv
;
1350 usbi_info (ITRANSFER_CTX (itransfer
), "an async io operation has completed");
1352 /* send a completion message to the device's file descriptor */
1353 message
= MESSAGE_ASYNC_IO_COMPLETE
;
1354 write (priv
->fds
[1], &message
, sizeof (message
));
1355 write (priv
->fds
[1], &itransfer
, sizeof (itransfer
));
1356 write (priv
->fds
[1], &result
, sizeof (IOReturn
));
1357 write (priv
->fds
[1], &arg0
, sizeof (UInt32
));
1360 static int darwin_transfer_status (struct usbi_transfer
*itransfer
, kern_return_t result
) {
1362 case kIOReturnUnderrun
:
1363 case kIOReturnSuccess
:
1364 return LIBUSB_TRANSFER_COMPLETED
;
1365 case kIOReturnAborted
:
1366 return LIBUSB_TRANSFER_CANCELLED
;
1367 case kIOUSBPipeStalled
:
1368 usbi_warn (ITRANSFER_CTX (itransfer
), "transfer error: pipe is stalled");
1369 return LIBUSB_TRANSFER_STALL
;
1370 case kIOReturnOverrun
:
1371 usbi_err (ITRANSFER_CTX (itransfer
), "transfer error: data overrun");
1372 return LIBUSB_TRANSFER_OVERFLOW
;
1373 case kIOUSBTransactionTimeout
:
1374 usbi_err (ITRANSFER_CTX (itransfer
), "transfer error: timed out");
1375 return LIBUSB_TRANSFER_TIMED_OUT
;
1377 usbi_err (ITRANSFER_CTX (itransfer
), "transfer error: %s (value = 0x%08x)", darwin_error_str (result
), result
);
1378 return LIBUSB_TRANSFER_ERROR
;
1382 static void darwin_handle_callback (struct usbi_transfer
*itransfer
, kern_return_t result
, UInt32 io_size
) {
1383 struct libusb_transfer
*transfer
= __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer
);
1384 struct darwin_transfer_priv
*tpriv
= usbi_transfer_get_os_priv(itransfer
);
1385 int isIsoc
= LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
== transfer
->type
;
1386 int isBulk
= LIBUSB_TRANSFER_TYPE_BULK
== transfer
->type
;
1387 int isControl
= LIBUSB_TRANSFER_TYPE_CONTROL
== transfer
->type
;
1388 int isInterrupt
= LIBUSB_TRANSFER_TYPE_INTERRUPT
== transfer
->type
;
1391 if (!isIsoc
&& !isBulk
&& !isControl
&& !isInterrupt
) {
1392 usbi_err (TRANSFER_CTX(transfer
), "unknown endpoint type %d", transfer
->type
);
1396 usbi_info (ITRANSFER_CTX (itransfer
), "handling %s completion with kernel status %d",
1397 isControl
? "control" : isBulk
? "bulk" : isIsoc
? "isoc" : "interrupt", result
);
1399 if (kIOReturnSuccess
== result
|| kIOReturnUnderrun
== result
) {
1400 if (isIsoc
&& tpriv
->isoc_framelist
) {
1401 /* copy isochronous results back */
1403 for (i
= 0; i
< transfer
->num_iso_packets
; i
++) {
1404 struct libusb_iso_packet_descriptor
*lib_desc
= &transfer
->iso_packet_desc
[i
];
1405 lib_desc
->status
= darwin_to_libusb (tpriv
->isoc_framelist
[i
].frStatus
);
1406 lib_desc
->actual_length
= tpriv
->isoc_framelist
[i
].frActCount
;
1409 itransfer
->transferred
+= io_size
;
1412 /* it is ok to handle cancelled transfers without calling usbi_handle_transfer_cancellation (we catch timeout transfers) */
1413 usbi_handle_transfer_completion (itransfer
, darwin_transfer_status (itransfer
, result
));
1416 static int op_handle_events(struct libusb_context
*ctx
, struct pollfd
*fds
, nfds_t nfds
, int num_ready
) {
1417 struct usbi_transfer
*itransfer
;
1423 usbi_mutex_lock(&ctx
->open_devs_lock
);
1424 for (i
= 0; i
< nfds
&& num_ready
> 0; i
++) {
1425 struct pollfd
*pollfd
= &fds
[i
];
1426 struct libusb_device_handle
*handle
;
1427 struct darwin_device_handle_priv
*hpriv
= NULL
;
1429 usbi_info (ctx
, "checking fd %i with revents = %x", fds
[i
], pollfd
->revents
);
1431 if (!pollfd
->revents
)
1435 list_for_each_entry(handle
, &ctx
->open_devs
, list
, struct libusb_device_handle
) {
1436 hpriv
= (struct darwin_device_handle_priv
*)handle
->os_priv
;
1437 if (hpriv
->fds
[0] == pollfd
->fd
)
1441 if (!(pollfd
->revents
& POLLERR
)) {
1442 ret
= read (hpriv
->fds
[0], &message
, sizeof (message
));
1443 if (ret
< sizeof (message
))
1446 /* could not poll the device-- response is to delete the device (this seems a little heavy-handed) */
1447 message
= MESSAGE_DEVICE_GONE
;
1450 case MESSAGE_DEVICE_GONE
:
1451 /* remove the device's async port from the runloop */
1452 if (hpriv
->cfSource
) {
1453 if (libusb_darwin_acfl
)
1454 CFRunLoopRemoveSource (libusb_darwin_acfl
, hpriv
->cfSource
, kCFRunLoopDefaultMode
);
1455 CFRelease (hpriv
->cfSource
);
1456 hpriv
->cfSource
= NULL
;
1459 usbi_remove_pollfd(HANDLE_CTX(handle
), hpriv
->fds
[0]);
1460 usbi_handle_disconnect(handle
);
1462 /* done with this device */
1464 case MESSAGE_ASYNC_IO_COMPLETE
:
1465 read (hpriv
->fds
[0], &itransfer
, sizeof (itransfer
));
1466 read (hpriv
->fds
[0], &kresult
, sizeof (IOReturn
));
1467 read (hpriv
->fds
[0], &io_size
, sizeof (UInt32
));
1469 darwin_handle_callback (itransfer
, kresult
, io_size
);
1472 usbi_err (ctx
, "unknown message received from device pipe");
1476 usbi_mutex_unlock(&ctx
->open_devs_lock
);
1481 static int darwin_clock_gettime(int clk_id
, struct timespec
*tp
) {
1482 mach_timespec_t sys_time
;
1483 clock_serv_t clock_ref
;
1486 case USBI_CLOCK_REALTIME
:
1487 /* CLOCK_REALTIME represents time since the epoch */
1488 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &clock_ref
);
1490 case USBI_CLOCK_MONOTONIC
:
1491 /* use system boot time as reference for the monotonic clock */
1492 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK
, &clock_ref
);
1495 return LIBUSB_ERROR_INVALID_PARAM
;
1498 clock_get_time (clock_ref
, &sys_time
);
1500 tp
->tv_sec
= sys_time
.tv_sec
;
1501 tp
->tv_nsec
= sys_time
.tv_nsec
;
1506 const struct usbi_os_backend darwin_backend
= {
1508 .init
= darwin_init
,
1509 .exit
= darwin_exit
,
1510 .get_device_list
= darwin_get_device_list
,
1511 .get_device_descriptor
= darwin_get_device_descriptor
,
1512 .get_active_config_descriptor
= darwin_get_active_config_descriptor
,
1513 .get_config_descriptor
= darwin_get_config_descriptor
,
1515 .open
= darwin_open
,
1516 .close
= darwin_close
,
1517 .get_configuration
= darwin_get_configuration
,
1518 .set_configuration
= darwin_set_configuration
,
1519 .claim_interface
= darwin_claim_interface
,
1520 .release_interface
= darwin_release_interface
,
1522 .set_interface_altsetting
= darwin_set_interface_altsetting
,
1523 .clear_halt
= darwin_clear_halt
,
1524 .reset_device
= darwin_reset_device
,
1526 .kernel_driver_active
= darwin_kernel_driver_active
,
1527 .detach_kernel_driver
= darwin_detach_kernel_driver
,
1528 .attach_kernel_driver
= darwin_attach_kernel_driver
,
1530 .destroy_device
= darwin_destroy_device
,
1532 .submit_transfer
= darwin_submit_transfer
,
1533 .cancel_transfer
= darwin_cancel_transfer
,
1534 .clear_transfer_priv
= darwin_clear_transfer_priv
,
1536 .handle_events
= op_handle_events
,
1538 .clock_gettime
= darwin_clock_gettime
,
1540 .device_priv_size
= sizeof(struct darwin_device_priv
),
1541 .device_handle_priv_size
= sizeof(struct darwin_device_handle_priv
),
1542 .transfer_priv_size
= sizeof(struct darwin_transfer_priv
),
1543 .add_iso_packet_size
= 0,