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