SCSIPrimaryCommands.cpp [plain text]
#include <libkern/OSByteOrder.h>
#include "SCSIPrimaryCommands.h"
#include "SCSICommandOperationCodes.h"
#define DEBUG 0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "SPC Command Set"
#if DEBUG
#define SCSI_SPC_COMMANDS_DEBUGGING_LEVEL 0
#endif
#include "IOSCSIArchitectureModelFamilyDebugging.h"
#if ( SCSI_SPC_COMMANDS_DEBUGGING_LEVEL >= 1 )
#define PANIC_NOW(x) IOPanic x
#define DEBUG_ASSERT(x) assert x
#else
#define PANIC_NOW(x)
#define DEBUG_ASSERT(x)
#endif
#if ( SCSI_SPC_COMMANDS_DEBUGGING_LEVEL >= 2 )
#define ERROR_LOG(x) IOLog x
#else
#define ERROR_LOG(x)
#endif
#if ( SCSI_SPC_COMMANDS_DEBUGGING_LEVEL >= 3 )
#define STATUS_LOG(x) IOLog x
#else
#define STATUS_LOG(x)
#endif
#define super OSObject
OSDefineMetaClassAndStructors ( SCSIPrimaryCommands, OSObject );
#if 0
#pragma mark -
#pragma mark ₯ SPC Command Methods
#pragma mark -
#endif
bool
SCSIPrimaryCommands::CHANGE_DEFINITION (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit SAVE,
SCSICmdField7Bit DEFINITION_PARAMETER,
SCSICmdField1Byte PARAMETER_DATA_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::CHANGE_DEFINITION *OBSOLETE* called\n" ) );
require ( IsParameterValid ( SAVE, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DEFINITION_PARAMETER, kSCSICmdFieldMask7Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_DATA_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_DATA_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_CHANGE_DEFINITION,
0x00,
SAVE,
DEFINITION_PARAMETER,
0x00,
0x00,
0x00,
0x00,
PARAMETER_DATA_LENGTH,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_DATA_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::COMPARE (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PAD,
SCSICmdField3Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::COMPARE called\n" ) );
require ( IsParameterValid ( PAD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_COMPARE,
PAD,
0x00,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::COPY (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PAD,
SCSICmdField3Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::COPY called\n" ) );
require ( IsParameterValid ( PAD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_COPY,
PAD,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::COPY_AND_VERIFY (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit BYTCHK,
SCSICmdField1Bit PAD,
SCSICmdField3Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::COPY_AND_VERIFY called\n" ) );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PAD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_COPY_AND_VERIFY,
( BYTCHK << 1 ) | PAD,
0x00,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::EXTENDED_COPY (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::EXTENDED_COPY called\n" ) );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_EXTENDED_COPY,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 24 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::INQUIRY (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit CMDDT,
SCSICmdField1Bit EVPD,
SCSICmdField1Byte PAGE_OR_OPERATION_CODE,
SCSICmdField1Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::INQUIRY called\n" ) );
require ( IsParameterValid ( CMDDT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( EVPD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PAGE_OR_OPERATION_CODE, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
if ( PAGE_OR_OPERATION_CODE != 0 )
{
if ( ( ( CMDDT == 1 ) && ( EVPD == 1 ) ) || ( ( CMDDT == 0 ) && ( EVPD == 0 ) ) )
{
goto ErrorExit;
}
}
SetCommandDescriptorBlock ( request,
kSCSICmd_INQUIRY,
( CMDDT << 1 ) | EVPD,
PAGE_OR_OPERATION_CODE,
0x00,
ALLOCATION_LENGTH,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::LOG_SELECT (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PCR,
SCSICmdField1Bit SP,
SCSICmdField2Bit PC,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::LOG_SELECT called\n" ) );
require ( IsParameterValid ( PCR, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SP, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PC, kSCSICmdFieldMask2Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_LOG_SELECT,
( PCR << 1) | SP,
PC << 6,
0x00,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::LOG_SENSE (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PPC,
SCSICmdField1Bit SP,
SCSICmdField2Bit PC,
SCSICmdField6Bit PAGE_CODE,
SCSICmdField2Byte PARAMETER_POINTER,
SCSICmdField2Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::LOG_SENSE called\n" ) );
require ( IsParameterValid ( PPC, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SP, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PC, kSCSICmdFieldMask2Bit ), ErrorExit );
require ( IsParameterValid ( PAGE_CODE, kSCSICmdFieldMask6Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_POINTER, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_LOG_SENSE,
( PPC << 1 ) | SP,
( PC << 6 ) | PAGE_CODE,
0x00,
0x00,
( PARAMETER_POINTER >> 8 ) & 0xFF,
PARAMETER_POINTER & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::MODE_SELECT_6 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PF,
SCSICmdField1Bit SP,
SCSICmdField1Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::MODE_SELECT_6 called\n" ) );
require ( IsParameterValid ( PF, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SP, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_MODE_SELECT_6,
( PF << 4) | SP,
0x00,
0x00,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::MODE_SELECT_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PF,
SCSICmdField1Bit SP,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::MODE_SELECT_10 called\n" ) );
require ( IsParameterValid ( PF, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SP, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_MODE_SELECT_10,
( PF << 4 ) | SP,
0x00,
0x00,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::MODE_SENSE_6 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DBD,
SCSICmdField2Bit PC,
SCSICmdField6Bit PAGE_CODE,
SCSICmdField1Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::MODE_SENSE_6 called\n" ) );
require ( IsParameterValid ( DBD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PC, kSCSICmdFieldMask2Bit ), ErrorExit );
require ( IsParameterValid ( PAGE_CODE, kSCSICmdFieldMask6Bit ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_MODE_SENSE_6,
DBD << 3,
( PC << 6) | PAGE_CODE,
0x00,
ALLOCATION_LENGTH,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::MODE_SENSE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit LLBAA,
SCSICmdField1Bit DBD,
SCSICmdField2Bit PC,
SCSICmdField6Bit PAGE_CODE,
SCSICmdField2Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::MODE_SENSE_10 called\n" ) );
require ( IsParameterValid ( LLBAA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DBD, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PC, kSCSICmdFieldMask2Bit ), ErrorExit );
require ( IsParameterValid ( PAGE_CODE, kSCSICmdFieldMask6Bit ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_MODE_SENSE_10,
( LLBAA << 4 ) | ( DBD << 3 ),
( PC << 6 ) | PAGE_CODE,
0x00,
0x00,
0x00,
0x00,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::PERSISTENT_RESERVE_IN (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField5Bit SERVICE_ACTION,
SCSICmdField2Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::PERSISTENT_RESERVE_IN called\n" ) );
require ( IsParameterValid ( SERVICE_ACTION, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_PERSISTENT_RESERVE_IN,
SERVICE_ACTION,
0x00,
0x00,
0x00,
0x00,
0x00,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::PERSISTENT_RESERVE_OUT (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField5Bit SERVICE_ACTION,
SCSICmdField4Bit SCOPE,
SCSICmdField4Bit TYPE,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::PERSISTENT_RESERVE_OUT called\n" ) );
require ( IsParameterValid ( SERVICE_ACTION, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( SCOPE, kSCSICmdFieldMask4Bit ), ErrorExit );
require ( IsParameterValid ( TYPE, kSCSICmdFieldMask4Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, 0x18 ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_PERSISTENT_RESERVE_OUT,
SERVICE_ACTION,
( SCOPE << 4 ) | TYPE,
0x00,
0x00,
0x00,
0x00,
0x00,
0x18,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
0x18 );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::PREVENT_ALLOW_MEDIUM_REMOVAL (
SCSITask * request,
SCSICmdField2Bit PREVENT,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::PREVENT_ALLOW_MEDIUM_REMOVAL called\n" ) );
require ( IsParameterValid ( PREVENT, kSCSICmdFieldMask2Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_PREVENT_ALLOW_MEDIUM_REMOVAL,
0x00,
0x00,
0x00,
PREVENT,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::READ_BUFFER (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Bit MODE,
SCSICmdField1Byte BUFFER_ID,
SCSICmdField3Byte BUFFER_OFFSET,
SCSICmdField3Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::READ_BUFFER called\n" ) );
require ( IsParameterValid ( MODE, kSCSICmdFieldMask4Bit ), ErrorExit );
require ( IsParameterValid ( BUFFER_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( BUFFER_OFFSET, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_BUFFER,
MODE,
BUFFER_ID,
( BUFFER_OFFSET >> 16 ) & 0xFF,
( BUFFER_OFFSET >> 8 ) & 0xFF,
BUFFER_OFFSET & 0xFF,
( ALLOCATION_LENGTH >> 16 ) & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RECEIVE (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RECEIVE called\n" ) );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RECEIVE,
0x00,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
TRANSFER_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RECEIVE_COPY_RESULTS (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField5Bit SERVICE_ACTION,
SCSICmdField1Byte LIST_IDENTIFIER,
SCSICmdField4Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RECEIVE_COPY_RESULTS called\n" ) );
require ( IsParameterValid ( SERVICE_ACTION, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( LIST_IDENTIFIER, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RECEIVE_COPY_RESULTS,
SERVICE_ACTION,
LIST_IDENTIFIER,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
( ALLOCATION_LENGTH >> 24 ) & 0xFF,
( ALLOCATION_LENGTH >> 16 ) & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RECEIVE_DIAGNOSTICS_RESULTS (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PCV,
SCSICmdField1Byte PAGE_CODE,
SCSICmdField2Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RECEIVE_DIAGNOSTICS_RESULTS called\n" ) );
require ( IsParameterValid ( PCV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PAGE_CODE, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RECEIVE_DIAGNOSTICS_RESULTS,
PCV,
PAGE_CODE,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RELEASE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit THRDPTY,
SCSICmdField1Bit LONGID,
SCSICmdField1Byte THIRD_PARTY_DEVICE_ID,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RELEASE_10 called\n" ) );
require ( IsParameterValid ( THRDPTY, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGID, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( THIRD_PARTY_DEVICE_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RELEASE_10,
( THRDPTY << 4 ) | ( LONGID << 1 ),
0x00,
THIRD_PARTY_DEVICE_ID,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RELEASE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit THRDPTY,
SCSICmdField1Bit LONGID,
SCSICmdField1Bit EXTENT,
SCSICmdField1Byte RESERVATION_IDENTIFICATION,
SCSICmdField1Byte THIRD_PARTY_DEVICE_ID,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RELEASE_10 *OBSOLETE* called\n" ) );
require ( IsParameterValid ( THRDPTY, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGID, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( EXTENT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( RESERVATION_IDENTIFICATION, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( THIRD_PARTY_DEVICE_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RELEASE_10,
( THRDPTY << 4 ) | ( LONGID << 1 ) | EXTENT,
RESERVATION_IDENTIFICATION,
THIRD_PARTY_DEVICE_ID,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RELEASE_6 (
SCSITask * request,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RELEASE_6 called\n" ) );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RELEASE_6,
0x00,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RELEASE_6 (
SCSITask * request,
SCSICmdField1Bit EXTENT,
SCSICmdField1Byte RESERVATION_IDENTIFICATION,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RELEASE_6 *OBSOLETE* called\n" ) );
require ( IsParameterValid ( EXTENT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( RESERVATION_IDENTIFICATION, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RELEASE_6,
EXTENT,
RESERVATION_IDENTIFICATION,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::REPORT_DEVICE_IDENTIFIER (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::REPORT_DEVICE_IDENTIFIER called\n" ) );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_REPORT_DEVICE_IDENTIFIER,
0x05,
0x00,
0x00,
0x00,
0x00,
( ALLOCATION_LENGTH >> 24 ) & 0xFF,
( ALLOCATION_LENGTH >> 16 ) & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::REPORT_LUNS (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::REPORT_LUNS called\n" ) );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_REPORT_LUNS,
0x00,
0x00,
0x00,
0x00,
0x00,
( ALLOCATION_LENGTH >> 24 ) & 0xFF,
( ALLOCATION_LENGTH >> 16 ) & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::REQUEST_SENSE (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::REQUEST_SENSE called\n" ) );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_REQUEST_SENSE,
0x00,
0x00,
0x00,
ALLOCATION_LENGTH,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromTargetToInitiator,
dataBuffer,
ALLOCATION_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RESERVE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit THRDPTY,
SCSICmdField1Bit LONGID,
SCSICmdField1Byte THIRD_PARTY_DEVICE_ID,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RESERVE_10 called\n" ) );
require ( IsParameterValid ( THRDPTY, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGID, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( THIRD_PARTY_DEVICE_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RESERVE_10,
( THRDPTY << 4 ) | ( LONGID << 1 ),
0x00,
THIRD_PARTY_DEVICE_ID,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RESERVE_10 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit THRDPTY,
SCSICmdField1Bit LONGID,
SCSICmdField1Bit EXTENT,
SCSICmdField1Byte RESERVATION_IDENTIFICATION,
SCSICmdField1Byte THIRD_PARTY_DEVICE_ID,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RESERVE_10 *OBSOLETE* called\n" ) );
require ( IsParameterValid ( THRDPTY, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGID, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( EXTENT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( RESERVATION_IDENTIFICATION, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( THIRD_PARTY_DEVICE_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RESERVE_10,
( THRDPTY << 4 ) | ( LONGID << 1 ) | EXTENT,
RESERVATION_IDENTIFICATION,
THIRD_PARTY_DEVICE_ID,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RESERVE_6 (
SCSITask * request,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RESERVE_6 called\n" ) );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RESERVE_6,
0x00,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::RESERVE_6 (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit EXTENT,
SCSICmdField1Byte RESERVATION_IDENTIFICATION,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::RESERVE_6 *OBSOLETE* called\n" ) );
require ( IsParameterValid ( EXTENT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( RESERVATION_IDENTIFICATION, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_RESERVE_6,
EXTENT,
RESERVATION_IDENTIFICATION,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::SEND (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit AER,
SCSICmdField3Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::SEND called\n" ) );
require ( IsParameterValid ( AER, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SEND,
AER,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
TRANSFER_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::SEND_DIAGNOSTICS (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Bit SELF_TEST_CODE,
SCSICmdField1Bit PF,
SCSICmdField1Bit SELF_TEST,
SCSICmdField1Bit DEVOFFL,
SCSICmdField1Bit UNITOFFL,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::SEND_DIAGNOSTICS called\n" ) );
require ( IsParameterValid ( SELF_TEST_CODE, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( PF, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SELF_TEST, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DEVOFFL, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( UNITOFFL, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
if ( SELF_TEST == 1 )
{
require ( ( SELF_TEST_CODE == 0x00 ), ErrorExit );
}
SetCommandDescriptorBlock ( request,
kSCSICmd_SEND_DIAGNOSTICS,
( SELF_TEST_CODE << 5 ) | ( PF << 4 ) |
( SELF_TEST << 2 ) | ( DEVOFFL << 1 ) | UNITOFFL,
0x00,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::SET_DEVICE_IDENTIFIER (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField5Bit SERVICE_ACTION,
SCSICmdField4Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::SET_DEVICE_IDENTIFIER called\n" ) );
require ( IsParameterValid ( SERVICE_ACTION, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SET_DEVICE_IDENTIFIER,
SERVICE_ACTION,
0x00,
0x00,
0x00,
0x00,
( PARAMETER_LIST_LENGTH >> 24 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::TEST_UNIT_READY (
SCSITask * request,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::TEST_UNIT_READY called\n" ) );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_TEST_UNIT_READY,
0x00,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferControl ( request,
10 * 1000,
kSCSIDataTransfer_NoDataTransfer );
result = true;
ErrorExit:
return result;
}
bool
SCSIPrimaryCommands::WRITE_BUFFER (
SCSITask * request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Bit MODE,
SCSICmdField1Byte BUFFER_ID,
SCSICmdField3Byte BUFFER_OFFSET,
SCSICmdField3Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool result = false;
STATUS_LOG ( ( "SCSIPrimaryCommands::WRITE_BUFFER called\n" ) );
require ( IsParameterValid ( MODE, kSCSICmdFieldMask4Bit ), ErrorExit );
require ( IsParameterValid ( BUFFER_ID, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( BUFFER_OFFSET, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask3Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_BUFFER,
MODE,
BUFFER_ID,
( BUFFER_OFFSET >> 16 ) & 0xFF,
( BUFFER_OFFSET >> 8 ) & 0xFF,
BUFFER_OFFSET & 0xFF,
( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF,
( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF,
PARAMETER_LIST_LENGTH & 0xFF,
CONTROL );
SetDataTransferControl ( request,
0,
kSCSIDataTransfer_FromInitiatorToTarget,
dataBuffer,
PARAMETER_LIST_LENGTH );
result = true;
ErrorExit:
return result;
}
#if 0
#pragma mark -
#pragma mark ₯ Utility Methods
#pragma mark -
#endif
bool
SCSIPrimaryCommands::IsParameterValid ( SCSICmdField1Byte param,
SCSICmdField1Byte mask )
{
bool valid = false;
require ( ( param | mask ) == mask, ErrorExit );
valid = true;
ErrorExit:
return valid;
}
bool
SCSIPrimaryCommands::IsParameterValid ( SCSICmdField2Byte param,
SCSICmdField2Byte mask )
{
bool valid = false;
require ( ( param | mask ) == mask, ErrorExit );
valid = true;
ErrorExit:
return valid;
}
bool
SCSIPrimaryCommands::IsParameterValid ( SCSICmdField4Byte param,
SCSICmdField4Byte mask )
{
bool valid = false;
require ( ( param | mask ) == mask, ErrorExit );
valid = true;
ErrorExit:
return valid;
}
bool
SCSIPrimaryCommands::IsBufferAndCapacityValid (
IOMemoryDescriptor * dataBuffer,
UInt32 requiredSize )
{
bool valid = false;
require_nonzero ( dataBuffer, ErrorExit );
require ( ( dataBuffer->getLength ( ) >= requiredSize ), ErrorExit );
valid = true;
ErrorExit:
return valid;
}
bool
SCSIPrimaryCommands::SetCommandDescriptorBlock (
SCSITask * request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5 )
{
check ( request != NULL );
return request->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5 );
}
bool
SCSIPrimaryCommands::SetCommandDescriptorBlock (
SCSITask * request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9 )
{
check ( request != NULL );
return request->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9 );
}
bool
SCSIPrimaryCommands::SetCommandDescriptorBlock (
SCSITask * request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9,
UInt8 cdbByte10,
UInt8 cdbByte11 )
{
check ( request != NULL );
return request->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9,
cdbByte10,
cdbByte11 );
}
bool
SCSIPrimaryCommands::SetCommandDescriptorBlock (
SCSITask * request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9,
UInt8 cdbByte10,
UInt8 cdbByte11,
UInt8 cdbByte12,
UInt8 cdbByte13,
UInt8 cdbByte14,
UInt8 cdbByte15 )
{
check ( request != NULL );
return request->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9,
cdbByte10,
cdbByte11,
cdbByte12,
cdbByte13,
cdbByte14,
cdbByte15 );
}
bool
SCSIPrimaryCommands::SetDataTransferControl (
SCSITask * request,
UInt32 timeoutDuration,
UInt8 dataTransferDirection,
IOMemoryDescriptor * dataBuffer,
UInt64 transferCountInBytes )
{
bool result = false;
check ( request != NULL );
if ( transferCountInBytes != 0 )
{
require_nonzero ( dataBuffer, ErrorExit );
}
result = request->SetTimeoutDuration ( timeoutDuration );
require ( result, ErrorExit );
result = request->SetDataTransferDirection ( dataTransferDirection );
require ( result, ErrorExit );
result = request->SetDataBuffer ( dataBuffer );
require ( result, ErrorExit );
result = request->SetRequestedDataTransferCount ( transferCountInBytes );
require ( result, ErrorExit );
result = true;
ErrorExit:
return result;
}
#if 0
#pragma mark -
#pragma mark ₯ Static Methods
#pragma mark -
#endif
SCSIPrimaryCommands *
SCSIPrimaryCommands::CreateSCSIPrimaryCommandObject ( void )
{
return OSTypeAlloc ( SCSIPrimaryCommands );
}