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#ifndef _IOKIT_IOUSBMASSSTORAGECLASS_H 26#define _IOKIT_IOUSBMASSSTORAGECLASS_H 27 28// Headers for general IOKit definitions 29#include <IOKit/IOLib.h> 30#include <IOKit/IOService.h> 31#include <IOKit/IOMemoryDescriptor.h> 32#include <IOKit/IOMessage.h> 33 34// Headers for USB specific definitions 35#include <IOKit/usb/IOUSBInterface.h> 36#include <IOKit/usb/IOUSBPipe.h> 37#include <IOKit/usb/USBSpec.h> 38#include <IOKit/usb/USB.h> 39 40// Headers for SCSI Protocol support definitions 41#include <IOKit/scsi/IOSCSIProtocolServices.h> 42 43// BSD includes 44#include <sys/sysctl.h> 45 46#define UNUSED(x) ((void)x) 47 48#pragma mark - 49#pragma mark Vendor Specific Device Support 50#define kIOUSBMassStorageCharacteristics "USB Mass Storage Characteristics" 51#define kIOUSBMassStoragePreferredSubclass "Preferred Subclass" 52#define kIOUSBMassStoragePreferredProtocol "Preferred Protocol" 53#define kIOUSBMassStorageUseStandardUSBReset "Use Standard USB Reset" 54#define kIOUSBKnownCSWTagIssues "Known CSW Tag Issues" 55#define kIOUSBMassStorageMaxLogicalUnitNumber "Max Logical Unit Number" 56#define kIOPropertyIOUnitKey "IOUnit" 57#define kIOUSBMassStorageDoNotMatch "Do Not Match MSC" 58#define kIOUSBMassStorageDoNotOperate "Do Not Operate" 59#define kIOUSBMassStorageEnableSuspendResumePM "Enable Port Suspend-Resume PM" 60#define kIOUSBMassStoragePostResetCoolDown "Reset Recovery Time" 61 62#ifndef EMBEDDED 63#define kIOUSBMassStorageSuspendOnReboot "Suspend On Reboot" 64#define kIOUSBMassStorageResetOnResume "Reset On Resume" 65#endif // EMBEDDED 66 67enum 68{ 69 kUSBDAddressLength = 10 70}; 71 72enum 73{ 74 kIOUSBMassStorageReconfigurationTimeoutMS = 5000 75}; 76 77 78#pragma mark - 79#pragma mark CBI Protocol Strutures 80// Structure for the global PB's 81struct CBIRequestBlock 82{ 83 SCSITaskIdentifier request; 84 IOUSBDevRequest cbiDevRequest; 85 SCSICommandDescriptorBlock cbiCDB; 86 IOUSBCompletion cbiCompletion; 87 UInt32 currentState; 88 IOMemoryDescriptor * cbiPhaseDesc; 89 UInt8 cbiGetStatusBuffer[2]; // 2 bytes as specified in the USB spec 90}; 91 92typedef struct CBIRequestBlock CBIRequestBlock; 93 94#pragma mark - 95#pragma mark Bulk Only Protocol Structures 96 97struct StorageBulkOnlyCBW 98{ 99 UInt32 cbwSignature; 100 UInt32 cbwTag; 101 UInt32 cbwTransferLength; 102 UInt8 cbwFlags; 103 UInt8 cbwLUN; // Bits 0-3: LUN, 4-7: Reserved 104 UInt8 cbwCDBLength; // Bits 0-4: CDB Length, 5-7: Reserved 105 UInt8 cbwCDB[16]; 106}; 107 108typedef struct StorageBulkOnlyCBW StorageBulkOnlyCBW; 109 110struct StorageBulkOnlyCSW 111{ 112 UInt32 cswSignature; 113 UInt32 cswTag; 114 UInt32 cswDataResidue; 115 UInt8 cswStatus; 116}; 117 118typedef struct StorageBulkOnlyCSW StorageBulkOnlyCSW; 119 120struct BulkOnlyRequestBlock 121{ 122 SCSITaskIdentifier request; 123 IOUSBCompletion boCompletion; 124 UInt32 currentState; 125 StorageBulkOnlyCBW boCBW; 126 StorageBulkOnlyCSW boCSW; 127 IOMemoryDescriptor * boPhaseDesc; 128 UInt8 boGetStatusBuffer[2]; // 2 bytes as specified in the USB spec 129}; 130 131typedef struct BulkOnlyRequestBlock BulkOnlyRequestBlock; 132 133 134#pragma mark - 135#pragma mark IOUSBMassStorageClass definition 136 137class IOUSBMassStorageClass : public IOSCSIProtocolServices 138{ 139 OSDeclareDefaultStructors(IOUSBMassStorageClass) 140 141private: 142 // ---- Member variables used by all protocols ---- 143 // The interface object that provides the driver with access to the 144 // USB so that it may talk to its device. 145 IOUSBInterface * fInterface; 146 147 // The pipe objects that the driver uses to transport data through a 148 // pipe to the appropriate endpoint. 149 IOUSBPipe * fBulkInPipe; 150 IOUSBPipe * fBulkOutPipe; 151 IOUSBPipe * fInterruptPipe; 152 153 IOUSBDevRequest fUSBDeviceRequest; 154 UInt8 fPreferredSubclass; 155 UInt8 fPreferredProtocol; 156 157 // The maximum Logical Unit Number. This is the highest valid LUN 158 // that the USB device supports, so if the device only supports one 159 // LUN, such as CBI and CB, this number will be zero. 160 UInt8 fMaxLogicalUnitNumber; 161 162 // ---- Member variables used by CBI protocol ---- 163 bool fCBICommandStructInUse; 164 165 CBIRequestBlock fCBICommandRequestBlock; 166 167 // ---- Member variables used by Bulk Only protocol ---- 168 // Command tag, this driver just uses a sequential counter that is 169 // incremented for each CBW that is sent to the device. 170 UInt32 fBulkOnlyCommandTag; 171 172 bool fBulkOnlyCommandStructInUse; 173 174 // Dedicated CBW and CSW IOMemoryDescriptors are listed in the ExpansionData struct. 175 176 // The Request block that contains all the necessary data for 177 // transporting a Bulk Only request across the USB. 178 BulkOnlyRequestBlock fBulkOnlyCommandRequestBlock; 179 180protected: 181 // Reserve space for future expansion. 182 183 // We flatten the ExpansionData for iOS since we're relieved of the burden binary compatibility. 184#ifndef EMBEDDED 185 struct ExpansionData 186 { 187#endif // EMBEDDED 188 bool fResetInProgress; 189 OSSet * fClients; 190 IOUSBPipe * fPotentiallyStalledPipe; 191 bool fUseUSBResetNotBOReset; 192 bool fAbortCurrentSCSITaskInProgress; 193 IOMemoryDescriptor * fCBIMemoryDescriptor; 194 IOMemoryDescriptor * fBulkOnlyCBWMemoryDescriptor; 195 IOMemoryDescriptor * fBulkOnlyCSWMemoryDescriptor; 196 bool fDeviceAttached; 197 bool fWaitingForReconfigurationMessage; 198 bool fTerminating; 199 bool fKnownCSWTagMismatchIssues; 200 bool fPortSuspendResumeForPMEnabled; 201 bool fPortIsSuspended; 202#ifndef EMBEDDED 203 bool fRequiresResetOnResume; 204 bool fAutonomousSpinDownWorkAround; 205#endif // EMBEDDED 206 UInt8 fConsecutiveResetCount; 207#ifndef EMBEDDED 208 bool fClearStallInProgress; /* OBSOLETE */ 209#endif // EMBEDDED 210 bool fTerminationDeferred; 211#ifndef EMBEDDED 212 UInt32 fRequiredMaxBusStall; 213#endif // EMBEDDED 214 bool fBlockOnResetThread; 215#ifndef EMBEDDED 216 UInt32 fPostDeviceResetCoolDownInterval; 217 bool fSuspendOnReboot; 218#endif // EMBEDDED 219 UInt8 fResetStatus; 220 221#ifndef EMBEDDED 222 }; 223 ExpansionData * reserved; 224#endif // EMBEDDED 225 226#ifndef EMBEDDED 227 #define fResetInProgress reserved->fResetInProgress 228 #define fClients reserved->fClients 229 #define fPotentiallyStalledPipe reserved->fPotentiallyStalledPipe 230 #define fUseUSBResetNotBOReset reserved->fUseUSBResetNotBOReset 231 #define fAbortCurrentSCSITaskInProgress reserved->fAbortCurrentSCSITaskInProgress 232 #define fCBIMemoryDescriptor reserved->fCBIMemoryDescriptor 233 #define fBulkOnlyCBWMemoryDescriptor reserved->fBulkOnlyCBWMemoryDescriptor 234 #define fBulkOnlyCSWMemoryDescriptor reserved->fBulkOnlyCSWMemoryDescriptor 235 #define fDeviceAttached reserved->fDeviceAttached 236 #define fWaitingForReconfigurationMessage reserved->fWaitingForReconfigurationMessage 237 #define fTerminating reserved->fTerminating 238 #define fKnownCSWTagMismatchIssues reserved->fKnownCSWTagMismatchIssues 239 #define fPortSuspendResumeForPMEnabled reserved->fPortSuspendResumeForPMEnabled 240 #define fPortIsSuspended reserved->fPortIsSuspended 241 #define fRequiresResetOnResume reserved->fRequiresResetOnResume 242 #define fAutonomousSpinDownWorkAround reserved->fAutonomousSpinDownWorkAround 243 #define fConsecutiveResetCount reserved->fConsecutiveResetCount 244 #define fClearStallInProgress reserved->fClearStallInProgress 245 #define fTerminationDeferred reserved->fTerminationDeferred 246 #define fRequiredMaxBusStall reserved->fRequiredMaxBusStall 247 #define fBlockOnResetThread reserved->fBlockOnResetThread 248 #define fPostDeviceResetCoolDownInterval reserved->fPostDeviceResetCoolDownInterval 249 #define fSuspendOnReboot reserved->fSuspendOnReboot 250 #define fResetStatus reserved->fResetStatus 251#endif // EMBEDDED 252 253 // Enumerated constants used to control various aspects of this 254 // driver. 255 256 // Enumerates the fResetStatus 257 enum 258 { 259 kUSBResetStatusSuccess = 0, 260 kUSBResetStatusFailure = 1 261 }; 262 263 // Enumerations for Mass Storage Class Subclass types 264 enum 265 { 266 kUSBStorageRBCSubclass = 1, 267 kUSBStorageSFF8020iSubclass = 2, 268 kUSBStorageQIC157Subclass = 3, 269 kUSBStorageUFISubclass = 4, 270 kUSBStorageSFF8070iSubclass = 5, 271 kUSBStorageSCSITransparentSubclass = 6 272 }; 273 274 // The supported USB Mass Storage Class transport protocols. 275 enum 276 { 277 kProtocolControlBulkInterrupt = 0x00, 278 kProtocolControlBulk = 0x01, 279 kProtocolBulkOnly = 0x50 280 }; 281 282 // ------- Protocol support functions ------------ 283 // The SendSCSICommand function will take a SCSITask Object and transport 284 // it across the physical wire(s) to the device 285 virtual bool SendSCSICommand( 286 SCSITaskIdentifier request, 287 SCSIServiceResponse * serviceResponse, 288 SCSITaskStatus * taskStatus ); 289 290 // The AbortSCSICommand function will abort the indicated SCSITask object, 291 // if it is possible and the SCSITask has not already completed. 292 virtual SCSIServiceResponse AbortSCSICommand( SCSITaskIdentifier abortTask ); 293 294 virtual bool IsProtocolServiceSupported( 295 SCSIProtocolFeature feature, 296 void * serviceValue ); 297 298 virtual bool HandleProtocolServiceFeature( 299 SCSIProtocolFeature feature, 300 void * serviceValue ); 301 302 // Methods for retrieving and setting the object for the Interface 303 IOUSBInterface * GetInterfaceReference( void ); 304 void SetInterfaceReference( IOUSBInterface * newInterface ); 305 306 UInt8 GetInterfaceSubclass( void ); 307 UInt8 GetInterfaceProtocol( void ); 308 309 // Methods for retrieving an object for a Pipe. 310 IOUSBPipe * GetControlPipe( void ); 311 IOUSBPipe * GetBulkInPipe( void ); 312 IOUSBPipe * GetBulkOutPipe( void ); 313 IOUSBPipe * GetInterruptPipe( void ); 314 315 // Methods for getting and setting the maximum LUN of a device. 316 UInt8 GetMaxLogicalUnitNumber( void ) const; 317 void SetMaxLogicalUnitNumber( UInt8 maxLUN ); 318 319 virtual void CompleteSCSICommand( 320 SCSITaskIdentifier request, 321 IOReturn status ); 322 323 virtual bool BeginProvidedServices( void ); 324 virtual bool EndProvidedServices( void ); 325 326 // The Protocol specific helper methods for SendSCSICommand 327 virtual IOReturn SendSCSICommandForCBIProtocol( 328 SCSITaskIdentifier request ); 329 330 virtual IOReturn SendSCSICommandForBulkOnlyProtocol( 331 SCSITaskIdentifier request ); 332 333 // The Protocol specific helper methods for AbortSCSICommand 334 virtual IOReturn AbortSCSICommandForCBIProtocol( 335 SCSITaskIdentifier abortTask ); 336 337 virtual IOReturn AbortSCSICommandForBulkOnlyProtocol( 338 SCSITaskIdentifier abortTask ); 339 340 // Helper methods for performing general USB device requests 341 virtual IOReturn ClearFeatureEndpointStall( 342 IOUSBPipe * thePipe, 343 IOUSBCompletion * completion ); 344 virtual IOReturn GetStatusEndpointStatus( 345 IOUSBPipe * thePipe, 346 void * endpointStatus, 347 IOUSBCompletion * completion ); 348 349 /* All CBI transport related methods. 350 */ 351 // All definitions and structures for the CBI Protocol 352 enum 353 { 354 kUSBStorageAutoStatusSize = 2 // Per the USB CBI Protocol 355 }; 356 357 // Methods for accessing Bulk Only specific member variables. 358 CBIRequestBlock * GetCBIRequestBlock( void ); 359 360 void ReleaseCBIRequestBlock( 361 CBIRequestBlock * cbiRequestBlock ); 362 363 // Methods used for CBI/CB command transportation. 364 static void CBIProtocolUSBCompletionAction( 365 void * target, 366 void * parameter, 367 IOReturn status, 368 UInt32 bufferSizeRemaining); 369 370 IOReturn CBIProtocolTransferData( 371 CBIRequestBlock * cbiRequestBlock, 372 UInt32 nextExecutionState ); 373 374 IOReturn CBIProtocolReadInterrupt( 375 CBIRequestBlock * cbiRequestBlock, 376 UInt32 nextExecutionState ); 377 378 IOReturn CBIGetStatusEndpointStatus( 379 IOUSBPipe * targetPipe, 380 CBIRequestBlock * cbiRequestBlock, 381 UInt32 nextExecutionState ); 382 383 IOReturn CBIClearFeatureEndpointStall( 384 IOUSBPipe * targetPipe, 385 CBIRequestBlock * cbiRequestBlock, 386 UInt32 nextExecutionState ); 387 388 void CBIProtocolCommandCompletion( 389 CBIRequestBlock * cbiRequestBlock, 390 IOReturn resultingStatus, 391 UInt32 bufferSizeRemaining ); 392 393 /* All Bulk Only transport related methods, structures and enums. 394 */ 395 // All Bulk Only specific structures and enums. 396 397 // All definitions and structures for the Bulk Only Protocol 398 // Command Block Wrapper (CBW) 399 enum 400 { 401 // CBW general struture definitions 402 kCommandBlockWrapperSignature = OSSwapHostToBigConstInt32 ( 'USBC' ), 403 kByteCountOfCBW = 31, 404 405 // CBW LUN related definitions 406 kCBWLUNMask = 0x0F, 407 408 kCBWFlagsDataOut = 0x00, 409 kCBWFlagsDataIn = 0x80 410 }; 411 412 // All definitions and structures for the Bulk Only Protocol 413 // Command Status Wrapper (CSW) 414 enum 415 { 416 // CSW general struture definitions 417 kCommandStatusWrapperSignature = OSSwapHostToBigConstInt32 ( 'USBS' ), 418 kByteCountOfCSW = 13, 419 420 // CSW status definitions 421 kCSWCommandPassedError = 0x00, // No error occurred 422 kCSWCommandFailedError = 0x01, /* An error occurred (probably a 423 * bad command or parameter ) */ 424 kCSWPhaseError = 0x02 /* A transfer was performed in 425 * the wrong sequence */ 426 }; 427 428 // Methods for accessing Bulk Only specific member variables. 429 BulkOnlyRequestBlock * GetBulkOnlyRequestBlock( void ); 430 431 void ReleaseBulkOnlyRequestBlock( 432 BulkOnlyRequestBlock * boRequestBlock ); 433 434 UInt32 GetNextBulkOnlyCommandTag( void ); 435 436 // Methods for Bulk Only specific utility commands 437 IOReturn BulkDeviceResetDevice( 438 BulkOnlyRequestBlock * boRequestBlock, 439 UInt32 nextExecutionState ); 440 441 // Methods used for Bulk Only command transportation. 442 IOReturn BulkOnlySendCBWPacket( 443 BulkOnlyRequestBlock * boRequestBlock, 444 UInt32 nextExecutionState ); 445 446 IOReturn BulkOnlyTransferData( 447 BulkOnlyRequestBlock * boRequestBlock, 448 UInt32 nextExecutionState ); 449 450 IOReturn BulkOnlyReceiveCSWPacket( 451 BulkOnlyRequestBlock * boRequestBlock, 452 UInt32 nextExecutionState ); 453 454 void BulkOnlyExecuteCommandCompletion ( 455 BulkOnlyRequestBlock * boRequestBlock, 456 IOReturn resultingStatus, 457 UInt32 bufferSizeRemaining ); 458 459 static void BulkOnlyUSBCompletionAction ( 460 void * target, 461 void * parameter, 462 IOReturn status, 463 UInt32 bufferSizeRemaining ); 464 465public: 466 467 bool init( OSDictionary * propTable ); 468 virtual bool start( IOService * provider ); 469 virtual void stop( IOService * provider ); 470 virtual void free( void ); 471 virtual IOReturn message( UInt32 type, IOService * provider, void * argument = 0 ); 472 473 virtual bool willTerminate( IOService * provider, 474 IOOptionBits options ); 475 476 virtual bool didTerminate( IOService * provider, 477 IOOptionBits options, 478 bool * defer ); 479 480 virtual bool handleOpen( IOService * client, 481 IOOptionBits options, 482 void * arg ); 483 484 virtual void handleClose( IOService * client, 485 IOOptionBits options ); 486 487 virtual bool handleIsOpen( const IOService * client ) const; 488 489 virtual IOReturn HandlePowerOn( void ); 490 491#ifndef EMBEDDED 492 virtual void systemWillShutdown ( IOOptionBits specifier ); 493#endif // EMBEDDED 494 495protected: 496 497 static IOReturn sWaitForReset( void * refcon ); 498 IOReturn GatedWaitForReset( void ); 499 500#ifndef EMBEDDED 501 static IOReturn sWaitForTaskAbort( void * refcon ); /* OBSOLETE */ 502 IOReturn GatedWaitForTaskAbort( void ); /* OBSOLETE */ 503#endif // EMBEDDED 504 505 static void sResetDevice( void * refcon ); 506 507#ifndef EMBEDDED 508 static void sAbortCurrentSCSITask( void * refcon ); /* OBSOLETE */ 509 510 OSMetaClassDeclareReservedUsed( IOUSBMassStorageClass, 1 ); 511 virtual IOReturn StartDeviceRecovery( void ); /* OBSOLETE */ 512 513 OSMetaClassDeclareReservedUsed( IOUSBMassStorageClass, 2 ); 514 virtual void FinishDeviceRecovery( IOReturn status ); /* OBSOLETE */ 515 516 static void DeviceRecoveryCompletionAction( 517 void * target, 518 void * parameter, 519 IOReturn status, 520 UInt32 bufferSizeRemaining ); /* OBSOLETE */ 521#endif // EMBEDDED 522 523 IOReturn ResetDeviceNow( bool waitForReset ); 524 525 void AbortCurrentSCSITask( void ); 526 527 bool IsPhysicalInterconnectLocationInternal ( void ); 528 529 IOReturn SuspendPort ( bool suspend ); 530 531private: 532 533 void ClearPipeStall ( void ); 534 535 IOReturn AcceptSCSITask ( SCSITaskIdentifier scsiTask, bool * pAccepted ); 536 537 void CheckDeferredTermination ( void ); 538 539 void GatedCompleteSCSICommand ( SCSITaskIdentifier request, SCSIServiceResponse * serviceResponse, SCSITaskStatus * taskStatus ); 540 541 // Space reserved for future expansion. 542 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 3 ); 543 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 4 ); 544 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 5 ); 545 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 6 ); 546 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 7 ); 547 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 8 ); 548 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 9 ); 549 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 10 ); 550 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 11 ); 551 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 12 ); 552 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 13 ); 553 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 14 ); 554 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 15 ); 555 OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 16 ); 556 557}; 558 559 560#endif //_IOKIT_IOUSBMASSSTORAGECLASS_H 561