1/* 2 * Copyright (c) 1998-2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25//-------------------------------------------------------------------------------------------------- 26// Includes 27//-------------------------------------------------------------------------------------------------- 28 29// General OS Services header files 30#include <libkern/OSByteOrder.h> 31 32// Local includes 33#include "IOUSBMassStorageClass.h" 34#include "IOUSBMassStorageClassTimestamps.h" 35#include "Debugging.h" 36 37// IOKit includes 38#include <IOKit/scsi/IOSCSIPeripheralDeviceNub.h> 39#include <IOKit/IODeviceTreeSupport.h> 40#include <IOKit/IOKitKeys.h> 41 42//-------------------------------------------------------------------------------------------------- 43// Defines 44//-------------------------------------------------------------------------------------------------- 45 46// Default timeout values 47enum 48{ 49 kDefaultReadTimeoutDuration = 30000, 50 kDefaultWriteTimeoutDuration = 30000 51}; 52 53// Default maximum transfer count, in bytes 54enum 55{ 56 kDefaultMaximumByteCountRead = 131072, 57 kDefaultMaximumByteCountWrite = 131072, 58 kDefaultMaximumByteCountReadUSB3 = 1048576, 59 kDefaultMaximumByteCountWriteUSB3 = 1048576 60}; 61 62// Maximum number of consecutive I/Os which can be aborted with a Device Reset, 63// before the device will be considered removed. 64enum 65{ 66 kMaxConsecutiveResets = 5 67}; 68 69 70//-------------------------------------------------------------------------------------------------- 71// Macros 72//-------------------------------------------------------------------------------------------------- 73 74#define fWorkLoop fIOSCSIProtocolInterfaceReserved->fWorkLoop 75 76 77//-------------------------------------------------------------------------------------------------- 78// Declarations - USBMassStorageClassGlobals 79//-------------------------------------------------------------------------------------------------- 80 81class USBMassStorageClassGlobals 82{ 83 84 public: 85 86 // Constructor 87 USBMassStorageClassGlobals ( void ); 88 89 // Desctructor 90 virtual ~USBMassStorageClassGlobals ( void ); 91 92}; 93 94 95//-------------------------------------------------------------------------------------------------- 96// Globals - USBMassStorageClassGlobals 97//-------------------------------------------------------------------------------------------------- 98 99 100UInt32 gUSBDebugFlags = 0; // Externally defined in IOUSBMassStorageClass.h 101static USBMassStorageClassGlobals gUSBGlobals; 102 103static int USBMassStorageClassSysctl ( struct sysctl_oid * oidp, void * arg1, int arg2, struct sysctl_req * req ); 104SYSCTL_PROC ( _debug, OID_AUTO, USBMassStorageClass, CTLFLAG_RW, 0, 0, USBMassStorageClassSysctl, "USBMassStorageClass", "USBMassStorageClass debug interface" ); 105 106 107//-------------------------------------------------------------------------------------------------- 108// USBMassStorageClassSysctl - Sysctl handler. [STATIC] 109//-------------------------------------------------------------------------------------------------- 110 111static int 112USBMassStorageClassSysctl ( struct sysctl_oid * oidp, void * arg1, int arg2, struct sysctl_req * req ) 113{ 114 115 int error = 0; 116 USBSysctlArgs usbArgs; 117 118 UNUSED ( oidp ); 119 UNUSED ( arg1 ); 120 UNUSED ( arg2 ); 121 122 STATUS_LOG ( ( 1, "+USBMassStorageClassGlobals: gUSBDebugFlags = 0x%08X\n", ( unsigned int ) gUSBDebugFlags ) ); 123 124 error = SYSCTL_IN ( req, &usbArgs, sizeof ( usbArgs ) ); 125 if ( ( error == 0 ) && ( usbArgs.type == kUSBTypeDebug ) ) 126 { 127 128 if ( usbArgs.operation == kUSBOperationGetFlags ) 129 { 130 131 usbArgs.debugFlags = gUSBDebugFlags; 132 error = SYSCTL_OUT ( req, &usbArgs, sizeof ( usbArgs ) ); 133 134 } 135 136 else if ( usbArgs.operation == kUSBOperationSetFlags ) 137 { 138 gUSBDebugFlags = usbArgs.debugFlags; 139 } 140 141 } 142 143 STATUS_LOG ( ( 1, "-USBMassStorageClassGlobals: gUSBDebugFlags = 0x%08X\n", ( unsigned int ) gUSBDebugFlags ) ); 144 145 return error; 146 147} 148 149 150//-------------------------------------------------------------------------------------------------- 151// USBMassStorageClassGlobals - Default Constructor [PUBLIC] 152//-------------------------------------------------------------------------------------------------- 153 154USBMassStorageClassGlobals::USBMassStorageClassGlobals ( void ) 155{ 156 157 int debugFlags; 158 159 STATUS_LOG ( ( 1, "+USBMassStorageClassGlobals::USBMassStorageClassGlobals\n" ) ); 160 161 if ( PE_parse_boot_argn ( "USB-MassStorage", &debugFlags, sizeof ( debugFlags ) ) ) 162 { 163 gUSBDebugFlags = debugFlags; 164 } 165 166 // Register our sysctl interface 167 sysctl_register_oid ( &sysctl__debug_USBMassStorageClass ); 168 169 STATUS_LOG ( ( 1, "-USBMassStorageClassGlobals::USBMassStorageClassGlobals\n" ) ); 170 171} 172 173 174//-------------------------------------------------------------------------------------------------- 175// USBMassStorageClassGlobals - Destructor [PUBLIC] 176//-------------------------------------------------------------------------------------------------- 177 178USBMassStorageClassGlobals::~USBMassStorageClassGlobals ( void ) 179{ 180 181 STATUS_LOG ( ( 1, "+~USBMassStorageClassGlobals::USBMassStorageClassGlobals\n" ) ); 182 183 // Unregister our sysctl interface 184 sysctl_unregister_oid ( &sysctl__debug_USBMassStorageClass ); 185 186 STATUS_LOG ( ( 1, "-~USBMassStorageClassGlobals::USBMassStorageClassGlobals\n" ) ); 187 188} 189 190 191//-------------------------------------------------------------------------------------------------- 192// Declarations - IOUSBMassStorageClass 193//-------------------------------------------------------------------------------------------------- 194 195#define super IOSCSIProtocolServices 196 197OSDefineMetaClassAndStructors( IOUSBMassStorageClass, IOSCSIProtocolServices ) 198 199 200//-------------------------------------------------------------------------------------------------- 201// init - Called at initialization time [PUBLIC] 202//-------------------------------------------------------------------------------------------------- 203 204bool 205IOUSBMassStorageClass::init ( OSDictionary * propTable ) 206{ 207 if ( super::init( propTable ) == false) 208 { 209 return false; 210 } 211 212 return true; 213 214} 215 216//-------------------------------------------------------------------------------------------------- 217// start - Called at services start time (after successful matching) [PUBLIC] 218//-------------------------------------------------------------------------------------------------- 219 220bool 221IOUSBMassStorageClass::start ( IOService * provider ) 222{ 223 IOUSBFindEndpointRequest request; 224 OSDictionary * characterDict = NULL; 225 OSObject * obj = NULL; 226 IOReturn result = kIOReturnError; 227 bool retVal = false; 228 OSNumber * number = NULL; 229 bool success = false; 230 231 232 if ( super::start( provider ) == false ) 233 { 234 STATUS_LOG(( 1, "%s[%p]: superclass start failure.", getName(), this)); 235 return false; 236 } 237 238 RecordUSBTimeStamp ( UMC_TRACE ( kIOUSBMassStorageClassStart ), 239 ( uintptr_t ) this, NULL, 240 NULL, NULL ); 241 242#ifndef EMBEDDED 243 // Allocate data for our expansion data. 244 reserved = ( ExpansionData * ) IOMalloc ( sizeof ( ExpansionData ) ); 245 bzero ( reserved, sizeof ( ExpansionData ) ); 246#endif // EMBEDDED 247 248 // Save the reference to the interface on the device that will be 249 // the provider for this object. 250 SetInterfaceReference ( OSDynamicCast ( IOUSBInterface, provider ) ); 251 if ( GetInterfaceReference ( ) == NULL ) 252 { 253 254 STATUS_LOG ( ( 1, "%s[%p]: the provider is not an IOUSBInterface object", 255 getName(), this ) ); 256 // If our provider is not a IOUSBInterface object, return false 257 // to indicate that the object could not be correctly 258 // instantiated. 259 // The USB Mass Storage Class specification requires that all 260 // devices be a composite device with a Mass Storage interface 261 // so this object will always be an interface driver. 262 goto Exit; 263 264 } 265 266 // Check if a subclass has marked this device as not to be operated at all. 267 if ( provider->getProperty ( kIOUSBMassStorageDoNotMatch ) != NULL ) 268 { 269 goto abortStart; 270 } 271 272 RecordUSBTimeStamp ( UMC_TRACE ( kAtUSBAddress ), 273 ( uintptr_t ) this, ( unsigned int ) GetInterfaceReference()->GetDevice()->GetAddress(), 274 NULL, NULL ); 275 276 STATUS_LOG ( ( 6, "%s[%p]: USB Mass Storage @ %d", 277 getName(), this, 278 GetInterfaceReference()->GetDevice()->GetAddress() ) ); 279 280 if ( GetInterfaceReference()->open( this ) == false) 281 { 282 283 STATUS_LOG ( ( 1, "%s[%p]: could not open the interface", getName(), this ) ); 284 goto Exit; 285 286 } 287 288 // Set the IOUSBPipe object pointers to NULL so that the driver can 289 // release these objects if instantition is not successful. 290 fBulkInPipe = NULL; 291 fBulkOutPipe = NULL; 292 fInterruptPipe = NULL; 293 294 // Default is to have no clients 295 fClients = NULL; 296 297 // Default is to have a max lun of 0. 298 SetMaxLogicalUnitNumber ( 0 ); 299 300 // Initialize all Bulk Only related member variables to their default 301 // states. 302 fBulkOnlyCommandTag = 0; 303 fBulkOnlyCommandStructInUse = false; 304 305 // Initialize all CBI related member variables to their default 306 // states. 307 fCBICommandStructInUse = false; 308 309 // Flag we use to indicate whether or not the device requires the standard 310 // USB device reset instead of the BO reset. This applies to BO devices only. 311 fUseUSBResetNotBOReset = false; 312 313 // Certain Bulk-Only device are subject to erroneous CSW tags. 314 fKnownCSWTagMismatchIssues = false; 315 316 // Flag to let us know if we've seen the reconfiguration message following a device reset. 317 // If we proceed with operations prior to receiving the message we may end up booting a 318 // CBW out on the bus prior to the SET_CONFIGURATION which follows the reset. This will 319 // hamper recovery and confuse the state machine of the USB device we're operating. 320 fWaitingForReconfigurationMessage = false; 321 322 // Used to determine if we're going to block on the reset thread or not. 323 fBlockOnResetThread = false; 324 325 // Used to determine where we should close our provider at time of termination. 326 fTerminating = false; 327 328 // IOSAM may request that we suspend/resume our port instead of spin up/down media. 329 fPortSuspendResumeForPMEnabled = false; 330 331#ifndef EMBEDDED 332 // Workaround flag for devices which spin themselves up/down and have problems with driver intervention. 333 fAutonomousSpinDownWorkAround = false; 334 335 // Some devices with complicated interal logic require some "cool down" time following a 336 // USB device reset before they can resume servicing requests. 337 fPostDeviceResetCoolDownInterval = 0; 338#endif // EMBEDDED 339 340 // Check if the personality for this device specifies a preferred protocol 341 characterDict = OSDynamicCast ( OSDictionary, getProperty( kIOUSBMassStorageCharacteristics ) ); 342 if ( characterDict == NULL ) 343 { 344 // This device does not specify a preferred protocol, use the protocol 345 // defined in the descriptor. 346 fPreferredProtocol = GetInterfaceReference()->GetInterfaceProtocol(); 347 fPreferredSubclass = GetInterfaceReference()->GetInterfaceSubClass(); 348 349 } 350 else 351 { 352 353 OSNumber * preferredProtocol; 354 OSNumber * preferredSubclass; 355 356 357 RecordUSBTimeStamp ( UMC_TRACE ( kIOUMCStorageCharacDictFound ), 358 ( uintptr_t ) this, NULL, NULL, NULL ); 359 360 // Check if we have a USB storage personality for this particular device. 361 preferredProtocol = OSDynamicCast ( OSNumber, characterDict->getObject( kIOUSBMassStoragePreferredProtocol ) ); 362 if ( preferredProtocol == NULL ) 363 { 364 // This device does not specify a preferred protocol, use the 365 // protocol defined in the interface descriptor. 366 fPreferredProtocol = GetInterfaceReference()->GetInterfaceProtocol(); 367 368 } 369 else 370 { 371 // This device has a preferred protocol, use that. 372 fPreferredProtocol = preferredProtocol->unsigned32BitValue(); 373 374 } 375 376 // Check if this device is not to be operated at all. 377 if ( characterDict->getObject( kIOUSBMassStorageDoNotOperate ) != NULL ) 378 { 379 goto abortStart; 380 } 381 382 // Check if this device is known not to support the bulk-only USB reset. 383 if ( characterDict->getObject ( kIOUSBMassStorageUseStandardUSBReset ) != NULL ) 384 { 385 fUseUSBResetNotBOReset = true; 386 } 387 388 // Is this a device which has CBW/CSW tag issues? 389 if ( characterDict->getObject ( kIOUSBKnownCSWTagIssues ) != NULL ) 390 { 391 fKnownCSWTagMismatchIssues = true; 392 } 393 394 if ( characterDict->getObject( kIOUSBMassStorageEnableSuspendResumePM ) != NULL ) 395 { 396 fPortSuspendResumeForPMEnabled = true; 397 } 398 399#ifndef EMBEDDED 400 // Check if this device is known to have problems when waking from sleep 401 if ( characterDict->getObject( kIOUSBMassStorageResetOnResume ) != NULL ) 402 { 403 404 STATUS_LOG ( ( 4, "%s[%p]: knownResetOnResumeDevice", getName(), this ) ); 405 fRequiresResetOnResume = true; 406 407 } 408 409 // Check to see if this device requires some time after USB reset to collect itself. 410 if ( characterDict->getObject( kIOUSBMassStoragePostResetCoolDown ) != NULL ) 411 { 412 413 OSNumber * coolDownPeriod = NULL; 414 415 coolDownPeriod = OSDynamicCast ( OSNumber, characterDict->getObject( kIOUSBMassStoragePostResetCoolDown ) ); 416 417 // Ensure we didn't get something of thew wrong type. 418 if ( coolDownPeriod != NULL ) 419 { 420 421 // Fetch our cool down interval. 422 fPostDeviceResetCoolDownInterval = coolDownPeriod->unsigned32BitValue ( ); 423 424 } 425 426 } 427#endif // EMBEDDED 428 429 // Check if the personality for this device specifies a preferred subclass 430 preferredSubclass = OSDynamicCast ( OSNumber, characterDict->getObject( kIOUSBMassStoragePreferredSubclass )); 431 if ( preferredSubclass == NULL ) 432 { 433 // This device does not specify a preferred subclass, use the 434 // subclass defined in the interface descriptor. 435 fPreferredSubclass = GetInterfaceReference()->GetInterfaceSubClass(); 436 437 } 438 else 439 { 440 // This device has a preferred protocol, use that. 441 fPreferredSubclass = preferredSubclass->unsigned32BitValue(); 442 443 } 444 445#ifndef EMBEDDED 446 // Check if the device needs to be suspended on reboot 447 if ( characterDict->getObject ( kIOUSBMassStorageSuspendOnReboot ) != NULL ) 448 { 449 450 fSuspendOnReboot = true; 451 452 } 453#endif // EMBEDDED 454 455 } 456 457 STATUS_LOG ( ( 6, "%s[%p]: Preferred Protocol is: %d", getName(), this, fPreferredProtocol ) ); 458 STATUS_LOG ( ( 6, "%s[%p]: Preferred Subclass is: %d", getName(), this, fPreferredSubclass ) ); 459 460 // Verify that the device has a supported interface type and configure that 461 // Interrupt pipe if the protocol requires one. 462 STATUS_LOG ( ( 7, "%s[%p]: Configure the Storage interface", getName(), this ) ); 463 switch ( GetInterfaceProtocol() ) 464 { 465 466 case kProtocolControlBulkInterrupt: 467 { 468 RecordUSBTimeStamp ( UMC_TRACE ( kCBIProtocolDeviceDetected ), 469 ( uintptr_t ) this, NULL, 470 NULL, NULL ); 471 472 // Find the interrupt pipe for the device. 473 // Note that the pipe will already be retained on our behalf. 474 request.type = kUSBInterrupt; 475 request.direction = kUSBIn; 476 fInterruptPipe = GetInterfaceReference()->FindNextPipe ( NULL, &request, true ); 477 478 STATUS_LOG ( ( 7, "%s[%p]: find interrupt pipe", getName(), this ) ); 479 require_nonzero ( fInterruptPipe, abortStart ); 480 481 fCBIMemoryDescriptor = IOMemoryDescriptor::withAddress ( 482 &fCBICommandRequestBlock.cbiGetStatusBuffer, 483 kUSBStorageAutoStatusSize, 484 kIODirectionIn ); 485 require_nonzero ( fCBIMemoryDescriptor, abortStart ); 486 487 result = fCBIMemoryDescriptor->prepare(); 488 require_success ( result, abortStart ); 489 } 490 break; 491 492 case kProtocolControlBulk: 493 // Since all the CB devices I have seen do not use the interrupt 494 // endpoint, even if it exists, ignore it if present. 495 case kProtocolBulkOnly: 496 { 497 498 STATUS_LOG ( ( 7, "%s[%p]: Bulk Only - skip interrupt pipe", getName(), this ) ); 499 500 RecordUSBTimeStamp ( UMC_TRACE ( kBODeviceDetected ), 501 ( uintptr_t ) this, NULL, NULL, NULL ); 502 503 // Allocate the memory descriptor needed to send the CBW out. 504 fBulkOnlyCBWMemoryDescriptor = IOMemoryDescriptor::withAddress ( 505 &fBulkOnlyCommandRequestBlock.boCBW, 506 kByteCountOfCBW, 507 kIODirectionOut ); 508 require_nonzero ( fBulkOnlyCBWMemoryDescriptor, abortStart ); 509 510 result = fBulkOnlyCBWMemoryDescriptor->prepare(); 511 require_success ( result, abortStart ); 512 513 // Allocate the memory descriptor needed to retrieve the CSW. 514 fBulkOnlyCSWMemoryDescriptor = IOMemoryDescriptor::withAddress ( 515 &fBulkOnlyCommandRequestBlock.boCSW, 516 kByteCountOfCSW, 517 kIODirectionIn ); 518 require_nonzero ( fBulkOnlyCSWMemoryDescriptor, abortStart ); 519 520 result = fBulkOnlyCSWMemoryDescriptor->prepare(); 521 require_success ( result, abortStart ); 522 523 } 524 break; 525 526 default: 527 { 528 RecordUSBTimeStamp ( UMC_TRACE ( kNoProtocolForDevice ), 529 ( uintptr_t ) this, NULL, NULL, NULL ); 530 531 // The device has a protocol that the driver does not 532 // support. Return false to indicate that instantiation was 533 // not successful. 534 goto abortStart; 535 } 536 break; 537 } 538 539 // Find the Bulk In pipe for the device 540 STATUS_LOG ( ( 7, "%s[%p]: find bulk in pipe", getName(), this ) ); 541 request.type = kUSBBulk; 542 request.direction = kUSBIn; 543 fBulkInPipe = GetInterfaceReference()->FindNextPipe ( NULL, &request, true ); 544 require_nonzero ( fBulkInPipe, abortStart ); 545 546 // Find the Bulk Out pipe for the device 547 STATUS_LOG ( ( 7, "%s[%p]: find bulk out pipe", getName(), this ) ); 548 request.type = kUSBBulk; 549 request.direction = kUSBOut; 550 fBulkOutPipe = GetInterfaceReference()->FindNextPipe ( NULL, &request, true ); 551 require_nonzero ( fBulkOutPipe, abortStart ); 552 553 // Build the Protocol Characteristics dictionary since not all devices will have a 554 // SCSI Peripheral Device Nub to guarantee its existance. 555 characterDict = OSDynamicCast ( OSDictionary, getProperty ( kIOPropertyProtocolCharacteristicsKey ) ); 556 if ( characterDict == NULL ) 557 { 558 characterDict = OSDictionary::withCapacity ( 1 ); 559 } 560 561 else 562 { 563 characterDict->retain ( ); 564 } 565 566 require_nonzero ( characterDict, abortStart ); 567 568 obj = getProperty ( kIOPropertyPhysicalInterconnectTypeKey ); 569 if ( obj != NULL ) 570 { 571 characterDict->setObject ( kIOPropertyPhysicalInterconnectTypeKey, obj ); 572 } 573 574 obj = getProperty ( kIOPropertyPhysicalInterconnectLocationKey ); 575 if ( obj != NULL ) 576 { 577 characterDict->setObject ( kIOPropertyPhysicalInterconnectLocationKey, obj ); 578 } 579 580 // Check to see if this device is internal or not. The results of this check if successful 581 // will override location data provided in IOKit personalities. 582 if ( IsPhysicalInterconnectLocationInternal ( ) ) 583 { 584 585 OSString * internalString = NULL; 586 587 588 internalString = OSString::withCString ( kIOPropertyInternalKey ); 589 if ( internalString != NULL ) 590 { 591 592 characterDict->setObject ( kIOPropertyPhysicalInterconnectLocationKey, internalString ); 593 internalString->release ( ); 594 internalString = NULL; 595 596 } 597 598 } 599 600 obj = getProperty ( kIOPropertyReadTimeOutDurationKey ); 601 if ( obj != NULL ) 602 { 603 characterDict->setObject ( kIOPropertyReadTimeOutDurationKey, obj ); 604 } 605 else 606 { 607 608 number = OSNumber::withNumber ( kDefaultReadTimeoutDuration, 32 ); 609 if ( number != NULL ) 610 { 611 612 characterDict->setObject ( kIOPropertyReadTimeOutDurationKey, number ); 613 number->release ( ); 614 number = NULL; 615 616 } 617 618 } 619 620 obj = getProperty ( kIOPropertyWriteTimeOutDurationKey ); 621 if ( obj != NULL ) 622 { 623 characterDict->setObject ( kIOPropertyWriteTimeOutDurationKey, obj ); 624 } 625 else 626 { 627 628 number = OSNumber::withNumber ( kDefaultWriteTimeoutDuration, 32 ); 629 if ( number != NULL ) 630 { 631 632 characterDict->setObject ( kIOPropertyWriteTimeOutDurationKey, number ); 633 number->release ( ); 634 number = NULL; 635 636 } 637 638 } 639 640 setProperty ( kIOPropertyProtocolCharacteristicsKey, characterDict ); 641 642 characterDict->release ( ); 643 characterDict = NULL; 644 645 STATUS_LOG ( ( 6, "%s[%p]: successfully configured", getName(), this ) ); 646 647#if defined (__i386__) || defined (__x86_64__) 648 { 649 // As USB booting is only supporting on i386 based, do not compile for PPC. 650 char usbDeviceAddress [ kUSBDAddressLength ]; 651 OSNumber * usbDeviceID; 652 653 snprintf ( usbDeviceAddress, kUSBDAddressLength, "%x", ( int ) GetInterfaceReference()->GetDevice()->GetAddress() ); 654 655 usbDeviceID = OSNumber::withNumber ( ( int ) GetInterfaceReference()->GetDevice()->GetAddress(), 64 ); 656 if ( usbDeviceID != NULL ) 657 { 658 659 setProperty ( kIOPropertyIOUnitKey, usbDeviceID ); 660 setLocation ( ( const char * ) usbDeviceAddress, gIODTPlane ); 661 662 usbDeviceID->release ( ); 663 664 } 665 } 666#endif 667 668 669 // Device configured. We're attached. 670 fDeviceAttached = true; 671 672 InitializePowerManagement ( GetInterfaceReference() ); 673 674 success = BeginProvidedServices(); 675 require ( success, abortStart ); 676 677 retVal = true; 678 goto Exit; 679 680abortStart: 681 682 STATUS_LOG ( ( 1, "%s[%p]: aborting startup. Stop the provider.", getName(), this ) ); 683 684 if ( IsPowerManagementIntialized() ) 685 { 686 687 PMstop(); 688 689 } 690 691 // Close and nullify our USB Interface. 692 { 693 IOUSBInterface * currentInterface; 694 695 currentInterface = GetInterfaceReference(); 696 697 if ( currentInterface != NULL ) 698 { 699 700 SetInterfaceReference( NULL ); 701 currentInterface->close( this ); 702 703 } 704 705 } 706 707 if ( fCBIMemoryDescriptor != NULL ) 708 { 709 fCBIMemoryDescriptor->complete(); 710 fCBIMemoryDescriptor->release(); 711 fCBIMemoryDescriptor = NULL; 712 } 713 714 if ( fBulkOnlyCBWMemoryDescriptor != NULL ) 715 { 716 fBulkOnlyCBWMemoryDescriptor->complete(); 717 fBulkOnlyCBWMemoryDescriptor->release(); 718 fBulkOnlyCBWMemoryDescriptor = NULL; 719 } 720 721 if ( fBulkOnlyCSWMemoryDescriptor != NULL ) 722 { 723 fBulkOnlyCSWMemoryDescriptor->complete(); 724 fBulkOnlyCSWMemoryDescriptor->release(); 725 fBulkOnlyCSWMemoryDescriptor = NULL; 726 } 727 728 // Call the stop method to clean up any allocated resources. 729 stop ( provider ); 730 731Exit: 732 733 return retVal; 734 735} 736 737//-------------------------------------------------------------------------------------------------- 738// stop - Called at stop time [PUBLIC] 739//-------------------------------------------------------------------------------------------------- 740 741void 742IOUSBMassStorageClass::stop ( IOService * provider ) 743{ 744 // I am logging this as a 1 because if anything is logging after this we want to know about it. 745 // This should be the last message we see. Bye bye! 746 STATUS_LOG ( ( 1, "%s[%p]: stop: Called", getName(), this ) ); 747 748 RecordUSBTimeStamp ( UMC_TRACE ( kIOUSBMassStorageClassStop ), 749 ( uintptr_t ) this, NULL, NULL, NULL ); 750 751 EndProvidedServices ( ); 752 753 // Release and NULL our pipe pointers so we don't try to access our provider. 754 755 if ( fBulkInPipe != NULL ) 756 { 757 758 fBulkInPipe->release ( ); 759 fBulkInPipe = NULL; 760 761 } 762 763 if ( fBulkOutPipe != NULL ) 764 { 765 766 fBulkOutPipe->release ( ); 767 fBulkOutPipe = NULL; 768 769 } 770 771 if ( fInterruptPipe != NULL ) 772 { 773 774 fInterruptPipe->release ( ); 775 fInterruptPipe = NULL; 776 777 } 778 779 // Release our retain on the provider's workLoop. 780 781 super::stop ( provider ); 782} 783 784 785//-------------------------------------------------------------------------------------------------- 786// free - Called by IOKit to free any resources. [PUBLIC] 787//-------------------------------------------------------------------------------------------------- 788 789void 790IOUSBMassStorageClass::free ( void ) 791{ 792 793 STATUS_LOG ( ( 1, "%s[%p]: free: Called", getName(), this ) ); 794 795#ifndef EMBEDDED 796require_nonzero ( reserved, Exit ); 797#endif // EMBEDDED 798 799 // Since fClients is defined as reserved->fClients we don't want 800 // to dereference it unless reserved is non-NULL. 801 if ( fClients != NULL ) 802 { 803 804 fClients->release ( ); 805 fClients = NULL; 806 807 } 808 809 if ( fCBIMemoryDescriptor != NULL ) 810 { 811 812 fCBIMemoryDescriptor->complete ( ); 813 fCBIMemoryDescriptor->release ( ); 814 fCBIMemoryDescriptor = NULL; 815 816 } 817 818 if ( fBulkOnlyCBWMemoryDescriptor != NULL ) 819 { 820 821 fBulkOnlyCBWMemoryDescriptor->complete ( ); 822 fBulkOnlyCBWMemoryDescriptor->release ( ); 823 fBulkOnlyCBWMemoryDescriptor = NULL; 824 825 } 826 827 if ( fBulkOnlyCSWMemoryDescriptor != NULL ) 828 { 829 830 fBulkOnlyCSWMemoryDescriptor->complete ( ); 831 fBulkOnlyCSWMemoryDescriptor->release ( ); 832 fBulkOnlyCSWMemoryDescriptor = NULL; 833 834 } 835 836#ifndef EMBEDDED 837 IOFree ( reserved, sizeof ( ExpansionData ) ); 838 reserved = NULL; 839 840Exit: 841#endif // EMBEDDED 842 843 844 super::free ( ); 845 846} 847 848 849//-------------------------------------------------------------------------------------------------- 850// message - Called by IOKit to deliver messages. [PUBLIC] 851//-------------------------------------------------------------------------------------------------- 852 853IOReturn 854IOUSBMassStorageClass::message ( UInt32 type, IOService * provider, void * argument ) 855{ 856 IOReturn result = kIOReturnSuccess; 857 858 RecordUSBTimeStamp ( UMC_TRACE ( kMessagedCalled ), ( uintptr_t ) this, type, NULL, NULL ); 859 860 STATUS_LOG ( ( 4, "%s[%p]: message = %lx called", getName ( ), this, type ) ); 861 switch ( type ) 862 { 863 864 case kIOUSBMessagePortHasBeenResumed: 865 { 866 867 STATUS_LOG ( ( 2, "%s[%p]: message kIOUSBMessagePortHasBeenResumed.", getName ( ), this ) ); 868 869#ifndef EMBEDDED 870 if ( fRequiresResetOnResume == true ) 871 { 872 result = ResetDeviceNow ( true ); 873 } 874#else // EMBEDDED 875 result = ResetDeviceNow ( true ); 876#endif // EMBEDDED 877 878 } 879 break; 880 881 case kIOUSBMessageCompositeDriverReconfigured: 882 { 883 fWaitingForReconfigurationMessage = false; 884 } 885 break; 886 887 default: 888 { 889 STATUS_LOG ( ( 2, "%s[%p]: message default case.", getName ( ), this ) ); 890 result = super::message ( type, provider, argument ); 891 } 892 893 } 894 895 return result; 896 897} 898 899 900//-------------------------------------------------------------------------------------------------- 901// willTerminate [PUBLIC] 902//-------------------------------------------------------------------------------------------------- 903 904bool 905IOUSBMassStorageClass::willTerminate ( IOService * provider, 906 IOOptionBits options ) 907{ 908 909 STATUS_LOG ( ( 2, "%s[%p]: willTerminate called.", getName ( ), this ) ); 910 911 RecordUSBTimeStamp ( UMC_TRACE ( kWillTerminateCalled ), 912 ( uintptr_t ) this, ( uintptr_t ) GetInterfaceReference ( ), 913 ( unsigned int ) isInactive ( ), NULL ); 914 915 // Mark ourselves as terminating so we don't accept any additional I/O. 916 fTerminating = true; 917 918 // Let clients know that the device is gone. 919 SendNotification_DeviceRemoved ( ); 920 921 return super::willTerminate ( provider, options ); 922 923} 924 925 926//-------------------------------------------------------------------------------------------------- 927// didTerminate [PUBLIC] 928//-------------------------------------------------------------------------------------------------- 929 930bool 931IOUSBMassStorageClass::didTerminate ( IOService * provider, IOOptionBits options, bool * defer ) 932{ 933 934 IOUSBInterface * currentInterface; 935 IOReturn status; 936 bool success; 937 938 // This method comes at the end of the termination sequence. Hopefully, all of our outstanding IO is complete 939 // in which case we can just close our provider and IOKit will take care of the rest. Otherwise, we need to 940 // hold on to the device and IOKit will terminate us when we close it later. 941 942 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Entered with options=0x%x defer=%d", getName ( ), this, options, ( defer ? *defer : false ) ) ); 943 944 // Abort pipes to ensure that any outstanding USB requests are returned to us. 945 // For USB it is the responsibility of the client driver to request outstanding 946 // I/O requests be returned once driver termination has been initiated. 947 948 if ( fBulkInPipe != NULL ) 949 { 950 fBulkInPipe->Abort ( ); 951 } 952 953 if ( fBulkOutPipe != NULL ) 954 { 955 fBulkOutPipe->Abort ( ); 956 } 957 958 if ( fInterruptPipe != NULL ) 959 { 960 fInterruptPipe->Abort ( ); 961 } 962 963 // If we have a SCSI task outstanding, we will block here until it completes. 964 // This ensures that we don't try to send requests to our provider after we have closed it. 965 fTerminationDeferred = fBulkOnlyCommandStructInUse | fCBICommandStructInUse; 966 967 RecordUSBTimeStamp ( UMC_TRACE ( kDidTerminateCalled ), 968 ( uintptr_t ) this, ( unsigned int ) fTerminationDeferred, NULL, NULL ); 969 970 while ( fTerminationDeferred == true ) 971 { 972 973 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Sleeping on fTerminationDeferred", getName ( ), this ) ); 974 status = fCommandGate->commandSleep ( &fTerminationDeferred, THREAD_UNINT ); 975 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Awoke with status=0x%x fTerminationDeferred=%d", getName ( ), this, status, fTerminationDeferred ) ); 976 977 } 978 979 // Close our provider, and clear our reference to it. 980 currentInterface = GetInterfaceReference ( ); 981 require_nonzero ( currentInterface, ErrorExit ); 982 983 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Closing provider", getName ( ), this ) ); 984 SetInterfaceReference ( NULL ); 985 currentInterface->close ( this ); 986 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Closed provider", getName ( ), this ) ); 987 988 989#ifndef EMBEDDED 990 // Make sure that if we had a max bus stall requirement set that we clear it before 991 // terminating. Waiting on fTerminationDeferred should have ensured that this should 992 // never happen, but just in case. 993 if ( fRequiredMaxBusStall != 0 ) 994 { 995 996 // As this is an exceptional case we should panic on debug builds so that we can 997 // better deduce how we got into this state. 998 PANIC_NOW ( ( "IOUSBMassStorageClass::didTerminate fRequiredMaxBusStall != 0 after waiting for all I/O to complete" ) ); 999 1000 requireMaxBusStall ( 0 ); 1001 fRequiredMaxBusStall = 0; 1002 1003 } 1004#endif // EMBEDDED 1005 1006 1007ErrorExit: 1008 1009 1010 success = super::didTerminate ( provider, options, defer ); 1011 1012 STATUS_LOG ( ( 3 , "%s[%p]::didTerminate: Returning success=%d defer=%d", getName ( ), this, success, ( defer ? *defer : false ) ) ); 1013 1014 return success; 1015 1016} 1017 1018 1019#ifndef EMBEDDED 1020 1021//-------------------------------------------------------------------------------------------------- 1022// systemWillShutdown [PUBLIC] 1023//-------------------------------------------------------------------------------------------------- 1024 1025void 1026IOUSBMassStorageClass::systemWillShutdown ( IOOptionBits specifier ) 1027{ 1028 1029 STATUS_LOG ( ( 3 , "%s[%p]::systemWillShutdown: specifier = 0x%x fSuspendOnReboot = %s", getName ( ), this, specifier, fSuspendOnReboot ? "true" : "false" ) ); 1030 1031 if ( ( fSuspendOnReboot == true ) && ( ( specifier == kIOMessageSystemWillRestart ) || ( specifier == kIOMessageSystemWillPowerOff ) ) ) 1032 { 1033 1034 SuspendPort ( true ); 1035 1036 } 1037 1038 super::systemWillShutdown ( specifier ); 1039 1040} 1041 1042#endif // EMBEDDED 1043 1044 1045//-------------------------------------------------------------------------------------------------- 1046// BeginProvidedServices [PROTECTED] 1047//-------------------------------------------------------------------------------------------------- 1048 1049bool 1050IOUSBMassStorageClass::BeginProvidedServices ( void ) 1051{ 1052 1053 // If this is a BO device that supports multiple LUNs, we will need 1054 // to spawn off a nub for each valid LUN. If this is a CBI/CB 1055 // device or a BO device that only supports LUN 0, this object can 1056 // register itself as the nub. 1057 STATUS_LOG ( ( 7, "%s[%p]: Determine the maximum LUN", getName(), this ) ); 1058 1059 if ( GetInterfaceProtocol() == kProtocolBulkOnly ) 1060 { 1061 IOReturn status = kIOReturnError; 1062 bool maxLUNDetermined = false; 1063 OSDictionary * characterDict = NULL; 1064 1065 1066 // Before we issue the GetMaxLUN call let's check if this device 1067 // specifies a MaxLogicalUnitNumber as part of its personality. 1068 characterDict = OSDynamicCast ( OSDictionary, getProperty ( kIOUSBMassStorageCharacteristics ) ); 1069 if ( characterDict != NULL ) 1070 { 1071 1072 OSNumber * maxLUN = OSDynamicCast ( OSNumber, 1073 characterDict->getObject ( kIOUSBMassStorageMaxLogicalUnitNumber ) ); 1074 1075 if( maxLUN != NULL ) 1076 { 1077 1078 RecordUSBTimeStamp ( UMC_TRACE ( kBOPreferredMaxLUN ), 1079 ( uintptr_t ) this, maxLUN->unsigned8BitValue(), NULL, NULL ); 1080 1081 STATUS_LOG ( ( 4, "%s[%p]: Number of LUNs %u.", getName(), this, maxLUN->unsigned8BitValue() ) ); 1082 1083 SetMaxLogicalUnitNumber ( maxLUN->unsigned8BitValue() ); 1084 maxLUNDetermined = true; 1085 1086 } 1087 1088 } 1089 1090 if( maxLUNDetermined == false ) 1091 { 1092 // The device is a Bulk Only transport device, issue the 1093 // GetMaxLUN call to determine what the maximum value is. 1094 bool triedReset = false; 1095 UInt8 clearPipeAttempts = 0; 1096 1097 // We want to loop until we get a satisfactory response to GetMaxLUN, either an answer or failure. 1098 while ( status != kIOReturnSuccess ) 1099 { 1100 1101 // Build the USB command 1102 fUSBDeviceRequest.bmRequestType = USBmakebmRequestType( kUSBIn, kUSBClass, kUSBInterface ); 1103 fUSBDeviceRequest.bRequest = 0xFE; 1104 fUSBDeviceRequest.wValue = 0; 1105 fUSBDeviceRequest.wIndex = GetInterfaceReference()->GetInterfaceNumber(); 1106 fUSBDeviceRequest.wLength = 1; 1107 fUSBDeviceRequest.pData = &fMaxLogicalUnitNumber; 1108 1109 STATUS_LOG ( ( 4, "%s[%p]: Issuing device request to find max LUN", getName(), this ) ); 1110 1111 // Send the command over the control endpoint 1112 status = GetInterfaceReference()->DeviceRequest ( &fUSBDeviceRequest ); 1113 1114 RecordUSBTimeStamp ( UMC_TRACE ( kBOGetMaxLUNReturned ), 1115 ( uintptr_t ) this, status, fMaxLogicalUnitNumber, ( unsigned int ) triedReset ); 1116 1117 STATUS_LOG ( ( 4, "%s[%p]: DeviceRequest GetMaxLUN returned status = %x", getName(), this, status ) ); 1118 1119 if ( status != kIOReturnSuccess ) 1120 { 1121 1122 SetMaxLogicalUnitNumber( 0 ); 1123 if( ( status == kIOUSBPipeStalled ) && ( clearPipeAttempts < 3 ) ) 1124 { 1125 1126 UInt8 eStatus[2]; 1127 1128 STATUS_LOG ( ( 4, "%s[%p]: calling GetStatusEndpointStatus to clear stall", getName(), this ) ); 1129 1130 // Throw in an extra Get Status to clear up devices that stall the 1131 // control pipe like the early Iomega devices. 1132 GetStatusEndpointStatus( GetControlPipe(), &eStatus[0], NULL); 1133 1134 clearPipeAttempts++; 1135 1136 } 1137 else if ( ( status == kIOReturnNotResponding ) && ( triedReset == false ) ) 1138 { 1139 1140 // The device isn't responding. Let us reset the device, and try again. 1141 1142 STATUS_LOG ( ( 4, "%s[%p]: BeginProvidedServices: device not responding, reseting.", getName(), this ) ); 1143 1144 // Reset the device on its own thread so we don't deadlock. 1145 status = ResetDeviceNow ( true ); 1146 1147 triedReset = true; 1148 1149 } 1150 else 1151 { 1152 break; 1153 } 1154 1155 } 1156 1157 } 1158 1159 } 1160 1161 } 1162 else 1163 { 1164 // CBI and CB protocols do not support LUNs so for these the 1165 // maximum LUN will always be zero. 1166 SetMaxLogicalUnitNumber( 0 ); 1167 } 1168 1169 RecordUSBTimeStamp ( UMC_TRACE ( kLUNConfigurationComplete ), 1170 ( uintptr_t ) this, GetMaxLogicalUnitNumber ( ), NULL, NULL ); 1171 1172 STATUS_LOG ( ( 5, "%s[%p]: Configured, Max LUN = %d", getName(), this, GetMaxLogicalUnitNumber() ) ); 1173 1174 // If this is a BO device that supports multiple LUNs, we will need 1175 // to spawn off a nub for each valid LUN. If this is a CBI/CB 1176 // device or a BO device that only supports LUN 0, this object can 1177 // register itself as the nub. 1178 if ( GetMaxLogicalUnitNumber() > 0 ) 1179 { 1180 // Allocate space for our set that will keep track of the LUNs. 1181 fClients = OSSet::withCapacity ( GetMaxLogicalUnitNumber() + 1 ); 1182 1183 for( int loopLUN = 0; loopLUN <= GetMaxLogicalUnitNumber(); loopLUN++ ) 1184 { 1185 STATUS_LOG ( ( 6, "%s[%p]::CreatePeripheralDeviceNubForLUN entering.", getName(), this ) ); 1186 1187 IOSCSILogicalUnitNub * nub = OSTypeAlloc( IOSCSILogicalUnitNub ); 1188 1189 if( nub == NULL ) 1190 { 1191 PANIC_NOW ( ( "IOUSBMassStorageClass::CreatePeripheralDeviceNubForLUN failed" ) ); 1192 return false; 1193 } 1194 1195 if ( nub->init( 0 ) == false ) 1196 { 1197 // Release our nub before we return so we don't leak... 1198 nub->release(); 1199 // We didn't init successfully so we should return false. 1200 return false; 1201 } 1202 1203 if ( nub->attach( this ) == false ) 1204 { 1205 if( isInactive() == false ) 1206 { 1207 // panic since the nub can't attach and we are active 1208 PANIC_NOW ( ( "IOUSBMassStorageClass::CreatePeripheralDeviceNubForLUN unable to attach nub" ) ); 1209 } 1210 1211 // Release our nub before we return so we don't leak... 1212 nub->release(); 1213 // We didn't attach so we should return false. 1214 return false; 1215 } 1216 1217 nub->SetLogicalUnitNumber ( loopLUN ); 1218 if ( nub->start ( this ) == false ) 1219 { 1220 nub->detach ( this ); 1221 } 1222 else 1223 { 1224 nub->registerService ( kIOServiceAsynchronous ); 1225 } 1226 1227 nub->release(); 1228 nub = NULL; 1229 1230 STATUS_LOG ( ( 6, "%s[%p]::CreatePeripheralDeviceNubForLUN exiting.", getName(), this ) ); 1231 } 1232 } 1233 1234 // Calling registerService() will start driver matching and result in our handleOpen() method 1235 // being called by an IOSCSIPeripheralDeviceNub object. In the multi-LUN case in which our 1236 // nubs have already been instantiated (above), that open will fail because our MaxLogicalUnitNumber 1237 // is nonzero. In the single LUN case, the open will succeed and the rest of the storage stack 1238 // will be built upon it. 1239 registerService ( kIOServiceAsynchronous ); 1240 1241 return true; 1242 1243} 1244 1245 1246//-------------------------------------------------------------------------------------------------- 1247// EndProvidedServices [PROTECTED] 1248//-------------------------------------------------------------------------------------------------- 1249 1250bool 1251IOUSBMassStorageClass::EndProvidedServices 1252( void ) 1253{ 1254 return true; 1255} 1256 1257 1258#pragma mark - 1259#pragma mark *** CDB Transport Methods *** 1260#pragma mark - 1261 1262 1263//-------------------------------------------------------------------------------------------------- 1264// SendSCSICommand [PROTECTED] 1265//-------------------------------------------------------------------------------------------------- 1266 1267bool 1268IOUSBMassStorageClass::SendSCSICommand ( 1269 SCSITaskIdentifier request, 1270 SCSIServiceResponse * serviceResponse, 1271 SCSITaskStatus * taskStatus ) 1272{ 1273 1274 IOReturn status; 1275 SCSICommandDescriptorBlock cdbData; 1276 bool accepted = false; 1277 1278 STATUS_LOG ( ( 6, "%s[%p]: SendSCSICommand Entered with request=%p", getName ( ), this, request ) ); 1279 1280 // Close the commandGate, then check whether we can accept this new SCSI task. 1281 // If so, then atomically set the commandStructInUse flag. 1282 1283 fCommandGate->runAction ( OSMemberFunctionCast ( IOCommandGate::Action, 1284 this, 1285 &IOUSBMassStorageClass::AcceptSCSITask ), 1286 request, 1287 &accepted ); 1288 1289 require_quiet ( accepted, Exit ); 1290 1291 // Now that we have committed to accepting this task, we must return kSCSIServiceResponse_Request_In_Progress, 1292 // even if we subsequently fail that task from within this method via CommandCompleted(). 1293 1294 *taskStatus = kSCSITaskStatus_No_Status; 1295 *serviceResponse = kSCSIServiceResponse_Request_In_Process; 1296 1297 GetCommandDescriptorBlock( request, &cdbData ); 1298 1299 RecordUSBTimeStamp ( UMC_TRACE ( kCDBLog1 ), 1300 ( uintptr_t ) this, ( uintptr_t ) request, 1301 ( cdbData[ 0] ) | ( cdbData[ 1] << 8 ) | ( cdbData[ 2] << 16 ) | ( cdbData[ 3] << 24 ), 1302 ( cdbData[ 4] ) | ( cdbData[ 5] << 8 ) | ( cdbData[ 6] << 16 ) | ( cdbData[ 7] << 24 ) ); 1303 1304 RecordUSBTimeStamp ( UMC_TRACE ( kCDBLog2 ), 1305 ( uintptr_t ) this, ( uintptr_t ) request, 1306 ( cdbData[ 8] ) | ( cdbData[ 9] << 8 ) | ( cdbData[10] << 16 ) | ( cdbData[11] << 24 ), 1307 ( cdbData[12] ) | ( cdbData[13] << 8 ) | ( cdbData[14] << 16 ) | ( cdbData[15] << 24 ) ); 1308 1309#if USB_MASS_STORAGE_DEBUG 1310 1311 STATUS_LOG ( ( 4, "%s[%p]: SendSCSICommand CDB data: ", getName(), this ) ); 1312 1313 if ( GetCommandDescriptorBlockSize ( request ) == kSCSICDBSize_6Byte ) 1314 STATUS_LOG ( ( 4, "%s[%p]: %X : %X : %X : %X : %X : %X", 1315 getName(), this, cdbData[0], cdbData[1], 1316 cdbData[2], cdbData[3], cdbData[4], cdbData[5] ) ); 1317 else if ( GetCommandDescriptorBlockSize ( request ) == kSCSICDBSize_10Byte ) 1318 STATUS_LOG ( ( 4, "%s[%p]: %X : %X : %X : %X : %X : %X : %X : %X : %X : %X", 1319 getName(), this, cdbData[0], cdbData[1], 1320 cdbData[2], cdbData[3], cdbData[4], cdbData[5], 1321 cdbData[6], cdbData[7], cdbData[8], cdbData[9] ) ); 1322 else if ( GetCommandDescriptorBlockSize ( request ) == kSCSICDBSize_12Byte ) 1323 STATUS_LOG ( ( 4, "%s[%p]: %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X", 1324 getName(), this, cdbData[0], cdbData[1], 1325 cdbData[2], cdbData[3], cdbData[4], cdbData[5], 1326 cdbData[6], cdbData[7], cdbData[8], cdbData[9], 1327 cdbData[10], cdbData[11] ) ); 1328 else if ( GetCommandDescriptorBlockSize ( request ) == kSCSICDBSize_16Byte ) 1329 STATUS_LOG ( ( 4, "%s[%p]: %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X : %X", 1330 getName(), this, cdbData[0], cdbData[1], 1331 cdbData[2], cdbData[3], cdbData[4], cdbData[5], 1332 cdbData[6], cdbData[7], cdbData[8], cdbData[9], 1333 cdbData[10], cdbData[11], cdbData[12], cdbData[13], 1334 cdbData[14], cdbData[15] ) ); 1335#endif 1336 1337 require_action ( ( isInactive ( ) == false ), ErrorExit, status = kIOReturnNoDevice ); 1338 1339 if ( GetInterfaceProtocol() == kProtocolBulkOnly ) 1340 { 1341 1342 status = SendSCSICommandForBulkOnlyProtocol ( request ); 1343 1344 RecordUSBTimeStamp ( UMC_TRACE ( kBOSendSCSICommandReturned ), 1345 ( uintptr_t ) this, ( uintptr_t ) request, status, NULL ); 1346 1347 STATUS_LOG ( ( 5, "%s[%p]: SendSCSICommandforBulkOnlyProtocol returned %x", getName ( ), this, status ) ); 1348 1349 } 1350 1351 else 1352 { 1353 1354 status = SendSCSICommandForCBIProtocol ( request ); 1355 1356 RecordUSBTimeStamp ( UMC_TRACE ( kCBISendSCSICommandReturned ), 1357 ( uintptr_t ) this, ( uintptr_t ) request, status, NULL ); 1358 1359 STATUS_LOG ( ( 5, "%s[%p]: SendSCSICommandforCBIProtocol returned %x", getName ( ), this, status ) ); 1360 1361 } 1362 1363 // A nonzero status indicates that we could not post the USB CBW request to the device, probably due to termination. 1364 // In that case, we fail this task via a call to CommandCompleted(). 1365 // We never fail a task with an immediate serviceResponse, because the retain which ExecuteTask() took on us on 1366 // behalf of the SCSI task would never be released, preventing us from being freed. 1367 1368 1369ErrorExit: 1370 1371 1372 if ( status != kIOReturnSuccess ) 1373 { 1374 1375 SCSIServiceResponse localServiceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; 1376 SCSITaskStatus localTaskStatus = kSCSITaskStatus_DeliveryFailure; 1377 1378 STATUS_LOG ( ( 5, "%s[%p]: Failing immediately due to status=0x%x", getName ( ), this, status ) ); 1379 1380 // An error was seen which prevented the command from being sent. Fail the SCSI task. 1381 fCommandGate->runAction ( 1382 OSMemberFunctionCast ( IOCommandGate::Action, 1383 this, 1384 &IOUSBMassStorageClass::GatedCompleteSCSICommand ), 1385 request, 1386 ( void * ) &localServiceResponse, 1387 ( void * ) &localTaskStatus ); 1388 1389 } 1390 1391 1392Exit: 1393 1394 1395 STATUS_LOG ( ( 6, "%s[%p]: SendSCSICommand returning accepted=%d", getName ( ), this, accepted ) ); 1396 1397 return accepted; 1398 1399} 1400 1401 1402//-------------------------------------------------------------------------------------------------- 1403// CompleteSCSICommand [PROTECTED] 1404//-------------------------------------------------------------------------------------------------- 1405 1406void 1407IOUSBMassStorageClass::CompleteSCSICommand ( SCSITaskIdentifier request, IOReturn status ) 1408{ 1409 1410 SCSITaskStatus taskStatus; 1411 1412 check ( fWorkLoop->inGate ( ) == true ); 1413 1414 fBulkOnlyCommandStructInUse = false; 1415 fCBICommandStructInUse = false; 1416 1417 // Clear the count of consecutive I/Os which required a USB Device Reset. 1418 fConsecutiveResetCount = 0; 1419 1420 if ( status == kIOReturnSuccess ) 1421 { 1422 taskStatus = kSCSITaskStatus_GOOD; 1423 } 1424 else 1425 { 1426 1427 taskStatus = kSCSITaskStatus_CHECK_CONDITION; 1428 1429 // Make this error easier to see in the trace output. 1430 RecordUSBTimeStamp ( UMC_TRACE ( kCompletingCommandWithError ), ( uintptr_t ) this, NULL, NULL, NULL ); 1431 1432 } 1433 1434 STATUS_LOG ( ( 6, "%s[%p]: CompleteSCSICommand request=%p taskStatus=0x%02x", getName(), this, request, taskStatus ) ); 1435 1436 RecordUSBTimeStamp ( UMC_TRACE ( kCompleteSCSICommand ), 1437 ( uintptr_t ) this, ( uintptr_t ) request, 1438 kSCSIServiceResponse_TASK_COMPLETE, taskStatus ); 1439 1440 CommandCompleted ( request, kSCSIServiceResponse_TASK_COMPLETE, taskStatus ); 1441 1442 // If didTerminate() was called while this SCSI task was outstanding, then termination would 1443 // have been deferred until it completed. Check for that now, while behind the command gate. 1444 CheckDeferredTermination ( ); 1445 1446} 1447 1448 1449//-------------------------------------------------------------------------------------------------- 1450// AbortSCSICommand [PROTECTED] 1451//-------------------------------------------------------------------------------------------------- 1452 1453SCSIServiceResponse 1454IOUSBMassStorageClass::AbortSCSICommand ( SCSITaskIdentifier abortTask ) 1455{ 1456 1457 IOReturn status = kIOReturnSuccess; 1458 1459 STATUS_LOG ( ( 6, "%s[%p]: AbortSCSICommand was called", getName(), this ) ); 1460 if ( abortTask == NULL ) 1461 { 1462 // We were given an invalid SCSI Task object. Let the client know. 1463 STATUS_LOG ( ( 1, "%s[%p]: AbortSCSICommand was called with a NULL CDB object", getName(), this ) ); 1464 return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; 1465 } 1466 1467 if ( fTerminating == true ) 1468 { 1469 // We have an invalid interface, the device has probably been removed. 1470 // Nothing else to do except to report an error. 1471 STATUS_LOG ( ( 1, "%s[%p]: AbortSCSICommand was called with a NULL interface", getName(), this ) ); 1472 return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; 1473 } 1474 1475 RecordUSBTimeStamp ( UMC_TRACE( kAbortedTask ), 1476 ( uintptr_t ) this, ( uintptr_t ) abortTask, NULL, NULL ); 1477 1478 if ( GetInterfaceReference()->GetInterfaceProtocol() == kProtocolBulkOnly ) 1479 { 1480 status = AbortSCSICommandForBulkOnlyProtocol( abortTask ); 1481 STATUS_LOG ( ( 5, "%s[%p]: abortCDBforBulkOnlyProtocol returned %x", getName(), this, status ) ); 1482 } 1483 1484 else 1485 { 1486 status = AbortSCSICommandForCBIProtocol( abortTask ); 1487 STATUS_LOG ( ( 5, "%s[%p]: abortCDBforCBIProtocol returned %x", getName(), this, status ) ); 1488 } 1489 1490 // Since the driver currently does not support abort, return an error 1491 return kSCSIServiceResponse_FUNCTION_REJECTED; 1492 1493} 1494 1495 1496//-------------------------------------------------------------------------------------------------- 1497// IsProtocolServiceSupported [PROTECTED] 1498//-------------------------------------------------------------------------------------------------- 1499 1500bool 1501IOUSBMassStorageClass::IsProtocolServiceSupported ( 1502 SCSIProtocolFeature feature, 1503 void * serviceValue ) 1504{ 1505 1506 bool isSupported = false; 1507 OSDictionary * characterDict = NULL; 1508 IOUSBInterface * interfaceRef = NULL; 1509 IOUSBDevice * deviceRef = NULL; 1510 UInt8 deviceSpeed = 0; 1511 1512 // Check to see if we're super speed USB 3.0 device. If we are we can increase the size of the 1513 // maximum I/O size to something more befitting of a "super" speed bus. 1514 interfaceRef = GetInterfaceReference ( ); 1515 if ( interfaceRef != NULL ) 1516 { 1517 1518 deviceRef = interfaceRef->GetDevice ( ); 1519 if ( deviceRef != NULL ) 1520 { 1521 deviceSpeed = deviceRef->GetSpeed ( ); 1522 } 1523 1524 } 1525 1526 STATUS_LOG ( ( 6, "%s[%p]::IsProtocolServiceSupported called for feature=%d", getName ( ), this, feature ) ); 1527 1528 characterDict = OSDynamicCast ( OSDictionary, ( getProperty ( kIOPropertySCSIDeviceCharacteristicsKey ) ) ); 1529 1530 switch ( feature ) 1531 { 1532 1533 case kSCSIProtocolFeature_GetMaximumLogicalUnitNumber: 1534 { 1535 1536 * ( ( UInt32 * ) serviceValue ) = GetMaxLogicalUnitNumber ( ); 1537 isSupported = true; 1538 1539 } 1540 break; 1541 1542 // We must state our maximum byte counts, because the default values chosen by the 1543 // storage stack are too large for most USB devices. 1544 1545 case kSCSIProtocolFeature_MaximumReadTransferByteCount: 1546 { 1547 1548 UInt32 maxByteCount = kDefaultMaximumByteCountWrite; 1549 1550 // For super speed ( or faster ) devices we permit a larger I/O size. 1551 if ( deviceSpeed >= kUSBDeviceSpeedSuper ) 1552 { 1553 maxByteCount = kDefaultMaximumByteCountReadUSB3; 1554 } 1555 1556 if ( characterDict != NULL ) 1557 { 1558 1559 OSNumber * number = OSDynamicCast ( OSNumber, characterDict->getObject ( kIOMaximumByteCountReadKey ) ); 1560 if ( number != NULL) 1561 { 1562 1563 maxByteCount = number->unsigned32BitValue ( ); 1564 1565 } 1566 1567 } 1568 1569 *( ( UInt32 * ) serviceValue ) = maxByteCount; 1570 isSupported = true; 1571 1572 } 1573 break; 1574 1575 case kSCSIProtocolFeature_MaximumWriteTransferByteCount: 1576 { 1577 1578 UInt32 maxByteCount = kDefaultMaximumByteCountWrite; 1579 1580 // For super speed ( or faster ) devices we permit a larger I/O size. 1581 if ( deviceSpeed >= kUSBDeviceSpeedSuper ) 1582 { 1583 maxByteCount = kDefaultMaximumByteCountWriteUSB3; 1584 } 1585 1586 if ( characterDict != NULL ) 1587 { 1588 1589 OSNumber * number = OSDynamicCast ( OSNumber, characterDict->getObject ( kIOMaximumByteCountWriteKey ) ); 1590 if ( number != NULL) 1591 { 1592 1593 maxByteCount = number->unsigned32BitValue ( ); 1594 1595 } 1596 1597 } 1598 1599 *( ( UInt32 * ) serviceValue ) = maxByteCount; 1600 isSupported = true; 1601 1602 } 1603 break; 1604 1605 // We only state our maximum block counts if they are specified in the Device Characteristics dictionary. 1606 // Otherwise, we let the storage stack calculate the block counts from our byte counts. 1607 1608 case kSCSIProtocolFeature_MaximumReadBlockTransferCount: 1609 { 1610 1611 OSNumber * number = NULL; 1612 1613 require_quiet ( characterDict, Exit ); 1614 1615 number = OSDynamicCast ( OSNumber, characterDict->getObject ( kIOMaximumBlockCountReadKey ) ); 1616 require_quiet ( number, Exit ); 1617 1618 *( ( UInt32 * ) serviceValue ) = number->unsigned32BitValue ( ); 1619 isSupported = true; 1620 1621 } 1622 break; 1623 1624 case kSCSIProtocolFeature_MaximumWriteBlockTransferCount: 1625 { 1626 1627 OSNumber * number = NULL; 1628 1629 require_quiet ( characterDict, Exit ); 1630 1631 number = OSDynamicCast ( OSNumber, characterDict->getObject ( kIOMaximumBlockCountWriteKey ) ); 1632 require_quiet ( number, Exit ); 1633 1634 *( ( UInt32 * ) serviceValue ) = number->unsigned32BitValue ( ); 1635 isSupported = true; 1636 1637 } 1638 break; 1639 1640#ifndef EMBEDDED 1641 case kSCSIProtocolFeature_ProtocolSpecificPowerControl: 1642 { 1643 1644 if ( fPortSuspendResumeForPMEnabled == true ) 1645 { 1646 1647 STATUS_LOG ( ( 6, "%s[%p]::IsProtocolServiceSupported - fPortSuspendResumeForPMEnabled enabled", getName ( ), this ) ); 1648 isSupported = true; 1649 1650 } 1651 1652 if ( characterDict != NULL ) 1653 { 1654 1655 if ( characterDict->getObject ( kIOPropertyAutonomousSpinDownKey ) != NULL ) 1656 { 1657 1658 STATUS_LOG ( ( 6, "%s[%p]::IsProtocolServiceSupported - fAutonomousSpinDownWorkAround enabled", getName ( ), this ) ); 1659 1660 fAutonomousSpinDownWorkAround = true; 1661 isSupported = true; 1662 1663 } 1664 1665 } 1666 1667 } 1668 break; 1669#endif // EMBEDDED 1670 1671 default: 1672 break; 1673 1674 } 1675 1676 1677Exit: 1678 1679 1680 return isSupported; 1681 1682} 1683 1684 1685//-------------------------------------------------------------------------------------------------- 1686// HandleProtocolServiceFeature [PROTECTED] 1687//-------------------------------------------------------------------------------------------------- 1688 1689bool 1690IOUSBMassStorageClass::HandleProtocolServiceFeature ( 1691 SCSIProtocolFeature feature, 1692 void * serviceValue ) 1693{ 1694 1695 bool isSupported = false; 1696 1697 1698 STATUS_LOG ( ( 6, "%s[%p]::HandleProtocolServiceFeature called, feature=%lu", getName(), this, ( UInt32 ) feature ) ); 1699 1700 1701 switch ( feature ) 1702 { 1703 1704 case kSCSIProtocolFeature_ProtocolSpecificPowerControl: 1705 { 1706 1707 IOReturn status = kIOReturnError; 1708 UInt32 value = * ( UInt32 * ) serviceValue; 1709 1710 1711 // By having indicated support for this feature, the IOSAM layer calls this method during power 1712 // transitions, to allow us to perform any protocol-specific power handling in place of its 1713 // default power handling (e.g. - issue a START_STOP_UNIT command). 1714 1715 if ( fPortSuspendResumeForPMEnabled == true ) 1716 { 1717 1718 // This flag indicates that we should suspend the device when powering off, 1719 // and resume it when powering up. 1720 1721 if ( value == kSCSIProtocolPowerStateOff ) 1722 { 1723 1724 STATUS_LOG ( ( 6, "%s[%p]::HandleProtocolServiceFeature suspend port", getName(), this ) ); 1725 1726 // Suspend the port. 1727 status = SuspendPort ( true ); 1728 require ( ( status == kIOReturnSuccess ), Exit ); 1729 1730 } 1731 1732 if ( value == kSCSIProtocolPowerStateOn ) 1733 { 1734 1735 STATUS_LOG ( ( 6, "%s[%p]::HandleProtocolServiceFeature resume port", getName(), this ) ); 1736 1737 // Resume the port. 1738 status = SuspendPort ( false ); 1739 require ( ( status == kIOReturnSuccess ), Exit ); 1740 1741 } 1742 1743 isSupported = true; 1744 1745 } 1746 1747#ifndef EMBEDDED 1748 else if ( fAutonomousSpinDownWorkAround == true ) 1749 { 1750 1751 STATUS_LOG ( ( 6, "%s[%p]::HandleProtocolServiceFeature NOP START_STOP", getName(), this ) ); 1752 1753 // This a workaround for devices which spin themselves up/down and can't 1754 // properly handle START_STOP commands from the host when the drive is 1755 // already in the requested state. We need do nothing here - we've already 1756 // prevented IOSAM from issuing the START_STOP command. 1757 1758 isSupported = true; 1759 1760 } 1761#endif // EMBEDDED 1762 1763 } 1764 break; 1765 1766 // Default to super class. 1767 default: 1768 { 1769 1770 // Not a supported feature of this protocol. 1771 STATUS_LOG ( ( 6, "%s[%p]::HandleProtocolServiceFeature called for a feature we do not support", getName(), this ) ); 1772 1773 } 1774 break; 1775 1776 } 1777 1778 1779Exit: 1780 1781 return isSupported; 1782 1783} 1784 1785 1786#pragma mark - 1787#pragma mark *** Standard USB Command Methods *** 1788#pragma mark - 1789 1790 1791//-------------------------------------------------------------------------------------------------- 1792// ClearFeatureEndpointStall - Method to do the CLEAR_FEATURE command for 1793// an ENDPOINT_STALL feature. 1794// [PROTECTED] 1795//-------------------------------------------------------------------------------------------------- 1796 1797IOReturn 1798IOUSBMassStorageClass::ClearFeatureEndpointStall ( 1799 IOUSBPipe * thePipe, 1800 IOUSBCompletion * completion ) 1801{ 1802 1803 IOReturn status = kIOReturnInternalError; 1804 thread_t thread = NULL; 1805 1806 STATUS_LOG((5, "%s[%p]: ClearFeatureEndpointStall Entered with thePipe=%p", getName(), this, thePipe )); 1807 1808 if ( ( fTerminating == true ) || 1809 ( thePipe == NULL ) ) 1810 { 1811 // We're terminating, the device has probably been removed. 1812 // Nothing else to do except to report an error. 1813 status = kIOReturnDeviceError; 1814 goto Exit; 1815 } 1816 1817 // Use the fPotentiallyStalledPipe iVar to pass the stalled pipe to the spawned thread. 1818 fPotentiallyStalledPipe = thePipe; 1819 1820 // Verify the assumptions that the helper thread will make when finding the completion structure. 1821 if ( GetInterfaceProtocol() == kProtocolBulkOnly ) 1822 { 1823 require ( completion == &GetBulkOnlyRequestBlock()->boCompletion, Exit ); 1824 } 1825 1826 else 1827 { 1828 require ( completion == &GetCBIRequestBlock()->cbiCompletion, Exit ); 1829 } 1830 1831 // Increment the retain count here, in order to keep our object around while the spawned thread executes. 1832 // This retain will be balanced by a release in the spawned thread when it exits. 1833 retain(); 1834 1835 // Spawn a helper thread to actually clear the pipe stall, because some methods 1836 // may not be called from the USB completion thread. 1837 status = kernel_thread_start ( 1838 OSMemberFunctionCast ( thread_continue_t, this, &IOUSBMassStorageClass::ClearPipeStall ), 1839 this, 1840 &thread ); 1841 if ( status != kIOReturnSuccess ) 1842 { 1843 1844 // The thread won't run, so restore the state that it was supposed to do. 1845 release(); 1846 1847 } 1848 1849Exit: 1850 1851 STATUS_LOG ( ( 5, "%s[%p]: ClearFeatureEndpointStall returning status=0x%x thread=%p", getName(), this, status, thread ) ); 1852 1853 return status; 1854 1855} 1856 1857 1858//-------------------------------------------------------------------------------------------------- 1859// GetStatusEndpointStatus - Method to do the GET_STATUS command for the 1860// endpoint that the IOUSBPipe is connected to. 1861// [PROTECTED] 1862//-------------------------------------------------------------------------------------------------- 1863 1864IOReturn 1865IOUSBMassStorageClass::GetStatusEndpointStatus ( 1866 IOUSBPipe * thePipe, 1867 void * endpointStatus, 1868 IOUSBCompletion * completion ) 1869{ 1870 1871 IOReturn status; 1872 1873 if ( ( fTerminating == true ) || 1874 ( thePipe == NULL ) ) 1875 { 1876 // We're terminating, the device has probably been removed. 1877 // Nothing else to do except to report an error. 1878 return kIOReturnDeviceError; 1879 } 1880 1881 // Clear out the structure for the request 1882 bzero( &fUSBDeviceRequest, sizeof ( IOUSBDevRequest ) ); 1883 1884 // Build the USB command 1885 fUSBDeviceRequest.bmRequestType = USBmakebmRequestType ( kUSBIn, kUSBStandard, kUSBEndpoint ); 1886 fUSBDeviceRequest.bRequest = kUSBRqGetStatus; 1887 fUSBDeviceRequest.wValue = 0; // Zero is EndpointStall 1888 fUSBDeviceRequest.wIndex = thePipe->GetEndpointNumber(); 1889 1890 if ( thePipe == GetBulkInPipe() ) 1891 { 1892 fUSBDeviceRequest.wIndex |= 0x80; 1893 } 1894 1895 fUSBDeviceRequest.wLength = 2; 1896 fUSBDeviceRequest.pData = endpointStatus; 1897 1898 // Send the command over the control endpoint 1899 status = GetInterfaceReference()->DeviceRequest ( &fUSBDeviceRequest, completion ); 1900 STATUS_LOG ( ( 5, "%s[%p]: GetStatusEndpointStatus returned %x", getName(), this, status ) ); 1901 1902 RecordUSBTimeStamp ( UMC_TRACE ( kGetEndPointStatus ), 1903 ( uintptr_t ) this, status, 1904 thePipe->GetEndpointNumber(), NULL ); 1905 1906 return status; 1907 1908} 1909 1910#pragma mark - 1911#pragma mark *** Accessor Methods For All Protocol Variables *** 1912#pragma mark - 1913 1914 1915/* The following methods are for use only by this class */ 1916 1917 1918//-------------------------------------------------------------------------------------------------- 1919// GetInterfaceReference - Method to do the GET_STATUS command for the 1920// endpoint that the IOUSBPipe is connected to. 1921// [PROTECTED] 1922//-------------------------------------------------------------------------------------------------- 1923 1924IOUSBInterface * 1925IOUSBMassStorageClass::GetInterfaceReference ( void ) 1926{ 1927 1928 if ( fInterface == NULL ) 1929 { 1930 STATUS_LOG ( ( 2, "%s[%p]: GetInterfaceReference - Interface is NULL.", getName(), this ) ); 1931 } 1932 1933 return fInterface; 1934 1935} 1936 1937 1938//-------------------------------------------------------------------------------------------------- 1939// SetInterfaceReference [PROTECTED] 1940//-------------------------------------------------------------------------------------------------- 1941 1942void 1943IOUSBMassStorageClass::SetInterfaceReference ( IOUSBInterface * newInterface ) 1944{ 1945 fInterface = newInterface; 1946} 1947 1948 1949//-------------------------------------------------------------------------------------------------- 1950// GetInterfaceSubClass [PROTECTED] 1951//-------------------------------------------------------------------------------------------------- 1952 1953UInt8 1954IOUSBMassStorageClass::GetInterfaceSubclass ( void ) 1955{ 1956 return fPreferredSubclass; 1957} 1958 1959 1960//-------------------------------------------------------------------------------------------------- 1961// GetInterfaceProtocol [PROTECTED] 1962//-------------------------------------------------------------------------------------------------- 1963 1964UInt8 1965IOUSBMassStorageClass::GetInterfaceProtocol ( void ) 1966{ 1967 return fPreferredProtocol; 1968} 1969 1970 1971//-------------------------------------------------------------------------------------------------- 1972// GetControlPipe [PROTECTED] 1973//-------------------------------------------------------------------------------------------------- 1974 1975IOUSBPipe * 1976IOUSBMassStorageClass::GetControlPipe ( void ) 1977{ 1978 1979 if ( fTerminating == true ) 1980 { 1981 return NULL; 1982 } 1983 1984 return GetInterfaceReference()->GetDevice()->GetPipeZero(); 1985 1986} 1987 1988 1989//-------------------------------------------------------------------------------------------------- 1990// GetBulkInPipe [PROTECTED] 1991//-------------------------------------------------------------------------------------------------- 1992 1993IOUSBPipe * 1994IOUSBMassStorageClass::GetBulkInPipe ( void ) 1995{ 1996 return fBulkInPipe; 1997} 1998 1999 2000//-------------------------------------------------------------------------------------------------- 2001// GetBulkOutPipe [PROTECTED] 2002//-------------------------------------------------------------------------------------------------- 2003 2004IOUSBPipe * 2005IOUSBMassStorageClass::GetBulkOutPipe ( void ) 2006{ 2007 return fBulkOutPipe; 2008} 2009 2010 2011//-------------------------------------------------------------------------------------------------- 2012// GetInterruptPipe [PROTECTED] 2013//-------------------------------------------------------------------------------------------------- 2014 2015IOUSBPipe * 2016IOUSBMassStorageClass::GetInterruptPipe ( void ) 2017{ 2018 return fInterruptPipe; 2019} 2020 2021 2022//-------------------------------------------------------------------------------------------------- 2023// GetMaxLogicalUnitNumber [PROTECTED] 2024//-------------------------------------------------------------------------------------------------- 2025 2026UInt8 2027IOUSBMassStorageClass::GetMaxLogicalUnitNumber ( void ) const 2028{ 2029 return fMaxLogicalUnitNumber; 2030} 2031 2032 2033//-------------------------------------------------------------------------------------------------- 2034// SetMaxLogicalUnitNumber [PROTECTED] 2035//-------------------------------------------------------------------------------------------------- 2036 2037void 2038IOUSBMassStorageClass::SetMaxLogicalUnitNumber ( UInt8 maxLUN ) 2039{ 2040 fMaxLogicalUnitNumber = maxLUN; 2041} 2042 2043 2044#pragma mark - 2045#pragma mark *** Accessor Methods For CBI Protocol Variables *** 2046#pragma mark - 2047 2048 2049//-------------------------------------------------------------------------------------------------- 2050// GetCBIRequestBlock [PROTECTED] 2051//-------------------------------------------------------------------------------------------------- 2052 2053CBIRequestBlock * 2054IOUSBMassStorageClass::GetCBIRequestBlock ( void ) 2055{ 2056 2057 // Return a pointer to the CBIRequestBlock 2058 return &fCBICommandRequestBlock; 2059 2060} 2061 2062 2063//-------------------------------------------------------------------------------------------------- 2064// ReleaseCBIRequestBlock [PROTECTED] 2065//-------------------------------------------------------------------------------------------------- 2066 2067void 2068IOUSBMassStorageClass::ReleaseCBIRequestBlock ( CBIRequestBlock * cbiRequestBlock ) 2069{ 2070 2071 // Clear the request and completion to avoid possible double callbacks. 2072 cbiRequestBlock->request = NULL; 2073 2074 // Since we only allow one command and the CBIRequestBlock is 2075 // a member variable, no need to do anything. 2076 return; 2077 2078} 2079 2080#pragma mark - 2081#pragma mark *** Accessor Methods For Bulk Only Protocol Variables *** 2082#pragma mark - 2083 2084 2085//-------------------------------------------------------------------------------------------------- 2086// GetBulkOnlyRequestBlock [PROTECTED] 2087//-------------------------------------------------------------------------------------------------- 2088 2089BulkOnlyRequestBlock * 2090IOUSBMassStorageClass::GetBulkOnlyRequestBlock ( void ) 2091{ 2092 2093 // Return a pointer to the BulkOnlyRequestBlock 2094 return &fBulkOnlyCommandRequestBlock; 2095 2096} 2097 2098 2099//-------------------------------------------------------------------------------------------------- 2100// ReleaseBulkOnlyRequestBlock [PROTECTED] 2101//-------------------------------------------------------------------------------------------------- 2102 2103void 2104IOUSBMassStorageClass::ReleaseBulkOnlyRequestBlock ( BulkOnlyRequestBlock * boRequestBlock ) 2105{ 2106 2107 // Clear the request and completion to avoid possible double callbacks. 2108 boRequestBlock->request = NULL; 2109 2110 // Since we only allow one command and the BulkOnlyRequestBlock is 2111 // a member variable, no need to do anything. 2112 return; 2113 2114} 2115 2116 2117//-------------------------------------------------------------------------------------------------- 2118// GetNextBulkOnlyCommandTag [PROTECTED] 2119//-------------------------------------------------------------------------------------------------- 2120 2121UInt32 2122IOUSBMassStorageClass::GetNextBulkOnlyCommandTag ( void ) 2123{ 2124 2125 fBulkOnlyCommandTag++; 2126 2127 return fBulkOnlyCommandTag; 2128 2129} 2130 2131#pragma mark - 2132#pragma mark *** Miscellaneous Methods *** 2133#pragma mark - 2134 2135 2136//-------------------------------------------------------------------------------------------------- 2137// AcceptSCSITask [PRIVATE] 2138//-------------------------------------------------------------------------------------------------- 2139 2140IOReturn 2141IOUSBMassStorageClass::AcceptSCSITask ( SCSITaskIdentifier request, bool * accepted ) 2142{ 2143 2144 *accepted = false; 2145 2146 if ( GetInterfaceProtocol ( ) == kProtocolBulkOnly ) 2147 { 2148 2149 if ( fBulkOnlyCommandStructInUse == true ) 2150 { 2151 2152 RecordUSBTimeStamp ( UMC_TRACE ( kBOCommandAlreadyInProgress ), 2153 ( uintptr_t ) this, ( uintptr_t ) request, NULL, NULL ); 2154 goto Exit; 2155 2156 } 2157 2158 fBulkOnlyCommandStructInUse = true; 2159 2160 } 2161 2162 else 2163 { 2164 2165 if ( fCBICommandStructInUse == true ) 2166 { 2167 2168 RecordUSBTimeStamp ( UMC_TRACE ( kCBICommandAlreadyInProgress ), 2169 ( uintptr_t ) this, ( uintptr_t ) request, NULL, NULL ); 2170 2171 goto Exit; 2172 2173 } 2174 2175 fCBICommandStructInUse = true; 2176 2177 } 2178 2179 *accepted = true; 2180 2181 2182Exit: 2183 2184 2185 return kIOReturnSuccess; 2186 2187} 2188 2189 2190//-------------------------------------------------------------------------------------------------- 2191// CheckDeferredTermination [PRIVATE] 2192//-------------------------------------------------------------------------------------------------- 2193 2194void 2195IOUSBMassStorageClass::CheckDeferredTermination ( void ) 2196{ 2197 2198 require ( fWorkLoop->inGate ( ) == true, Exit ); 2199 2200 if ( fTerminationDeferred == true ) 2201 { 2202 2203 fTerminationDeferred = false; 2204 2205 STATUS_LOG ( ( 6, "%s[%p]: CheckDeferredTermination: Waking didTerminate thread", getName(), this ) ); 2206 2207 fCommandGate->commandWakeup ( &fTerminationDeferred, false ); 2208 2209 } 2210 2211 2212Exit: 2213 2214 2215 return; 2216 2217} 2218 2219 2220//-------------------------------------------------------------------------------------------------- 2221// GatedCompleteSCSICommand [PRIVATE] 2222//-------------------------------------------------------------------------------------------------- 2223 2224void 2225IOUSBMassStorageClass::GatedCompleteSCSICommand ( 2226 SCSITaskIdentifier request, 2227 SCSIServiceResponse * serviceResponse, 2228 SCSITaskStatus * taskStatus ) 2229{ 2230 2231 require ( request != NULL, Exit ); 2232 require ( serviceResponse != NULL, Exit ); 2233 require ( taskStatus != NULL, Exit ); 2234 2235 fBulkOnlyCommandStructInUse = false; 2236 fCBICommandStructInUse = false; 2237 2238 // Clear the count of consecutive I/Os which required a USB Device Reset. 2239 fConsecutiveResetCount = 0; 2240 2241 STATUS_LOG ( ( 4, "%s[%p]: GatedCompleteSCSICommand request=%p serviceResponse=%d taskStatus=0x%02x", getName(), this, request, *serviceResponse, *taskStatus ) ); 2242 2243 RecordUSBTimeStamp ( UMC_TRACE ( kCompleteSCSICommand ), 2244 ( uintptr_t ) this, ( uintptr_t ) request, 2245 *serviceResponse, *taskStatus ); 2246 2247 CommandCompleted ( request, *serviceResponse, *taskStatus ); 2248 2249 // If didTerminate() was called while this SCSI task was outstanding, then termination would 2250 // have been deferred until it completed. Check for that now, while behind the command gate. 2251 CheckDeferredTermination ( ); 2252 2253 2254Exit: 2255 2256 2257 return; 2258 2259} 2260 2261 2262//-------------------------------------------------------------------------------------------------- 2263// HandlePowerOn - Will get called when a device has been resumed [PUBLIC] 2264//-------------------------------------------------------------------------------------------------- 2265 2266IOReturn 2267IOUSBMassStorageClass::HandlePowerOn ( void ) 2268{ 2269 IOReturn status = kIOReturnSuccess; 2270#ifndef EMBEDDED 2271 UInt8 eStatus[2]; 2272 2273#endif // EMBEDDED 2274 2275 // The USB hub port that the device is connected to has been resumed, 2276 // check to see if the device is still responding correctly and if not, 2277 // fix it so that it is. 2278 STATUS_LOG(( 6, "%s[%p]: HandlePowerOn", getName(), this )); 2279 2280#ifndef EMBEDDED 2281 if ( ( GetStatusEndpointStatus ( GetBulkInPipe(), &eStatus[0], NULL ) != kIOReturnSuccess ) || 2282 ( fRequiresResetOnResume == true ) ) 2283 { 2284 2285 RecordUSBTimeStamp ( UMC_TRACE ( kHandlePowerOnUSBReset ), ( uintptr_t ) this, NULL, NULL, NULL ); 2286 2287 status = ResetDeviceNow ( true ); 2288 2289 } 2290#else // EMBEDDED 2291 status = ResetDeviceNow( true ); 2292#endif // EMBEDDED 2293 2294 // If our port was suspended before sleep, it would have been resumed as part 2295 // of the global resume on system wake. 2296 fPortIsSuspended = false; 2297 2298 return status; 2299 2300} 2301 2302 2303//-------------------------------------------------------------------------------------------------- 2304// handleOpen [PUBLIC] 2305//-------------------------------------------------------------------------------------------------- 2306 2307bool 2308IOUSBMassStorageClass::handleOpen ( IOService * client, 2309 IOOptionBits options, 2310 void * arg ) 2311{ 2312 2313 bool result = false; 2314 2315 2316 // If this is a normal open on a single LUN device. 2317 if ( GetMaxLogicalUnitNumber() == 0 ) 2318 { 2319 2320 result = super::handleOpen ( client, options, arg ); 2321 goto Exit; 2322 2323 } 2324 2325 // It's an open from a multi-LUN client 2326 require_nonzero ( fClients, ErrorExit ); 2327 require_nonzero ( OSDynamicCast ( IOSCSILogicalUnitNub, client ), ErrorExit ); 2328 result = fClients->setObject ( client ); 2329 2330 2331Exit: 2332ErrorExit: 2333 2334 2335 return result; 2336 2337} 2338 2339 2340//-------------------------------------------------------------------------------------------------- 2341// handleClose [PUBLIC] 2342//-------------------------------------------------------------------------------------------------- 2343 2344void 2345IOUSBMassStorageClass::handleClose ( IOService * client, 2346 IOOptionBits options ) 2347{ 2348 2349 if ( GetMaxLogicalUnitNumber() == 0 ) 2350 { 2351 super::handleClose ( client, options ); 2352 return; 2353 } 2354 2355 require_nonzero ( fClients, Exit ); 2356 2357 if ( fClients->containsObject ( client ) ) 2358 { 2359 fClients->removeObject( client ); 2360 2361 if ( ( fClients->getCount() == 0 ) && isInactive() ) 2362 { 2363 message ( kIOMessageServiceIsRequestingClose, getProvider(), 0 ); 2364 } 2365 } 2366 2367 2368Exit: 2369 2370 2371 return; 2372 2373} 2374 2375 2376//-------------------------------------------------------------------------------------------------- 2377// handleIsOpen [PUBLIC] 2378//-------------------------------------------------------------------------------------------------- 2379 2380bool 2381IOUSBMassStorageClass::handleIsOpen ( const IOService * client ) const 2382{ 2383 2384 bool result = false; 2385 UInt8 lun = GetMaxLogicalUnitNumber(); 2386 2387 require_nonzero ( lun, CallSuperClass ); 2388 require_nonzero ( fClients, CallSuperClass ); 2389 2390 // General case (is anybody open) 2391 if ( ( client == NULL ) && ( fClients->getCount ( ) != 0 ) ) 2392 { 2393 result = true; 2394 } 2395 2396 else 2397 { 2398 // specific case (is this client open) 2399 result = fClients->containsObject ( client ); 2400 } 2401 2402 return result; 2403 2404 2405CallSuperClass: 2406 2407 2408 result = super::handleIsOpen ( client ); 2409 return result; 2410 2411} 2412 2413 2414//-------------------------------------------------------------------------------------------------- 2415// sWaitForReset [STATIC][PROTECTED] 2416//-------------------------------------------------------------------------------------------------- 2417 2418IOReturn 2419IOUSBMassStorageClass::sWaitForReset ( void * refcon ) 2420{ 2421 2422 return ( ( IOUSBMassStorageClass * ) refcon )->GatedWaitForReset(); 2423 2424} 2425 2426 2427//-------------------------------------------------------------------------------------------------- 2428// GatedWaitForReset [PROTECTED] 2429//-------------------------------------------------------------------------------------------------- 2430 2431IOReturn 2432IOUSBMassStorageClass::GatedWaitForReset ( void ) 2433{ 2434 2435 IOReturn status = kIOReturnSuccess; 2436 2437 while ( fResetInProgress == true ) 2438 { 2439 status = fCommandGate->commandSleep ( &fResetInProgress, THREAD_UNINT ); 2440 } 2441 2442 return status; 2443 2444} 2445 2446 2447#ifndef EMBEDDED 2448//-------------------------------------------------------------------------------------------------- 2449// sWaitForTaskAbort [STATIC][PROTECTED] 2450//-------------------------------------------------------------------------------------------------- 2451 2452IOReturn 2453IOUSBMassStorageClass::sWaitForTaskAbort ( void * refcon ) 2454{ 2455 return kIOReturnUnsupported; 2456} 2457 2458 2459//-------------------------------------------------------------------------------------------------- 2460// GatedWaitForTaskAbort [PROTECTED] 2461//-------------------------------------------------------------------------------------------------- 2462 2463IOReturn 2464IOUSBMassStorageClass::GatedWaitForTaskAbort ( void ) 2465{ 2466 return kIOReturnUnsupported; 2467} 2468#endif // EMBEDDED 2469 2470 2471//-------------------------------------------------------------------------------------------------- 2472// sResetDevice [STATIC][PROTECTED] 2473//-------------------------------------------------------------------------------------------------- 2474 2475void 2476IOUSBMassStorageClass::sResetDevice ( void * refcon ) 2477{ 2478 2479 IOUSBMassStorageClass * driver = NULL; 2480 IOUSBInterface * interfaceRef = NULL; 2481 IOUSBDevice * deviceRef = NULL; 2482 IOReturn status = kIOReturnError; 2483 thread_t thread = THREAD_NULL; 2484 UInt32 deviceInfo = 0; 2485 2486 driver = ( IOUSBMassStorageClass * ) refcon; 2487 require ( ( driver != NULL ), Exit ); 2488 2489 STATUS_LOG ( ( 4, "%s[%p]: sResetDevice Entered", driver->getName ( ), driver ) ); 2490 2491 // Check if we should bail out because we are 2492 // being terminated. 2493 if ( ( driver->fTerminating == true ) || 2494 ( driver->isInactive ( ) == true ) ) 2495 { 2496 2497 STATUS_LOG ( ( 2, "%s[%p]: sResetDevice - We are being terminated!", driver->getName ( ), driver ) ); 2498 RecordUSBTimeStamp ( UMC_TRACE ( kUSBDeviceResetWhileTerminating ), ( uintptr_t ) driver, 2499 ( unsigned int ) driver->fTerminating, ( unsigned int ) driver->isInactive ( ), NULL ); 2500 2501 goto ErrorExit; 2502 2503 } 2504 2505 interfaceRef = driver->GetInterfaceReference ( ); 2506 require ( ( interfaceRef != NULL ), ErrorExit ); 2507 2508 deviceRef = interfaceRef->GetDevice ( ); 2509 require ( ( deviceRef != NULL ), ErrorExit ); 2510 2511 // Check that we are still connected to the hub and that our port is enabled. 2512 status = deviceRef->GetDeviceInformation ( &deviceInfo ); 2513 STATUS_LOG ( ( 5, "%s[%p]: GetDeviceInfo returned status = %x deviceInfo = %x", driver->getName ( ), driver, status, deviceInfo ) ); 2514 RecordUSBTimeStamp ( UMC_TRACE ( kDeviceInformation ), ( uintptr_t ) driver, status, deviceInfo, NULL ); 2515 require_noerr ( status, ErrorExit ); 2516 2517 // If GetDeviceInformation ( ) failed, or if the device is no longer connected, or if the device 2518 // has been disabled by the IOUSBFamily, don't reset it. 2519 if ( ( ( deviceInfo & kUSBInformationDeviceIsConnectedMask ) == 0 ) || 2520 ( ( ( deviceInfo & kUSBInformationDeviceIsEnabledMask ) == 0 ) && ( ( deviceInfo & kUSBInformationDeviceIsInternalMask ) == 0 ) ) ) 2521 { 2522 2523 status = kIOReturnNoDevice; 2524 RecordUSBTimeStamp ( UMC_TRACE ( kUSBDeviceResetAfterDisconnect ), ( uintptr_t ) driver, NULL, NULL, NULL ); 2525 goto ErrorExit; 2526 2527 } 2528 2529 // Make sure our port isn't suspended, it shouldn't be, but just in case. 2530 // If the port is active this will be a NOP. 2531 if ( deviceInfo & kUSBInformationDeviceIsSuspendedMask ) 2532 { 2533 driver->SuspendPort ( false ); 2534 } 2535 2536 // Device is still attached. Lets try resetting it. 2537 status = deviceRef->ResetDevice(); 2538 STATUS_LOG ( ( 5, "%s[%p]: ResetDevice() returned = %x", driver->getName ( ), driver, status ) ); 2539 RecordUSBTimeStamp ( UMC_TRACE ( kUSBDeviceResetReturned ), ( uintptr_t ) driver, status, NULL, NULL ); 2540 require ( ( status == kIOReturnSuccess ), ErrorExit ); 2541 2542 // We successfully reset the device. Now we have to wait for the fWaitingForReconfigurationMessage 2543 // message in order for the reset process to be considered complete. If we resume activity prior 2544 // to receive the message our I/O may resume before the SET_CONFIGURATION following device reset 2545 // makes it to our device. 2546 driver->fWaitingForReconfigurationMessage = true; 2547 2548 // Reset host side data toggles. 2549 if ( driver->fBulkInPipe != NULL ) 2550 { 2551 driver->fBulkInPipe->ClearPipeStall ( false ); 2552 } 2553 2554 if ( driver->fBulkOutPipe != NULL ) 2555 { 2556 driver->fBulkOutPipe->ClearPipeStall ( false ); 2557 } 2558 2559 if ( driver->fInterruptPipe != NULL ) 2560 { 2561 driver->fInterruptPipe->ClearPipeStall ( false ); 2562 } 2563 2564 2565ErrorExit: 2566 2567 2568 STATUS_LOG ( ( 2, "%s[%p]: sResetDevice status=0x%x fResetInProgress=%d", driver->getName ( ), driver, status, driver->fResetInProgress ) ); 2569 2570 if ( status != kIOReturnSuccess ) 2571 { 2572 2573 // We set the device state to detached so the proper status for the 2574 // device is returned along with the aborted SCSITask. 2575 driver->fDeviceAttached = false; 2576 2577 // Let the clients know that the device is gone. 2578 driver->SendNotification_DeviceRemoved ( ); 2579 2580 } 2581 2582 else 2583 { 2584 2585 UInt16 timeout = 0; 2586 2587 while ( ( timeout < kIOUSBMassStorageReconfigurationTimeoutMS ) && 2588 ( driver->fWaitingForReconfigurationMessage == true ) ) 2589 { 2590 2591 // Hang out for a ms. 2592 IOSleep ( 1 ); 2593 2594 // Increment our timeout counter. 2595 timeout++; 2596 2597 } 2598 2599#ifndef EMBEDDED 2600 // Do we have a device which requires some to collect itself following a USB device reset? 2601 // We only do this if the device successfully reconfigured. 2602 if ( ( driver->fPostDeviceResetCoolDownInterval != 0 ) && 2603 ( driver->fWaitingForReconfigurationMessage == false ) ) 2604 { 2605 2606 // We do. Wait the prescribed amount of time. 2607 IOSleep ( driver->fPostDeviceResetCoolDownInterval ); 2608 2609 } 2610#endif // EMBEDDED 2611 2612 } 2613 2614 // We complete the failed I/O with kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE 2615 // and either kSCSITaskStatus_DeliveryFailure or kSCSITaskStatus_DeviceNotPresent, 2616 // as per the fDeviceAttached flag. 2617 driver->AbortCurrentSCSITask ( ); 2618 2619 // If the maximum number of unsuccessful resets has been exceeded, then terminate ourself. 2620 if ( driver->fDeviceAttached == false && ( driver->isInactive() == false ) ) 2621 { 2622 2623 // Leave behind some of evidence that there was a catastorphic failure which guided us to self termination. 2624 IOLog ( "[%p](%u)/(%u) Device not responding\n", driver, driver->fConsecutiveResetCount, kMaxConsecutiveResets ); 2625 2626 if ( driver->GetInterfaceReference() != NULL ) 2627 { 2628 driver->GetInterfaceReference()->setProperty ( "IOUSBMassStorageClass Detached", driver->fConsecutiveResetCount, 8 ); 2629 } 2630 2631 driver->fResetInProgress = false; 2632 2633 if ( driver->fBlockOnResetThread == false ) 2634 { 2635 driver->fResetStatus = kUSBResetStatusFailure; 2636 // Unblock our main thread. 2637 driver->fCommandGate->commandWakeup ( &driver->fResetInProgress, false ); 2638 2639 } 2640 // Terminate. 2641 driver->terminate(); 2642 2643 } 2644 2645 else 2646 2647 { 2648 2649 driver->fResetInProgress = false; 2650 2651 if ( driver->fBlockOnResetThread == false ) 2652 { 2653 driver->fResetStatus = kUSBResetStatusSuccess; 2654 // Unblock our main thread. 2655 driver->fCommandGate->commandWakeup ( &driver->fResetInProgress, false ); 2656 2657 } 2658 } 2659 2660 STATUS_LOG ( ( 6, "%s[%p]: sResetDevice exiting.", driver->getName ( ), driver ) ); 2661 2662 // We retained the driver in ResetDeviceNow() when 2663 // we created a thread for sResetDevice(). 2664 driver->release(); 2665 2666 2667Exit: 2668 2669 2670 // Terminate the thread. 2671 thread = current_thread ( ); 2672 if ( thread != THREAD_NULL ) 2673 { 2674 thread_deallocate ( thread ); 2675 thread_terminate ( thread ); 2676 } 2677 2678 return; 2679 2680} 2681 2682 2683#ifndef EMBEDDED 2684//-------------------------------------------------------------------------------------------------- 2685// sAbortCurrentSCSITask [STATIC][PROTECTED] 2686//-------------------------------------------------------------------------------------------------- 2687 2688void 2689IOUSBMassStorageClass::sAbortCurrentSCSITask ( void * refcon ) 2690{ 2691} 2692#endif // EMBEDDED 2693 2694 2695//-------------------------------------------------------------------------------------------------- 2696// ClearPipeStall - Method to recover from a pipe stall. 2697// 2698// This method runs on a helper thread because IOUSBPipe::ClearPipeStall() must 2699// not be called from the USB completion thread. 2700// [PRIVATE] 2701//-------------------------------------------------------------------------------------------------- 2702 2703void 2704IOUSBMassStorageClass::ClearPipeStall( void ) 2705{ 2706 2707 IOReturn status = kIOReturnBadArgument; 2708 IOUSBPipe * pipe; 2709 UInt8 endpointNumber; 2710 IOUSBCompletion * completion; 2711 IOUSBInterface * interfaceRef; 2712 thread_t thread; 2713 2714 STATUS_LOG ( ( 4, "%s[%p]: ClearPipeStall Entered with endpoint %d", getName ( ), this, fPotentiallyStalledPipe ? fPotentiallyStalledPipe->GetEndpointNumber() : -1 ) ); 2715 2716 // The pipe to be cleared is specified by instance variable. 2717 pipe = fPotentiallyStalledPipe; 2718 require ( ( pipe != NULL ), Exit ); 2719 2720 endpointNumber = pipe->GetEndpointNumber(); 2721 if ( pipe->GetDirection() == kUSBIn ) 2722 { 2723 endpointNumber |= 0x80; 2724 } 2725 2726 if ( fTerminating == true ) 2727 { 2728 status = kIOReturnOffline; 2729 goto Exit; 2730 } 2731 2732 // Make sure that the Data Toggles are reset before issuing the CLEAR_FEATURE device request. 2733 // This synchronous method must not be called from the USB completion thread. 2734 status = pipe->ClearPipeStall ( false ); 2735 require_success ( status, Exit ); 2736 2737 // Clear out the structure for the request 2738 bzero ( &fUSBDeviceRequest, sizeof ( IOUSBDevRequest ) ); 2739 2740 // Build the USB command 2741 fUSBDeviceRequest.bmRequestType = USBmakebmRequestType ( kUSBNone, kUSBStandard, kUSBEndpoint ); 2742 fUSBDeviceRequest.bRequest = kUSBRqClearFeature; 2743 fUSBDeviceRequest.wValue = kUSBFeatureEndpointStall; 2744 fUSBDeviceRequest.wIndex = endpointNumber; 2745 2746 // We assume that the relevent IOUSBCompletion block can be determined solely from the interface protocol. 2747 if ( GetInterfaceProtocol() == kProtocolBulkOnly ) 2748 { 2749 completion = &GetBulkOnlyRequestBlock()->boCompletion; 2750 } 2751 2752 else 2753 { 2754 completion = &GetCBIRequestBlock()->cbiCompletion; 2755 } 2756 2757 interfaceRef = GetInterfaceReference(); 2758 require ( interfaceRef != NULL, Exit ); 2759 2760 // Send the command over the control endpoint. Because we specify a completion argument, it executes 2761 // asynchronously, with a callback to the protocol-specific completion method. 2762 status = interfaceRef->DeviceRequest( &fUSBDeviceRequest, completion ); 2763 2764 RecordUSBTimeStamp ( UMC_TRACE ( kClearEndPointStall ), ( uintptr_t ) this, status, 2765 pipe->GetEndpointNumber(), NULL ); 2766 2767Exit: 2768 2769 STATUS_LOG ( ( 5, "%s[%p]: ClearPipeStall Returning with status=0x%x", getName(), this, status ) ); 2770 2771 // Decrement our retain count here, to balance the retain which occurred when our task was spawned. 2772 release(); 2773 2774 // Terminate our helper thread. 2775 thread = current_thread ( ); 2776 thread_deallocate ( thread ); 2777 thread_terminate ( thread ); 2778 2779} 2780 2781 2782#ifndef EMBEDDED 2783OSMetaClassDefineReservedUsed ( IOUSBMassStorageClass, 1 ); 2784 2785//-------------------------------------------------------------------------------------------------- 2786// StartDeviceRecovery - The recovery sequence to restore functionality for 2787// devices that stop responding (like many devices 2788// after a Suspend/Resume). [PROTECTED] 2789//-------------------------------------------------------------------------------------------------- 2790 2791IOReturn 2792IOUSBMassStorageClass::StartDeviceRecovery ( void ) 2793{ 2794 // First check to see if the device is still connected. 2795 UInt8 eStatus[2]; 2796 IOReturn status = kIOReturnError; 2797 2798 // The USB hub port that the device is connected to has been resumed, 2799 // check to see if the device is still responding correctly and if not, 2800 // fix it so that it is. 2801 STATUS_LOG ( ( 5, "%s[%p]: StartDeviceRecovery", getName(), this ) ); 2802 2803 if ( fBulkOnlyCommandStructInUse == true ) 2804 { 2805 // Set up the IOUSBCompletion structure 2806 fBulkOnlyCommandRequestBlock.boCompletion.target = this; 2807 fBulkOnlyCommandRequestBlock.boCompletion.action = &this->DeviceRecoveryCompletionAction; 2808 status = GetStatusEndpointStatus ( GetBulkInPipe(), &eStatus[0], &fBulkOnlyCommandRequestBlock.boCompletion); 2809 } 2810 2811 else if ( fCBICommandStructInUse == true ) 2812 { 2813 // Set up the IOUSBCompletion structure 2814 fCBICommandRequestBlock.cbiCompletion.target = this; 2815 fCBICommandRequestBlock.cbiCompletion.action = &this->DeviceRecoveryCompletionAction; 2816 status = GetStatusEndpointStatus ( GetBulkInPipe(), &eStatus[0], &fCBICommandRequestBlock.cbiCompletion); 2817 } 2818 2819 return status; 2820} 2821 2822OSMetaClassDefineReservedUsed ( IOUSBMassStorageClass, 2 ); 2823 2824 2825//-------------------------------------------------------------------------------------------------- 2826// FinishDeviceRecovery [PROTECTED] 2827//-------------------------------------------------------------------------------------------------- 2828 2829void 2830IOUSBMassStorageClass::FinishDeviceRecovery ( IOReturn status ) 2831{ 2832 (void) ResetDeviceNow( false ); 2833} 2834 2835 2836//-------------------------------------------------------------------------------------------------- 2837// DeviceRecoveryCompletionAction [PROTECTED] 2838//-------------------------------------------------------------------------------------------------- 2839 2840void 2841IOUSBMassStorageClass::DeviceRecoveryCompletionAction ( 2842 void * target, 2843 void * parameter, 2844 IOReturn status, 2845 UInt32 bufferSizeRemaining) 2846{ 2847 2848 UNUSED ( parameter ); 2849 UNUSED ( bufferSizeRemaining ); 2850 2851 IOUSBMassStorageClass * theMSC; 2852 2853 theMSC = ( IOUSBMassStorageClass * ) target; 2854 theMSC->FinishDeviceRecovery ( status ); 2855 2856} 2857#endif // EMBEDDED 2858 2859 2860//-------------------------------------------------------------------------------------------------- 2861// ResetDeviceNow [PROTECTED] 2862//-------------------------------------------------------------------------------------------------- 2863 2864IOReturn 2865IOUSBMassStorageClass::ResetDeviceNow ( bool waitForReset ) 2866{ 2867 2868 thread_t thread = THREAD_NULL; 2869 kern_return_t result = KERN_FAILURE; 2870 IOReturn status = kIOReturnError; 2871 2872 // Make sure we aren't terminating. 2873 require ( ( fTerminating == false ), Exit ); 2874 require ( ( isInactive ( ) == false ), Exit ); 2875 2876 // We call retain here so that the driver will stick around long enough for 2877 // sResetDevice() to do it's thing in case we are being terminated. The 2878 // retain() is balanced with a release in sResetDevice(). 2879 retain ( ); 2880 2881 STATUS_LOG ( ( 4, "%s[%p]: ResetDeviceNow waitForReset=%d fConsecutiveResetCount=%d", getName(), this, waitForReset, fConsecutiveResetCount ) ); 2882 2883 // Reset the device on its own thread so we don't deadlock. 2884 fResetInProgress = true; 2885 2886 // When peforming a USB device reset, we have two options. We can actively block on the reset thread, 2887 // or we can not block and wait for the IOUSBFamily to send us a message about our device being 2888 // reset. If we're reseting from a callback thread, we can't block, so we have to use the message option. 2889 2890 fBlockOnResetThread = !waitForReset; 2891 2892 result = kernel_thread_start ( ( thread_continue_t ) &IOUSBMassStorageClass::sResetDevice, 2893 this, 2894 &thread ); 2895 require ( ( result == KERN_SUCCESS ), ErrorExit ); 2896 2897 if (result == KERN_SUCCESS) 2898 { 2899 status = kIOReturnSuccess; 2900 } 2901 2902 if ( waitForReset == true ) 2903 { 2904 fCommandGate->runAction ( ( IOCommandGate::Action ) &IOUSBMassStorageClass::sWaitForReset ); 2905 if ( fResetStatus != kUSBResetStatusSuccess ) 2906 { 2907 fResetStatus = 0; 2908 status = kIOReturnNotResponding; 2909 } 2910 } 2911 2912 2913Exit: 2914 2915 2916 // If the reset didnt happen complete the failed command with an error here. 2917 if ( ( result == KERN_FAILURE ) && 2918 ( fBulkOnlyCommandStructInUse | fCBICommandStructInUse ) ) 2919 { 2920 AbortCurrentSCSITask ( ); 2921 } 2922 2923 STATUS_LOG ( ( 4, "%s[%p]: ResetDeviceNow exiting\n", getName(), this ) ); 2924 2925 2926 return status; 2927 2928 2929ErrorExit: 2930 2931 2932 fResetInProgress = false; 2933 2934 release ( ); 2935 2936 return status; 2937 2938 2939} 2940 2941 2942//-------------------------------------------------------------------------------------------------- 2943// AbortCurrentSCSITask [PROTECTED] 2944// 2945// This method is used to fail an I/O for which its error recovery required either a Bulk Only 2946// Reset or a Device Reset. It has the important side effect of incrementing the 2947// fConsecutiveReset counter which is used to escalate the type of reset, and to terminate 2948// ourself when multiple reset attempts fail to recover the device. 2949//-------------------------------------------------------------------------------------------------- 2950 2951void 2952IOUSBMassStorageClass::AbortCurrentSCSITask ( void ) 2953{ 2954 2955 SCSITaskIdentifier currentTask = NULL; 2956 2957 if ( fWorkLoop->inGate ( ) == false ) 2958 { 2959 2960 fCommandGate->runAction ( 2961 OSMemberFunctionCast ( 2962 IOCommandGate::Action, 2963 this, 2964 &IOUSBMassStorageClass::AbortCurrentSCSITask ) ); 2965 2966 return; 2967 2968 } 2969 2970 // We are holding the workLoop gate. 2971 2972 STATUS_LOG ( ( 4, "%s[%p]: AbortCurrentSCSITask Entered", getName(), this ) ); 2973 2974 if( fBulkOnlyCommandStructInUse == true ) 2975 { 2976 currentTask = fBulkOnlyCommandRequestBlock.request; 2977 } 2978 2979 else if( fCBICommandStructInUse == true ) 2980 { 2981 currentTask = fCBICommandRequestBlock.request; 2982 } 2983 2984 if ( currentTask != NULL ) 2985 { 2986 2987 SCSITaskStatus taskStatus; 2988 2989 fBulkOnlyCommandStructInUse = false; 2990 fBulkOnlyCommandRequestBlock.request = NULL; 2991 fCBICommandStructInUse = false; 2992 fCBICommandRequestBlock.request = NULL; 2993 2994 // Increment the count of consecutive I/Os which were aborted during a reset. 2995 // If that count is greater than the max, then consider the drive unusable, and mark the device as detached 2996 // so that the non-responsive volume doesn't hang restart, shutdown or applications. 2997 // Note that we will call terminate after releasing the WorkLoop because it also requires the 2998 // arbitration lock, and this could cause a deadlock if a software eject causes a close which requires I/Os. 2999 fConsecutiveResetCount++; 3000 if ( ( fConsecutiveResetCount > kMaxConsecutiveResets ) && ( fDeviceAttached == true ) ) 3001 { 3002 3003 IOLog ( "%s[%p]: The device is still unresponsive after %u consecutive USB Device Resets; it will be terminated.\n", getName(), this, fConsecutiveResetCount ); 3004 fDeviceAttached = false; 3005 3006 } 3007 3008 else 3009 { 3010 STATUS_LOG ( ( 4, "%s[%p]: AbortCurrentSCSITask fConsecutiveResetCount=%u", getName(), this, fConsecutiveResetCount ) ); 3011 } 3012 3013 RecordUSBTimeStamp ( UMC_TRACE( kAbortCurrentSCSITask ), 3014 ( uintptr_t ) this, ( uintptr_t ) currentTask, ( uintptr_t ) fDeviceAttached, ( uintptr_t ) fConsecutiveResetCount ); 3015 3016 if ( fDeviceAttached == false ) 3017 { 3018 3019 STATUS_LOG ( ( 1, "%s[%p]: AbortCurrentSCSITask Aborting currentTask=%p with device not present.", getName(), this, currentTask ) ); 3020 fTerminating = true; 3021 SendNotification_DeviceRemoved ( ); 3022 taskStatus = kSCSITaskStatus_DeviceNotPresent; 3023 3024 } 3025 3026 else 3027 { 3028 3029 STATUS_LOG ( ( 1, "%s[%p]: AbortCurrentSCSITask Aborting currentTask=%p with delivery failure.", getName(), this, currentTask ) ); 3030 taskStatus = kSCSITaskStatus_DeliveryFailure; 3031 3032 } 3033 3034 RecordUSBTimeStamp ( UMC_TRACE ( kCompleteSCSICommand ), 3035 ( uintptr_t ) this, ( uintptr_t ) currentTask, 3036 kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE, taskStatus ); 3037 3038 CommandCompleted ( currentTask, kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE, taskStatus ); 3039 3040 // If didTerminate() was called while this SCSI task was outstanding, then termination would 3041 // have been deferred until it completed. Check for that now, while behind the command gate. 3042 CheckDeferredTermination ( ); 3043 3044 } 3045 3046 STATUS_LOG ( ( 4, "%s[%p]: AbortCurrentSCSITask Exiting", getName(), this ) ); 3047 3048} 3049 3050 3051//----------------------------------------------------------------------------- 3052// - IsPhysicalInterconnectLocationInternal [PROTECTED] 3053//----------------------------------------------------------------------------- 3054 3055bool 3056IOUSBMassStorageClass::IsPhysicalInterconnectLocationInternal ( void ) 3057{ 3058 3059 IOReturn status = kIOReturnError; 3060 IOUSBInterface * usbInterface = NULL; 3061 IOUSBDevice * usbDevice = NULL; 3062 UInt32 deviceInformation = 0; 3063 bool internal = false; 3064 3065 3066 // We acquire our references individually to avoid panics. 3067 3068 // Get a reference to our USB interface. 3069 usbInterface = GetInterfaceReference(); 3070 require ( ( usbInterface != NULL ), ErrorExit ); 3071 3072 // Get a reference to our USB device. 3073 usbDevice = usbInterface->GetDevice(); 3074 require ( ( usbDevice != NULL ), ErrorExit ); 3075 3076 status = usbDevice->GetDeviceInformation ( &deviceInformation ); 3077 require_success ( status, ErrorExit ); 3078 3079 // Marking both captive and internal devices as internal. 3080 if ( ( deviceInformation & ( 1 << kUSBInformationDeviceIsCaptiveBit ) ) || 3081 ( deviceInformation & ( 1 << kUSBInformationDeviceIsInternalBit ) ) ) 3082 { 3083 internal = true; 3084 } 3085 3086 3087ErrorExit: 3088 3089 return internal; 3090 3091} 3092 3093 3094//----------------------------------------------------------------------------- 3095// - SuspendPort [PROTECTED] 3096//----------------------------------------------------------------------------- 3097 3098IOReturn 3099IOUSBMassStorageClass::SuspendPort ( bool suspend ) 3100{ 3101 3102 3103 STATUS_LOG ( ( 4, "%s[%p]: SuspendPort entered with suspend=%d onThread=%d", getName ( ), this, suspend, fWorkLoop->onThread ( ) ) ); 3104 3105 IOReturn status = kIOReturnError; 3106 IOUSBInterface * usbInterfaceRef = NULL; 3107 IOUSBDevice * usbDeviceRef = NULL; 3108 3109 3110 // See if we're already in the desired state. 3111 if ( suspend == fPortIsSuspended ) 3112 { 3113 3114 STATUS_LOG ( ( 4, "%s[%p]: SuspendPort !!!ALREADY!!! in desired state.", getName(), this ) ); 3115 3116 status = kIOReturnSuccess; 3117 goto Exit; 3118 3119 } 3120 3121 // Get our Device reference safely. 3122 usbInterfaceRef = GetInterfaceReference(); 3123 require ( usbInterfaceRef, Exit ); 3124 3125 usbDeviceRef = usbInterfaceRef->GetDevice(); 3126 require ( usbDeviceRef, Exit ); 3127 3128 // Suspend the USB port so that a remote wakeup will detect new media. 3129 if ( suspend == true ) 3130 { 3131 3132 STATUS_LOG ( ( 6, "%s[%p]::SuspendPort suspend port", getName(), this ) ); 3133 3134 // Suspend the port. 3135 status = usbDeviceRef->SuspendDevice ( true ); 3136 require ( ( status == kIOReturnSuccess ), Exit ); 3137 3138 // Suspend was successful, our USB port is now suspended. 3139 fPortIsSuspended = true; 3140 3141 } 3142 3143 // If the port was suspended, resume it, the host wants the drive back online. 3144 if ( suspend == false ) 3145 { 3146 3147 STATUS_LOG ( ( 6, "%s[%p]::SuspendPort resume port", getName(), this ) ); 3148 3149 // Resume the port. 3150 status = usbDeviceRef->SuspendDevice ( false ); 3151 require ( ( status == kIOReturnSuccess ), Exit ); 3152 3153 // It takes the USB controller a little while to get back on the line. 3154 IOSleep ( 15 ); 3155 // Resume was successful, our USB port is now active. 3156 fPortIsSuspended = false; 3157 3158 } 3159 3160 3161Exit: 3162 3163 3164 RecordUSBTimeStamp ( UMC_TRACE ( kSuspendPort ), ( uintptr_t ) this, status, suspend, NULL ); 3165 3166 STATUS_LOG ( ( 4, "%s[%p]: SuspendPort: returning status=0x%x fPortIsSuspended=%d", getName ( ), this, status, fPortIsSuspended ) ); 3167 return status; 3168 3169} 3170 3171#pragma mark 3172#pragma mark *** Reserved for future expansion *** 3173#pragma mark 3174 3175// Space reserved for future expansion. 3176OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 3 ); 3177OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 4 ); 3178OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 5 ); 3179OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 6 ); 3180OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 7 ); 3181OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 8 ); 3182OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 9 ); 3183OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 10 ); 3184OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 11 ); 3185OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 12 ); 3186OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 13 ); 3187OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 14 ); 3188OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 15 ); 3189OSMetaClassDefineReservedUnused( IOUSBMassStorageClass, 16 ); 3190