Darwin: 64-bit type fixes
[platform/upstream/libusb.git] / libusb / os / darwin_usb.c
1 /*
2  * darwin backend for libusb 1.0
3  * Copyright (C) 2008-2009 Nathan Hjelm <hjelmn@users.sourceforge.net>
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <config.h>
21 #include <ctype.h>
22 #include <dirent.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/ioctl.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33
34 #include <mach/clock.h>
35 #include <mach/clock_types.h>
36 #include <mach/mach_host.h>
37
38 #include <mach/mach_port.h>
39 #include <IOKit/IOCFBundle.h>
40 #include <IOKit/usb/IOUSBLib.h>
41 #include <IOKit/IOCFPlugIn.h>
42
43 #include "darwin_usb.h"
44
45 static mach_port_t  libusb_darwin_mp = 0; /* master port */
46 static CFRunLoopRef libusb_darwin_acfl = NULL; /* async cf loop */
47
48 /* async event thread */
49 static pthread_t libusb_darwin_at;
50
51 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian);
52 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface);
53 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface);
54 static int darwin_reset_device(struct libusb_device_handle *dev_handle);
55 static void darwin_bulk_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size);
56 static void darwin_isoc_callback (struct usbi_transfer *itransfer, kern_return_t result);
57 static void darwin_control_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size);
58 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0);
59
60 static char *darwin_error_str (int result) {
61   switch (result) {
62   case kIOReturnSuccess:
63     return "no error";
64   case kIOReturnNotOpen:
65     return "device not opened for exclusive access";
66   case kIOReturnNoDevice:
67     return "no connection to an IOService";
68   case kIOUSBNoAsyncPortErr:
69     return "no async port has been opened for interface";
70   case kIOReturnExclusiveAccess:
71     return "another process has device opened for exclusive access";
72   case kIOUSBPipeStalled:
73     return "pipe is stalled";
74   case kIOReturnError:
75     return "could not establish a connection to the Darwin kernel";
76   case kIOUSBTransactionTimeout:
77     return "transaction timed out";
78   case kIOReturnBadArgument:
79     return "invalid argument";
80   case kIOReturnAborted:
81     return "transaction aborted";
82   case kIOReturnNotResponding:
83     return "device not responding";
84   default:
85     return "unknown error";
86   }
87 }
88
89 static int darwin_to_libusb (int result) {
90   switch (result) {
91   case kIOReturnSuccess:
92     return LIBUSB_SUCCESS;
93   case kIOReturnNotOpen:
94   case kIOReturnNoDevice:
95     return LIBUSB_ERROR_NO_DEVICE;
96   case kIOReturnExclusiveAccess:
97     return LIBUSB_ERROR_ACCESS;
98   case kIOUSBPipeStalled:
99     return LIBUSB_ERROR_PIPE;
100   case kIOReturnBadArgument:
101     return LIBUSB_ERROR_INVALID_PARAM;
102   case kIOUSBTransactionTimeout:
103     return LIBUSB_ERROR_TIMEOUT;
104   case kIOReturnNotResponding:
105   case kIOReturnAborted:
106   case kIOReturnError:
107   case kIOUSBNoAsyncPortErr:
108   default:
109     return LIBUSB_ERROR_OTHER;
110   }
111 }
112
113
114 static int ep_to_pipeRef(struct libusb_device_handle *dev_handle, uint8_t ep, uint8_t *pipep, uint8_t *ifcp) {
115   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
116
117   /* current interface */
118   struct __darwin_interface *cInterface;
119
120   int8_t i, iface;
121
122   _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_INFO, "converting ep address 0x%02x to pipeRef and interface", ep);
123
124   for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
125     cInterface = &priv->interfaces[iface];
126
127     if (dev_handle->claimed_interfaces & (1 << iface)) {
128       for (i = 0 ; i < cInterface->num_endpoints ; i++) {
129         if (cInterface->endpoint_addrs[i] == ep) {
130           *pipep = i + 1;
131           *ifcp = iface;
132           _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_INFO, "pipe %d on interface %d matches", *pipep, *ifcp);
133           return 0;
134         }
135       }
136     }
137   }
138
139   /* No pipe found with the correct endpoint address */
140   _usbi_log (HANDLE_CTX(dev_handle), LOG_LEVEL_WARNING, "no pipeRef found with endpoint address 0x%02x.", ep);
141   
142   return -1;
143 }
144
145 static int usb_setup_device_iterator (io_iterator_t *deviceIterator) {
146   return IOServiceGetMatchingServices(libusb_darwin_mp, IOServiceMatching(kIOUSBDeviceClassName), deviceIterator);
147 }
148
149 static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp) {
150   io_cf_plugin_ref_t *plugInInterface = NULL;
151   usb_device_t **device;
152   io_service_t usbDevice;
153   long result;
154   SInt32 score;
155
156   if (!IOIteratorIsValid (deviceIterator) || !(usbDevice = IOIteratorNext(deviceIterator)))
157     return NULL;
158   
159   result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
160                                              kIOCFPlugInInterfaceID, &plugInInterface,
161                                              &score);
162   
163   if (result || !plugInInterface) {
164     usbi_dbg ("libusb/darwin.c usb_get_next_device: could not set up plugin for service: %s\n", darwin_error_str (result));
165
166     return NULL;
167   }
168
169   (void)IOObjectRelease(usbDevice);
170   (void)(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
171                                            (LPVOID)&device);
172
173   (*plugInInterface)->Stop(plugInInterface);
174   IODestroyPlugInInterface (plugInInterface);
175   
176   (*(device))->GetLocationID(device, locationp);
177
178   return device;
179 }
180
181 static kern_return_t darwin_get_device (uint32_t dev_location, usb_device_t ***darwin_device) {
182   kern_return_t kresult;
183   UInt32        location;
184   io_iterator_t deviceIterator;
185
186   kresult = usb_setup_device_iterator (&deviceIterator);
187   if (kresult)
188     return kresult;
189
190   /* This port of libusb uses locations to keep track of devices. */
191   while ((*darwin_device = usb_get_next_device (deviceIterator, &location)) != NULL) {
192     if (location == dev_location)
193       break;
194
195     (**darwin_device)->Release(*darwin_device);
196   }
197
198   IOObjectRelease (deviceIterator);
199
200   if (!(*darwin_device))
201     return kIOReturnNoDevice;
202
203   return kIOReturnSuccess;
204 }
205
206
207
208 static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {  
209   struct libusb_context *ctx = (struct libusb_context *)ptr;
210   struct libusb_device_handle *handle;
211   struct darwin_device_priv *dpriv;
212   struct darwin_device_handle_priv *priv;
213
214   io_service_t device;
215   long location;
216   CFTypeRef locationCF;
217   UInt32 message;
218
219   _usbi_log (ctx, LOG_LEVEL_INFO, "a device has been detached");
220
221   while ((device = IOIteratorNext (rem_devices)) != 0) {
222     /* get the location from the i/o registry */
223     locationCF = IORegistryEntryCreateCFProperty (device, CFSTR(kUSBDevicePropertyLocationID), kCFAllocatorDefault, 0);
224
225     CFNumberGetValue(locationCF, kCFNumberLongType, &location);
226     CFRelease (locationCF);
227     IOObjectRelease (device);
228
229     pthread_mutex_lock(&ctx->open_devs_lock);
230     list_for_each_entry(handle, &ctx->open_devs, list) {
231       dpriv = (struct darwin_device_priv *)handle->dev->os_priv;
232       if (dpriv->location == location)
233         break;
234     }
235
236     if (handle && handle->os_priv) {
237       priv  = (struct darwin_device_handle_priv *)handle->os_priv;
238
239       message = MESSAGE_DEVICE_GONE;
240       write (priv->fds[1], &message, sizeof (message));
241     }
242
243     pthread_mutex_unlock(&ctx->open_devs_lock);
244
245   }
246 }
247
248 static void darwin_clear_iterator (io_iterator_t iter) {
249   io_service_t device;
250
251   while ((device = IOIteratorNext (iter)) != 0)
252     IOObjectRelease (device);
253 }
254
255 static void *event_thread_main (void *arg0) {
256   IOReturn kresult;
257   struct libusb_context *ctx = (struct libusb_context *)arg0;
258
259   /* hotplug (device removal) source */
260   CFRunLoopSourceRef     libusb_notification_cfsource;
261   io_notification_port_t libusb_notification_port;
262   io_iterator_t          libusb_rem_device_iterator;
263
264   _usbi_log (ctx, LOG_LEVEL_INFO, "creating hotplug event source");
265
266   CFRetain (CFRunLoopGetCurrent ());
267
268   /* add the notification port to the run loop */
269   libusb_notification_port     = IONotificationPortCreate (libusb_darwin_mp);
270   libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
271   CFRunLoopAddSource(CFRunLoopGetCurrent (), libusb_notification_cfsource, kCFRunLoopDefaultMode);
272
273   /* create notifications for removed devices */
274   kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
275                                               IOServiceMatching(kIOUSBDeviceClassName),
276                                               (IOServiceMatchingCallback)darwin_devices_detached,
277                                               (void *)ctx, &libusb_rem_device_iterator);
278  
279   if (kresult != kIOReturnSuccess) {
280     _usbi_log (ctx, LOG_LEVEL_ERROR, "could not add hotplug event source: %s", darwin_error_str (kresult));
281
282     pthread_exit ((void *)kresult);
283   }
284
285   /* arm notifiers */
286   darwin_clear_iterator (libusb_rem_device_iterator);
287
288   /* let the main thread know about the async runloop */
289   libusb_darwin_acfl = CFRunLoopGetCurrent ();
290
291   _usbi_log (ctx, LOG_LEVEL_INFO, "libopenusb/darwin.c event_thread_main: thread ready to receive events");
292
293   /* run the runloop */
294   CFRunLoopRun();
295
296   _usbi_log (ctx, LOG_LEVEL_INFO, "libopenusb/darwin.c event_thread_main: thread exiting");
297
298   /* delete notification port */
299   CFRunLoopSourceInvalidate (libusb_notification_cfsource);
300   IONotificationPortDestroy (libusb_notification_port);
301
302   CFRelease (CFRunLoopGetCurrent ());
303
304   libusb_darwin_acfl = NULL;
305
306   pthread_exit (0);
307 }
308
309 static int darwin_init(struct libusb_context *ctx) {
310   IOReturn kresult;
311
312   /* Create the master port for talking to IOKit */
313   if (!libusb_darwin_mp) {
314     kresult = IOMasterPort (MACH_PORT_NULL, &libusb_darwin_mp);
315
316     if (kresult != kIOReturnSuccess || !libusb_darwin_mp)
317       return darwin_to_libusb (kresult);
318   }
319
320   pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx);
321
322   while (!libusb_darwin_acfl)
323     usleep (10);
324
325   return 0;
326 }
327
328 static void darwin_exit (void) {
329   void *ret;
330
331   /* stop the async runloop */
332   CFRunLoopStop (libusb_darwin_acfl);
333   pthread_join (libusb_darwin_at, &ret);
334
335   if (libusb_darwin_mp)
336     mach_port_deallocate(mach_task_self(), libusb_darwin_mp);
337
338   libusb_darwin_mp = 0;
339 }
340
341 static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) {
342   struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
343
344   /* return cached copy */
345   memmove (buffer, &(priv->dev_descriptor), DEVICE_DESC_LENGTH);
346
347   *host_endian = 0;
348
349   return 0;
350 }
351
352 static int get_configuration_index (struct libusb_device *dev, int config_value) {
353   struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
354   UInt8 i, numConfig;
355   IOUSBConfigurationDescriptorPtr desc;
356   IOReturn kresult;
357
358   /* is there a simpler way to determine the index? */
359   kresult = (*(priv->device))->GetNumberOfConfigurations (priv->device, &numConfig);
360   if (kresult != kIOReturnSuccess)
361     return darwin_to_libusb (kresult);
362
363   for (i = 0 ; i < numConfig ; i++) {
364     (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
365
366     if (libusb_le16_to_cpu (desc->bConfigurationValue) == config_value)
367       return i;
368   }
369
370   /* configuration not found */
371   return LIBUSB_ERROR_OTHER;
372 }
373
374 static int darwin_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian) {
375   struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
376   UInt8 config_value;
377   int config_index;
378   IOReturn kresult;
379
380   kresult = (*(priv->device))->GetConfiguration (priv->device, &config_value);
381   if (kresult != kIOReturnSuccess)
382     return darwin_to_libusb (kresult);
383
384   config_index = get_configuration_index (dev, config_value);
385   if (config_index < 0)
386     return config_index;
387
388   return darwin_get_config_descriptor (dev, config_index, buffer, len, host_endian);
389 }
390
391 static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) {
392   struct darwin_device_priv *priv = (struct darwin_device_priv *)dev->os_priv;
393   IOUSBConfigurationDescriptorPtr desc;
394   IOReturn kresult;
395   usb_device_t **device = NULL;
396
397   if (!priv)
398     return LIBUSB_ERROR_OTHER;
399
400   if (!priv->device) {
401     kresult = darwin_get_device (priv->location, &device);
402     if (kresult || !device) {
403       _usbi_log (DEVICE_CTX (dev), LOG_LEVEL_ERROR, "could not find device: %s", darwin_error_str (kresult));
404
405       return darwin_to_libusb (kresult);
406     }
407
408     /* don't have to open the device to get a config descriptor */
409   } else
410     device = priv->device;
411
412   kresult = (*device)->GetConfigurationDescriptorPtr (device, config_index, &desc);
413   if (kresult == kIOReturnSuccess) {
414     /* copy descriptor */
415     if (libusb_le16_to_cpu(desc->wTotalLength) < len)
416       len = libusb_le16_to_cpu(desc->wTotalLength);
417
418     memmove (buffer, desc, len);
419
420     /* GetConfigurationDescriptorPtr returns the descriptor in USB bus order */
421     *host_endian = 0;
422   }
423
424   if (!priv->device)
425     (*device)->Release (device);
426
427   return darwin_to_libusb (kresult);
428 }
429
430 static int process_new_device (struct libusb_context *ctx, usb_device_t **device, UInt32 locationID, struct discovered_devs **_discdevs) {
431   struct darwin_device_priv *priv;
432   struct libusb_device *dev; 
433   struct discovered_devs *discdevs;
434   UInt16                address, idVendor, idProduct;
435   UInt8                 bDeviceClass, bDeviceSubClass;
436   IOUSBDevRequest      req;
437   int ret;
438
439   dev = usbi_get_device_by_session_id(ctx, locationID);
440   if (!dev) {
441     _usbi_log (ctx, LOG_LEVEL_INFO, "allocating new device for location 0x%08x", locationID);
442     dev = usbi_alloc_device(ctx, locationID);
443     if (!dev)
444       return LIBUSB_ERROR_NO_MEM;
445
446     priv = (struct darwin_device_priv *)dev->os_priv;
447
448     /* Set up request for device descriptor */
449     req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
450     req.bRequest      = kUSBRqGetDescriptor;
451     req.wValue        = kUSBDeviceDesc << 8;
452     req.wIndex        = 0;
453     req.wLength       = sizeof(IOUSBDeviceDescriptor);
454     req.pData         = &(priv->dev_descriptor);
455     
456     (*(device))->GetDeviceAddress (device, (USBDeviceAddress *)&address);
457     (*(device))->GetDeviceProduct (device, &idProduct);
458     (*(device))->GetDeviceVendor (device, &idVendor);
459     (*(device))->GetDeviceClass (device, &bDeviceClass);
460     (*(device))->GetDeviceSubClass (device, &bDeviceSubClass);
461
462     /**** retrieve device descriptors ****/
463     /* device must be open for DeviceRequest */
464     (*device)->USBDeviceOpen(device);
465     
466     ret = (*(device))->DeviceRequest (device, &req);
467     if (ret != kIOReturnSuccess) {
468       int try_unsuspend = 1;
469 #if DeviceVersion >= 320
470       UInt32 info;
471
472       /* device may be suspended. unsuspend it and try again */
473       /* IOUSBFamily 320+ provides a way to detect device suspension but earlier versions do not */
474       (void)(*device)->GetUSBDeviceInformation (device, &info);
475
476       try_unsuspend = info & (1 << kUSBInformationDeviceIsSuspendedBit);
477 #endif
478
479       if (try_unsuspend) {
480         /* resume the device */
481         (void)(*device)->USBDeviceSuspend (device, 0);
482
483         ret = (*(device))->DeviceRequest (device, &req);
484
485         /* resuspend the device */
486         (void)(*device)->USBDeviceSuspend (device, 1);
487       }
488     }
489
490     (*device)->USBDeviceClose (device);
491
492     if (ret != kIOReturnSuccess) {
493       _usbi_log (ctx, LOG_LEVEL_WARNING, "could not retrieve device descriptor: %s. skipping device", darwin_error_str (ret));
494       libusb_unref_device(dev);
495       return -1;
496     }
497     /**** end: retrieve device descriptors ****/
498     
499     /* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices. */
500     if (libusb_le16_to_cpu (priv->dev_descriptor.idProduct) != idProduct) {
501       /* not a valid device */
502       _usbi_log (ctx, LOG_LEVEL_WARNING, "idProduct from iokit (%04x) does not match idProduct in descriptor (%04x). skipping device",
503                  idProduct, libusb_le16_to_cpu (priv->dev_descriptor.idProduct));
504       libusb_unref_device(dev);
505       return -1;
506     }
507
508     dev->bus_number     = locationID >> 24;
509     dev->device_address = address;
510
511     /* save our location, we'll need this later */
512     priv->location = locationID;
513     snprintf(priv->sys_path, 20, "%03i-%04x-%04x-%02x-%02x", address, idVendor, idProduct, bDeviceClass, bDeviceSubClass);
514
515     ret = usbi_sanitize_device(dev);
516
517     if (ret < 0) {
518       libusb_unref_device(dev);
519       return -1;
520     }
521   } else {
522     priv = (struct darwin_device_priv *)dev->os_priv;
523
524     _usbi_log (ctx, LOG_LEVEL_INFO, "using existing device for location 0x%08x", locationID);
525   }
526
527   /* append the device to the list of discovered devices */
528   discdevs = discovered_devs_append(*_discdevs, dev);
529   if (!discdevs)
530     return LIBUSB_ERROR_NO_MEM;
531     
532   *_discdevs = discdevs;
533   
534   _usbi_log (ctx, LOG_LEVEL_INFO, "found device with address %d at %s", dev->device_address, priv->sys_path);
535   
536   return 0;
537 }
538
539 static int darwin_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs) {
540   io_iterator_t        deviceIterator;
541   usb_device_t         **device;
542   kern_return_t        kresult;
543   UInt32               location;
544
545   if (!libusb_darwin_mp)
546     return LIBUSB_ERROR_INVALID_PARAM;
547   
548   kresult = usb_setup_device_iterator (&deviceIterator);
549   if (kresult != kIOReturnSuccess)
550     return darwin_to_libusb (kresult);
551
552   while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
553     (void) process_new_device (ctx, device, location, _discdevs);
554
555     (*(device))->Release(device);
556   }
557
558   IOObjectRelease(deviceIterator);
559
560   return 0;
561 }
562
563 static int darwin_open (struct libusb_device_handle *dev_handle) {
564   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
565   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
566   usb_device_t  **darwin_device;
567   IOReturn kresult;
568
569   kresult = darwin_get_device (dpriv->location, &darwin_device);
570   if (kresult) {
571     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not find device: %s", darwin_error_str (kresult));
572     return darwin_to_libusb (kresult);
573   }
574
575   dpriv->device = darwin_device;
576
577   /* try to open the device */
578   kresult = (*(dpriv->device))->USBDeviceOpenSeize (dpriv->device);
579
580   if (kresult != kIOReturnSuccess) {
581     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBDeviceOpen: %s", darwin_error_str(kresult));
582
583     switch (kresult) {
584     case kIOReturnExclusiveAccess:
585       /* it is possible to perform some actions on a device that is not open so do not return an error */
586       priv->is_open = 0;
587
588       break;
589     default:
590       (*(dpriv->device))->Release (dpriv->device);
591       dpriv->device = NULL;
592       return darwin_to_libusb (kresult);
593     }
594   } else {
595     priv->is_open = 1;
596
597     /* create async event source */
598     kresult = (*(dpriv->device))->CreateDeviceAsyncEventSource (dpriv->device, &priv->cfSource);
599
600     CFRetain (libusb_darwin_acfl);
601
602     /* add the cfSource to the aync run loop */
603     CFRunLoopAddSource(libusb_darwin_acfl, priv->cfSource, kCFRunLoopCommonModes);
604   }
605
606   /* create a file descriptor for notifications */
607   pipe (priv->fds);
608
609   /* set the pipe to be non-blocking */
610   fcntl (priv->fds[1], F_SETFD, O_NONBLOCK);
611
612   usbi_add_pollfd(HANDLE_CTX(dev_handle), priv->fds[0], POLLIN);
613
614   _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "device open for access");
615
616   return 0;
617 }
618
619 static void darwin_close (struct libusb_device_handle *dev_handle) {
620   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
621   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
622   IOReturn kresult;
623   int i;
624
625   /* make sure all interfaces are released */
626   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
627     if (dev_handle->claimed_interfaces & (1 << i))
628       libusb_release_interface (dev_handle, i);
629
630   if (priv->is_open) {
631     /* delete the device's async event source */
632     if (priv->cfSource) {
633       CFRunLoopRemoveSource (libusb_darwin_acfl, priv->cfSource, kCFRunLoopDefaultMode);
634       CFRelease (priv->cfSource);
635     }
636
637     /* close the device */
638     kresult = (*(dpriv->device))->USBDeviceClose(dpriv->device);
639     if (kresult) {
640       /* Log the fact that we had a problem closing the file, however failing a
641        * close isn't really an error, so return success anyway */
642       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBDeviceClose: %s", darwin_error_str(kresult));
643     }
644   }
645   
646   kresult = (*(dpriv->device))->Release(dpriv->device);
647   if (kresult) {
648     /* Log the fact that we had a problem closing the file, however failing a
649      * close isn't really an error, so return success anyway */
650     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "Release: %s", darwin_error_str(kresult));
651   }
652
653   usbi_remove_pollfd (HANDLE_CTX (dev_handle), priv->fds[0]);
654   close (priv->fds[1]);
655   close (priv->fds[0]);
656
657   dpriv->device = NULL;
658   priv->fds[0] = priv->fds[1] = -1;
659 }
660
661 static int darwin_get_configuration(struct libusb_device_handle *dev_handle, int *config) {
662   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
663   UInt8 configNum;
664   IOReturn kresult;
665
666   kresult = (*(dpriv->device))->GetConfiguration (dpriv->device, &configNum);
667   if (kresult != kIOReturnSuccess)
668     return darwin_to_libusb (kresult);
669
670   *config = (int) configNum;
671
672   return 0;
673 }
674
675 static int darwin_set_configuration(struct libusb_device_handle *dev_handle, int config) {
676   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
677   IOReturn kresult;
678   int i;
679
680   /* Setting configuration will invalidate the interface, so we need
681      to reclaim it. First, dispose of existing interfaces, if any. */
682   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
683     if (dev_handle->claimed_interfaces & (1 << i))
684       darwin_release_interface (dev_handle, i);
685
686   kresult = (*(dpriv->device))->SetConfiguration (dpriv->device, config);
687   if (kresult != kIOReturnSuccess)
688     return darwin_to_libusb (kresult);
689
690   /* Reclaim any interfaces. */
691   for (i = 0 ; i < USB_MAXINTERFACES ; i++)
692     if (dev_handle->claimed_interfaces & (1 << i))
693       darwin_claim_interface (dev_handle, i);
694
695   return 0;
696 }
697
698 static int darwin_get_interface (usb_device_t **darwin_device, uint8_t ifc, io_service_t *usbInterfacep) {
699   IOUSBFindInterfaceRequest request;
700   uint8_t                   current_interface;
701   kern_return_t             kresult;
702   io_iterator_t             interface_iterator;
703
704   *usbInterfacep = IO_OBJECT_NULL;
705   
706   /* Setup the Interface Request */
707   request.bInterfaceClass    = kIOUSBFindInterfaceDontCare;
708   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
709   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
710   request.bAlternateSetting  = kIOUSBFindInterfaceDontCare;
711
712   kresult = (*(darwin_device))->CreateInterfaceIterator(darwin_device, &request, &interface_iterator);
713   if (kresult)
714     return kresult;
715
716   for ( current_interface = 0 ; current_interface <= ifc ; current_interface++ )
717     *usbInterfacep = IOIteratorNext(interface_iterator);
718   
719   /* done with the interface iterator */
720   IOObjectRelease(interface_iterator);
721   
722   return 0;
723 }
724
725 static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
726   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
727
728   /* current interface */
729   struct __darwin_interface *cInterface = &priv->interfaces[iface];
730
731   kern_return_t kresult;
732
733   u_int8_t numep, direction, number;
734   u_int8_t dont_care1, dont_care3;
735   u_int16_t dont_care2;
736   int i;
737
738   _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "building table of endpoints.");
739   
740   /* retrieve the total number of endpoints on this interface */
741   kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
742   if (kresult) {
743     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
744     return darwin_to_libusb (kresult);
745   }
746
747   /* iterate through pipe references */
748   for (i = 1 ; i <= numep ; i++) {
749     kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
750                                                             &dont_care2, &dont_care3);
751
752     if (kresult != kIOReturnSuccess) {
753       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult));
754
755       return darwin_to_libusb (kresult);
756     }
757
758     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
759
760     cInterface->endpoint_addrs[i - 1] = ((direction << 7 & LIBUSB_ENDPOINT_DIR_MASK) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
761   }
762
763   cInterface->num_endpoints = numep;
764   
765   return 0;
766 }
767
768 static int darwin_claim_interface(struct libusb_device_handle *dev_handle, int iface) {
769   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
770   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
771   io_service_t          usbInterface = IO_OBJECT_NULL;
772   IOReturn kresult;
773   IOCFPlugInInterface **plugInInterface = NULL;
774   SInt32                score;
775   uint8_t               new_config;
776
777   /* current interface */
778   struct __darwin_interface *cInterface = &priv->interfaces[iface];
779
780   kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
781   if (kresult != kIOReturnSuccess)
782     return darwin_to_libusb (kresult);
783
784   /* make sure we have an interface */
785   if (!usbInterface) {
786     u_int8_t nConfig;     /* Index of configuration to use */
787     IOUSBConfigurationDescriptorPtr configDesc; /* to describe which configuration to select */
788     /* Only a composite class device with no vendor-specific driver will
789        be configured. Otherwise, we need to do it ourselves, or there
790        will be no interfaces for the device. */
791
792     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "no interface found; selecting configuration" );
793
794     kresult = (*(dpriv->device))->GetNumberOfConfigurations (dpriv->device, &nConfig);
795     if (kresult != kIOReturnSuccess) {
796       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetNumberOfConfigurations: %s", darwin_error_str(kresult));
797       return darwin_to_libusb(kresult);
798     }
799     
800     if (nConfig < 1) {
801       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetNumberOfConfigurations: no configurations");
802       return LIBUSB_ERROR_OTHER;
803     }
804
805     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "device has %d configuration%s. using the first",
806               (int)nConfig, (nConfig > 1 ? "s" : "") );
807
808     /* Always use the first configuration */
809     kresult = (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, 0, &configDesc);
810     if (kresult != kIOReturnSuccess) {
811       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "GetConfigurationDescriptorPtr: %s",
812                 darwin_error_str(kresult));
813
814       new_config = 1;
815     } else
816       new_config = configDesc->bConfigurationValue;
817
818     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "new configuration value is %d", new_config);
819
820     /* set the configuration */
821     kresult = darwin_set_configuration (dev_handle, new_config);
822     if (kresult != LIBUSB_SUCCESS) {
823       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not set configuration");
824       return kresult;
825     }
826
827     kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
828     if (kresult) {
829       _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "darwin_get_interface: %s", darwin_error_str(kresult));
830       return darwin_to_libusb (kresult);
831     }
832   }
833
834   if (!usbInterface) {
835     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "interface not found");
836     return LIBUSB_ERROR_NOT_FOUND;
837   }
838   
839   /* get an interface to the device's interface */
840   kresult = IOCreatePlugInInterfaceForService (usbInterface, kIOUSBInterfaceUserClientTypeID,
841                                                kIOCFPlugInInterfaceID, &plugInInterface, &score);
842   if (kresult) {
843     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
844     return darwin_to_libusb (kresult);
845   }
846
847   if (!plugInInterface) {
848     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "plugin interface not found");
849     return LIBUSB_ERROR_NOT_FOUND;
850   }
851
852   /* ignore release error */
853   (void)IOObjectRelease (usbInterface);
854   
855   /* Do the actual claim */
856   kresult = (*plugInInterface)->QueryInterface(plugInInterface,
857                                                CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
858                                                (LPVOID)&cInterface->interface);
859   if (kresult || !cInterface->interface) {
860     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "QueryInterface: %s", darwin_error_str(kresult));
861     return darwin_to_libusb (kresult);
862   }
863   
864   /* We no longer need the intermediate plug-in */
865   (*plugInInterface)->Release(plugInInterface);
866
867   /* claim the interface */
868   kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
869   if (kresult) {
870     _usbi_log(HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBInterfaceOpen: %s", darwin_error_str(kresult));
871     return darwin_to_libusb (kresult);
872   }
873
874   /* update list of endpoints */
875   kresult = get_endpoints (dev_handle, iface);
876   if (kresult) {
877     /* this should not happen */
878     darwin_release_interface (dev_handle, iface);
879     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not build endpoint table");
880     return kresult;
881   }
882
883   cInterface->cfSource = NULL;
884
885   /* create async event source */
886   kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
887   if (kresult != kIOReturnSuccess) {
888     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "could not create async event source");
889
890     /* can't continue without an async event source */
891     (void)darwin_release_interface (dev_handle, iface);
892
893     return darwin_to_libusb (kresult);
894   }
895
896   /* add the cfSource to the async thread's run loop */
897   CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
898
899   _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_INFO, "interface opened");
900
901   return 0;
902 }
903
904 static int darwin_release_interface(struct libusb_device_handle *dev_handle, int iface) {
905   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
906   IOReturn kresult;
907
908   /* current interface */
909   struct __darwin_interface *cInterface = &priv->interfaces[iface];
910
911   /* Check to see if an interface is open */
912   if (!cInterface->interface)
913     return LIBUSB_SUCCESS;
914
915   /* clean up endpoint data */
916   cInterface->num_endpoints = 0;
917   
918   /* delete the interface's async event source */
919   if (cInterface->cfSource) {
920     CFRunLoopRemoveSource (libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
921     CFRelease (cInterface->cfSource);
922   }
923
924   kresult = (*(cInterface->interface))->USBInterfaceClose(cInterface->interface);
925   if (kresult)
926     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "USBInterfaceClose: %s", darwin_error_str(kresult));
927
928   kresult = (*(cInterface->interface))->Release(cInterface->interface);
929   if (kresult != kIOReturnSuccess)
930     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "Release: %s", darwin_error_str(kresult));
931
932   cInterface->interface = IO_OBJECT_NULL;
933
934   return darwin_to_libusb (kresult);
935 }
936
937 static int darwin_set_interface_altsetting(struct libusb_device_handle *dev_handle, int iface, int altsetting) {
938   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
939   IOReturn kresult;
940
941   /* current interface */
942   struct __darwin_interface *cInterface = &priv->interfaces[iface];
943
944   if (!cInterface->interface)
945     return LIBUSB_ERROR_NO_DEVICE;
946
947   kresult = (*(cInterface->interface))->SetAlternateInterface (cInterface->interface, altsetting);
948   if (kresult != kIOReturnSuccess)
949     darwin_reset_device (dev_handle);
950
951   return darwin_to_libusb (kresult);
952 }
953
954 static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint) {
955   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)dev_handle->os_priv;
956
957   /* current interface */
958   struct __darwin_interface *cInterface;
959   uint8_t pipeRef, iface;
960   IOReturn kresult;
961
962   /* determine the interface/endpoint to use */
963   if (ep_to_pipeRef (dev_handle, endpoint, &pipeRef, &iface) != 0) {
964     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
965
966     return LIBUSB_ERROR_NOT_FOUND;
967   }
968
969   cInterface = &priv->interfaces[iface];
970
971 #if (InterfaceVersion < 190)
972   kresult = (*(cInterface->interface))->ClearPipeStall(cInterface->interface, pipeRef);
973 #else
974   /* newer versions of darwin support clearing additional bits on the device's endpoint */
975   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
976 #endif
977   if (kresult)
978     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "ClearPipeStall: %s", darwin_error_str (kresult));
979
980   return darwin_to_libusb (kresult);
981 }
982
983 static int darwin_reset_device(struct libusb_device_handle *dev_handle) {
984   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
985   IOReturn kresult;
986
987   kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
988   if (kresult)
989     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "ResetDevice: %s", darwin_error_str (kresult));
990
991   return darwin_to_libusb (kresult);
992 }
993
994 static int darwin_kernel_driver_active(struct libusb_device_handle *dev_handle, int interface) {
995   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)dev_handle->dev->os_priv;
996   io_service_t usbInterface;
997   CFTypeRef driver;
998   IOReturn kresult;
999
1000   kresult = darwin_get_interface (dpriv->device, interface, &usbInterface);
1001   if (kresult) {
1002     _usbi_log (HANDLE_CTX (dev_handle), LOG_LEVEL_ERROR, "darwin_get_interface: %s", darwin_error_str(kresult));
1003
1004     return darwin_to_libusb (kresult);
1005   }
1006   
1007   driver = IORegistryEntryCreateCFProperty (usbInterface, kIOBundleIdentifierKey, kCFAllocatorDefault, 0);
1008   IOObjectRelease (usbInterface);
1009
1010   if (driver) {
1011     CFRelease (driver);
1012
1013     return 1;
1014   }
1015
1016   /* no driver */
1017   return 0;
1018 }
1019
1020 /* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */
1021 static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
1022   return LIBUSB_ERROR_NOT_SUPPORTED;
1023 }
1024
1025 static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
1026   return LIBUSB_ERROR_NOT_SUPPORTED;
1027 }
1028
1029 static void darwin_destroy_device(struct libusb_device *dev) {
1030 }
1031
1032 static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
1033   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1034   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1035
1036   IOReturn               ret;
1037   uint8_t                is_read; /* 0 = we're reading, 1 = we're writing */
1038   uint8_t                transferType;
1039   /* None of the values below are used in libusb for bulk transfers */
1040   uint8_t                direction, number, interval, pipeRef, iface;
1041   uint16_t               maxPacketSize;
1042
1043   struct __darwin_interface *cInterface;
1044
1045   /* are we reading or writing? */
1046   is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
1047   
1048   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1049     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
1050
1051     return LIBUSB_ERROR_NOT_FOUND;
1052   }
1053
1054   cInterface = &priv->interfaces[iface];
1055
1056   (*(cInterface->interface))->GetPipeProperties (cInterface->interface, pipeRef, &direction, &number,
1057                                                  &transferType, &maxPacketSize, &interval);
1058   
1059   /* submit the request */
1060   /* timeouts are unavailable on interrupt endpoints */
1061   if (transferType == kUSBInterrupt) {
1062     if (is_read)
1063       ret = (*(cInterface->interface))->ReadPipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1064                                                       transfer->length, darwin_async_io_callback, itransfer);
1065     else
1066       ret = (*(cInterface->interface))->WritePipeAsync(cInterface->interface, pipeRef, transfer->buffer,
1067                                                        transfer->length, darwin_async_io_callback, itransfer);
1068   } else {
1069     if (is_read)
1070       ret = (*(cInterface->interface))->ReadPipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1071                                                         transfer->length, transfer->timeout, transfer->timeout,
1072                                                         darwin_async_io_callback, (void *)itransfer);
1073     else
1074       ret = (*(cInterface->interface))->WritePipeAsyncTO(cInterface->interface, pipeRef, transfer->buffer,
1075                                                          transfer->length, transfer->timeout, transfer->timeout,
1076                                                          darwin_async_io_callback, (void *)itransfer);
1077   }
1078
1079   if (ret)
1080     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "bulk transfer failed (dir = %s): %s", is_read ? "In" : "Out",
1081                darwin_error_str(ret));
1082
1083   return darwin_to_libusb (ret);
1084 }
1085
1086 static int submit_iso_transfer(struct usbi_transfer *itransfer) {
1087   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1088   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1089   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1090
1091   IOReturn                kresult;
1092   uint8_t                 is_read; /* 0 = we're writing, 1 = we're reading */
1093   uint8_t                 pipeRef, iface;
1094   UInt64                  frame;
1095   AbsoluteTime            atTime;
1096   int                     i;
1097
1098   struct __darwin_interface *cInterface;
1099
1100   /* are we reading or writing? */
1101   is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
1102   
1103   /* construct an array of IOUSBIsocFrames */
1104   tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
1105   if (!tpriv->isoc_framelist)
1106     return LIBUSB_ERROR_NO_MEM;
1107
1108   /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
1109   for (i = 0 ; i < transfer->num_iso_packets ; i++)
1110     tpriv->isoc_framelist[i].frReqCount = transfer->iso_packet_desc[i].length;
1111
1112   /* determine the interface/endpoint to use */
1113   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1114     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
1115
1116     return LIBUSB_ERROR_NOT_FOUND;
1117   }
1118
1119   cInterface = &priv->interfaces[iface];
1120
1121   /* Last but not least we need the bus frame number */
1122   kresult = (*(cInterface->interface))->GetBusFrameNumber(cInterface->interface, &frame, &atTime);
1123   if (kresult) {
1124     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "failed to get bus frame number: %d", kresult);
1125     free(tpriv->isoc_framelist);
1126     tpriv->isoc_framelist = NULL;
1127
1128     return darwin_to_libusb (kresult);
1129   }
1130
1131   /* schedule for a frame a little in the future */
1132   frame += 2;
1133         
1134   /* submit the request */
1135   if (is_read)
1136     kresult = (*(cInterface->interface))->ReadIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1137                                                              transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1138                                                              itransfer);
1139   else
1140     kresult = (*(cInterface->interface))->WriteIsochPipeAsync(cInterface->interface, pipeRef, transfer->buffer, frame,
1141                                                               transfer->num_iso_packets, tpriv->isoc_framelist, darwin_async_io_callback,
1142                                                               itransfer);
1143
1144   if (kresult != kIOReturnSuccess) {
1145     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "isochronous transfer failed (dir: %s): %s", is_read ? "In" : "Out",
1146                darwin_error_str(kresult));
1147     free (tpriv->isoc_framelist);
1148     tpriv->isoc_framelist = NULL;
1149   }
1150
1151   return darwin_to_libusb (kresult);
1152 }
1153
1154 static int submit_control_transfer(struct usbi_transfer *itransfer) {  
1155   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1156   struct libusb_control_setup *setup = (struct libusb_control_setup *) transfer->buffer;
1157   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
1158   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1159
1160   IOReturn               kresult;
1161
1162   bzero(&tpriv->req, sizeof(tpriv->req));
1163
1164   /* IOUSBDeviceInterface expects the request in cpu endianess */
1165   tpriv->req.bmRequestType     = setup->bmRequestType;
1166   tpriv->req.bRequest          = setup->bRequest;
1167   /* these values should already be in bus order */
1168   tpriv->req.wValue            = setup->wValue;
1169   tpriv->req.wIndex            = setup->wIndex;
1170   tpriv->req.wLength           = setup->wLength;
1171   /* data is stored after the libusb control block */
1172   tpriv->req.pData             = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
1173   tpriv->req.completionTimeout = transfer->timeout;
1174   tpriv->req.noDataTimeout     = transfer->timeout;
1175
1176   /* all transfers in libusb-1.0 are async */
1177   kresult = (*(dpriv->device))->DeviceRequestAsyncTO(dpriv->device, &(tpriv->req), darwin_async_io_callback, itransfer);
1178
1179   if (kresult != kIOReturnSuccess)
1180     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "control request failed: %s", darwin_error_str(kresult));
1181   
1182   return darwin_to_libusb (kresult);
1183 }
1184
1185 static int darwin_submit_transfer(struct usbi_transfer *itransfer) {
1186   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1187
1188   switch (transfer->type) {
1189   case LIBUSB_TRANSFER_TYPE_CONTROL:
1190     return submit_control_transfer(itransfer);
1191   case LIBUSB_TRANSFER_TYPE_BULK:
1192   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1193     return submit_bulk_transfer(itransfer);
1194   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1195     return submit_iso_transfer(itransfer);
1196   default:
1197     _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
1198     return LIBUSB_ERROR_INVALID_PARAM;
1199   }
1200 }
1201
1202 static int cancel_control_transfer(struct usbi_transfer *itransfer) {
1203   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1204   struct darwin_device_priv *dpriv = (struct darwin_device_priv *)transfer->dev_handle->dev->os_priv;
1205   IOReturn kresult;
1206
1207   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "WARNING: aborting all transactions control pipe");
1208
1209   kresult = (*(dpriv->device))->USBDeviceAbortPipeZero (dpriv->device);
1210
1211   return darwin_to_libusb (kresult);
1212 }
1213
1214 static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
1215   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1216   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1217   struct __darwin_interface *cInterface;
1218   uint8_t pipeRef, iface;
1219   IOReturn kresult;
1220
1221   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface) != 0) {
1222     _usbi_log (TRANSFER_CTX (transfer), LOG_LEVEL_ERROR, "endpoint not found on any open interface");
1223
1224     return LIBUSB_ERROR_NOT_FOUND;
1225   }
1226
1227   cInterface = &priv->interfaces[iface];
1228
1229   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "WARNING: aborting all transactions on interface %d pipe %d", iface, pipeRef);
1230
1231   /* abort transactions */
1232   (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
1233   
1234   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "calling clear pipe stall to clear the data toggle bit");
1235
1236   /* clear the data toggle bit */
1237 #if (InterfaceVersion < 190)
1238   kresult = (*(cInterface->interface))->ClearPipeStall(cInterface->interface, pipeRef);
1239 #else
1240   /* newer versions of darwin support clearing additional bits on the device's endpoint */
1241   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
1242 #endif
1243
1244   return darwin_to_libusb (kresult);
1245 }
1246
1247 static int darwin_cancel_transfer(struct usbi_transfer *itransfer) {
1248   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1249
1250   switch (transfer->type) {
1251   case LIBUSB_TRANSFER_TYPE_CONTROL:
1252     return cancel_control_transfer(itransfer);
1253   case LIBUSB_TRANSFER_TYPE_BULK:
1254   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1255   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1256     return darwin_abort_transfers (itransfer);
1257   default:
1258     _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
1259     return LIBUSB_ERROR_INVALID_PARAM;
1260   }
1261 }
1262
1263 static void darwin_clear_transfer_priv (struct usbi_transfer *itransfer) {
1264   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1265   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1266
1267   if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS && tpriv->isoc_framelist) {
1268     free (tpriv->isoc_framelist);
1269     tpriv->isoc_framelist = NULL;
1270   }
1271 }
1272
1273 static void darwin_async_io_callback (void *refcon, IOReturn result, void *arg0) {
1274   struct usbi_transfer *itransfer = (struct usbi_transfer *)refcon;
1275   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1276   struct darwin_device_handle_priv *priv = (struct darwin_device_handle_priv *)transfer->dev_handle->os_priv;
1277   UInt32 message;
1278
1279   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "an async io operation has completed");
1280
1281   /* send a completion message to the device's file descriptor */
1282   message = MESSAGE_ASYNC_IO_COMPLETE;
1283   write (priv->fds[1], &message, sizeof (message));
1284   write (priv->fds[1], &itransfer, sizeof (itransfer));
1285   write (priv->fds[1], &result, sizeof (IOReturn));
1286   write (priv->fds[1], &arg0, sizeof (UInt32));
1287 }
1288
1289 static void darwin_bulk_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
1290   enum libusb_transfer_status status;
1291
1292   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling bulk completion with status %d", result);
1293
1294   switch (result) {
1295   case kIOReturnSuccess:
1296     status = LIBUSB_TRANSFER_COMPLETED;
1297     itransfer->transferred += io_size;
1298     break;
1299   case kIOReturnAborted:
1300     usbi_handle_transfer_cancellation(itransfer);
1301     return;
1302   case kIOUSBPipeStalled:
1303     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "unsupported control request");
1304     status = LIBUSB_TRANSFER_STALL;
1305     
1306     break;
1307   default:
1308     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "control error = %s", darwin_error_str (result));
1309     status = LIBUSB_TRANSFER_ERROR;
1310   }
1311
1312   usbi_handle_transfer_completion(itransfer, status);
1313 }
1314
1315 static void darwin_isoc_callback (struct usbi_transfer *itransfer, kern_return_t result) {
1316   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1317   struct darwin_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer);
1318   int i, status;
1319
1320   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling isoc completion with status %d", result);
1321
1322   if (result == kIOReturnSuccess && tpriv->isoc_framelist) {
1323     /* copy isochronous results back */
1324
1325     for (i = 0; i < transfer->num_iso_packets ; i++) {
1326       struct libusb_iso_packet_descriptor *lib_desc = transfer->iso_packet_desc;
1327       lib_desc->status = darwin_to_libusb (tpriv->isoc_framelist[i].frStatus);
1328       lib_desc->actual_length = tpriv->isoc_framelist[i].frActCount;
1329     }
1330   }
1331
1332   switch (result) {
1333   case kIOReturnSuccess:
1334     status = LIBUSB_TRANSFER_COMPLETED;
1335     break;
1336   case kIOReturnAborted:
1337     usbi_handle_transfer_cancellation(itransfer);
1338     return;
1339   case kIOUSBPipeStalled:
1340     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "unsupported control request");
1341     status = LIBUSB_TRANSFER_STALL;
1342
1343     break;
1344   default:
1345     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "control error = %s", darwin_error_str (result));
1346     status = LIBUSB_TRANSFER_ERROR;
1347   }
1348
1349   usbi_handle_transfer_completion(itransfer, status);
1350 }
1351
1352 static void darwin_control_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
1353   int status;
1354
1355   _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_INFO, "handling control completion with status %d", result);
1356
1357   switch (result) {
1358   case kIOReturnSuccess:
1359     status = LIBUSB_TRANSFER_COMPLETED;
1360     itransfer->transferred += io_size;
1361     break;
1362   case kIOReturnAborted:
1363     usbi_handle_transfer_cancellation(itransfer);
1364     return;
1365   case kIOUSBPipeStalled:
1366     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_WARNING, "unsupported control request");
1367     status = LIBUSB_TRANSFER_STALL;
1368     
1369     break;
1370   default:
1371     _usbi_log (ITRANSFER_CTX (itransfer), LOG_LEVEL_ERROR, "control error = %s", darwin_error_str (result));
1372     status = LIBUSB_TRANSFER_ERROR;
1373   }
1374
1375   usbi_handle_transfer_completion(itransfer, status);
1376 }
1377
1378 static void darwin_handle_callback (struct usbi_transfer *itransfer, kern_return_t result, UInt32 io_size) {
1379   struct libusb_transfer *transfer = __USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1380
1381   switch (transfer->type) {
1382   case LIBUSB_TRANSFER_TYPE_CONTROL:
1383     darwin_control_callback (itransfer, result, io_size);
1384     break;
1385   case LIBUSB_TRANSFER_TYPE_BULK:
1386   case LIBUSB_TRANSFER_TYPE_INTERRUPT:
1387     darwin_bulk_callback (itransfer, result, io_size);
1388     break;
1389   case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
1390     darwin_isoc_callback (itransfer, result);
1391     break;
1392   default:
1393     _usbi_log (TRANSFER_CTX(transfer), LOG_LEVEL_ERROR, "unknown endpoint type %d", transfer->type);
1394   }
1395 }
1396
1397 static int op_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds, int num_ready) {
1398   struct usbi_transfer *itransfer;
1399   UInt32 io_size;
1400   IOReturn kresult;
1401   int i = 0, ret;
1402   UInt32 message;
1403
1404   pthread_mutex_lock(&ctx->open_devs_lock);
1405   for (i = 0; i < nfds && num_ready > 0; i++) {
1406     struct pollfd *pollfd = &fds[i];
1407     struct libusb_device_handle *handle;
1408     struct darwin_device_handle_priv *hpriv = NULL;
1409
1410     _usbi_log (ctx, LOG_LEVEL_INFO, "checking fd %i with revents = %x", fds[i], pollfd->revents);
1411
1412     if (!pollfd->revents)
1413       continue;
1414
1415     num_ready--;
1416     list_for_each_entry(handle, &ctx->open_devs, list) {
1417       hpriv =  (struct darwin_device_handle_priv *)handle->os_priv;
1418       if (hpriv->fds[0] == pollfd->fd)
1419         break;
1420     }
1421
1422     if (!(pollfd->revents & POLLERR)) {
1423       ret = read (hpriv->fds[0], &message, sizeof (message));
1424       if (ret < sizeof (message))
1425         continue;
1426     } else
1427       /* could not poll the device-- response is to delete the device (this seems a little heavy-handed) */
1428       message = MESSAGE_DEVICE_GONE;
1429
1430     switch (message) {
1431     case MESSAGE_DEVICE_GONE:
1432       /* remove the device's async port from the runloop */
1433       if (hpriv->cfSource) {
1434         if (libusb_darwin_acfl)
1435           CFRunLoopRemoveSource (libusb_darwin_acfl, hpriv->cfSource, kCFRunLoopDefaultMode);
1436         CFRelease (hpriv->cfSource);
1437         hpriv->cfSource = NULL;
1438       }
1439
1440       usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fds[0]);
1441       usbi_handle_disconnect(handle);
1442       
1443       /* done with this device */
1444       continue;
1445     case MESSAGE_ASYNC_IO_COMPLETE:
1446       read (hpriv->fds[0], &itransfer, sizeof (itransfer));
1447       read (hpriv->fds[0], &kresult, sizeof (IOReturn));
1448       read (hpriv->fds[0], &io_size, sizeof (UInt32));
1449
1450       darwin_handle_callback (itransfer, kresult, io_size);
1451       break;
1452     default:
1453       _usbi_log (ctx, LOG_LEVEL_ERROR, "unknown message received from device pipe");
1454     }
1455   }
1456
1457   pthread_mutex_unlock(&ctx->open_devs_lock);
1458
1459   return 0;
1460 }
1461
1462 static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
1463   mach_timespec_t sys_time;
1464   clock_serv_t clock_ref;
1465
1466   switch (clk_id) {
1467   case USBI_CLOCK_REALTIME:
1468     /* CLOCK_REALTIME represents time since the epoch */
1469     host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &clock_ref);
1470     break;
1471   case USBI_CLOCK_MONOTONIC:
1472     /* use system boot time as reference for the monotonic clock */
1473     host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock_ref);
1474     break;
1475   default:
1476     return LIBUSB_ERROR_INVALID_PARAM;
1477   }
1478
1479   clock_get_time (clock_ref, &sys_time);
1480
1481   tp->tv_sec  = sys_time.tv_sec;
1482   tp->tv_nsec = sys_time.tv_nsec;
1483
1484   return 0;
1485 }
1486
1487 const struct usbi_os_backend darwin_backend = {
1488         .name = "Darwin",
1489         .init = darwin_init,
1490         .exit = darwin_exit,
1491         .get_device_list = darwin_get_device_list,
1492         .get_device_descriptor = darwin_get_device_descriptor,
1493         .get_active_config_descriptor = darwin_get_active_config_descriptor,
1494         .get_config_descriptor = darwin_get_config_descriptor,
1495
1496         .open = darwin_open,
1497         .close = darwin_close,
1498         .get_configuration = darwin_get_configuration,
1499         .set_configuration = darwin_set_configuration,
1500         .claim_interface = darwin_claim_interface,
1501         .release_interface = darwin_release_interface,
1502
1503         .set_interface_altsetting = darwin_set_interface_altsetting,
1504         .clear_halt = darwin_clear_halt,
1505         .reset_device = darwin_reset_device,
1506
1507         .kernel_driver_active = darwin_kernel_driver_active,
1508         .detach_kernel_driver = darwin_detach_kernel_driver,
1509         .attach_kernel_driver = darwin_attach_kernel_driver,
1510
1511         .destroy_device = darwin_destroy_device,
1512
1513         .submit_transfer = darwin_submit_transfer,
1514         .cancel_transfer = darwin_cancel_transfer,
1515         .clear_transfer_priv = darwin_clear_transfer_priv,
1516
1517         .handle_events = op_handle_events,
1518
1519         .clock_gettime = darwin_clock_gettime,
1520
1521         .device_priv_size = sizeof(struct darwin_device_priv),
1522         .device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
1523         .transfer_priv_size = sizeof(struct darwin_transfer_priv),
1524         .add_iso_packet_size = 0,
1525 };
1526