1/*
2 * Darwin/MacOS X Support
3 *
4 * (c) 2002-2007 Nathan Hjelm <hjelmn@users.sourceforge.net>
5 *
6 * (07/25/2007):
7 *   - Added a fix to ignore buggy (virtual?) hubs.
8 * (06/26/2006):
9 *   - Bulk functions no longer use async transfer functions.
10 * (04/17/2005):
11 *   - Lots of minor fixes.
12 *   - Endpoint table now made by claim_interface to fix a bug.
13 *   - Merged Read/Write to make modifications easier.
14 * (03/25/2005):
15 *   - Fixed a bug when using asynchronous callbacks within a multi-threaded application.
16 * (03/14/2005):
17 *   - Added an endpoint table to speed up bulk transfers.
18 * 0.1.11 (02/22/2005):
19 *   - Updated error checking in read/write routines to check completion codes.
20 *   - Updated set_configuration so that the open interface is reclaimed before completion.
21 *   - Fixed several typos.
22 * 0.1.8 (01/12/2004):
23 *   - Fixed several memory leaks.
24 *   - Readded 10.0 support
25 *   - Added support for USB fuctions defined in 10.3 and above
26 * (01/02/2003):
27 *   - Applied a patch by Philip Edelbrock <phil@edgedesign.us> that fixes a bug in usb_control_msg.
28 * (12/16/2003):
29 *   - Even better error printing.
30 *   - Devices that cannot be opened can have their interfaces opened.
31 * 0.1.6 (05/12/2002):
32 *   - Fixed problem where libusb holds resources after program completion.
33 *   - Mouse should no longer freeze up now.
34 * 0.1.2 (02/13/2002):
35 *   - Bulk functions should work properly now.
36 * 0.1.1 (02/11/2002):
37 *   - Fixed major bug (device and interface need to be released after use)
38 * 0.1.0 (01/06/2002):
39 *   - Tested driver with gphoto (works great as long as Image Capture isn't running)
40 * 0.1d  (01/04/2002):
41 *   - Implimented clear_halt and resetep
42 *   - Uploaded to CVS.
43 * 0.1b  (01/04/2002):
44 *   - Added usb_debug line to bulk read and write function.
45 * 0.1a  (01/03/2002):
46 *   - Driver mostly completed using the macosx driver I wrote for my rioutil software.
47 *
48 * Derived from Linux version by Richard Tobin.
49 * Also partly derived from BSD version.
50 *
51 * This library is covered by the LGPL, read LICENSE for details.
52 */
53
54#ifdef HAVE_CONFIG_H
55#include "config.h"
56#endif
57
58#include <stdlib.h>
59#include <stdio.h>
60#include <unistd.h>
61
62/* standard includes for darwin/os10 (IOKit) */
63#include <mach/mach_port.h>
64#include <IOKit/IOCFBundle.h>
65#include <IOKit/usb/IOUSBLib.h>
66#include <IOKit/IOCFPlugIn.h>
67
68#include "usbi.h"
69
70/* some defines */
71/* IOUSBInterfaceInferface */
72#if defined (kIOUSBInterfaceInterfaceID220)
73
74// #warning "libusb being compiled for 10.4 or later"
75#define usb_interface_t IOUSBInterfaceInterface220
76#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
77#define InterfaceVersion 220
78
79#elif defined (kIOUSBInterfaceInterfaceID197)
80
81// #warning "libusb being compiled for 10.3 or later"
82#define usb_interface_t IOUSBInterfaceInterface197
83#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197
84#define InterfaceVersion 197
85
86#elif defined (kIOUSBInterfaceInterfaceID190)
87
88// #warning "libusb being compiled for 10.2 or later"
89#define usb_interface_t IOUSBInterfaceInterface190
90#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190
91#define InterfaceVersion 190
92
93#elif defined (kIOUSBInterfaceInterfaceID182)
94
95// #warning "libusb being compiled for 10.1 or later"
96#define usb_interface_t IOUSBInterfaceInterface182
97#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID182
98#define InterfaceVersion 182
99
100#else
101
102/* No timeout functions available! Time to upgrade your os. */
103#warning "libusb being compiled without support for timeout bulk functions! 10.0 and up"
104#define usb_interface_t IOUSBInterfaceInterface
105#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID
106#define LIBUSB_NO_TIMEOUT_INTERFACE
107#define InterfaceVersion 180
108
109#endif
110
111/* IOUSBDeviceInterface */
112#if defined (kIOUSBDeviceInterfaceID197)
113
114#define usb_device_t    IOUSBDeviceInterface197
115#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
116#define DeviceVersion 197
117
118#elif defined (kIOUSBDeviceInterfaceID187)
119
120#define usb_device_t    IOUSBDeviceInterface187
121#define DeviceInterfaceID kIOUSBDeviceInterfaceID187
122#define DeviceVersion 187
123
124#elif defined (kIOUSBDeviceInterfaceID182)
125
126#define usb_device_t    IOUSBDeviceInterface182
127#define DeviceInterfaceID kIOUSBDeviceInterfaceID182
128#define DeviceVersion 182
129
130#else
131
132#define usb_device_t    IOUSBDeviceInterface
133#define DeviceInterfaceID kIOUSBDeviceInterfaceID
134#define LIBUSB_NO_TIMEOUT_DEVICE
135#define LIBUSB_NO_SEIZE_DEVICE
136#define DeviceVersion 180
137
138#endif
139
140#if !defined (LIBUSB_NO_SEIZE_DEVICE)
141
142#define LIBUSB_NO_SEIZE_DEVICE
143
144#endif
145
146typedef IOReturn io_return_t;
147typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
148typedef SInt32 s_int32_t;
149typedef IOReturn (*rw_async_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,
150				    IOAsyncCallback1 callback, void *refcon);
151typedef IOReturn (*rw_async_to_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,
152				       UInt32 noDataTimeout, UInt32 completionTimeout,
153				       IOAsyncCallback1 callback, void *refcon);
154
155#if !defined(IO_OBJECT_NULL)
156#define IO_OBJECT_NULL ((io_object_t)0)
157#endif
158
159struct darwin_dev_handle {
160  usb_device_t **device;
161  usb_interface_t **interface;
162  int open;
163
164  /* stored translation table for pipes to endpoints */
165  int num_endpoints;
166  unsigned char *endpoint_addrs;
167};
168
169static IONotificationPortRef gNotifyPort;
170static mach_port_t masterPort = MACH_PORT_NULL;
171
172static void darwin_cleanup (void)
173{
174  IONotificationPortDestroy(gNotifyPort);
175  mach_port_deallocate(mach_task_self(), masterPort);
176}
177
178static char *darwin_error_str (int result) {
179  switch (result) {
180  case kIOReturnSuccess:
181    return "no error";
182  case kIOReturnNotOpen:
183    return "device not opened for exclusive access";
184  case kIOReturnNoDevice:
185    return "no connection to an IOService";
186  case kIOUSBNoAsyncPortErr:
187    return "no async port has been opened for interface";
188  case kIOReturnExclusiveAccess:
189    return "another process has device opened for exclusive access";
190  case kIOUSBPipeStalled:
191    return "pipe is stalled";
192  case kIOReturnError:
193    return "could not establish a connection to the Darwin kernel";
194  case kIOUSBTransactionTimeout:
195    return "transaction timed out";
196  case kIOReturnBadArgument:
197    return "invalid argument";
198  case kIOReturnAborted:
199    return "transaction aborted";
200  case kIOReturnNotResponding:
201    return "device not responding";
202  default:
203    return "unknown error";
204  }
205}
206
207/* not a valid errorno outside darwin.c */
208#define LUSBDARWINSTALL (ELAST+1)
209
210static int darwin_to_errno (int result) {
211  switch (result) {
212  case kIOReturnSuccess:
213    return 0;
214  case kIOReturnNotOpen:
215    return EBADF;
216  case kIOReturnNoDevice:
217  case kIOUSBNoAsyncPortErr:
218    return ENXIO;
219  case kIOReturnExclusiveAccess:
220    return EBUSY;
221  case kIOUSBPipeStalled:
222    return LUSBDARWINSTALL;
223  case kIOReturnBadArgument:
224    return EINVAL;
225  case kIOUSBTransactionTimeout:
226    return ETIMEDOUT;
227  case kIOReturnNotResponding:
228    return EIO;
229  case kIOReturnError:
230  default:
231    return 1;
232  }
233}
234
235static int usb_setup_iterator (io_iterator_t *deviceIterator)
236{
237  int result;
238  CFMutableDictionaryRef matchingDict;
239
240  /* set up the matching dictionary for class IOUSBDevice and its subclasses.
241     It will be consumed by the IOServiceGetMatchingServices call */
242  if ((matchingDict = IOServiceMatching(kIOUSBDeviceClassName)) == NULL) {
243    darwin_cleanup ();
244
245    USB_ERROR_STR(-1, "libusb/darwin.c usb_setup_iterator: Could not create a matching dictionary.\n");
246  }
247
248  result = IOServiceGetMatchingServices(masterPort, matchingDict, deviceIterator);
249  matchingDict = NULL;
250
251  if (result != kIOReturnSuccess)
252    USB_ERROR_STR (-darwin_to_errno (result), "libusb/darwin.c usb_setup_iterator: IOServiceGetMatchingServices: %s\n",
253		   darwin_error_str(result));
254
255  return 0;
256}
257
258static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp)
259{
260  io_cf_plugin_ref_t *plugInInterface = NULL;
261  usb_device_t **device;
262  io_service_t usbDevice;
263  long result; int32_t score;
264
265  if (!IOIteratorIsValid (deviceIterator) || !(usbDevice = IOIteratorNext(deviceIterator)))
266    return NULL;
267
268  result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
269					     kIOCFPlugInInterfaceID, &plugInInterface,
270					     &score);
271
272  result = IOObjectRelease(usbDevice);
273  if (result || !plugInInterface)
274    return NULL;
275
276  (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
277				     (LPVOID)&device);
278
279  (*plugInInterface)->Stop(plugInInterface);
280  IODestroyPlugInInterface (plugInInterface);
281  plugInInterface = NULL;
282
283  (*(device))->GetLocationID(device, locationp);
284
285  return device;
286}
287
288int usb_os_open(usb_dev_handle *dev)
289{
290  struct darwin_dev_handle *device;
291
292  io_return_t result;
293  io_iterator_t deviceIterator;
294
295  usb_device_t **darwin_device;
296
297  UInt32 location = *((UInt32 *)dev->device->dev);
298  UInt32 dlocation;
299
300  if (!dev)
301    USB_ERROR(-ENXIO);
302
303  if (masterPort == MACH_PORT_NULL)
304    USB_ERROR(-EINVAL);
305
306  device = calloc(1, sizeof(struct darwin_dev_handle));
307  if (!device)
308    USB_ERROR(-ENOMEM);
309
310  if (usb_debug > 3)
311    fprintf(stderr, "usb_os_open: %04x:%04x\n",
312	    dev->device->descriptor.idVendor,
313	    dev->device->descriptor.idProduct);
314
315  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
316    return result;
317
318  /* This port of libusb uses locations to keep track of devices. */
319  while ((darwin_device = usb_get_next_device (deviceIterator, &dlocation)) != NULL) {
320    if (dlocation == location)
321      break;
322
323    (*darwin_device)->Release(darwin_device);
324  }
325
326  IOObjectRelease(deviceIterator);
327  device->device = darwin_device;
328
329  if (device->device == NULL)
330    USB_ERROR_STR (-ENOENT, "usb_os_open: %s\n", "Device not found!");
331
332#if !defined (LIBUSB_NO_SEIZE_DEVICE)
333  result = (*(device->device))->USBDeviceOpenSeize (device->device);
334#else
335  /* No Seize in OS X 10.0 (Darwin 1.4) */
336  result = (*(device->device))->USBDeviceOpen (device->device);
337#endif
338
339  if (result != kIOReturnSuccess) {
340    switch (result) {
341    case kIOReturnExclusiveAccess:
342      if (usb_debug > 0)
343	fprintf (stderr, "usb_os_open(USBDeviceOpenSeize): %s\n", darwin_error_str(result));
344      break;
345    default:
346      (*(device->device))->Release (device->device);
347      USB_ERROR_STR(-darwin_to_errno (result), "usb_os_open(USBDeviceOpenSeize): %s",
348		    darwin_error_str(result));
349    }
350
351    device->open = 0;
352  } else
353    device->open = 1;
354
355  dev->impl_info = device;
356  dev->interface = -1;
357  dev->altsetting = -1;
358
359  device->num_endpoints  = 0;
360  device->endpoint_addrs = NULL;
361
362  return 0;
363}
364
365int usb_os_close(usb_dev_handle *dev)
366{
367  struct darwin_dev_handle *device;
368  io_return_t result;
369
370  if (!dev)
371    USB_ERROR(-ENXIO);
372
373  if ((device = dev->impl_info) == NULL)
374    USB_ERROR(-ENOENT);
375
376  usb_release_interface(dev, dev->interface);
377
378  if (usb_debug > 3)
379    fprintf(stderr, "usb_os_close: %04x:%04x\n",
380	    dev->device->descriptor.idVendor,
381	    dev->device->descriptor.idProduct);
382
383  if (device->open == 1)
384    result = (*(device->device))->USBDeviceClose(device->device);
385  else
386    result = kIOReturnSuccess;
387
388  /* device may not need to be released, but if it has to... */
389  (*(device->device))->Release(device->device);
390
391  if (result != kIOReturnSuccess)
392    USB_ERROR_STR(-darwin_to_errno(result), "usb_os_close(USBDeviceClose): %s", darwin_error_str(result));
393
394  free (device);
395
396  return 0;
397}
398
399static int get_endpoints (struct darwin_dev_handle *device)
400{
401  io_return_t ret;
402
403  u_int8_t numep, direction, number;
404  u_int8_t dont_care1, dont_care3;
405  u_int16_t dont_care2;
406
407  int i;
408
409  if (device == NULL || device->interface == NULL)
410    return -EINVAL;
411
412  if (usb_debug > 1)
413    fprintf(stderr, "libusb/darwin.c get_endpoints: building table of endpoints.\n");
414
415  /* retrieve the total number of endpoints on this interface */
416  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
417  if ( ret ) {
418    if ( usb_debug > 1 )
419      fprintf ( stderr, "get_endpoints: interface is %p\n", device->interface );
420
421    USB_ERROR_STR ( -ret, "get_endpoints: can't get number of endpoints for interface" );
422  }
423
424  free (device->endpoint_addrs);
425  device->endpoint_addrs = calloc (sizeof (unsigned char), numep);
426
427  /* iterate through pipe references */
428  for (i = 1 ; i <= numep ; i++) {
429    ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
430						    &dont_care1, &dont_care2, &dont_care3);
431
432    if (ret != kIOReturnSuccess) {
433      fprintf (stderr, "get_endpoints: an error occurred getting pipe information on pipe %d\n",
434	       i );
435      USB_ERROR_STR(-darwin_to_errno(ret), "get_endpoints(GetPipeProperties): %s", darwin_error_str(ret));
436    }
437
438    if (usb_debug > 1)
439      fprintf (stderr, "get_endpoints: Pipe %i: DIR: %i number: %i\n", i, direction, number);
440
441    device->endpoint_addrs[i - 1] = ((direction << 7 & USB_ENDPOINT_DIR_MASK) |
442				     (number & USB_ENDPOINT_ADDRESS_MASK));
443  }
444
445  device->num_endpoints = numep;
446
447  if (usb_debug > 1)
448    fprintf(stderr, "libusb/darwin.c get_endpoints: complete.\n");
449
450  return 0;
451}
452
453static int claim_interface (usb_dev_handle *dev, int interface)
454{
455  io_iterator_t interface_iterator;
456  io_service_t  usbInterface = IO_OBJECT_NULL;
457  io_return_t result;
458  io_cf_plugin_ref_t *plugInInterface = NULL;
459
460  IOUSBFindInterfaceRequest request;
461
462  struct darwin_dev_handle *device;
463  SInt32 score;
464  int current_interface;
465
466  device = dev->impl_info;
467
468  request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
469  request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
470  request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
471  request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
472
473  result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator);
474  if (result != kIOReturnSuccess)
475    USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s",
476		   darwin_error_str(result));
477
478  for ( current_interface=0 ; current_interface <= interface ; current_interface++ ) {
479    usbInterface = IOIteratorNext(interface_iterator);
480    if ( usb_debug > 3 )
481      fprintf ( stderr, "Interface %d of device is 0x%08x\n",
482		current_interface, usbInterface );
483  }
484
485  current_interface--;
486
487  /* the interface iterator is no longer needed, release it */
488  IOObjectRelease(interface_iterator);
489
490  if (!usbInterface) {
491    u_int8_t nConfig;			     /* Index of configuration to use */
492    IOUSBConfigurationDescriptorPtr configDesc; /* to describe which configuration to select */
493    /* Only a composite class device with no vendor-specific driver will
494       be configured. Otherwise, we need to do it ourselves, or there
495       will be no interfaces for the device. */
496
497    if ( usb_debug > 3 )
498      fprintf ( stderr,"claim_interface: No interface found; selecting configuration\n" );
499
500    result = (*(device->device))->GetNumberOfConfigurations ( device->device, &nConfig );
501    if (result != kIOReturnSuccess)
502      USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetNumberOfConfigurations): %s",
503		    darwin_error_str(result));
504
505    if (nConfig < 1)
506      USB_ERROR_STR(-ENXIO ,"claim_interface(GetNumberOfConfigurations): no configurations");
507    else if ( nConfig > 1 && usb_debug > 0 )
508      fprintf ( stderr, "claim_interface: device has more than one"
509		" configuration, using the first (warning)\n" );
510
511    if ( usb_debug > 3 )
512      fprintf ( stderr, "claim_interface: device has %d configuration%s\n",
513		(int)nConfig, (nConfig>1?"s":"") );
514
515    /* Always use the first configuration */
516    result = (*(device->device))->GetConfigurationDescriptorPtr ( (device->device), 0, &configDesc );
517    if (result != kIOReturnSuccess) {
518      if (device->open == 1) {
519        (*(device->device))->USBDeviceClose ( (device->device) );
520        (*(device->device))->Release ( (device->device) );
521      }
522
523      USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetConfigurationDescriptorPtr): %s",
524		    darwin_error_str(result));
525    } else if ( usb_debug > 3 )
526      fprintf ( stderr, "claim_interface: configuration value is %d\n",
527		configDesc->bConfigurationValue );
528
529    if (device->open == 1) {
530      result = (*(device->device))->SetConfiguration ( (device->device), configDesc->bConfigurationValue );
531
532      if (result != kIOReturnSuccess) {
533	(*(device->device))->USBDeviceClose ( (device->device) );
534	(*(device->device))->Release ( (device->device) );
535
536	USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(SetConfiguration): %s",
537		      darwin_error_str(result));
538      }
539
540      dev->config = configDesc->bConfigurationValue;
541    }
542
543    request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
544    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
545    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
546    request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
547
548    /* Now go back and get the chosen interface */
549    result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator);
550    if (result != kIOReturnSuccess)
551      USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s",
552		     darwin_error_str(result));
553
554    for (current_interface = 0 ; current_interface <= interface ; current_interface++) {
555      usbInterface = IOIteratorNext(interface_iterator);
556
557      if ( usb_debug > 3 )
558	fprintf ( stderr, "claim_interface: Interface %d of device is 0x%08x\n",
559		  current_interface, usbInterface );
560    }
561    current_interface--;
562
563    /* the interface iterator is no longer needed, release it */
564    IOObjectRelease(interface_iterator);
565
566    if (!usbInterface)
567      USB_ERROR_STR (-ENOENT, "claim_interface: interface iterator returned NULL");
568  }
569
570  result = IOCreatePlugInInterfaceForService(usbInterface,
571					     kIOUSBInterfaceUserClientTypeID,
572					     kIOCFPlugInInterfaceID,
573					     &plugInInterface, &score);
574  /* No longer need the usbInterface object after getting the plug-in */
575  result = IOObjectRelease(usbInterface);
576  if (result || !plugInInterface)
577    USB_ERROR(-ENOENT);
578
579  /* Now create the device interface for the interface */
580  result = (*plugInInterface)->QueryInterface(plugInInterface,
581					      CFUUIDGetUUIDBytes(InterfaceInterfaceID),
582					      (LPVOID) &device->interface);
583
584  /* No longer need the intermediate plug-in */
585  (*plugInInterface)->Stop(plugInInterface);
586  IODestroyPlugInInterface (plugInInterface);
587
588  if (result != kIOReturnSuccess)
589    USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(QueryInterface): %s",
590		  darwin_error_str(result));
591
592  if (!device->interface)
593    USB_ERROR(-EACCES);
594
595  if ( usb_debug > 3 )
596    fprintf ( stderr, "claim_interface: Interface %d of device from QueryInterface is %p\n",
597	      current_interface, device->interface);
598
599  /* claim the interface */
600  result = (*(device->interface))->USBInterfaceOpen(device->interface);
601  if (result)
602    USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(USBInterfaceOpen): %s",
603		  darwin_error_str(result));
604
605  result = get_endpoints (device);
606
607  if (result) {
608    /* this should not happen */
609    usb_release_interface (dev, interface);
610    USB_ERROR_STR ( result, "claim_interface: could not build endpoint table");
611  }
612
613  return 0;
614}
615
616int usb_set_configuration (usb_dev_handle *dev, int configuration)
617{
618  struct darwin_dev_handle *device;
619  io_return_t result;
620  int interface;
621
622  if ( usb_debug > 3 )
623    fprintf ( stderr, "usb_set_configuration: called for config %x\n", configuration );
624
625  if (!dev)
626    USB_ERROR_STR ( -ENXIO, "usb_set_configuration: called with null device\n" );
627
628  if ((device = dev->impl_info) == NULL)
629    USB_ERROR_STR ( -ENOENT, "usb_set_configuration: device not properly initialized" );
630
631  /* Setting configuration will invalidate the interface, so we need
632     to reclaim it. First, dispose of existing interface, if any. */
633  interface = dev->interface;
634
635  if ( device->interface )
636    usb_release_interface(dev, dev->interface);
637
638  result = (*(device->device))->SetConfiguration(device->device, configuration);
639
640  if (result)
641    USB_ERROR_STR(-darwin_to_errno(result), "usb_set_configuration(SetConfiguration): %s",
642		  darwin_error_str(result));
643
644  /* Reclaim interface */
645  if (interface != -1)
646    result = usb_claim_interface (dev, interface);
647
648  dev->config = configuration;
649
650  return result;
651}
652
653int usb_claim_interface(usb_dev_handle *dev, int interface)
654{
655  struct darwin_dev_handle *device = dev->impl_info;
656
657  io_return_t result;
658
659  if ( usb_debug > 3 )
660    fprintf ( stderr, "usb_claim_interface: called for interface %d\n", interface );
661
662  if (!device)
663    USB_ERROR_STR ( -ENOENT, "usb_claim_interface: device is NULL" );
664
665  if (!(device->device))
666    USB_ERROR_STR ( -EINVAL, "usb_claim_interface: device->device is NULL" );
667
668  /* If we have already claimed an interface, release it */
669  if ( device->interface )
670    usb_release_interface(dev, dev->interface);
671
672  result = claim_interface ( dev, interface );
673  if ( result )
674    USB_ERROR_STR ( result, "usb_claim_interface: couldn't claim interface" );
675
676  dev->interface = interface;
677
678  /* interface is claimed and async IO is set up: return 0 */
679  return 0;
680}
681
682int usb_release_interface(usb_dev_handle *dev, int interface)
683{
684  struct darwin_dev_handle *device;
685  io_return_t result;
686
687  if (!dev)
688    USB_ERROR(-ENXIO);
689
690  if ((device = dev->impl_info) == NULL)
691    USB_ERROR(-ENOENT);
692
693  /* interface is not open */
694  if (!device->interface)
695    return 0;
696
697  result = (*(device->interface))->USBInterfaceClose(device->interface);
698
699  if (result != kIOReturnSuccess)
700    USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(USBInterfaceClose): %s",
701		  darwin_error_str(result));
702
703  result = (*(device->interface))->Release(device->interface);
704
705  if (result != kIOReturnSuccess)
706    USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(Release): %s",
707		  darwin_error_str(result));
708
709  device->interface = NULL;
710
711  free (device->endpoint_addrs);
712
713  device->num_endpoints  = 0;
714  device->endpoint_addrs = NULL;
715
716  dev->interface = -1;
717  dev->altsetting = -1;
718
719  return 0;
720}
721
722int usb_set_altinterface(usb_dev_handle *dev, int alternate)
723{
724  struct darwin_dev_handle *device;
725  io_return_t result;
726
727  if (!dev)
728    USB_ERROR(-ENXIO);
729
730  if ((device = dev->impl_info) == NULL)
731    USB_ERROR(-ENOENT);
732
733  /* interface is not open */
734  if (!device->interface)
735    USB_ERROR_STR(-EACCES, "usb_set_altinterface: interface used without being claimed");
736
737  result = (*(device->interface))->SetAlternateInterface(device->interface, alternate);
738
739  if (result)
740    USB_ERROR_STR(result, "usb_set_altinterface: could not set alternate interface");
741
742  dev->altsetting = alternate;
743
744  result = get_endpoints (device);
745  if (result) {
746    /* this should not happen */
747    USB_ERROR_STR ( result, "usb_set_altinterface: could not build endpoint table");
748  }
749
750  return 0;
751}
752
753/* simple function that figures out what pipeRef is associated with an endpoint */
754static int ep_to_pipeRef (struct darwin_dev_handle *device, int ep)
755{
756  int i;
757
758  if (usb_debug > 1)
759    fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: Converting ep address to pipeRef.\n");
760
761  for (i = 0 ; i < device->num_endpoints ; i++)
762    if (device->endpoint_addrs[i] == ep)
763      return i + 1;
764
765  /* No pipe found with the correct endpoint address */
766  if (usb_debug > 1)
767    fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
768
769  return -1;
770}
771
772static int usb_bulk_transfer (usb_dev_handle *dev, int ep, char *bytes, u_int32_t size, int timeout, int usb_bt_read)
773{
774  struct darwin_dev_handle *device;
775
776  io_return_t result = -1;
777
778  int pipeRef;
779
780  u_int8_t  transferType, direction, number, interval;
781  u_int16_t maxPacketSize;
782
783  if (!dev)
784    USB_ERROR_STR ( -ENXIO, "libusb/darwin.c usb_bulk_transfer: Called with NULL device" );
785
786  if ((device = dev->impl_info) == NULL)
787    USB_ERROR_STR ( -ENOENT, "libusb/darwin.c usb_bulk_transfer: Device not open" );
788
789  /* interface is not open */
790  if (!device->interface)
791    USB_ERROR_STR(-EACCES, "libusb/darwin.c usb_bulk_transfer: Interface used before it was opened");
792
793
794  /* Set up transfer */
795  if ((pipeRef = ep_to_pipeRef(device, ep)) < 0)
796    USB_ERROR_STR ( -EINVAL, "libusb/darwin.c usb_bulk_transfer: Invalid pipe reference" );
797
798  (*(device->interface))->GetPipeProperties (device->interface, pipeRef, &direction, &number,
799					     &transferType, &maxPacketSize, &interval);
800  /* Transfer set up complete */
801
802  if (usb_debug > 0)
803    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: Transfering %i bytes of data on endpoint 0x%02x\n", size, ep);
804
805  /* Do bulk transfer */
806  if (transferType == kUSBInterrupt && usb_debug > 3)
807    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: USB pipe is an interrupt pipe. Timeouts will not be used.\n");
808
809#if !defined(LIBUSB_NO_TIMEOUT_INTERFACE)
810  if ( transferType != kUSBInterrupt) {
811    if (usb_bt_read != 0)
812      result = (*(device->interface))->ReadPipeTO (device->interface, pipeRef, bytes, (UInt32 *)&size, timeout, timeout);
813    else
814      result = (*(device->interface))->WritePipeTO (device->interface, pipeRef, bytes, size, timeout, timeout);
815
816    /* pipe bits may need to be cleared after a timeout. should this be done here or in user code? */
817    if (result == kIOUSBTransactionTimeout && (*(device->interface))->GetPipeStatus (device->interface, pipeRef) == kIOUSBPipeStalled)
818      usb_clear_halt (dev, ep);
819  } else
820#endif
821  {
822    if (usb_bt_read != 0)
823      result = (*(device->interface))->ReadPipe (device->interface, pipeRef, bytes, (UInt32 *)&size);
824    else
825      result = (*(device->interface))->WritePipe (device->interface, pipeRef, bytes, size);
826  }
827
828  if (result != kIOReturnSuccess)
829    USB_ERROR_STR (-darwin_to_errno (result), "libusb/darwin.c usb_bulk_transfer: %s", darwin_error_str (result));
830
831  return size;
832}
833
834#if 0
835/* NOT USED */
836/* argument to handle multiple parameters to rw_completed */
837struct rw_complete_arg {
838  UInt32        io_size;
839  IOReturn      result;
840  CFRunLoopRef  cf_loop;
841};
842
843static void rw_completed(void *refcon, io_return_t result, void *io_size)
844{
845  struct rw_complete_arg *rw_arg = (struct rw_complete_arg *)refcon;
846
847  if (usb_debug > 2)
848    fprintf(stderr, "io async operation completed: %s, size=%lu, result=0x%08x\n", darwin_error_str(result),
849	    (UInt32)io_size, result);
850
851  rw_arg->io_size = (UInt32)io_size;
852  rw_arg->result  = result;
853
854  CFRunLoopStop(rw_arg->cf_loop);
855}
856
857static int usb_bulk_transfer_async (usb_dev_handle *dev, int ep, char *bytes, int size, int timeout,
858			      rw_async_func_t rw_async, rw_async_to_func_t rw_async_to)
859{
860  struct darwin_dev_handle *device;
861
862  io_return_t result = -1;
863
864  CFRunLoopSourceRef cfSource;
865  int pipeRef;
866
867  struct rw_complete_arg rw_arg;
868
869  u_int8_t  transferType;
870
871  /* None of the values below are used in libusb for bulk transfers */
872  u_int8_t  direction, number, interval;
873  u_int16_t maxPacketSize;
874
875  if (!dev)
876    USB_ERROR_STR ( -ENXIO, "usb_bulk_transfer: Called with NULL device" );
877
878  if ((device = dev->impl_info) == NULL)
879    USB_ERROR_STR ( -ENOENT, "usb_bulk_transfer: Device not open" );
880
881  /* interface is not open */
882  if (!device->interface)
883    USB_ERROR_STR(-EACCES, "usb_bulk_transfer: Interface used before it was opened");
884
885
886  /* Set up transfer */
887  if ((pipeRef = ep_to_pipeRef(device, ep)) < 0)
888    USB_ERROR_STR ( -EINVAL, "usb_bulk_transfer: Invalid pipe reference" );
889
890  (*(device->interface))->GetPipeProperties (device->interface, pipeRef, &direction, &number,
891					     &transferType, &maxPacketSize, &interval);
892
893  bzero((void *)&rw_arg, sizeof(struct rw_complete_arg));
894  rw_arg.cf_loop = CFRunLoopGetCurrent();
895  CFRetain (rw_arg.cf_loop);
896
897  (*(device->interface))->CreateInterfaceAsyncEventSource(device->interface, &cfSource);
898  CFRunLoopAddSource(rw_arg.cf_loop, cfSource, kCFRunLoopDefaultMode);
899  /* Transfer set up complete */
900
901  if (usb_debug > 0)
902    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: Transfering %i bytes of data on endpoint 0x%02x\n",
903	     size, ep);
904
905  /* Bulk transfer */
906  if (transferType == kUSBInterrupt && usb_debug > 3)
907    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: USB pipe is an interrupt pipe. Timeouts will not be used.\n");
908
909  if ( transferType != kUSBInterrupt && rw_async_to != NULL)
910
911    result = rw_async_to (device->interface, pipeRef, bytes, size, timeout, timeout,
912			  (IOAsyncCallback1)rw_completed, (void *)&rw_arg);
913  else
914    result = rw_async (device->interface, pipeRef, bytes, size, (IOAsyncCallback1)rw_completed,
915		       (void *)&rw_arg);
916
917  if (result == kIOReturnSuccess) {
918    /* wait for write to complete */
919    if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, (timeout+999)/1000, true) == kCFRunLoopRunTimedOut) {
920      (*(device->interface))->AbortPipe(device->interface, pipeRef);
921      CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true); /* Pick up aborted callback */
922      if (usb_debug)
923	fprintf(stderr, "usb_bulk_transfer: timed out\n");
924    }
925  }
926
927  CFRunLoopRemoveSource(rw_arg.cf_loop, cfSource, kCFRunLoopDefaultMode);
928  CFRelease (rw_arg.cf_loop);
929
930  /* Check the return code of both the write and completion functions. */
931  if (result != kIOReturnSuccess || (rw_arg.result != kIOReturnSuccess &&
932      rw_arg.result != kIOReturnAborted) ) {
933    int error_code;
934    char *error_str;
935
936    if (result == kIOReturnSuccess) {
937      error_code = darwin_to_errno (rw_arg.result);
938      error_str  = darwin_error_str (rw_arg.result);
939    } else {
940      error_code = darwin_to_errno(result);
941      error_str  = darwin_error_str (result);
942    }
943
944    if (transferType != kUSBInterrupt && rw_async_to != NULL)
945      USB_ERROR_STR(-error_code, "usb_bulk_transfer (w/ Timeout): %s", error_str);
946    else
947      USB_ERROR_STR(-error_code, "usb_bulk_transfer (No Timeout): %s", error_str);
948  }
949
950  return rw_arg.io_size;
951}
952#endif
953
954int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
955{
956  int result;
957
958  if (dev == NULL || dev->impl_info == NULL)
959    return -EINVAL;
960
961  if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout, 0)) < 0)
962    USB_ERROR_STR (result, "usb_bulk_write: An error occured during write (see messages above)");
963
964  return result;
965}
966
967int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
968{
969  int result;
970
971  if (dev == NULL || dev->impl_info == NULL)
972    return -EINVAL;
973
974  ep |= 0x80;
975
976  if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout, 1)) < 0)
977    USB_ERROR_STR (result, "usb_bulk_read: An error occured during read (see messages above)");
978
979  return result;
980}
981
982/* interrupt endpoints appear to be treated the same as non-interrupt endpoints under OSX/Darwin */
983int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
984	int timeout)
985{
986  return usb_bulk_write (dev, ep, bytes, size, timeout);
987}
988
989int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
990	int timeout)
991{
992  return usb_bulk_read (dev, ep, bytes, size, timeout);
993}
994
995int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
996		    int value, int index, char *bytes, int size, int timeout)
997{
998  struct darwin_dev_handle *device = dev->impl_info;
999
1000  io_return_t result;
1001
1002#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
1003  IOUSBDevRequestTO urequest;
1004#else
1005  IOUSBDevRequest urequest;
1006#endif
1007
1008  if (usb_debug >= 3)
1009    fprintf(stderr, "libusb/darwin.c usb_control_msg (device: %s): %d %d %d %d %p %d %d\n",
1010            dev->device->filename, requesttype, request, value, index, bytes, size, timeout);
1011
1012  bzero(&urequest, sizeof(urequest));
1013
1014  urequest.bmRequestType = requesttype;
1015  urequest.bRequest = request;
1016  urequest.wValue = value;
1017  urequest.wIndex = index;
1018  urequest.wLength = size;
1019  urequest.pData = bytes;
1020#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
1021  urequest.completionTimeout = timeout;
1022  urequest.noDataTimeout = timeout;
1023
1024  result = (*(device->device))->DeviceRequestTO(device->device, &urequest);
1025#else
1026  result = (*(device->device))->DeviceRequest(device->device, &urequest);
1027#endif
1028  if (result != kIOReturnSuccess)
1029    USB_ERROR_STR(-darwin_to_errno(result), "libusb/darwin.c usb_control_msg(DeviceRequestTO): %s", darwin_error_str(result));
1030
1031  /* Bytes transfered is stored in the wLenDone field*/
1032  return urequest.wLenDone;
1033}
1034
1035int usb_os_find_busses(struct usb_bus **busses)
1036{
1037  struct usb_bus *fbus = NULL;
1038
1039  io_iterator_t deviceIterator;
1040  io_return_t result;
1041
1042  usb_device_t **device;
1043
1044  UInt32 location;
1045
1046  char buf[20];
1047  int i = 1;
1048
1049  /* Create a master port for communication with IOKit (this should
1050     have been created if the user called usb_init() )*/
1051  if (masterPort == MACH_PORT_NULL) {
1052    usb_init ();
1053
1054    if (masterPort == MACH_PORT_NULL)
1055      USB_ERROR(-ENOENT);
1056  }
1057
1058  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1059    return result;
1060
1061  while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1062    struct usb_bus *bus;
1063
1064    if (location & 0x00ffffff)
1065      continue;
1066
1067    bus = calloc(1, sizeof(struct usb_bus));
1068    if (bus == NULL)
1069      USB_ERROR(-ENOMEM);
1070
1071    sprintf(buf, "%03i", i++);
1072    bus->location = location;
1073
1074    strncpy(bus->dirname, buf, sizeof(bus->dirname) - 1);
1075    bus->dirname[sizeof(bus->dirname) - 1] = 0;
1076
1077    LIST_ADD(fbus, bus);
1078
1079    if (usb_debug >= 2)
1080      fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
1081
1082    (*(device))->Release(device);
1083  }
1084
1085  IOObjectRelease(deviceIterator);
1086
1087  *busses = fbus;
1088
1089  return 0;
1090}
1091
1092int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
1093{
1094  struct usb_device *fdev = NULL;
1095
1096  io_iterator_t deviceIterator;
1097  io_return_t result;
1098
1099  usb_device_t **device;
1100
1101  u_int16_t address;
1102  UInt32 location;
1103  UInt32 bus_loc = bus->location;
1104  int devnum;
1105
1106  /* for use in retrieving device description */
1107  IOUSBDevRequest req;
1108
1109  /* a master port should have been created by usb_os_init */
1110  if (masterPort == MACH_PORT_NULL)
1111    USB_ERROR(-ENOENT);
1112
1113  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1114    return result;
1115
1116  /* Set up request for device descriptor */
1117  req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
1118  req.bRequest = kUSBRqGetDescriptor;
1119  req.wValue = kUSBDeviceDesc << 8;
1120  req.wIndex = 0;
1121  req.wLength = sizeof(IOUSBDeviceDescriptor);
1122
1123  devnum = 0;
1124
1125  while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1126    unsigned char device_desc[DEVICE_DESC_LENGTH];
1127    UInt8 bDeviceClass, bDeviceSubClass;
1128    UInt16 idVendor, idProduct;
1129
1130    result = (*(device))->GetDeviceAddress(device, (USBDeviceAddress *)&address);
1131
1132    if (result == kIOReturnSuccess) {
1133      (*(device))->GetDeviceClass (device, &bDeviceClass);
1134      (*(device))->GetDeviceSubClass (device, &bDeviceSubClass);
1135      (*(device))->GetDeviceProduct (device, &idProduct);
1136      (*(device))->GetDeviceVendor (device, &idVendor);
1137
1138      if ((location >> 24) == (bus_loc >> 24)) {
1139	struct usb_device *dev;
1140
1141	if (usb_debug >= 2)
1142	  fprintf(stderr, "libusb/darwin.c usb_os_find_devices: Found USB device on bus 0x%08x: 0x%08x\n",
1143		  (uint32_t)bus_loc, (uint32_t)location);
1144
1145	dev = calloc(1, sizeof(struct usb_device));
1146	if (dev == NULL)
1147	  USB_ERROR(-ENOMEM);
1148
1149	dev->bus = bus;
1150
1151	/* retrieve device descriptor */
1152	req.pData = device_desc;
1153	result = (*(device))->DeviceRequest(device, &req);
1154
1155	if (result != kIOReturnSuccess) {
1156	  free (dev);
1157
1158	  if (usb_debug)
1159	    fprintf (stderr, "libusb/darwin.c usb_os_find_devices: Could not retrieve device descriptor: %s. Skipping device.\n",
1160		     darwin_error_str(result));
1161
1162	  /* release the device now */
1163	  (*(device))->Release(device);
1164	  continue; /* can't continue without a descriptor */
1165	}
1166
1167	usb_parse_descriptor(device_desc, "bbwbbbbwwwbbbb", &dev->descriptor);
1168
1169	/* catch buggy hubs (which appear to be virtual). Apple's own USB prober has problems with these devices */
1170	if (dev->descriptor.idProduct != idProduct) {
1171	  free (dev);
1172
1173	  if (usb_debug)
1174	    fprintf (stderr, "libusb/darwin.c usb_os_find_devices: idProduct from iokit does not match idProduct in descriptor. Skipping device\n");
1175
1176	  /* release the device now */
1177          (*(device))->Release(device);
1178          continue; /* can't continue without a descriptor */
1179	}
1180
1181	dev->devnum = devnum++;
1182
1183	sprintf(dev->filename, "%03i-%04x-%04x-%02x-%02x", address, idVendor, idProduct, bDeviceClass, bDeviceSubClass);
1184
1185	dev->dev = (USBDeviceAddress *) calloc (1, 4);
1186	if (dev->dev == NULL)
1187	  USB_ERROR(-ENOMEM);
1188
1189	memcpy(dev->dev, &location, 4);
1190
1191	LIST_ADD(fdev, dev);
1192
1193	if (usb_debug >= 2)
1194	  fprintf(stderr, "libusb/darwin.c usb_os_find_devices: Found %s on %s at location 0x%08x\n",
1195		  dev->filename, bus->dirname, (uint32_t)location);
1196      }
1197    } else if (usb_debug)
1198      fprintf (stderr, "libusb/darwin.c usb_os_find_devices: Could not retrieve device address: %s\n",
1199	       darwin_error_str(result));
1200
1201    /* release the device now */
1202    (*(device))->Release(device);
1203  }
1204
1205  IOObjectRelease(deviceIterator);
1206
1207  *devices = fdev;
1208
1209  if (usb_debug)
1210    fprintf (stderr, "libusb/darwin.c usb_os_find_devices: Complete\n");
1211
1212  return 0;
1213}
1214
1215int usb_os_determine_children(struct usb_bus *bus)
1216{
1217  /* Nothing yet */
1218  return 0;
1219}
1220
1221void usb_os_init(void)
1222{
1223  if (masterPort == MACH_PORT_NULL) {
1224    IOMasterPort(masterPort, &masterPort);
1225
1226    gNotifyPort = IONotificationPortCreate(masterPort);
1227  }
1228}
1229
1230void usb_os_cleanup (void)
1231{
1232  if (masterPort != MACH_PORT_NULL)
1233    darwin_cleanup ();
1234}
1235
1236int usb_resetep(usb_dev_handle *dev, unsigned int ep)
1237{
1238  struct darwin_dev_handle *device;
1239
1240  io_return_t result = -1;
1241
1242  int pipeRef;
1243
1244  if (!dev)
1245    USB_ERROR(-ENXIO);
1246
1247  if ((device = dev->impl_info) == NULL)
1248    USB_ERROR(-ENOENT);
1249
1250  /* interface is not open */
1251  if (!device->interface)
1252    USB_ERROR_STR(-EACCES, "usb_resetep: interface used without being claimed");
1253
1254  if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1255    USB_ERROR(-EINVAL);
1256
1257  result = (*(device->interface))->ResetPipe(device->interface, pipeRef);
1258
1259  if (result != kIOReturnSuccess)
1260    USB_ERROR_STR(-darwin_to_errno(result), "usb_resetep(ResetPipe): %s", darwin_error_str(result));
1261
1262  return 0;
1263}
1264
1265int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
1266{
1267  struct darwin_dev_handle *device;
1268
1269  io_return_t result = -1;
1270
1271  int pipeRef;
1272
1273  if (!dev)
1274    USB_ERROR(-ENXIO);
1275
1276  if ((device = dev->impl_info) == NULL)
1277    USB_ERROR(-ENOENT);
1278
1279  /* interface is not open */
1280  if (!device->interface)
1281    USB_ERROR_STR(-EACCES, "usb_clear_halt: interface used without being claimed");
1282
1283  if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1284    USB_ERROR(-EINVAL);
1285
1286#if (InterfaceVersion < 190)
1287  result = (*(device->interface))->ClearPipeStall(device->interface, pipeRef);
1288#else
1289  /* newer versions of darwin support clearing additional bits on the device's endpoint */
1290  result = (*(device->interface))->ClearPipeStallBothEnds(device->interface, pipeRef);
1291#endif
1292
1293  if (result != kIOReturnSuccess)
1294    USB_ERROR_STR(-darwin_to_errno(result), "usb_clear_halt(ClearPipeStall): %s", darwin_error_str(result));
1295
1296  return 0;
1297}
1298
1299int usb_reset(usb_dev_handle *dev)
1300{
1301  struct darwin_dev_handle *device;
1302
1303  io_return_t result;
1304
1305  if (!dev)
1306    USB_ERROR(-ENXIO);
1307
1308  if ((device = dev->impl_info) == NULL)
1309    USB_ERROR(-ENOENT);
1310
1311  if (!device->device)
1312    USB_ERROR_STR(-ENOENT, "usb_reset: no such device");
1313
1314  result = (*(device->device))->ResetDevice(device->device);
1315
1316  if (result != kIOReturnSuccess)
1317    USB_ERROR_STR(-darwin_to_errno(result), "usb_reset(ResetDevice): %s", darwin_error_str(result));
1318
1319  return 0;
1320}
1321