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