~ubuntu-branches/ubuntu/trusty/argyll/trusty-proposed

« back to all changes in this revision

Viewing changes to libusb/darwin.c

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2014-02-12 00:35:39 UTC
  • mfrom: (13.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20140212003539-24tautzlitsiz61w
Tags: 1.5.1-5ubuntu1
* Merge from Debian unstable. (LP: #1275572) Remaining changes:
  - debian/control:
    + Build-depend on libtiff-dev rather than libtiff4-dev.
  - debian/control, debian/patches/06_fix_udev_rule.patch:
    + Fix udev rules to actually work; ENV{ACL_MANAGE} has
      stopped working ages ago, and with logind it's now the
      "uaccess" tag. Dropping also consolekit from Recommends.
  - debian/patches/drop-usb-db.patch:
    + Use hwdb builtin, instead of the obsolete usb-db
      in the udev rules.
* debian/patches/05_ftbfs-underlinkage.diff:
  - Dropped change, no needed anymore.
* Refresh the patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Darwin/MacOS X Support
3
 
 *
4
 
 * (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
5
 
 *
6
 
 * (08/28/2008):        GWG
7
 
 *   - mod usb_get_next_device to continue itterating after errors.
8
 
 * (01/30/2007):        GWG
9
 
 *   - Fix problem with timeout handling
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
 
typedef IOReturn io_return_t;
141
 
typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
142
 
typedef SInt32 s_int32_t;
143
 
typedef IOReturn (*rw_async_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,
144
 
                                    IOAsyncCallback1 callback, void *refcon);
145
 
typedef IOReturn (*rw_async_to_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,
146
 
                                       UInt32 noDataTimeout, UInt32 completionTimeout,
147
 
                                       IOAsyncCallback1 callback, void *refcon);
148
 
 
149
 
#if !defined(IO_OBJECT_NULL)
150
 
#define IO_OBJECT_NULL ((io_object_t)0)
151
 
#endif
152
 
 
153
 
/* Darwin/OS X impl does not use fd field, instead it uses this */
154
 
struct darwin_dev_handle {
155
 
  usb_device_t **device;
156
 
  usb_interface_t **interface;
157
 
  int open;
158
 
 
159
 
  /* stored translation table for pipes to endpoints */
160
 
  int num_endpoints;
161
 
  unsigned char *endpoint_addrs;
162
 
};
163
 
 
164
 
static CFMutableDictionaryRef matchingDict;
165
 
static IONotificationPortRef gNotifyPort;
166
 
static mach_port_t masterPort = MACH_PORT_NULL;
167
 
 
168
 
static void darwin_cleanup (void)
169
 
{
170
 
  IONotificationPortDestroy(gNotifyPort);
171
 
  mach_port_deallocate(mach_task_self(), masterPort);
172
 
}
173
 
 
174
 
static char *darwin_error_str (int result) {
175
 
  switch (result) {
176
 
  case kIOReturnSuccess:
177
 
    return "no error";
178
 
  case kIOReturnNotOpen:
179
 
    return "device not opened for exclusive access";
180
 
  case kIOReturnNoDevice:
181
 
    return "no connection to an IOService";
182
 
  case kIOUSBNoAsyncPortErr:
183
 
    return "no async port has been opened for interface";
184
 
  case kIOReturnExclusiveAccess:
185
 
    return "another process has device opened for exclusive access";
186
 
  case kIOUSBPipeStalled:
187
 
    return "pipe is stalled";
188
 
  case kIOReturnError:
189
 
    return "could not establish a connection to the Darwin kernel";
190
 
  case kIOUSBTransactionTimeout:
191
 
    return "transaction timed out";
192
 
  case kIOReturnBadArgument:
193
 
    return "invalid argument";
194
 
  case kIOReturnAborted:
195
 
    return "transaction aborted";
196
 
  default:
197
 
    return "unknown error";
198
 
  }
199
 
}
200
 
 
201
 
/* not a valid errorno outside darwin.c */
202
 
#define LUSBDARWINSTALL (ELAST+1)
203
 
 
204
 
static int darwin_to_errno (int result) {
205
 
  switch (result) {
206
 
  case kIOReturnSuccess:
207
 
    return 0;
208
 
  case kIOReturnNotOpen:
209
 
    return EBADF;
210
 
  case kIOReturnNoDevice:
211
 
  case kIOUSBNoAsyncPortErr:
212
 
    return ENXIO;
213
 
  case kIOReturnExclusiveAccess:
214
 
    return EBUSY;
215
 
  case kIOUSBPipeStalled:
216
 
    return LUSBDARWINSTALL;
217
 
  case kIOReturnBadArgument:
218
 
    return EINVAL;
219
 
  case kIOUSBTransactionTimeout:
220
 
    return ETIMEDOUT;
221
 
  case kIOReturnError:
222
 
  default:
223
 
    return 1;
224
 
  }
225
 
}
226
 
 
227
 
static int usb_setup_iterator (io_iterator_t *deviceIterator)
228
 
{
229
 
  int result;
230
 
 
231
 
  /* set up the matching dictionary for class IOUSBDevice and its subclasses.
232
 
     It will be consumed by the IOServiceGetMatchingServices call */
233
 
  if ((matchingDict = IOServiceMatching(kIOUSBDeviceClassName)) == NULL) {
234
 
    darwin_cleanup ();
235
 
    
236
 
    USB_ERROR_STR(-1, "libusb/darwin.c usb_setup_iterator: Could not create a matching dictionary.\n");
237
 
  }
238
 
 
239
 
  result = IOServiceGetMatchingServices(masterPort, matchingDict, deviceIterator);
240
 
  matchingDict = NULL;
241
 
 
242
 
  if (result != kIOReturnSuccess)
243
 
    USB_ERROR_STR (-darwin_to_errno (result), "libusb/darwin.c usb_setup_iterator: IOServiceGetMatchingServices: %s\n",
244
 
                   darwin_error_str(result));
245
 
 
246
 
  return 0;
247
 
}
248
 
 
249
 
static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp)
250
 
{
251
 
  io_cf_plugin_ref_t *plugInInterface = NULL;
252
 
  usb_device_t **device;
253
 
  io_service_t usbDevice;
254
 
  long result, score;
255
 
 
256
 
  for (;;) {    /* Retry loop */
257
 
 
258
 
    if (!IOIteratorIsValid (deviceIterator) || !(usbDevice = IOIteratorNext(deviceIterator)))
259
 
      return NULL;
260
 
    
261
 
    result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
262
 
                                             kIOCFPlugInInterfaceID, &plugInInterface,
263
 
                                             &score);
264
 
    
265
 
    if (result) {
266
 
      if (usb_debug > 2)
267
 
        fprintf(stderr, "libusb/darwin.c usb_get_next_device: IOCreatePlugInInterfaceForService: %s\n", darwin_error_str(result));
268
 
      continue;
269
 
    }
270
 
    if (!plugInInterface) {
271
 
      if (usb_debug > 2)
272
 
        fprintf(stderr, "libusb/darwin.c usb_get_next_device: IOCreatePlugInInterfaceForService: !plugInInterface\n");
273
 
      continue;
274
 
    }
275
 
    
276
 
    result = IOObjectRelease(usbDevice);
277
 
    if (result) {
278
 
      if (usb_debug > 2)
279
 
        fprintf(stderr,"libusb/darwin.c usb_get_next_device: IOObjectRelease: %s\n", darwin_error_str(result));
280
 
      continue;
281
 
    }
282
 
    
283
 
    (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
284
 
                                     (LPVOID)&device);
285
 
    
286
 
    (*plugInInterface)->Stop(plugInInterface);
287
 
    IODestroyPlugInInterface (plugInInterface);
288
 
    plugInInterface = NULL;
289
 
    
290
 
    (*(device))->GetLocationID(device, locationp);
291
 
  
292
 
    return device;
293
 
  }
294
 
  return NULL;
295
 
}
296
 
 
297
 
int usb_os_open(usb_dev_handle *dev)
298
 
{
299
 
  struct darwin_dev_handle *device;
300
 
 
301
 
  io_return_t result;
302
 
  io_iterator_t deviceIterator;
303
 
 
304
 
  usb_device_t **darwin_device;
305
 
 
306
 
  UInt32 location = *((UInt32 *)dev->device->dev);
307
 
  UInt32 dlocation;
308
 
 
309
 
  if (!dev)
310
 
    USB_ERROR(-ENXIO);
311
 
 
312
 
  if (masterPort == MACH_PORT_NULL)
313
 
    USB_ERROR(-EINVAL);
314
 
 
315
 
  device = calloc(1, sizeof(struct darwin_dev_handle));
316
 
  if (!device)
317
 
    USB_ERROR(-ENOMEM);
318
 
 
319
 
  if (usb_debug > 3)
320
 
    fprintf(stderr, "usb_os_open: %04x:%04x\n",
321
 
            dev->device->descriptor.idVendor,
322
 
            dev->device->descriptor.idProduct);
323
 
 
324
 
  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
325
 
    return result;
326
 
 
327
 
  /* This port of libusb uses locations to keep track of devices. */
328
 
  while ((darwin_device = usb_get_next_device (deviceIterator, &dlocation)) != NULL) {
329
 
    if (dlocation == location)
330
 
      break;
331
 
 
332
 
    (*darwin_device)->Release(darwin_device);
333
 
  }
334
 
 
335
 
  IOObjectRelease(deviceIterator);
336
 
  device->device = darwin_device;
337
 
 
338
 
  if (device->device == NULL)
339
 
    USB_ERROR_STR (-ENOENT, "usb_os_open: %s\n", "Device not found!");
340
 
 
341
 
#if !defined (LIBUSB_NO_SEIZE_DEVICE)
342
 
  result = (*(device->device))->USBDeviceOpenSeize (device->device);
343
 
#else
344
 
  /* No Seize in OS X 10.0 (Darwin 1.4) */
345
 
  result = (*(device->device))->USBDeviceOpen (device->device);
346
 
#endif
347
 
 
348
 
  if (result != kIOReturnSuccess) {
349
 
    switch (result) {
350
 
    case kIOReturnExclusiveAccess:
351
 
      if (usb_debug > 0)
352
 
        fprintf (stderr, "usb_os_open(USBDeviceOpenSeize): %s\n", darwin_error_str(result));
353
 
      break;
354
 
    default:
355
 
      (*(device->device))->Release (device->device);
356
 
      USB_ERROR_STR(-darwin_to_errno (result), "usb_os_open(USBDeviceOpenSeize): %s",
357
 
                    darwin_error_str(result));
358
 
    }
359
 
    
360
 
    device->open = 0;
361
 
  } else
362
 
    device->open = 1;
363
 
    
364
 
  dev->impl_info = device;
365
 
  dev->interface = -1;
366
 
  dev->altsetting = -1;
367
 
 
368
 
  device->num_endpoints  = 0;
369
 
  device->endpoint_addrs = NULL;
370
 
 
371
 
  return 0;
372
 
}
373
 
 
374
 
int usb_os_close(usb_dev_handle *dev)
375
 
{
376
 
  struct darwin_dev_handle *device;
377
 
  io_return_t result;
378
 
 
379
 
  if (!dev)
380
 
    USB_ERROR(-ENXIO);
381
 
 
382
 
  if ((device = dev->impl_info) == NULL)
383
 
    USB_ERROR(-ENOENT);
384
 
 
385
 
  usb_release_interface(dev, dev->interface);
386
 
 
387
 
  if (usb_debug > 3)
388
 
    fprintf(stderr, "usb_os_close: %04x:%04x\n",
389
 
            dev->device->descriptor.idVendor,
390
 
            dev->device->descriptor.idProduct);
391
 
 
392
 
  if (device->open == 1)
393
 
    result = (*(device->device))->USBDeviceClose(device->device);
394
 
  else
395
 
    result = kIOReturnSuccess;
396
 
 
397
 
  /* device may not need to be released, but if it has to... */
398
 
  (*(device->device))->Release(device->device);
399
 
 
400
 
  if (result != kIOReturnSuccess)
401
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_os_close(USBDeviceClose): %s", darwin_error_str(result));
402
 
 
403
 
  free (device);
404
 
 
405
 
  return 0;
406
 
}
407
 
 
408
 
static int get_endpoints (struct darwin_dev_handle *device)
409
 
{
410
 
  io_return_t ret;
411
 
 
412
 
  u_int8_t numep, direction, number;
413
 
  u_int8_t dont_care1, dont_care3;
414
 
  u_int16_t dont_care2;
415
 
 
416
 
  int i;
417
 
 
418
 
  if (device == NULL || device->interface == NULL)
419
 
    return -EINVAL;
420
 
 
421
 
  if (usb_debug > 1)
422
 
    fprintf(stderr, "libusb/darwin.c get_endpoints: building table of endpoints.\n");
423
 
 
424
 
  /* retrieve the total number of endpoints on this interface */
425
 
  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
426
 
  if ( ret ) {
427
 
    if ( usb_debug > 1 )
428
 
      fprintf ( stderr, "get_endpoints: interface is %p\n", device->interface );
429
 
 
430
 
    USB_ERROR_STR ( -ret, "get_endpoints: can't get number of endpoints for interface" );
431
 
  }
432
 
 
433
 
  free (device->endpoint_addrs);
434
 
  device->endpoint_addrs = calloc (sizeof (unsigned char), numep);
435
 
 
436
 
  /* iterate through pipe references */
437
 
  for (i = 1 ; i <= numep ; i++) {
438
 
    ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
439
 
                                                    &dont_care1, &dont_care2, &dont_care3);
440
 
 
441
 
    if (ret != kIOReturnSuccess) {
442
 
      fprintf (stderr, "get_endpoints: an error occurred getting pipe information on pipe %d\n",
443
 
               i );
444
 
      USB_ERROR_STR(-darwin_to_errno(ret), "get_endpoints(GetPipeProperties): %s", darwin_error_str(ret));
445
 
    }
446
 
 
447
 
    if (usb_debug > 1)
448
 
      fprintf (stderr, "get_endpoints: Pipe %i: DIR: %i number: %i\n", i, direction, number);
449
 
 
450
 
    device->endpoint_addrs[i - 1] = ((direction << 7 & USB_ENDPOINT_DIR_MASK) |
451
 
                                     (number & USB_ENDPOINT_ADDRESS_MASK));
452
 
  }
453
 
 
454
 
  device->num_endpoints = numep;
455
 
 
456
 
  if (usb_debug > 1)
457
 
    fprintf(stderr, "libusb/darwin.c get_endpoints: complete.\n");
458
 
  
459
 
  return 0;
460
 
}
461
 
 
462
 
static int claim_interface (usb_dev_handle *dev, int interface)
463
 
{
464
 
  io_iterator_t interface_iterator;
465
 
  io_service_t  usbInterface = IO_OBJECT_NULL;
466
 
  io_return_t result;
467
 
  io_cf_plugin_ref_t *plugInInterface = NULL;
468
 
 
469
 
  IOUSBFindInterfaceRequest request;
470
 
 
471
 
  struct darwin_dev_handle *device;
472
 
  long score;
473
 
  int current_interface;
474
 
 
475
 
  device = dev->impl_info;
476
 
 
477
 
  request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
478
 
  request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
479
 
  request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
480
 
  request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
481
 
 
482
 
  result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator);
483
 
  if (result != kIOReturnSuccess)
484
 
    USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s",
485
 
                   darwin_error_str(result));
486
 
 
487
 
  for ( current_interface=0 ; current_interface <= interface ; current_interface++ ) {
488
 
    usbInterface = IOIteratorNext(interface_iterator);
489
 
    if ( usb_debug > 3 )
490
 
      fprintf ( stderr, "Interface %d of device is 0x%08x\n",
491
 
                current_interface, usbInterface );
492
 
  }
493
 
 
494
 
  current_interface--;
495
 
 
496
 
  /* the interface iterator is no longer needed, release it */
497
 
  IOObjectRelease(interface_iterator);
498
 
 
499
 
  if (!usbInterface) {
500
 
    u_int8_t nConfig;                        /* Index of configuration to use */
501
 
    IOUSBConfigurationDescriptorPtr configDesc; /* to describe which configuration to select */
502
 
    /* Only a composite class device with no vendor-specific driver will
503
 
       be configured. Otherwise, we need to do it ourselves, or there
504
 
       will be no interfaces for the device. */
505
 
 
506
 
    if ( usb_debug > 3 )
507
 
      fprintf ( stderr,"claim_interface: No interface found; selecting configuration\n" );
508
 
 
509
 
    result = (*(device->device))->GetNumberOfConfigurations ( device->device, &nConfig );
510
 
    if (result != kIOReturnSuccess)
511
 
      USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetNumberOfConfigurations): %s",
512
 
                    darwin_error_str(result));
513
 
    
514
 
    if (nConfig < 1)
515
 
      USB_ERROR_STR(-ENXIO ,"claim_interface(GetNumberOfConfigurations): no configurations");
516
 
    else if ( nConfig > 1 && usb_debug > 0 )
517
 
      fprintf ( stderr, "claim_interface: device has more than one"
518
 
                " configuration, using the first (warning)\n" );
519
 
 
520
 
    if ( usb_debug > 3 )
521
 
      fprintf ( stderr, "claim_interface: device has %d configuration%s\n",
522
 
                (int)nConfig, (nConfig>1?"s":"") );
523
 
 
524
 
    /* Always use the first configuration */
525
 
    result = (*(device->device))->GetConfigurationDescriptorPtr ( (device->device), 0, &configDesc );
526
 
    if (result != kIOReturnSuccess) {
527
 
      if (device->open == 1) {
528
 
        (*(device->device))->USBDeviceClose ( (device->device) );
529
 
        (*(device->device))->Release ( (device->device) );
530
 
      }
531
 
 
532
 
      USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetConfigurationDescriptorPtr): %s",
533
 
                    darwin_error_str(result));
534
 
    } else if ( usb_debug > 3 )
535
 
      fprintf ( stderr, "claim_interface: configuration value is %d\n",
536
 
                configDesc->bConfigurationValue );
537
 
 
538
 
    if (device->open == 1) {
539
 
      result = (*(device->device))->SetConfiguration ( (device->device), configDesc->bConfigurationValue );
540
 
 
541
 
      if (result != kIOReturnSuccess) {
542
 
        (*(device->device))->USBDeviceClose ( (device->device) );
543
 
        (*(device->device))->Release ( (device->device) );
544
 
 
545
 
        USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(SetConfiguration): %s",
546
 
                      darwin_error_str(result));
547
 
      }
548
 
 
549
 
      dev->config = configDesc->bConfigurationValue;
550
 
    }
551
 
    
552
 
    request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
553
 
    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
554
 
    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
555
 
    request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
556
 
 
557
 
    /* Now go back and get the chosen interface */
558
 
    result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator);
559
 
    if (result != kIOReturnSuccess)
560
 
      USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s",
561
 
                     darwin_error_str(result));
562
 
 
563
 
    for (current_interface = 0 ; current_interface <= interface ; current_interface++) {
564
 
      usbInterface = IOIteratorNext(interface_iterator);
565
 
 
566
 
      if ( usb_debug > 3 )
567
 
        fprintf ( stderr, "claim_interface: Interface %d of device is 0x%08x\n",
568
 
                  current_interface, usbInterface );
569
 
    }
570
 
    current_interface--;
571
 
 
572
 
    /* the interface iterator is no longer needed, release it */
573
 
    IOObjectRelease(interface_iterator);
574
 
 
575
 
    if (!usbInterface)
576
 
      USB_ERROR_STR (-ENOENT, "claim_interface: interface iterator returned NULL");
577
 
  }
578
 
 
579
 
  result = IOCreatePlugInInterfaceForService(usbInterface,
580
 
                                             kIOUSBInterfaceUserClientTypeID,
581
 
                                             kIOCFPlugInInterfaceID,
582
 
                                             &plugInInterface, &score);
583
 
  /* No longer need the usbInterface object after getting the plug-in */
584
 
  result = IOObjectRelease(usbInterface);
585
 
  if (result || !plugInInterface)
586
 
    USB_ERROR(-ENOENT);
587
 
 
588
 
  /* Now create the device interface for the interface */
589
 
  result = (*plugInInterface)->QueryInterface(plugInInterface,
590
 
                                              CFUUIDGetUUIDBytes(InterfaceInterfaceID),
591
 
                                              (LPVOID) &device->interface);
592
 
 
593
 
  /* No longer need the intermediate plug-in */
594
 
  (*plugInInterface)->Stop(plugInInterface);
595
 
  IODestroyPlugInInterface (plugInInterface);
596
 
 
597
 
  if (result != kIOReturnSuccess)
598
 
    USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(QueryInterface): %s",
599
 
                  darwin_error_str(result));
600
 
 
601
 
  if (!device->interface)
602
 
    USB_ERROR(-EACCES);
603
 
 
604
 
  if ( usb_debug > 3 )
605
 
    fprintf ( stderr, "claim_interface: Interface %d of device from QueryInterface is %p\n",
606
 
              current_interface, device->interface);
607
 
 
608
 
  /* claim the interface */
609
 
  result = (*(device->interface))->USBInterfaceOpen(device->interface);
610
 
  if (result)
611
 
    USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(USBInterfaceOpen): %s",
612
 
                  darwin_error_str(result));
613
 
 
614
 
  result = get_endpoints (device);
615
 
 
616
 
  if (result) {
617
 
    /* this should not happen */
618
 
    usb_release_interface (dev, interface);
619
 
    USB_ERROR_STR ( result, "claim_interface: could not build endpoint table");
620
 
  }
621
 
 
622
 
  return 0;
623
 
}
624
 
 
625
 
int usb_set_configuration (usb_dev_handle *dev, int configuration)
626
 
{
627
 
  struct darwin_dev_handle *device;
628
 
  io_return_t result;
629
 
  int interface;
630
 
 
631
 
  if ( usb_debug > 3 )
632
 
    fprintf ( stderr, "usb_set_configuration: called for config %x\n", configuration );
633
 
 
634
 
  if (!dev)
635
 
    USB_ERROR_STR ( -ENXIO, "usb_set_configuration: called with null device\n" );
636
 
 
637
 
  if ((device = dev->impl_info) == NULL)
638
 
    USB_ERROR_STR ( -ENOENT, "usb_set_configuration: device not properly initialized" );
639
 
 
640
 
  /* Setting configuration will invalidate the interface, so we need
641
 
     to reclaim it. First, dispose of existing interface, if any. */
642
 
  interface = dev->interface;
643
 
 
644
 
  if ( device->interface )
645
 
    usb_release_interface(dev, dev->interface);
646
 
 
647
 
  result = (*(device->device))->SetConfiguration(device->device, configuration);
648
 
 
649
 
  if (result)
650
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_set_configuration(SetConfiguration): %s",
651
 
                  darwin_error_str(result));
652
 
 
653
 
  /* Reclaim interface */
654
 
  if (interface != -1)
655
 
    result = usb_claim_interface (dev, interface);
656
 
 
657
 
  dev->config = configuration;
658
 
 
659
 
  return result;
660
 
}
661
 
 
662
 
int usb_claim_interface(usb_dev_handle *dev, int interface)
663
 
{
664
 
  struct darwin_dev_handle *device = dev->impl_info;
665
 
 
666
 
  io_return_t result;
667
 
 
668
 
  if ( usb_debug > 3 )
669
 
    fprintf ( stderr, "usb_claim_interface: called for interface %d\n", interface );
670
 
 
671
 
  if (!device)
672
 
    USB_ERROR_STR ( -ENOENT, "usb_claim_interface: device is NULL" );
673
 
 
674
 
  if (!(device->device))
675
 
    USB_ERROR_STR ( -EINVAL, "usb_claim_interface: device->device is NULL" );
676
 
 
677
 
  /* If we have already claimed an interface, release it */
678
 
  if ( device->interface )
679
 
    usb_release_interface(dev, dev->interface);
680
 
 
681
 
  result = claim_interface ( dev, interface );
682
 
  if ( result )
683
 
    USB_ERROR_STR ( result, "usb_claim_interface: couldn't claim interface" );
684
 
 
685
 
  dev->interface = interface;
686
 
 
687
 
  /* interface is claimed and async IO is set up: return 0 */
688
 
  return 0;
689
 
}
690
 
 
691
 
int usb_release_interface(usb_dev_handle *dev, int interface)
692
 
{
693
 
  struct darwin_dev_handle *device;
694
 
  io_return_t result;
695
 
 
696
 
  if (!dev)
697
 
    USB_ERROR(-ENXIO);
698
 
 
699
 
  if ((device = dev->impl_info) == NULL)
700
 
    USB_ERROR(-ENOENT);
701
 
 
702
 
  /* interface is not open */
703
 
  if (!device->interface)
704
 
    return 0;
705
 
 
706
 
  result = (*(device->interface))->USBInterfaceClose(device->interface);
707
 
 
708
 
  if (result != kIOReturnSuccess)
709
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(USBInterfaceClose): %s",
710
 
                  darwin_error_str(result));
711
 
 
712
 
  result = (*(device->interface))->Release(device->interface);
713
 
 
714
 
  if (result != kIOReturnSuccess)
715
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(Release): %s",
716
 
                  darwin_error_str(result));
717
 
 
718
 
  device->interface = NULL;
719
 
 
720
 
  free (device->endpoint_addrs);
721
 
 
722
 
  device->num_endpoints  = 0;
723
 
  device->endpoint_addrs = NULL;
724
 
 
725
 
  dev->interface = -1;
726
 
  dev->altsetting = -1;
727
 
 
728
 
  return 0;
729
 
}
730
 
 
731
 
int usb_set_altinterface(usb_dev_handle *dev, int alternate)
732
 
{
733
 
  struct darwin_dev_handle *device;
734
 
  io_return_t result;
735
 
 
736
 
  if (!dev)
737
 
    USB_ERROR(-ENXIO);
738
 
 
739
 
  if ((device = dev->impl_info) == NULL)
740
 
    USB_ERROR(-ENOENT);
741
 
 
742
 
  /* interface is not open */
743
 
  if (!device->interface)
744
 
    USB_ERROR_STR(-EACCES, "usb_set_altinterface: interface used without being claimed");
745
 
 
746
 
  result = (*(device->interface))->SetAlternateInterface(device->interface, alternate);
747
 
 
748
 
  if (result)
749
 
    USB_ERROR_STR(result, "usb_set_altinterface: could not set alternate interface");
750
 
 
751
 
  dev->altsetting = alternate;
752
 
 
753
 
  result = get_endpoints (device);
754
 
  if (result) {
755
 
    /* this should not happen */
756
 
    USB_ERROR_STR ( result, "usb_set_altinterface: could not build endpoint table");
757
 
  }
758
 
 
759
 
  return 0;
760
 
}
761
 
 
762
 
/* simple function that figures out what pipeRef is associated with an endpoint */
763
 
static int ep_to_pipeRef (struct darwin_dev_handle *device, int ep)
764
 
{
765
 
  int i;
766
 
 
767
 
  if (usb_debug > 1)
768
 
    fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: Converting ep address to pipeRef.\n");
769
 
 
770
 
  for (i = 0 ; i < device->num_endpoints ; i++)
771
 
    if (device->endpoint_addrs[i] == ep)
772
 
      return i + 1;
773
 
 
774
 
  /* No pipe found with the correct endpoint address */
775
 
  if (usb_debug > 1)
776
 
    fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
777
 
  
778
 
  return -1;
779
 
}
780
 
 
781
 
/* argument to handle multiple parameters to rw_completed */
782
 
struct rw_complete_arg {
783
 
  UInt32        io_size;
784
 
  IOReturn      result;
785
 
  CFRunLoopRef  cf_loop;
786
 
};
787
 
 
788
 
static void rw_completed(void *refcon, io_return_t result, void *io_size)
789
 
{
790
 
  struct rw_complete_arg *rw_arg = (struct rw_complete_arg *)refcon;
791
 
 
792
 
  if (usb_debug > 2)
793
 
    fprintf(stderr, "io async operation completed: %s, size=%lu, result=0x%08x\n", darwin_error_str(result),
794
 
            (UInt32)io_size, result);
795
 
 
796
 
  rw_arg->io_size = (UInt32)io_size;
797
 
  rw_arg->result  = result;
798
 
 
799
 
  CFRunLoopStop(rw_arg->cf_loop);
800
 
}
801
 
 
802
 
static int usb_bulk_transfer (usb_dev_handle *dev, int ep, char *bytes, int size, int timeout,
803
 
                              rw_async_func_t rw_async, rw_async_to_func_t rw_async_to)
804
 
{
805
 
  struct darwin_dev_handle *device;
806
 
 
807
 
  io_return_t result = -1;
808
 
 
809
 
  CFRunLoopSourceRef cfSource;
810
 
  int pipeRef;
811
 
 
812
 
  struct rw_complete_arg rw_arg;
813
 
 
814
 
  u_int8_t  transferType;
815
 
 
816
 
  /* None of the values below are used in libusb for bulk transfers */
817
 
  u_int8_t  direction, number, interval;
818
 
  u_int16_t maxPacketSize;
819
 
 
820
 
  if (!dev)
821
 
    USB_ERROR_STR ( -ENXIO, "usb_bulk_transfer: Called with NULL device" );
822
 
 
823
 
  if ((device = dev->impl_info) == NULL)
824
 
    USB_ERROR_STR ( -ENOENT, "usb_bulk_transfer: Device not open" );
825
 
 
826
 
  /* interface is not open */
827
 
  if (!device->interface)
828
 
    USB_ERROR_STR(-EACCES, "usb_bulk_transfer: Interface used before it was opened");
829
 
 
830
 
 
831
 
  /* Set up transfer */
832
 
  if ((pipeRef = ep_to_pipeRef(device, ep)) < 0)
833
 
    USB_ERROR_STR ( -EINVAL, "usb_bulk_transfer: Invalid pipe reference" );
834
 
 
835
 
  (*(device->interface))->GetPipeProperties (device->interface, pipeRef, &direction, &number,
836
 
                                             &transferType, &maxPacketSize, &interval);
837
 
 
838
 
  (*(device->interface))->CreateInterfaceAsyncEventSource(device->interface, &cfSource);
839
 
  CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
840
 
 
841
 
  bzero((void *)&rw_arg, sizeof(struct rw_complete_arg));
842
 
  rw_arg.cf_loop = CFRunLoopGetCurrent();
843
 
  /* Transfer set up complete */
844
 
 
845
 
  if (usb_debug > 0)
846
 
    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: Transfering %i bytes of data on endpoint 0x%02x\n",
847
 
             size, ep);
848
 
 
849
 
  /* Bulk transfer */
850
 
  if (transferType == kUSBInterrupt && usb_debug > 3)
851
 
    fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: USB pipe is an interrupt pipe. Timeouts will not be used.\n");
852
 
 
853
 
  if ( transferType != kUSBInterrupt && rw_async_to != NULL)
854
 
 
855
 
    result = rw_async_to (device->interface, pipeRef, bytes, size, timeout, timeout,
856
 
                          (IOAsyncCallback1)rw_completed, (void *)&rw_arg);
857
 
  else
858
 
    result = rw_async (device->interface, pipeRef, bytes, size, (IOAsyncCallback1)rw_completed,
859
 
                       (void *)&rw_arg);
860
 
 
861
 
  if (result == kIOReturnSuccess) {
862
 
    /* wait for write to complete */
863
 
    if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, (timeout+999)/1000, false) == kCFRunLoopRunTimedOut) {
864
 
      result = kIOUSBTransactionTimeout;
865
 
      (*(device->interface))->AbortPipe(device->interface, pipeRef);
866
 
      CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, true); /* Pick up aborted callback */
867
 
      if (usb_debug)
868
 
        fprintf(stderr, "libusb/darwin.c usb_bulk_transfer: timed out\n");
869
 
    }
870
 
  }
871
 
 
872
 
  CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
873
 
  
874
 
  /* Check the return code of both the write and completion functions. */
875
 
  if (result != kIOReturnSuccess || (rw_arg.result != kIOReturnSuccess && 
876
 
      rw_arg.result != kIOReturnAborted) ) {
877
 
    int error_code;
878
 
    char *error_str;
879
 
 
880
 
    if (result == kIOReturnSuccess) {
881
 
      error_code = darwin_to_errno (rw_arg.result);
882
 
      error_str  = darwin_error_str (rw_arg.result);
883
 
    } else {
884
 
      error_code = darwin_to_errno(result);
885
 
      error_str  = darwin_error_str (result);
886
 
    }
887
 
    
888
 
    if (transferType != kUSBInterrupt && rw_async_to != NULL)
889
 
      USB_ERROR_STR(-error_code, "usb_bulk_transfer (w/ Timeout): %s", error_str);
890
 
    else
891
 
      USB_ERROR_STR(-error_code, "usb_bulk_transfer (No Timeout): %s", error_str);
892
 
  }
893
 
 
894
 
  return rw_arg.io_size;
895
 
}
896
 
 
897
 
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
898
 
{
899
 
  int result;
900
 
  rw_async_to_func_t to_func = NULL;
901
 
  struct darwin_dev_handle *device;
902
 
  
903
 
  if (dev == NULL || dev->impl_info == NULL)
904
 
    return -EINVAL;
905
 
 
906
 
  device = dev->impl_info;
907
 
 
908
 
#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE)
909
 
  to_func = (*(device->interface))->WritePipeAsyncTO;
910
 
#endif
911
 
 
912
 
  if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout,
913
 
                                   (*(device->interface))->WritePipeAsync, to_func)) < 0)
914
 
    USB_ERROR_STR (result, "usb_bulk_write: An error occured during write (see messages above)");
915
 
  
916
 
  return result;
917
 
}
918
 
 
919
 
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
920
 
{
921
 
  int result;
922
 
  rw_async_to_func_t to_func = NULL;
923
 
  struct darwin_dev_handle *device;
924
 
  
925
 
  if (dev == NULL || dev->impl_info == NULL)
926
 
    return -EINVAL;
927
 
 
928
 
  ep |= 0x80;
929
 
  
930
 
  device = dev->impl_info;
931
 
 
932
 
#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE)
933
 
  to_func = (*(device->interface))->ReadPipeAsyncTO;
934
 
#endif
935
 
 
936
 
  if ((result = usb_bulk_transfer (dev, ep, bytes, size, timeout,
937
 
                                   (*(device->interface))->ReadPipeAsync, to_func)) < 0)
938
 
    USB_ERROR_STR (result, "usb_bulk_read: An error occured during read (see messages above)");
939
 
  
940
 
  return result;
941
 
}
942
 
 
943
 
/* interrupt endpoints seem to be treated just like any other endpoint under OSX/Darwin */
944
 
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
945
 
        int timeout)
946
 
{
947
 
  return usb_bulk_write (dev, ep, bytes, size, timeout);
948
 
}
949
 
 
950
 
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
951
 
        int timeout)
952
 
{
953
 
  return usb_bulk_read (dev, ep, bytes, size, timeout);
954
 
}
955
 
 
956
 
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
957
 
                    int value, int index, char *bytes, int size, int timeout)
958
 
{
959
 
  struct darwin_dev_handle *device = dev->impl_info;
960
 
 
961
 
  io_return_t result;
962
 
 
963
 
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
964
 
  IOUSBDevRequestTO urequest;
965
 
#else
966
 
  IOUSBDevRequest urequest;
967
 
#endif
968
 
 
969
 
  if (usb_debug >= 3)
970
 
    fprintf(stderr, "usb_control_msg: %d %d %d %d %p %d %d\n",
971
 
            requesttype, request, value, index, bytes, size, timeout);
972
 
 
973
 
  bzero(&urequest, sizeof(urequest));
974
 
 
975
 
  urequest.bmRequestType = requesttype;
976
 
  urequest.bRequest = request;
977
 
  urequest.wValue = value;
978
 
  urequest.wIndex = index;
979
 
  urequest.wLength = size;
980
 
  urequest.pData = bytes;
981
 
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
982
 
  urequest.completionTimeout = timeout;
983
 
  urequest.noDataTimeout = timeout;
984
 
 
985
 
  result = (*(device->device))->DeviceRequestTO(device->device, &urequest);
986
 
#else
987
 
  result = (*(device->device))->DeviceRequest(device->device, &urequest);
988
 
#endif
989
 
  if (result != kIOReturnSuccess)
990
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_control_msg(DeviceRequestTO): %s", darwin_error_str(result));
991
 
 
992
 
  /* Bytes transfered is stored in the wLenDone field*/
993
 
  return urequest.wLenDone;
994
 
}
995
 
 
996
 
int usb_os_find_busses(struct usb_bus **busses)
997
 
{
998
 
  struct usb_bus *fbus = NULL;
999
 
 
1000
 
  io_iterator_t deviceIterator;
1001
 
  io_return_t result;
1002
 
 
1003
 
  usb_device_t **device;
1004
 
 
1005
 
  UInt32 location;
1006
 
 
1007
 
  char buf[20];
1008
 
  int i = 1;
1009
 
 
1010
 
  /* Create a master port for communication with IOKit (this should
1011
 
     have been created if the user called usb_init() )*/
1012
 
  if (masterPort == MACH_PORT_NULL) {
1013
 
    usb_init ();
1014
 
 
1015
 
    if (masterPort == MACH_PORT_NULL)
1016
 
      USB_ERROR(-ENOENT);
1017
 
  }
1018
 
 
1019
 
  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1020
 
    return result;
1021
 
 
1022
 
  while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1023
 
    struct usb_bus *bus;
1024
 
 
1025
 
    if (location & 0x00ffffff)
1026
 
      continue;
1027
 
 
1028
 
    bus = calloc(1, sizeof(struct usb_bus));
1029
 
    if (bus == NULL)
1030
 
      USB_ERROR(-ENOMEM);
1031
 
    
1032
 
    sprintf(buf, "%03i", i++);
1033
 
    bus->location = location;
1034
 
 
1035
 
    strncpy(bus->dirname, buf, sizeof(bus->dirname) - 1);
1036
 
    bus->dirname[sizeof(bus->dirname) - 1] = 0;
1037
 
    
1038
 
    LIST_ADD(fbus, bus);
1039
 
    
1040
 
    if (usb_debug >= 2)
1041
 
      fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
1042
 
 
1043
 
    (*(device))->Release(device);
1044
 
  }
1045
 
 
1046
 
  IOObjectRelease(deviceIterator);
1047
 
 
1048
 
  *busses = fbus;
1049
 
 
1050
 
  return 0;
1051
 
}
1052
 
 
1053
 
int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
1054
 
{
1055
 
  struct usb_device *fdev = NULL;
1056
 
 
1057
 
  io_iterator_t deviceIterator;
1058
 
  io_return_t result;
1059
 
 
1060
 
  usb_device_t **device;
1061
 
 
1062
 
  u_int16_t address;
1063
 
  UInt32 location;
1064
 
  UInt32 bus_loc = bus->location;
1065
 
 
1066
 
  /* for use in retrieving device description */
1067
 
  IOUSBDevRequest req;
1068
 
 
1069
 
  /* a master port should have been created by usb_os_init */
1070
 
  if (masterPort == MACH_PORT_NULL)
1071
 
    USB_ERROR(-ENOENT);
1072
 
 
1073
 
  if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1074
 
    return result;
1075
 
 
1076
 
  /* Set up request for device descriptor */
1077
 
  req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
1078
 
  req.bRequest = kUSBRqGetDescriptor;
1079
 
  req.wValue = kUSBDeviceDesc << 8;
1080
 
  req.wIndex = 0;
1081
 
  req.wLength = sizeof(IOUSBDeviceDescriptor);
1082
 
 
1083
 
 
1084
 
  while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1085
 
    unsigned char device_desc[DEVICE_DESC_LENGTH];
1086
 
 
1087
 
    result = (*(device))->GetDeviceAddress(device, (USBDeviceAddress *)&address);
1088
 
 
1089
 
    if (usb_debug >= 2)
1090
 
      fprintf(stderr, "usb_os_find_devices: Found USB device at location 0x%08lx\n", location);
1091
 
 
1092
 
    /* first byte of location appears to be associated with the device's bus */
1093
 
    if (location >> 24 == bus_loc >> 24) {
1094
 
      struct usb_device *dev;
1095
 
 
1096
 
      dev = calloc(1, sizeof(struct usb_device));
1097
 
      if (dev == NULL)
1098
 
        USB_ERROR(-ENOMEM);
1099
 
 
1100
 
      dev->bus = bus;
1101
 
 
1102
 
      req.pData = device_desc;
1103
 
      result = (*(device))->DeviceRequest(device, &req);
1104
 
 
1105
 
      usb_parse_descriptor(device_desc, "bbwbbbbwwwbbbb", &dev->descriptor);
1106
 
 
1107
 
      sprintf(dev->filename, "%03i-%04x-%04x-%02x-%02x", address,
1108
 
              dev->descriptor.idVendor, dev->descriptor.idProduct,
1109
 
              dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass);
1110
 
 
1111
 
      dev->dev = (USBDeviceAddress *)malloc(4);
1112
 
      memcpy(dev->dev, &location, 4);
1113
 
 
1114
 
      LIST_ADD(fdev, dev);
1115
 
 
1116
 
      if (usb_debug >= 2)
1117
 
        fprintf(stderr, "usb_os_find_devices: Found %s on %s at location 0x%08lx\n",
1118
 
                dev->filename, bus->dirname, location);
1119
 
    }
1120
 
 
1121
 
    /* release the device now */
1122
 
    (*(device))->Release(device);
1123
 
  }
1124
 
 
1125
 
  IOObjectRelease(deviceIterator);
1126
 
 
1127
 
  *devices = fdev;
1128
 
 
1129
 
  return 0;
1130
 
}
1131
 
 
1132
 
int usb_os_determine_children(struct usb_bus *bus)
1133
 
{
1134
 
  /* Nothing yet */
1135
 
  return 0;
1136
 
}
1137
 
 
1138
 
void usb_os_init(void)
1139
 
{
1140
 
  if (masterPort == MACH_PORT_NULL) {
1141
 
    IOMasterPort(masterPort, &masterPort);
1142
 
    
1143
 
    gNotifyPort = IONotificationPortCreate(masterPort);
1144
 
  }
1145
 
}
1146
 
 
1147
 
void usb_os_cleanup (void)
1148
 
{
1149
 
  if (masterPort != MACH_PORT_NULL)
1150
 
    darwin_cleanup ();
1151
 
}
1152
 
 
1153
 
int usb_resetep(usb_dev_handle *dev, unsigned int ep)
1154
 
{
1155
 
  struct darwin_dev_handle *device;
1156
 
 
1157
 
  io_return_t result = -1;
1158
 
 
1159
 
  int pipeRef;
1160
 
 
1161
 
  if (!dev)
1162
 
    USB_ERROR(-ENXIO);
1163
 
 
1164
 
  if ((device = dev->impl_info) == NULL)
1165
 
    USB_ERROR(-ENOENT);
1166
 
 
1167
 
  /* interface is not open */
1168
 
  if (!device->interface)
1169
 
    USB_ERROR_STR(-EACCES, "usb_resetep: interface used without being claimed");
1170
 
 
1171
 
  if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1172
 
    USB_ERROR(-EINVAL);
1173
 
 
1174
 
  result = (*(device->interface))->ResetPipe(device->interface, pipeRef);
1175
 
 
1176
 
  if (result != kIOReturnSuccess)
1177
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_resetep(ResetPipe): %s", darwin_error_str(result));
1178
 
 
1179
 
  return 0;
1180
 
}
1181
 
 
1182
 
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
1183
 
{
1184
 
  struct darwin_dev_handle *device;
1185
 
 
1186
 
  io_return_t result = -1;
1187
 
 
1188
 
  int pipeRef;
1189
 
 
1190
 
  if (!dev)
1191
 
    USB_ERROR(-ENXIO);
1192
 
 
1193
 
  if ((device = dev->impl_info) == NULL)
1194
 
    USB_ERROR(-ENOENT);
1195
 
 
1196
 
  /* interface is not open */
1197
 
  if (!device->interface)
1198
 
    USB_ERROR_STR(-EACCES, "usb_clear_halt: interface used without being claimed");
1199
 
 
1200
 
  if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1201
 
    USB_ERROR(-EINVAL);
1202
 
 
1203
 
#if defined (kIOUSBInterfaceInterfaceID190)
1204
 
  result = (*(device->interface))->ClearPipeStallBothEnds(device->interface, pipeRef);
1205
 
#else
1206
 
  result = (*(device->interface))->ClearPipeStall(device->interface, pipeRef);
1207
 
#endif
1208
 
 
1209
 
  if (result != kIOReturnSuccess)
1210
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_clear_halt(ClearPipeStall): %s", darwin_error_str(result));
1211
 
 
1212
 
  return 0;
1213
 
}
1214
 
 
1215
 
int usb_reset(usb_dev_handle *dev)
1216
 
{
1217
 
  struct darwin_dev_handle *device;
1218
 
  
1219
 
  io_return_t result;
1220
 
 
1221
 
  if (!dev)
1222
 
    USB_ERROR(-ENXIO);
1223
 
 
1224
 
  if ((device = dev->impl_info) == NULL)
1225
 
    USB_ERROR(-ENOENT);
1226
 
 
1227
 
  if (!device->device)
1228
 
    USB_ERROR_STR(-ENOENT, "usb_reset: no such device");
1229
 
 
1230
 
  result = (*(device->device))->ResetDevice(device->device);
1231
 
 
1232
 
  if (result != kIOReturnSuccess)
1233
 
    USB_ERROR_STR(-darwin_to_errno(result), "usb_reset(ResetDevice): %s", darwin_error_str(result));
1234
 
  
1235
 
  return 0;
1236
 
}