2
* Darwin/MacOS X Support
4
* (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
7
* - mod usb_get_next_device to continue itterating after errors.
9
* - Fix problem with timeout handling
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.
15
* - Fixed a bug when using asynchronous callbacks within a multi-threaded application.
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.
23
* - Fixed several memory leaks.
24
* - Readded 10.0 support
25
* - Added support for USB fuctions defined in 10.3 and above
27
* - Applied a patch by Philip Edelbrock <phil@edgedesign.us> that fixes a bug in usb_control_msg.
29
* - Even better error printing.
30
* - Devices that cannot be opened can have their interfaces opened.
32
* - Fixed problem where libusb holds resources after program completion.
33
* - Mouse should no longer freeze up now.
35
* - Bulk functions should work properly now.
37
* - Fixed major bug (device and interface need to be released after use)
39
* - Tested driver with gphoto (works great as long as Image Capture isn't running)
41
* - Implimented clear_halt and resetep
44
* - Added usb_debug line to bulk read and write function.
46
* - Driver mostly completed using the macosx driver I wrote for my rioutil software.
48
* Derived from Linux version by Richard Tobin.
49
* Also partly derived from BSD version.
51
* This library is covered by the LGPL, read LICENSE for details.
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>
71
/* IOUSBInterfaceInferface */
72
#if defined (kIOUSBInterfaceInterfaceID220)
74
// #warning "libusb being compiled for 10.4 or later"
75
#define usb_interface_t IOUSBInterfaceInterface220
76
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
77
#define InterfaceVersion 220
79
#elif defined (kIOUSBInterfaceInterfaceID197)
81
// #warning "libusb being compiled for 10.3 or later"
82
#define usb_interface_t IOUSBInterfaceInterface197
83
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197
84
#define InterfaceVersion 197
86
#elif defined (kIOUSBInterfaceInterfaceID190)
88
// #warning "libusb being compiled for 10.2 or later"
89
#define usb_interface_t IOUSBInterfaceInterface190
90
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190
91
#define InterfaceVersion 190
93
#elif defined (kIOUSBInterfaceInterfaceID182)
95
// #warning "libusb being compiled for 10.1 or later"
96
#define usb_interface_t IOUSBInterfaceInterface182
97
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID182
98
#define InterfaceVersion 182
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
111
/* IOUSBDeviceInterface */
112
#if defined (kIOUSBDeviceInterfaceID197)
114
#define usb_device_t IOUSBDeviceInterface197
115
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
116
#define DeviceVersion 197
118
#elif defined (kIOUSBDeviceInterfaceID187)
120
#define usb_device_t IOUSBDeviceInterface187
121
#define DeviceInterfaceID kIOUSBDeviceInterfaceID187
122
#define DeviceVersion 187
124
#elif defined (kIOUSBDeviceInterfaceID182)
126
#define usb_device_t IOUSBDeviceInterface182
127
#define DeviceInterfaceID kIOUSBDeviceInterfaceID182
128
#define DeviceVersion 182
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
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);
149
#if !defined(IO_OBJECT_NULL)
150
#define IO_OBJECT_NULL ((io_object_t)0)
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;
159
/* stored translation table for pipes to endpoints */
161
unsigned char *endpoint_addrs;
164
static CFMutableDictionaryRef matchingDict;
165
static IONotificationPortRef gNotifyPort;
166
static mach_port_t masterPort = MACH_PORT_NULL;
168
static void darwin_cleanup (void)
170
IONotificationPortDestroy(gNotifyPort);
171
mach_port_deallocate(mach_task_self(), masterPort);
174
static char *darwin_error_str (int result) {
176
case kIOReturnSuccess:
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";
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";
197
return "unknown error";
201
/* not a valid errorno outside darwin.c */
202
#define LUSBDARWINSTALL (ELAST+1)
204
static int darwin_to_errno (int result) {
206
case kIOReturnSuccess:
208
case kIOReturnNotOpen:
210
case kIOReturnNoDevice:
211
case kIOUSBNoAsyncPortErr:
213
case kIOReturnExclusiveAccess:
215
case kIOUSBPipeStalled:
216
return LUSBDARWINSTALL;
217
case kIOReturnBadArgument:
219
case kIOUSBTransactionTimeout:
227
static int usb_setup_iterator (io_iterator_t *deviceIterator)
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) {
236
USB_ERROR_STR(-1, "libusb/darwin.c usb_setup_iterator: Could not create a matching dictionary.\n");
239
result = IOServiceGetMatchingServices(masterPort, matchingDict, deviceIterator);
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));
249
static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp)
251
io_cf_plugin_ref_t *plugInInterface = NULL;
252
usb_device_t **device;
253
io_service_t usbDevice;
256
for (;;) { /* Retry loop */
258
if (!IOIteratorIsValid (deviceIterator) || !(usbDevice = IOIteratorNext(deviceIterator)))
261
result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
262
kIOCFPlugInInterfaceID, &plugInInterface,
267
fprintf(stderr, "libusb/darwin.c usb_get_next_device: IOCreatePlugInInterfaceForService: %s\n", darwin_error_str(result));
270
if (!plugInInterface) {
272
fprintf(stderr, "libusb/darwin.c usb_get_next_device: IOCreatePlugInInterfaceForService: !plugInInterface\n");
276
result = IOObjectRelease(usbDevice);
279
fprintf(stderr,"libusb/darwin.c usb_get_next_device: IOObjectRelease: %s\n", darwin_error_str(result));
283
(*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),
286
(*plugInInterface)->Stop(plugInInterface);
287
IODestroyPlugInInterface (plugInInterface);
288
plugInInterface = NULL;
290
(*(device))->GetLocationID(device, locationp);
297
int usb_os_open(usb_dev_handle *dev)
299
struct darwin_dev_handle *device;
302
io_iterator_t deviceIterator;
304
usb_device_t **darwin_device;
306
UInt32 location = *((UInt32 *)dev->device->dev);
312
if (masterPort == MACH_PORT_NULL)
315
device = calloc(1, sizeof(struct darwin_dev_handle));
320
fprintf(stderr, "usb_os_open: %04x:%04x\n",
321
dev->device->descriptor.idVendor,
322
dev->device->descriptor.idProduct);
324
if ((result = usb_setup_iterator (&deviceIterator)) < 0)
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)
332
(*darwin_device)->Release(darwin_device);
335
IOObjectRelease(deviceIterator);
336
device->device = darwin_device;
338
if (device->device == NULL)
339
USB_ERROR_STR (-ENOENT, "usb_os_open: %s\n", "Device not found!");
341
#if !defined (LIBUSB_NO_SEIZE_DEVICE)
342
result = (*(device->device))->USBDeviceOpenSeize (device->device);
344
/* No Seize in OS X 10.0 (Darwin 1.4) */
345
result = (*(device->device))->USBDeviceOpen (device->device);
348
if (result != kIOReturnSuccess) {
350
case kIOReturnExclusiveAccess:
352
fprintf (stderr, "usb_os_open(USBDeviceOpenSeize): %s\n", darwin_error_str(result));
355
(*(device->device))->Release (device->device);
356
USB_ERROR_STR(-darwin_to_errno (result), "usb_os_open(USBDeviceOpenSeize): %s",
357
darwin_error_str(result));
364
dev->impl_info = device;
366
dev->altsetting = -1;
368
device->num_endpoints = 0;
369
device->endpoint_addrs = NULL;
374
int usb_os_close(usb_dev_handle *dev)
376
struct darwin_dev_handle *device;
382
if ((device = dev->impl_info) == NULL)
385
usb_release_interface(dev, dev->interface);
388
fprintf(stderr, "usb_os_close: %04x:%04x\n",
389
dev->device->descriptor.idVendor,
390
dev->device->descriptor.idProduct);
392
if (device->open == 1)
393
result = (*(device->device))->USBDeviceClose(device->device);
395
result = kIOReturnSuccess;
397
/* device may not need to be released, but if it has to... */
398
(*(device->device))->Release(device->device);
400
if (result != kIOReturnSuccess)
401
USB_ERROR_STR(-darwin_to_errno(result), "usb_os_close(USBDeviceClose): %s", darwin_error_str(result));
408
static int get_endpoints (struct darwin_dev_handle *device)
412
u_int8_t numep, direction, number;
413
u_int8_t dont_care1, dont_care3;
414
u_int16_t dont_care2;
418
if (device == NULL || device->interface == NULL)
422
fprintf(stderr, "libusb/darwin.c get_endpoints: building table of endpoints.\n");
424
/* retrieve the total number of endpoints on this interface */
425
ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
428
fprintf ( stderr, "get_endpoints: interface is %p\n", device->interface );
430
USB_ERROR_STR ( -ret, "get_endpoints: can't get number of endpoints for interface" );
433
free (device->endpoint_addrs);
434
device->endpoint_addrs = calloc (sizeof (unsigned char), numep);
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);
441
if (ret != kIOReturnSuccess) {
442
fprintf (stderr, "get_endpoints: an error occurred getting pipe information on pipe %d\n",
444
USB_ERROR_STR(-darwin_to_errno(ret), "get_endpoints(GetPipeProperties): %s", darwin_error_str(ret));
448
fprintf (stderr, "get_endpoints: Pipe %i: DIR: %i number: %i\n", i, direction, number);
450
device->endpoint_addrs[i - 1] = ((direction << 7 & USB_ENDPOINT_DIR_MASK) |
451
(number & USB_ENDPOINT_ADDRESS_MASK));
454
device->num_endpoints = numep;
457
fprintf(stderr, "libusb/darwin.c get_endpoints: complete.\n");
462
static int claim_interface (usb_dev_handle *dev, int interface)
464
io_iterator_t interface_iterator;
465
io_service_t usbInterface = IO_OBJECT_NULL;
467
io_cf_plugin_ref_t *plugInInterface = NULL;
469
IOUSBFindInterfaceRequest request;
471
struct darwin_dev_handle *device;
473
int current_interface;
475
device = dev->impl_info;
477
request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
478
request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
479
request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
480
request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
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));
487
for ( current_interface=0 ; current_interface <= interface ; current_interface++ ) {
488
usbInterface = IOIteratorNext(interface_iterator);
490
fprintf ( stderr, "Interface %d of device is 0x%08x\n",
491
current_interface, usbInterface );
496
/* the interface iterator is no longer needed, release it */
497
IOObjectRelease(interface_iterator);
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. */
507
fprintf ( stderr,"claim_interface: No interface found; selecting configuration\n" );
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));
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" );
521
fprintf ( stderr, "claim_interface: device has %d configuration%s\n",
522
(int)nConfig, (nConfig>1?"s":"") );
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) );
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 );
538
if (device->open == 1) {
539
result = (*(device->device))->SetConfiguration ( (device->device), configDesc->bConfigurationValue );
541
if (result != kIOReturnSuccess) {
542
(*(device->device))->USBDeviceClose ( (device->device) );
543
(*(device->device))->Release ( (device->device) );
545
USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(SetConfiguration): %s",
546
darwin_error_str(result));
549
dev->config = configDesc->bConfigurationValue;
552
request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
553
request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
554
request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
555
request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
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));
563
for (current_interface = 0 ; current_interface <= interface ; current_interface++) {
564
usbInterface = IOIteratorNext(interface_iterator);
567
fprintf ( stderr, "claim_interface: Interface %d of device is 0x%08x\n",
568
current_interface, usbInterface );
572
/* the interface iterator is no longer needed, release it */
573
IOObjectRelease(interface_iterator);
576
USB_ERROR_STR (-ENOENT, "claim_interface: interface iterator returned NULL");
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)
588
/* Now create the device interface for the interface */
589
result = (*plugInInterface)->QueryInterface(plugInInterface,
590
CFUUIDGetUUIDBytes(InterfaceInterfaceID),
591
(LPVOID) &device->interface);
593
/* No longer need the intermediate plug-in */
594
(*plugInInterface)->Stop(plugInInterface);
595
IODestroyPlugInInterface (plugInInterface);
597
if (result != kIOReturnSuccess)
598
USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(QueryInterface): %s",
599
darwin_error_str(result));
601
if (!device->interface)
605
fprintf ( stderr, "claim_interface: Interface %d of device from QueryInterface is %p\n",
606
current_interface, device->interface);
608
/* claim the interface */
609
result = (*(device->interface))->USBInterfaceOpen(device->interface);
611
USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(USBInterfaceOpen): %s",
612
darwin_error_str(result));
614
result = get_endpoints (device);
617
/* this should not happen */
618
usb_release_interface (dev, interface);
619
USB_ERROR_STR ( result, "claim_interface: could not build endpoint table");
625
int usb_set_configuration (usb_dev_handle *dev, int configuration)
627
struct darwin_dev_handle *device;
632
fprintf ( stderr, "usb_set_configuration: called for config %x\n", configuration );
635
USB_ERROR_STR ( -ENXIO, "usb_set_configuration: called with null device\n" );
637
if ((device = dev->impl_info) == NULL)
638
USB_ERROR_STR ( -ENOENT, "usb_set_configuration: device not properly initialized" );
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;
644
if ( device->interface )
645
usb_release_interface(dev, dev->interface);
647
result = (*(device->device))->SetConfiguration(device->device, configuration);
650
USB_ERROR_STR(-darwin_to_errno(result), "usb_set_configuration(SetConfiguration): %s",
651
darwin_error_str(result));
653
/* Reclaim interface */
655
result = usb_claim_interface (dev, interface);
657
dev->config = configuration;
662
int usb_claim_interface(usb_dev_handle *dev, int interface)
664
struct darwin_dev_handle *device = dev->impl_info;
669
fprintf ( stderr, "usb_claim_interface: called for interface %d\n", interface );
672
USB_ERROR_STR ( -ENOENT, "usb_claim_interface: device is NULL" );
674
if (!(device->device))
675
USB_ERROR_STR ( -EINVAL, "usb_claim_interface: device->device is NULL" );
677
/* If we have already claimed an interface, release it */
678
if ( device->interface )
679
usb_release_interface(dev, dev->interface);
681
result = claim_interface ( dev, interface );
683
USB_ERROR_STR ( result, "usb_claim_interface: couldn't claim interface" );
685
dev->interface = interface;
687
/* interface is claimed and async IO is set up: return 0 */
691
int usb_release_interface(usb_dev_handle *dev, int interface)
693
struct darwin_dev_handle *device;
699
if ((device = dev->impl_info) == NULL)
702
/* interface is not open */
703
if (!device->interface)
706
result = (*(device->interface))->USBInterfaceClose(device->interface);
708
if (result != kIOReturnSuccess)
709
USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(USBInterfaceClose): %s",
710
darwin_error_str(result));
712
result = (*(device->interface))->Release(device->interface);
714
if (result != kIOReturnSuccess)
715
USB_ERROR_STR(-darwin_to_errno(result), "usb_release_interface(Release): %s",
716
darwin_error_str(result));
718
device->interface = NULL;
720
free (device->endpoint_addrs);
722
device->num_endpoints = 0;
723
device->endpoint_addrs = NULL;
726
dev->altsetting = -1;
731
int usb_set_altinterface(usb_dev_handle *dev, int alternate)
733
struct darwin_dev_handle *device;
739
if ((device = dev->impl_info) == NULL)
742
/* interface is not open */
743
if (!device->interface)
744
USB_ERROR_STR(-EACCES, "usb_set_altinterface: interface used without being claimed");
746
result = (*(device->interface))->SetAlternateInterface(device->interface, alternate);
749
USB_ERROR_STR(result, "usb_set_altinterface: could not set alternate interface");
751
dev->altsetting = alternate;
753
result = get_endpoints (device);
755
/* this should not happen */
756
USB_ERROR_STR ( result, "usb_set_altinterface: could not build endpoint table");
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)
768
fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: Converting ep address to pipeRef.\n");
770
for (i = 0 ; i < device->num_endpoints ; i++)
771
if (device->endpoint_addrs[i] == ep)
774
/* No pipe found with the correct endpoint address */
776
fprintf(stderr, "libusb/darwin.c ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
781
/* argument to handle multiple parameters to rw_completed */
782
struct rw_complete_arg {
785
CFRunLoopRef cf_loop;
788
static void rw_completed(void *refcon, io_return_t result, void *io_size)
790
struct rw_complete_arg *rw_arg = (struct rw_complete_arg *)refcon;
793
fprintf(stderr, "io async operation completed: %s, size=%lu, result=0x%08x\n", darwin_error_str(result),
794
(UInt32)io_size, result);
796
rw_arg->io_size = (UInt32)io_size;
797
rw_arg->result = result;
799
CFRunLoopStop(rw_arg->cf_loop);
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)
805
struct darwin_dev_handle *device;
807
io_return_t result = -1;
809
CFRunLoopSourceRef cfSource;
812
struct rw_complete_arg rw_arg;
814
u_int8_t transferType;
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;
821
USB_ERROR_STR ( -ENXIO, "usb_bulk_transfer: Called with NULL device" );
823
if ((device = dev->impl_info) == NULL)
824
USB_ERROR_STR ( -ENOENT, "usb_bulk_transfer: Device not open" );
826
/* interface is not open */
827
if (!device->interface)
828
USB_ERROR_STR(-EACCES, "usb_bulk_transfer: Interface used before it was opened");
831
/* Set up transfer */
832
if ((pipeRef = ep_to_pipeRef(device, ep)) < 0)
833
USB_ERROR_STR ( -EINVAL, "usb_bulk_transfer: Invalid pipe reference" );
835
(*(device->interface))->GetPipeProperties (device->interface, pipeRef, &direction, &number,
836
&transferType, &maxPacketSize, &interval);
838
(*(device->interface))->CreateInterfaceAsyncEventSource(device->interface, &cfSource);
839
CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
841
bzero((void *)&rw_arg, sizeof(struct rw_complete_arg));
842
rw_arg.cf_loop = CFRunLoopGetCurrent();
843
/* Transfer set up complete */
846
fprintf (stderr, "libusb/darwin.c usb_bulk_transfer: Transfering %i bytes of data on endpoint 0x%02x\n",
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");
853
if ( transferType != kUSBInterrupt && rw_async_to != NULL)
855
result = rw_async_to (device->interface, pipeRef, bytes, size, timeout, timeout,
856
(IOAsyncCallback1)rw_completed, (void *)&rw_arg);
858
result = rw_async (device->interface, pipeRef, bytes, size, (IOAsyncCallback1)rw_completed,
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 */
868
fprintf(stderr, "libusb/darwin.c usb_bulk_transfer: timed out\n");
872
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);
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) ) {
880
if (result == kIOReturnSuccess) {
881
error_code = darwin_to_errno (rw_arg.result);
882
error_str = darwin_error_str (rw_arg.result);
884
error_code = darwin_to_errno(result);
885
error_str = darwin_error_str (result);
888
if (transferType != kUSBInterrupt && rw_async_to != NULL)
889
USB_ERROR_STR(-error_code, "usb_bulk_transfer (w/ Timeout): %s", error_str);
891
USB_ERROR_STR(-error_code, "usb_bulk_transfer (No Timeout): %s", error_str);
894
return rw_arg.io_size;
897
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
900
rw_async_to_func_t to_func = NULL;
901
struct darwin_dev_handle *device;
903
if (dev == NULL || dev->impl_info == NULL)
906
device = dev->impl_info;
908
#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE)
909
to_func = (*(device->interface))->WritePipeAsyncTO;
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)");
919
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout)
922
rw_async_to_func_t to_func = NULL;
923
struct darwin_dev_handle *device;
925
if (dev == NULL || dev->impl_info == NULL)
930
device = dev->impl_info;
932
#if !defined (LIBUSB_NO_TIMEOUT_INTERFACE)
933
to_func = (*(device->interface))->ReadPipeAsyncTO;
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)");
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,
947
return usb_bulk_write (dev, ep, bytes, size, timeout);
950
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
953
return usb_bulk_read (dev, ep, bytes, size, timeout);
956
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
957
int value, int index, char *bytes, int size, int timeout)
959
struct darwin_dev_handle *device = dev->impl_info;
963
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
964
IOUSBDevRequestTO urequest;
966
IOUSBDevRequest urequest;
970
fprintf(stderr, "usb_control_msg: %d %d %d %d %p %d %d\n",
971
requesttype, request, value, index, bytes, size, timeout);
973
bzero(&urequest, sizeof(urequest));
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;
985
result = (*(device->device))->DeviceRequestTO(device->device, &urequest);
987
result = (*(device->device))->DeviceRequest(device->device, &urequest);
989
if (result != kIOReturnSuccess)
990
USB_ERROR_STR(-darwin_to_errno(result), "usb_control_msg(DeviceRequestTO): %s", darwin_error_str(result));
992
/* Bytes transfered is stored in the wLenDone field*/
993
return urequest.wLenDone;
996
int usb_os_find_busses(struct usb_bus **busses)
998
struct usb_bus *fbus = NULL;
1000
io_iterator_t deviceIterator;
1003
usb_device_t **device;
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) {
1015
if (masterPort == MACH_PORT_NULL)
1019
if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1022
while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1023
struct usb_bus *bus;
1025
if (location & 0x00ffffff)
1028
bus = calloc(1, sizeof(struct usb_bus));
1032
sprintf(buf, "%03i", i++);
1033
bus->location = location;
1035
strncpy(bus->dirname, buf, sizeof(bus->dirname) - 1);
1036
bus->dirname[sizeof(bus->dirname) - 1] = 0;
1038
LIST_ADD(fbus, bus);
1041
fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
1043
(*(device))->Release(device);
1046
IOObjectRelease(deviceIterator);
1053
int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
1055
struct usb_device *fdev = NULL;
1057
io_iterator_t deviceIterator;
1060
usb_device_t **device;
1064
UInt32 bus_loc = bus->location;
1066
/* for use in retrieving device description */
1067
IOUSBDevRequest req;
1069
/* a master port should have been created by usb_os_init */
1070
if (masterPort == MACH_PORT_NULL)
1073
if ((result = usb_setup_iterator (&deviceIterator)) < 0)
1076
/* Set up request for device descriptor */
1077
req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
1078
req.bRequest = kUSBRqGetDescriptor;
1079
req.wValue = kUSBDeviceDesc << 8;
1081
req.wLength = sizeof(IOUSBDeviceDescriptor);
1084
while ((device = usb_get_next_device (deviceIterator, &location)) != NULL) {
1085
unsigned char device_desc[DEVICE_DESC_LENGTH];
1087
result = (*(device))->GetDeviceAddress(device, (USBDeviceAddress *)&address);
1090
fprintf(stderr, "usb_os_find_devices: Found USB device at location 0x%08lx\n", location);
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;
1096
dev = calloc(1, sizeof(struct usb_device));
1102
req.pData = device_desc;
1103
result = (*(device))->DeviceRequest(device, &req);
1105
usb_parse_descriptor(device_desc, "bbwbbbbwwwbbbb", &dev->descriptor);
1107
sprintf(dev->filename, "%03i-%04x-%04x-%02x-%02x", address,
1108
dev->descriptor.idVendor, dev->descriptor.idProduct,
1109
dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass);
1111
dev->dev = (USBDeviceAddress *)malloc(4);
1112
memcpy(dev->dev, &location, 4);
1114
LIST_ADD(fdev, dev);
1117
fprintf(stderr, "usb_os_find_devices: Found %s on %s at location 0x%08lx\n",
1118
dev->filename, bus->dirname, location);
1121
/* release the device now */
1122
(*(device))->Release(device);
1125
IOObjectRelease(deviceIterator);
1132
int usb_os_determine_children(struct usb_bus *bus)
1138
void usb_os_init(void)
1140
if (masterPort == MACH_PORT_NULL) {
1141
IOMasterPort(masterPort, &masterPort);
1143
gNotifyPort = IONotificationPortCreate(masterPort);
1147
void usb_os_cleanup (void)
1149
if (masterPort != MACH_PORT_NULL)
1153
int usb_resetep(usb_dev_handle *dev, unsigned int ep)
1155
struct darwin_dev_handle *device;
1157
io_return_t result = -1;
1164
if ((device = dev->impl_info) == NULL)
1167
/* interface is not open */
1168
if (!device->interface)
1169
USB_ERROR_STR(-EACCES, "usb_resetep: interface used without being claimed");
1171
if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1174
result = (*(device->interface))->ResetPipe(device->interface, pipeRef);
1176
if (result != kIOReturnSuccess)
1177
USB_ERROR_STR(-darwin_to_errno(result), "usb_resetep(ResetPipe): %s", darwin_error_str(result));
1182
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
1184
struct darwin_dev_handle *device;
1186
io_return_t result = -1;
1193
if ((device = dev->impl_info) == NULL)
1196
/* interface is not open */
1197
if (!device->interface)
1198
USB_ERROR_STR(-EACCES, "usb_clear_halt: interface used without being claimed");
1200
if ((pipeRef = ep_to_pipeRef(device, ep)) == -1)
1203
#if defined (kIOUSBInterfaceInterfaceID190)
1204
result = (*(device->interface))->ClearPipeStallBothEnds(device->interface, pipeRef);
1206
result = (*(device->interface))->ClearPipeStall(device->interface, pipeRef);
1209
if (result != kIOReturnSuccess)
1210
USB_ERROR_STR(-darwin_to_errno(result), "usb_clear_halt(ClearPipeStall): %s", darwin_error_str(result));
1215
int usb_reset(usb_dev_handle *dev)
1217
struct darwin_dev_handle *device;
1224
if ((device = dev->impl_info) == NULL)
1227
if (!device->device)
1228
USB_ERROR_STR(-ENOENT, "usb_reset: no such device");
1230
result = (*(device->device))->ResetDevice(device->device);
1232
if (result != kIOReturnSuccess)
1233
USB_ERROR_STR(-darwin_to_errno(result), "usb_reset(ResetDevice): %s", darwin_error_str(result));