IOSCSIBlockCommandsBuilder.cpp [plain text]
#include <IOKit/scsi/SCSICommandDefinitions.h>
#include "IOSCSIBlockCommandsDevice.h"
#include "SCSIBlockCommands.h"
#include "SCSICommandOperationCodes.h"
#define DEBUG 0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "SBC"
#if DEBUG
#define SCSI_SBC_DEVICE_DEBUGGING_LEVEL 0
#endif
#include "IOSCSIArchitectureModelFamilyDebugging.h"
#if 0
#pragma mark -
#pragma mark ₯ Block Commands Builders
#pragma mark -
#endif
bool
IOSCSIBlockCommandsDevice::ERASE_10 (
SCSITaskIdentifier request,
SCSICmdField1Bit ERA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->ERASE_10 (
scsiRequest,
ERA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::ERASE_12 (
SCSITaskIdentifier request,
SCSICmdField1Bit ERA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->ERASE_12 (
scsiRequest,
ERA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::FORMAT_UNIT(
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
IOByteCount defectListSize,
SCSICmdField1Bit FMTDATA,
SCSICmdField1Bit CMPLST,
SCSICmdField3Bit DEFECT_LIST_FORMAT,
SCSICmdField1Byte VENDOR_SPECIFIC,
SCSICmdField2Byte INTERLEAVE,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->FORMAT_UNIT (
scsiRequest,
dataBuffer,
defectListSize,
FMTDATA,
CMPLST,
DEFECT_LIST_FORMAT,
VENDOR_SPECIFIC,
INTERLEAVE,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::FORMAT_UNIT (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
IOByteCount defectListSize,
SCSICmdField1Bit FMTPINFO,
SCSICmdField1Bit RTO_REQ,
SCSICmdField1Bit LONGLIST,
SCSICmdField1Bit FMTDATA,
SCSICmdField1Bit CMPLST,
SCSICmdField3Bit DEFECT_LIST_FORMAT,
SCSICmdField1Byte VENDOR_SPECIFIC,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( FMTPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( RTO_REQ, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGLIST, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FMTDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( CMPLST, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DEFECT_LIST_FORMAT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( VENDOR_SPECIFIC, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
if ( defectListSize > 0 )
{
require ( IsMemoryDescriptorValid ( dataBuffer, defectListSize ), ErrorExit );
}
SetCommandDescriptorBlock ( request,
kSCSICmd_FORMAT_UNIT,
( FMTPINFO << 7 ) | ( RTO_REQ << 6 ) | ( LONGLIST << 5 ) | ( FMTDATA << 4 ) | ( CMPLST << 3 ) | DEFECT_LIST_FORMAT,
VENDOR_SPECIFIC,
0x00,
0x00,
CONTROL );
if ( FMTDATA == 0 )
{
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
}
else
{
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, defectListSize );
}
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE (
SCSITaskIdentifier request,
SCSICmdField1Bit LOCK,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->LOCK_UNLOCK_CACHE (
scsiRequest,
LOCK,
RELADR,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE (
SCSITaskIdentifier request,
SCSICmdField1Bit LOCK,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( LOCK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_LOCK_UNLOCK_CACHE,
( LOCK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
NUMBER_OF_BLOCKS & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE_16 (
SCSITaskIdentifier request,
SCSICmdField1Bit LOCK,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require( IsParameterValid( LOCK, kSCSICmdFieldMask1Bit ), ErrorExit );
require( IsParameterValid( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require( IsParameterValid( NUMBER_OF_BLOCKS, kSCSICmdFieldMask4Byte ), ErrorExit );
require( IsParameterValid( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_LOCK_UNLOCK_CACHE_16,
LOCK << 1,
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( NUMBER_OF_BLOCKS >> 24 ) & 0xFF,
( NUMBER_OF_BLOCKS >> 16 ) & 0xFF,
( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
NUMBER_OF_BLOCKS & 0xFF,
0x00,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::MEDIUM_SCAN (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit WBS,
SCSICmdField1Bit ASA,
SCSICmdField1Bit RSD,
SCSICmdField1Bit PRA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->MEDIUM_SCAN (
scsiRequest,
dataBuffer,
WBS,
ASA,
RSD,
PRA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
PARAMETER_LIST_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::PREFETCH (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->PREFETCH (
scsiRequest,
IMMED,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::PREFETCH (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require( IsParameterValid( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_PREFETCH,
( IMMED << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::PREFETCH_16 (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require( IsParameterValid( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require( IsParameterValid( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require( IsParameterValid( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require( IsParameterValid( CONTROL, kSCSICmdFieldMask1Bit ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_PREFETCH_16,
IMMED << 1,
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_6 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField21Bit LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt32 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
if ( TRANSFER_LENGTH == 0 )
{
requestedByteCount = 256 * blockSize;
}
else
{
requestedByteCount = TRANSFER_LENGTH * blockSize;
}
status = GetSCSIBlockCommandObject ( )->READ_6 (
scsiRequest,
dataBuffer,
requestedByteCount,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->READ_10 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
FUA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit RDPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_10,
( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromTargetToInitiator );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->READ_12 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
FUA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit RDPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_12,
( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromTargetToInitiator );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit RDPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_READ_16,
( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromTargetToInitiator );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_CAPACITY (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Bit PMI,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_CAPACITY (
scsiRequest,
dataBuffer,
RELADR,
LOGICAL_BLOCK_ADDRESS,
PMI,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_CAPACITY_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte ALLOCATION_LENGTH,
SCSICmdField1Bit PMI,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( PMI, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SERVICE_ACTION_IN,
kSCSIServiceAction_READ_CAPACITY_16,
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( ALLOCATION_LENGTH >> 24 ) & 0xFF,
( ALLOCATION_LENGTH >> 16 ) & 0xFF,
( ALLOCATION_LENGTH >> 8 ) & 0xFF,
ALLOCATION_LENGTH & 0xFF,
PMI,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromTargetToInitiator );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, ALLOCATION_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_DEFECT_DATA_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PLIST,
SCSICmdField1Bit GLIST,
SCSICmdField3Bit DEFECT_LIST_FORMAT,
SCSICmdField2Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_DEFECT_DATA_10 (
scsiRequest,
dataBuffer,
PLIST,
GLIST,
DEFECT_LIST_FORMAT,
ALLOCATION_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_DEFECT_DATA_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PLIST,
SCSICmdField1Bit GLIST,
SCSICmdField3Bit DEFECT_LIST_FORMAT,
SCSICmdField4Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_DEFECT_DATA_12 (
scsiRequest,
dataBuffer,
PLIST,
GLIST,
DEFECT_LIST_FORMAT,
ALLOCATION_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_GENERATION (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte ALLOCATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_GENERATION (
scsiRequest,
dataBuffer,
RELADR,
LOGICAL_BLOCK_ADDRESS,
ALLOCATION_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_LONG (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit CORRCT,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte BYTE_TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_LONG (
scsiRequest,
dataBuffer,
CORRCT,
RELADR,
LOGICAL_BLOCK_ADDRESS,
BYTE_TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_LONG_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte BYTE_TRANSFER_LENGTH,
SCSICmdField1Bit CORRCT,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( BYTE_TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CORRCT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, BYTE_TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SERVICE_ACTION_IN,
kSCSIServiceAction_READ_LONG_16,
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
0x00,
( BYTE_TRANSFER_LENGTH >> 8 ) & 0xFF,
BYTE_TRANSFER_LENGTH & 0xFF,
CORRCT,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromTargetToInitiator );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, BYTE_TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::READ_UPDATED_BLOCK_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Bit LATEST,
SCSICmdField15Bit GENERATION_ADDRESS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->READ_UPDATED_BLOCK_10 (
scsiRequest,
dataBuffer,
fMediumBlockSize,
DPO,
FUA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
LATEST,
GENERATION_ADDRESS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::REASSIGN_BLOCKS (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->REASSIGN_BLOCKS (
scsiRequest,
dataBuffer,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::REASSIGN_BLOCKS (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit LONGLBA,
SCSICmdField1Bit LONGLIST,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( LONGLBA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LONGLIST, kSCSICmdFieldMask1Bit ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_REASSIGN_BLOCKS,
( LONGLBA << 1 ) | LONGLIST,
0x00,
0x00,
0x00,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::REBUILD (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit INTDATA,
SCSICmdField2Bit PORT_CONTROL,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte REBUILD_LENGTH,
SCSICmdField4Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->REBUILD (
scsiRequest,
dataBuffer,
DPO,
FUA,
INTDATA,
PORT_CONTROL,
LOGICAL_BLOCK_ADDRESS,
REBUILD_LENGTH,
PARAMETER_LIST_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::REGENERATE (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit INTDATA,
SCSICmdField2Bit PORT_CONTROL,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte REBUILD_LENGTH,
SCSICmdField4Byte PARAMETER_LIST_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->REGENERATE (
scsiRequest,
dataBuffer,
DPO,
FUA,
INTDATA,
PORT_CONTROL,
LOGICAL_BLOCK_ADDRESS,
REBUILD_LENGTH,
PARAMETER_LIST_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::REZERO_UNIT (
SCSITaskIdentifier request,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->REZERO_UNIT (
scsiRequest,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_EQUAL_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit INVERT,
SCSICmdField1Bit SPNDAT,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_EQUAL_10 (
scsiRequest,
dataBuffer,
dataBuffer->getLength ( ),
INVERT,
SPNDAT,
RELADR,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS_TO_SEARCH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_HIGH_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit INVERT,
SCSICmdField1Bit SPNDAT,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_HIGH_10 (
scsiRequest,
dataBuffer,
dataBuffer->getLength ( ),
INVERT,
SPNDAT,
RELADR,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS_TO_SEARCH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_LOW_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit INVERT,
SCSICmdField1Bit SPNDAT,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_LOW_10 (
scsiRequest,
dataBuffer,
dataBuffer->getLength ( ),
INVERT,
SPNDAT,
RELADR,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS_TO_SEARCH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SEEK_6 (
SCSITaskIdentifier request,
SCSICmdField21Bit LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SEEK_6 (
scsiRequest,
LOGICAL_BLOCK_ADDRESS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SEEK_10 (
SCSITaskIdentifier request,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SEEK_10 (
scsiRequest,
LOGICAL_BLOCK_ADDRESS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SET_LIMITS_10 (
SCSITaskIdentifier request,
SCSICmdField1Bit RDINH,
SCSICmdField1Bit WRINH,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SET_LIMITS_10 (
scsiRequest,
RDINH,
WRINH,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SET_LIMITS_12 (
SCSITaskIdentifier request,
SCSICmdField1Bit RDINH,
SCSICmdField1Bit WRINH,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SET_LIMITS_12 (
scsiRequest,
RDINH,
WRINH,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::START_STOP_UNIT (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField4Bit POWER_CONDITIONS,
SCSICmdField1Bit LOEJ,
SCSICmdField1Bit START,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->START_STOP_UNIT (
scsiRequest,
IMMED,
POWER_CONDITIONS,
LOEJ,
START,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SYNCHRONIZE_CACHE (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->SYNCHRONIZE_CACHE (
scsiRequest,
IMMED,
RELADR,
LOGICAL_BLOCK_ADDRESS,
NUMBER_OF_BLOCKS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SYNCHRONIZE_CACHE (
SCSITaskIdentifier request,
SCSICmdField1Bit IMMED,
SCSICmdField1Bit SYNC_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte NUMBER_OF_BLOCKS,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( SYNC_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SYNCHRONIZE_CACHE,
( SYNC_NV << 2 ) | ( IMMED << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
NUMBER_OF_BLOCKS & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::SYNCRONIZE_CACHE_16 (
SCSITaskIdentifier request,
SCSICmdField1Bit SYNC_NV,
SCSICmdField1Bit IMMED,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte NUMBER_OF_BLOCKS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( SYNC_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_SYNCHRONIZE_CACHE_16,
( SYNC_NV << 2 ) | ( IMMED << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( NUMBER_OF_BLOCKS >> 24 ) & 0xFF,
( NUMBER_OF_BLOCKS >> 16 ) & 0xFF,
( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
NUMBER_OF_BLOCKS & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::UPDATE_BLOCK (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->UPDATE_BLOCK (
scsiRequest,
dataBuffer,
fMediumBlockSize,
RELADR,
LOGICAL_BLOCK_ADDRESS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::VERIFY_10 (
SCSITaskIdentifier request,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BLKVFY,
SCSICmdField1Bit BYTCHK,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte VERIFICATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->VERIFY_10 (
scsiRequest,
DPO,
BLKVFY,
BYTCHK,
RELADR,
LOGICAL_BLOCK_ADDRESS,
VERIFICATION_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::VERIFY_10 (
SCSITaskIdentifier request,
SCSICmdField3Bit VRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte VERIFICATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_VERIFY_10,
( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( VERIFICATION_LENGTH >> 8 ) & 0xFF,
VERIFICATION_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::VERIFY_12 (
SCSITaskIdentifier request,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BLKVFY,
SCSICmdField1Bit BYTCHK,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte VERIFICATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->VERIFY_12 (
scsiRequest,
DPO,
BLKVFY,
BYTCHK,
RELADR,
LOGICAL_BLOCK_ADDRESS,
VERIFICATION_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::VERIFY_12 (
SCSITaskIdentifier request,
SCSICmdField3Bit VRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField4Byte VERIFICATION_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_VERIFY_12,
( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( VERIFICATION_LENGTH >> 24 ) & 0xFF,
( VERIFICATION_LENGTH >> 16 ) & 0xFF,
( VERIFICATION_LENGTH >> 8 ) & 0xFF,
VERIFICATION_LENGTH & 0xFF,
0x00,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::VERIFY_16 (
SCSITaskIdentifier request,
SCSICmdField3Bit VRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte VERIFICATION_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_VERIFY_16,
( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( VERIFICATION_LENGTH >> 24 ) & 0xFF,
( VERIFICATION_LENGTH >> 16 ) & 0xFF,
( VERIFICATION_LENGTH >> 8 ) & 0xFF,
VERIFICATION_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_NoDataTransfer );
SetTimeoutDuration ( request, 0 );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_6 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField2Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField1Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt32 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
if ( TRANSFER_LENGTH == 0 )
{
requestedByteCount = 256 * blockSize;
}
else
{
requestedByteCount = TRANSFER_LENGTH * blockSize;
}
status = GetSCSIBlockCommandObject ( )->WRITE_6 (
scsiRequest,
dataBuffer,
requestedByteCount,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit EBP,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->WRITE_10 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
FUA,
EBP,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_10,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit EBP,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->WRITE_12 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
FUA,
EBP,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_12,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_16,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit EBP,
SCSICmdField1Bit BYTCHK,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->WRITE_AND_VERIFY_10 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
EBP,
BYTCHK,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_AND_VERIFY_10,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField1Bit DPO,
SCSICmdField1Bit EBP,
SCSICmdField1Bit BYTCHK,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
UInt64 requestedByteCount = 0;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
status = GetSCSIBlockCommandObject ( )->WRITE_AND_VERIFY_12 (
scsiRequest,
dataBuffer,
requestedByteCount,
DPO,
EBP,
BYTCHK,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_12 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_AND_VERIFY_10,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
UInt32 blockSize,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit BYTCHK,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
UInt64 requestedByteCount = 0;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require_nonzero ( blockSize, ErrorExit );
requestedByteCount = TRANSFER_LENGTH * blockSize;
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_AND_VERIFY_16,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, requestedByteCount );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_LONG (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->WRITE_LONG (
scsiRequest,
dataBuffer,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_LONG_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Bit CORRCT,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CORRCT, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_LONG,
0x11, ( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
0x00,
0x00,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CORRCT,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_SAME (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit PBDATA,
SCSICmdField1Bit LBDATA,
SCSICmdField1Bit RELADR,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->WRITE_SAME (
scsiRequest,
dataBuffer,
PBDATA,
LBDATA,
RELADR,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_SAME (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit PBDATA,
SCSICmdField1Bit LBDATA,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( PBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
require ( ( PBDATA == !LBDATA ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_SAME,
( WRPROTECT << 5 ) | ( PBDATA << 2 ) | ( LBDATA << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::WRITE_SAME_16 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit PBDATA,
SCSICmdField1Bit LBDATA,
SCSICmdField8Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( PBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
require ( ( PBDATA == !LBDATA ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_WRITE_SAME_16,
( WRPROTECT << 5 ) | ( PBDATA << 2 ) | ( LBDATA << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
( TRANSFER_LENGTH >> 24 ) & 0xFF,
( TRANSFER_LENGTH >> 16 ) & 0xFF,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
GROUP_NUMBER,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDREAD (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->XDREAD (
scsiRequest,
dataBuffer,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDREAD (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit XORPINFO,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( XORPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_XDREAD,
XORPINFO,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDWRITE (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit DISABLE_WRITE,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->XDWRITE (
scsiRequest,
dataBuffer,
DPO,
FUA,
DISABLE_WRITE,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDWRITE (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit DISABLE_WRITE,
SCSICmdField1Bit FUA_NV,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_XDWRITE,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE << 2 ) | ( FUA_NV << 1 ),
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDWRITE_EXTENDED (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit TABLE_ADDRESS,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit DISABLE_WRITE,
SCSICmdField2Bit PORT_CONTROL,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField4Byte SECONDARY_BLOCK_ADDRESS,
SCSICmdField4Byte TRANSFER_LENGTH,
SCSICmdField1Byte SECONDARY_ADDRESS,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->XDWRITE_EXTENDED (
scsiRequest,
dataBuffer,
TABLE_ADDRESS,
DPO,
FUA,
DISABLE_WRITE,
PORT_CONTROL,
LOGICAL_BLOCK_ADDRESS,
SECONDARY_BLOCK_ADDRESS,
TRANSFER_LENGTH,
SECONDARY_ADDRESS,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XDWRITEREAD_10 (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField3Bit WRPROTECT,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit DISABLE_WRITE,
SCSICmdField1Bit FUA_NV,
SCSICmdField1Bit XORPINFO,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( XORPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_XDWRITE,
( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE << 2 ) | ( FUA_NV << 1 ) | XORPINFO,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XPWRITE (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
SCSITask * scsiRequest = NULL;
bool status = false;
scsiRequest = OSDynamicCast ( SCSITask, request );
require_nonzero ( scsiRequest, ErrorExit );
require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
status = GetSCSIBlockCommandObject ( )->XPWRITE (
scsiRequest,
dataBuffer,
DPO,
FUA,
LOGICAL_BLOCK_ADDRESS,
TRANSFER_LENGTH,
CONTROL );
ErrorExit:
return status;
}
bool
IOSCSIBlockCommandsDevice::XPWRITE (
SCSITaskIdentifier request,
IOMemoryDescriptor * dataBuffer,
SCSICmdField1Bit DPO,
SCSICmdField1Bit FUA,
SCSICmdField1Bit FUA_NV,
SCSICmdField1Bit XORPINFO,
SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS,
SCSICmdField5Bit GROUP_NUMBER,
SCSICmdField2Byte TRANSFER_LENGTH,
SCSICmdField1Byte CONTROL )
{
bool status = false;
require_nonzero ( request, ErrorExit );
require ( ResetForNewTask ( request ), ErrorExit );
require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
SetCommandDescriptorBlock ( request,
kSCSICmd_XPWRITE,
( DPO << 4 ) | ( FUA << 3 ) | (FUA_NV << 1) | XORPINFO,
( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
LOGICAL_BLOCK_ADDRESS & 0xFF,
GROUP_NUMBER,
( TRANSFER_LENGTH >> 8 ) & 0xFF,
TRANSFER_LENGTH & 0xFF,
CONTROL );
SetDataTransferDirection ( request, kSCSIDataTransfer_FromInitiatorToTarget );
SetTimeoutDuration ( request, 0 );
SetDataBuffer ( request, dataBuffer );
SetRequestedDataTransferCount ( request, TRANSFER_LENGTH );
status = true;
ErrorExit:
return status;
}