IOUSBMassStorageClass.h [plain text]
#ifndef _IOKIT_IOUSBMASSSTORAGECLASS_H
#define _IOKIT_IOUSBMASSSTORAGECLASS_H
#include <IOKit/IOLib.h>
#include <IOKit/IOService.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOMessage.h>
#include <IOKit/usb/IOUSBInterface.h>
#include <IOKit/usb/IOUSBPipe.h>
#include <IOKit/usb/USBSpec.h>
#include <IOKit/usb/USB.h>
#include <IOKit/scsi-commands/IOSCSIProtocolServices.h>
#define USB_MASS_STORAGE_DEBUG 0
#define UNUSED(x) ((void)x)
#pragma mark -
#pragma mark Vendor Specific Device Support
#define kIOUSBMassStorageCharacteristics "USB Mass Storage Characteristics"
#define kIOUSBMassStoragePreferredSubclass "Preferred Subclass"
#define kIOUSBMassStoragePreferredProtocol "Preferred Protocol"
#define kIOUSBMassStorageResetOnResume "Reset On Resume"
#define kIOUSBMassStorageUseStandardUSBReset "Use Standard USB Reset"
#define kIOUSBMassStorageMaxLogicalUnitNumber "Max Logical Unit Number"
#pragma mark -
#pragma mark CBI Protocol Strutures
struct CBIRequestBlock
{
SCSITaskIdentifier request;
IOUSBDevRequest cbiDevRequest;
SCSICommandDescriptorBlock cbiCDB;
IOUSBCompletion cbiCompletion;
UInt32 currentState;
IOMemoryDescriptor * cbiPhaseDesc;
UInt8 cbiGetStatusBuffer[2]; };
typedef struct CBIRequestBlock CBIRequestBlock;
#pragma mark -
#pragma mark Bulk Only Protocol Structures
struct StorageBulkOnlyCBW
{
UInt32 cbwSignature;
UInt32 cbwTag;
UInt32 cbwTransferLength;
UInt8 cbwFlags;
UInt8 cbwLUN; UInt8 cbwCDBLength; UInt8 cbwCDB[16];
};
typedef struct StorageBulkOnlyCBW StorageBulkOnlyCBW;
struct StorageBulkOnlyCSW
{
UInt32 cswSignature;
UInt32 cswTag;
UInt32 cswDataResidue;
UInt8 cswStatus;
};
typedef struct StorageBulkOnlyCSW StorageBulkOnlyCSW;
struct BulkOnlyRequestBlock
{
SCSITaskIdentifier request;
IOUSBCompletion boCompletion;
UInt32 currentState;
StorageBulkOnlyCBW boCBW;
StorageBulkOnlyCSW boCSW;
IOMemoryDescriptor * boPhaseDesc;
UInt8 boGetStatusBuffer[2]; };
typedef struct BulkOnlyRequestBlock BulkOnlyRequestBlock;
#pragma mark -
#pragma mark IOUSBMassStorageClass definition
class IOUSBMassStorageClass : public IOSCSIProtocolServices
{
OSDeclareDefaultStructors(IOUSBMassStorageClass)
private:
IOUSBInterface * fInterface;
IOUSBPipe * fBulkInPipe;
IOUSBPipe * fBulkOutPipe;
IOUSBPipe * fInterruptPipe;
IOUSBDevRequest fUSBDeviceRequest;
UInt8 fPreferredSubclass;
UInt8 fPreferredProtocol;
UInt8 fMaxLogicalUnitNumber;
bool fCBICommandStructInUse;
CBIRequestBlock fCBICommandRequestBlock;
UInt32 fBulkOnlyCommandTag;
bool fBulkOnlyCommandStructInUse;
BulkOnlyRequestBlock fBulkOnlyCommandRequestBlock;
protected:
struct ExpansionData
{
bool fResetInProgress;
OSSet * fClients;
IOUSBPipe * fPotentiallyStalledPipe;
bool fUseUSBResetNotBOReset;
bool fAbortCurrentSCSITaskInProgress;
IOMemoryDescriptor * fCBIMemoryDescriptor;
IOMemoryDescriptor * fBulkOnlyCBWMemoryDescriptor;
IOMemoryDescriptor * fBulkOnlyCSWMemoryDescriptor;
bool fDeviceAttached;
bool fWaitingForReconfigurationMessage;
bool fTerminating;
};
ExpansionData * reserved;
#define fResetInProgress reserved->fResetInProgress
#define fClients reserved->fClients
#define fPotentiallyStalledPipe reserved->fPotentiallyStalledPipe
#define fUseUSBResetNotBOReset reserved->fUseUSBResetNotBOReset
#define fAbortCurrentSCSITaskInProgress reserved->fAbortCurrentSCSITaskInProgress
#define fCBIMemoryDescriptor reserved->fCBIMemoryDescriptor
#define fBulkOnlyCBWMemoryDescriptor reserved->fBulkOnlyCBWMemoryDescriptor
#define fBulkOnlyCSWMemoryDescriptor reserved->fBulkOnlyCSWMemoryDescriptor
#define fDeviceAttached reserved->fDeviceAttached
#define fWaitingForReconfigurationMessage reserved->fWaitingForReconfigurationMessage
#define fTerminating reserved->fTerminating
enum
{
kUSBStorageRBCSubclass = 1,
kUSBStorageSFF8020iSubclass = 2,
kUSBStorageQIC157Subclass = 3,
kUSBStorageUFISubclass = 4,
kUSBStorageSFF8070iSubclass = 5,
kUSBStorageSCSITransparentSubclass = 6
};
enum
{
kProtocolControlBulkInterrupt = 0x00,
kProtocolControlBulk = 0x01,
kProtocolBulkOnly = 0x50
};
virtual bool SendSCSICommand(
SCSITaskIdentifier request,
SCSIServiceResponse * serviceResponse,
SCSITaskStatus * taskStatus );
virtual SCSIServiceResponse AbortSCSICommand( SCSITaskIdentifier abortTask );
virtual bool IsProtocolServiceSupported(
SCSIProtocolFeature feature,
void * serviceValue );
virtual bool HandleProtocolServiceFeature(
SCSIProtocolFeature feature,
void * serviceValue );
IOUSBInterface * GetInterfaceReference( void );
void SetInterfaceReference( IOUSBInterface * newInterface );
UInt8 GetInterfaceSubclass( void );
UInt8 GetInterfaceProtocol( void );
IOUSBPipe * GetControlPipe( void );
IOUSBPipe * GetBulkInPipe( void );
IOUSBPipe * GetBulkOutPipe( void );
IOUSBPipe * GetInterruptPipe( void );
UInt8 GetMaxLogicalUnitNumber( void ) const;
void SetMaxLogicalUnitNumber( UInt8 maxLUN );
virtual void CompleteSCSICommand(
SCSITaskIdentifier request,
IOReturn status );
virtual bool BeginProvidedServices( void );
virtual bool EndProvidedServices( void );
virtual IOReturn SendSCSICommandForCBIProtocol(
SCSITaskIdentifier request );
virtual IOReturn SendSCSICommandForBulkOnlyProtocol(
SCSITaskIdentifier request );
virtual IOReturn AbortSCSICommandForCBIProtocol(
SCSITaskIdentifier abortTask );
virtual IOReturn AbortSCSICommandForBulkOnlyProtocol(
SCSITaskIdentifier abortTask );
virtual IOReturn ClearFeatureEndpointStall(
IOUSBPipe * thePipe,
IOUSBCompletion * completion );
virtual IOReturn GetStatusEndpointStatus(
IOUSBPipe * thePipe,
void * endpointStatus,
IOUSBCompletion * completion );
enum
{
kUSBStorageAutoStatusSize = 2 };
CBIRequestBlock * GetCBIRequestBlock( void );
void ReleaseCBIRequestBlock(
CBIRequestBlock * cbiRequestBlock );
static void CBIProtocolUSBCompletionAction(
void * target,
void * parameter,
IOReturn status,
UInt32 bufferSizeRemaining);
IOReturn CBIProtocolTransferData(
CBIRequestBlock * cbiRequestBlock,
UInt32 nextExecutionState );
IOReturn CBIProtocolReadInterrupt(
CBIRequestBlock * cbiRequestBlock,
UInt32 nextExecutionState );
IOReturn CBIGetStatusEndpointStatus(
IOUSBPipe * targetPipe,
CBIRequestBlock * cbiRequestBlock,
UInt32 nextExecutionState );
IOReturn CBIClearFeatureEndpointStall(
IOUSBPipe * targetPipe,
CBIRequestBlock * cbiRequestBlock,
UInt32 nextExecutionState );
void CBIProtocolCommandCompletion(
CBIRequestBlock * cbiRequestBlock,
IOReturn resultingStatus,
UInt32 bufferSizeRemaining );
enum
{
kCommandBlockWrapperSignature = OSSwapHostToBigConstInt32 ( 'USBC' ),
kByteCountOfCBW = 31,
kCBWLUNMask = 0x07,
kCBWFlagsDataOut = 0x00,
kCBWFlagsDataIn = 0x80
};
enum
{
kCommandStatusWrapperSignature = OSSwapHostToBigConstInt32 ( 'USBS' ),
kByteCountOfCSW = 13,
kCSWCommandPassedError = 0x00, kCSWCommandFailedError = 0x01,
kCSWPhaseError = 0x02
};
BulkOnlyRequestBlock * GetBulkOnlyRequestBlock( void );
void ReleaseBulkOnlyRequestBlock(
BulkOnlyRequestBlock * boRequestBlock );
UInt32 GetNextBulkOnlyCommandTag( void );
IOReturn BulkDeviceResetDevice(
BulkOnlyRequestBlock * boRequestBlock,
UInt32 nextExecutionState );
IOReturn BulkOnlySendCBWPacket(
BulkOnlyRequestBlock * boRequestBlock,
UInt32 nextExecutionState );
IOReturn BulkOnlyTransferData(
BulkOnlyRequestBlock * boRequestBlock,
UInt32 nextExecutionState );
IOReturn BulkOnlyReceiveCSWPacket(
BulkOnlyRequestBlock * boRequestBlock,
UInt32 nextExecutionState );
void BulkOnlyExecuteCommandCompletion (
BulkOnlyRequestBlock * boRequestBlock,
IOReturn resultingStatus,
UInt32 bufferSizeRemaining );
static void BulkOnlyUSBCompletionAction (
void * target,
void * parameter,
IOReturn status,
UInt32 bufferSizeRemaining );
public:
bool init( OSDictionary * propTable );
virtual bool start( IOService * provider );
virtual void stop( IOService * provider );
virtual void free( void );
virtual IOReturn message( UInt32 type, IOService * provider, void * argument = 0 );
virtual bool willTerminate( IOService * provider,
IOOptionBits options );
virtual bool didTerminate( IOService * provider,
IOOptionBits options,
bool * defer );
virtual bool handleOpen( IOService * client,
IOOptionBits options,
void * arg );
virtual void handleClose( IOService * client,
IOOptionBits options );
virtual bool handleIsOpen( const IOService * client ) const;
virtual IOReturn HandlePowerOn( void );
protected:
static IOReturn sWaitForReset( void * refcon );
IOReturn GatedWaitForReset( void );
static IOReturn sWaitForTaskAbort( void * refcon );
IOReturn GatedWaitForTaskAbort( void );
static void sResetDevice( void * refcon );
static void sAbortCurrentSCSITask( void * refcon );
OSMetaClassDeclareReservedUsed( IOUSBMassStorageClass, 1 );
virtual IOReturn StartDeviceRecovery( void );
OSMetaClassDeclareReservedUsed( IOUSBMassStorageClass, 2 );
virtual void FinishDeviceRecovery( IOReturn status );
static void DeviceRecoveryCompletionAction(
void * target,
void * parameter,
IOReturn status,
UInt32 bufferSizeRemaining );
void ResetDeviceNow( bool waitForReset );
void AbortCurrentSCSITask( void );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 3 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 4 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 5 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 6 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 7 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 8 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 9 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 10 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 11 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 12 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 13 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 14 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 15 );
OSMetaClassDeclareReservedUnused( IOUSBMassStorageClass, 16 );
};
#endif _IOKIT_IOUSBMASSSTORAGECLASS_H