SCSIReducedBlockCommands.cpp [plain text]
#include <IOKit/scsi-commands/SCSICommandOperationCodes.h>
#include "SCSIReducedBlockCommands.h"
#define DEBUG 0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "RBC Command Set"
#if DEBUG
#define SCSI_RBC_COMMANDS_DEBUGGING_LEVEL 0
#endif
#include "IOSCSIArchitectureModelFamilyDebugging.h"
#if ( SCSI_RBC_COMMANDS_DEBUGGING_LEVEL >= 1 )
#define PANIC_NOW(x) IOPanic x
#else
#define PANIC_NOW(x)
#endif
#if ( SCSI_RBC_COMMANDS_DEBUGGING_LEVEL >= 2 )
#define ERROR_LOG(x) IOLog x
#else
#define ERROR_LOG(x)
#endif
#if ( SCSI_RBC_COMMANDS_DEBUGGING_LEVEL >= 3 )
#define STATUS_LOG(x) IOLog x
#else
#define STATUS_LOG(x)
#endif
#define READ_CAPACITY_DATA_SIZE 8
#define super SCSIPrimaryCommands
OSDefineMetaClassAndStructors ( SCSIReducedBlockCommands, SCSIPrimaryCommands );
#if 0
#pragma mark -
#pragma mark RBC Command Methods
#pragma mark -
#endif
bool
SCSIReducedBlockCommands::FORMAT_UNIT (
SCSITask * request,
SCSICmdField1Bit IMMED,
SCSICmdField1Bit PROGRESS,
SCSICmdField1Bit PERCENT_TIME,
SCSICmdField1Bit INCREMENT )
{
bool result = false;
STATUS_LOG ( ( "SCSIReducedBlockCommands::FORMAT_UNIT called\n" ) );
require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PROGRESS, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PERCENT_TIME, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( INCREMENT, kSCSICmdFieldMask1Bit ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_FORMAT_UNIT,
0x00,
( IMMED << 3 ) | ( PROGRESS << 2 ) |
( PERCENT_TIME << 1 ) | INCREMENT,
0x00,
0x00,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIReducedBlockCommands::READ_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH )
{
UInt32 requestedByteCount = 0;
bool result = false;
STATUS_LOG ( ( "SCSIReducedBlockCommands::READ_10 called\n" ) );
require_nonzero ( blockSize, ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsBufferAndCapacityValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_10,
0x00,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
requestedByteCount );
result = true;
ErrorExit:
return result;
}
bool
SCSIReducedBlockCommands::READ_CAPACITY (
SCSITask * request,
IOMemoryDescriptor * dataBuffer )
{
bool result = false;
STATUS_LOG ( ( "SCSIReducedBlockCommands::READ_CAPACITY called\n" ) );
require ( IsBufferAndCapacityValid ( dataBuffer, READ_CAPACITY_DATA_SIZE ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_CAPACITY,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
READ_CAPACITY_DATA_SIZE );
result = true;
ErrorExit:
return result;
}
bool
SCSIReducedBlockCommands::START_STOP_UNIT (
SCSITask * request,
SCSICmdField1Bit IMMED,
SCSICmdField4Bit POWER_CONDITIONS,
SCSICmdField1Bit LOEJ,
SCSICmdField1Bit START )
{
bool result = false;
STATUS_LOG ( ( "SCSIReducedBlockCommands::START_STOP_UNIT called\n" ) );
require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( POWER_CONDITIONS, kSCSICmdFieldMask4Bit ), ErrorExit );
require ( IsParameterValid ( LOEJ, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( START, kSCSICmdFieldMask1Bit ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_START_STOP_UNIT,
IMMED,
0x00,
0x00,
( POWER_CONDITIONS << 4 ) | ( LOEJ << 1 ) | START,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIReducedBlockCommands::SYNCHRONIZE_CACHE (
SCSITask * request )
{
STATUS_LOG ( ( "SCSIReducedBlockCommands::SYNCRONIZE_CACHE called\n" ) );
SetCommandDescriptorBlock ( request,
kSCSICmd_SYNCHRONIZE_CACHE,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
return true;
}
bool
SCSIReducedBlockCommands::WRITE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit FUA,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH )
{
bool result = false;
UInt32 requestedByteCount = 0;
STATUS_LOG ( ( "SCSIReducedBlockCommands::WRITE_10 called\n" ) );
require_nonzero ( blockSize, ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsBufferAndCapacityValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_10,
( FUA << 3 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
requestedByteCount );
result = true;
ErrorExit:
return result;
}
bool
SCSIReducedBlockCommands::VERIFY (
SCSITask * request,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte VERIFICATION_LENGTH )
{
bool result = false;
STATUS_LOG ( ( "SCSIReducedBlockCommands::VERIFY called\n" ) );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_VERIFY_10,
0x00,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
( VERIFICATION_LENGTH >> 8 ) & 0xFF,
VERIFICATION_LENGTH & 0xFF,
0x00 );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
#if 0
#pragma mark -
#pragma mark ₯ Static Methods
#pragma mark -
#endif
SCSIReducedBlockCommands *
SCSIReducedBlockCommands::CreateSCSIReducedBlockCommandObject ( void )
{
return OSTypeAlloc ( SCSIReducedBlockCommands );
}