#include "SCSITask.h"
#define super IOCommand
OSDefineMetaClassAndStructors ( SCSITask, IOCommand );
bool
SCSITask::init ( void )
{
if ( super::init ( ) == false )
{
return false;
}
fOwner = NULL;
fAutosenseDescriptor = NULL;
fTaskState = kSCSITaskState_NEW_TASK;
return ResetForNewTask ( );
}
void
SCSITask::free ( void )
{
if ( fOwner != NULL )
{
fOwner->release ( );
}
if ( fAutosenseDescriptor != NULL )
{
fAutosenseDescriptor->release ( );
fAutosenseDescriptor = NULL;
}
super::free ( );
}
bool
SCSITask::ResetForNewTask ( void )
{
if ( IsTaskActive ( ) == true )
{
return false;
}
fTaskAttribute = kSCSITask_SIMPLE;
fTaskState = kSCSITaskState_NEW_TASK;
fTaskStatus = kSCSITaskStatus_GOOD;
fLogicalUnitNumber = 0;
bzero ( &fCommandDescriptorBlock, kSCSICDBSize_Maximum );
fCommandSize = 0;
fTransferDirection = 0;
fDataBuffer = NULL;
fDataBufferOffset = 0;
fRequestedByteCountOfTransfer = 0;
fRealizedByteCountOfTransfer = 0;
fTimeoutDuration = 0;
fCompletionCallback = NULL;
fServiceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
fNextTaskInQueue = NULL;
fProtocolLayerReference = NULL;
fApplicationLayerReference = NULL;
fAutosenseDataRequested = false;
fAutosenseCDBSize = 0;
fAutoSenseDataIsValid = false;
bzero ( &fAutosenseCDB, kSCSICDBSize_Maximum );
bzero ( &fAutoSenseData, sizeof ( SCSI_Sense_Data ) );
if ( fAutosenseDescriptor == NULL )
{
fAutosenseDescriptor = IOMemoryDescriptor::withAddress (
( void * ) &fAutoSenseData, sizeof ( SCSI_Sense_Data ), kIODirectionIn );
}
fAutoSenseRealizedByteCountOfTransfer = 0;
return true;
}
bool
SCSITask::SetTaskOwner ( OSObject * taskOwner )
{
if ( fOwner != NULL )
{
fOwner->release ( );
}
fOwner = taskOwner;
fOwner->retain ( );
return true;
}
OSObject *
SCSITask::GetTaskOwner ( void )
{
return fOwner;
}
bool
SCSITask::IsTaskActive ( void )
{
if ( ( fTaskState == kSCSITaskState_NEW_TASK ) ||
( fTaskState == kSCSITaskState_ENDED ) )
{
return false;
}
return true;
}
bool
SCSITask::SetLogicalUnitNumber( UInt8 newLUN )
{
fLogicalUnitNumber = newLUN;
return true;
}
UInt8
SCSITask::GetLogicalUnitNumber( void )
{
return fLogicalUnitNumber;
}
bool
SCSITask::SetTaskAttribute ( SCSITaskAttribute newAttributeValue )
{
fTaskAttribute = newAttributeValue;
return true;
}
SCSITaskAttribute
SCSITask::GetTaskAttribute ( void )
{
return fTaskAttribute;
}
bool
SCSITask::SetTaskState ( SCSITaskState newTaskState )
{
fTaskState = newTaskState;
return true;
}
SCSITaskState
SCSITask::GetTaskState ( void )
{
return fTaskState;
}
bool
SCSITask::SetTaskStatus ( SCSITaskStatus newTaskStatus )
{
fTaskStatus = newTaskStatus;
return true;
}
SCSITaskStatus
SCSITask::GetTaskStatus ( void )
{
return fTaskStatus;
}
bool
SCSITask::SetCommandDescriptorBlock (
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5 )
{
fCommandDescriptorBlock[0] = cdbByte0;
fCommandDescriptorBlock[1] = cdbByte1;
fCommandDescriptorBlock[2] = cdbByte2;
fCommandDescriptorBlock[3] = cdbByte3;
fCommandDescriptorBlock[4] = cdbByte4;
fCommandDescriptorBlock[5] = cdbByte5;
fCommandDescriptorBlock[6] = 0x00;
fCommandDescriptorBlock[7] = 0x00;
fCommandDescriptorBlock[8] = 0x00;
fCommandDescriptorBlock[9] = 0x00;
fCommandDescriptorBlock[10] = 0x00;
fCommandDescriptorBlock[11] = 0x00;
fCommandDescriptorBlock[12] = 0x00;
fCommandDescriptorBlock[13] = 0x00;
fCommandDescriptorBlock[14] = 0x00;
fCommandDescriptorBlock[15] = 0x00;
fCommandSize = kSCSICDBSize_6Byte;
return true;
}
bool
SCSITask::SetCommandDescriptorBlock (
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9 )
{
fCommandDescriptorBlock[0] = cdbByte0;
fCommandDescriptorBlock[1] = cdbByte1;
fCommandDescriptorBlock[2] = cdbByte2;
fCommandDescriptorBlock[3] = cdbByte3;
fCommandDescriptorBlock[4] = cdbByte4;
fCommandDescriptorBlock[5] = cdbByte5;
fCommandDescriptorBlock[6] = cdbByte6;
fCommandDescriptorBlock[7] = cdbByte7;
fCommandDescriptorBlock[8] = cdbByte8;
fCommandDescriptorBlock[9] = cdbByte9;
fCommandDescriptorBlock[10] = 0x00;
fCommandDescriptorBlock[11] = 0x00;
fCommandDescriptorBlock[12] = 0x00;
fCommandDescriptorBlock[13] = 0x00;
fCommandDescriptorBlock[14] = 0x00;
fCommandDescriptorBlock[15] = 0x00;
fCommandSize = kSCSICDBSize_10Byte;
return true;
}
bool
SCSITask::SetCommandDescriptorBlock (
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9,
UInt8 cdbByte10,
UInt8 cdbByte11 )
{
fCommandDescriptorBlock[0] = cdbByte0;
fCommandDescriptorBlock[1] = cdbByte1;
fCommandDescriptorBlock[2] = cdbByte2;
fCommandDescriptorBlock[3] = cdbByte3;
fCommandDescriptorBlock[4] = cdbByte4;
fCommandDescriptorBlock[5] = cdbByte5;
fCommandDescriptorBlock[6] = cdbByte6;
fCommandDescriptorBlock[7] = cdbByte7;
fCommandDescriptorBlock[8] = cdbByte8;
fCommandDescriptorBlock[9] = cdbByte9;
fCommandDescriptorBlock[10] = cdbByte10;
fCommandDescriptorBlock[11] = cdbByte11;
fCommandDescriptorBlock[12] = 0x00;
fCommandDescriptorBlock[13] = 0x00;
fCommandDescriptorBlock[14] = 0x00;
fCommandDescriptorBlock[15] = 0x00;
fCommandSize = kSCSICDBSize_12Byte;
return true;
}
bool
SCSITask::SetCommandDescriptorBlock (
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 )
{
fCommandDescriptorBlock[0] = cdbByte0;
fCommandDescriptorBlock[1] = cdbByte1;
fCommandDescriptorBlock[2] = cdbByte2;
fCommandDescriptorBlock[3] = cdbByte3;
fCommandDescriptorBlock[4] = cdbByte4;
fCommandDescriptorBlock[5] = cdbByte5;
fCommandDescriptorBlock[6] = cdbByte6;
fCommandDescriptorBlock[7] = cdbByte7;
fCommandDescriptorBlock[8] = cdbByte8;
fCommandDescriptorBlock[9] = cdbByte9;
fCommandDescriptorBlock[10] = cdbByte10;
fCommandDescriptorBlock[11] = cdbByte11;
fCommandDescriptorBlock[12] = cdbByte12;
fCommandDescriptorBlock[13] = cdbByte13;
fCommandDescriptorBlock[14] = cdbByte14;
fCommandDescriptorBlock[15] = cdbByte15;
fCommandSize = kSCSICDBSize_16Byte;
return true;
}
UInt8
SCSITask::GetCommandDescriptorBlockSize ( void )
{
return fCommandSize;
}
bool
SCSITask::GetCommandDescriptorBlock ( SCSICommandDescriptorBlock * cdbData )
{
bcopy ( fCommandDescriptorBlock, cdbData, sizeof ( SCSICommandDescriptorBlock ) );
return true;
}
bool
SCSITask::SetDataTransferDirection ( UInt8 newDataTransferDirection )
{
fTransferDirection = newDataTransferDirection;
return true;
}
UInt8
SCSITask::GetDataTransferDirection ( void )
{
return fTransferDirection;
}
bool
SCSITask::SetRequestedDataTransferCount ( UInt64 requestedTransferCountInBytes )
{
fRequestedByteCountOfTransfer = requestedTransferCountInBytes;
return true;
}
UInt64
SCSITask::GetRequestedDataTransferCount ( void )
{
return fRequestedByteCountOfTransfer;
}
bool
SCSITask::SetRealizedDataTransferCount ( UInt64 realizedTransferCountInBytes )
{
fRealizedByteCountOfTransfer = realizedTransferCountInBytes;
return true;
}
UInt64
SCSITask::GetRealizedDataTransferCount ( void )
{
return fRealizedByteCountOfTransfer;
}
bool
SCSITask::SetDataBuffer ( IOMemoryDescriptor * newDataBuffer )
{
fDataBuffer = newDataBuffer;
return true;
}
IOMemoryDescriptor *
SCSITask::GetDataBuffer ( void )
{
return fDataBuffer;
}
bool
SCSITask::SetDataBufferOffset ( UInt64 newDataBufferOffset )
{
fDataBufferOffset = newDataBufferOffset;
return true;
}
UInt64
SCSITask::GetDataBufferOffset ( void )
{
return fDataBufferOffset;
}
bool
SCSITask::SetTimeoutDuration ( UInt32 timeoutValue )
{
fTimeoutDuration = timeoutValue;
return true;
}
UInt32
SCSITask::GetTimeoutDuration ( void )
{
return fTimeoutDuration;
}
bool
SCSITask::SetTaskCompletionCallback ( SCSITaskCompletion newCallback )
{
fCompletionCallback = newCallback;
return true;
}
void
SCSITask::TaskCompletedNotification ( void )
{
fCompletionCallback( this );
}
bool
SCSITask::SetServiceResponse ( SCSIServiceResponse serviceResponse )
{
fServiceResponse = serviceResponse;
return true;
}
SCSIServiceResponse
SCSITask::GetServiceResponse ( void )
{
return fServiceResponse;
}
bool
SCSITask::SetAutoSenseData ( SCSI_Sense_Data * senseData )
{
bcopy ( senseData, &fAutoSenseData, kSenseDefaultSize );
fAutoSenseDataIsValid = true;
return true;
}
bool
SCSITask::GetAutoSenseData ( SCSI_Sense_Data * receivingBuffer )
{
if ( fAutoSenseDataIsValid == false )
{
return false;
}
if ( receivingBuffer != NULL )
{
bcopy ( &fAutoSenseData, receivingBuffer, kSenseDefaultSize );
}
return true;
}
bool
SCSITask::SetProtocolLayerReference ( void * newReferenceValue )
{
fProtocolLayerReference = newReferenceValue;
return true;
}
void *
SCSITask::GetProtocolLayerReference ( void )
{
return fProtocolLayerReference;
}
bool
SCSITask::SetApplicationLayerReference ( void * newReferenceValue )
{
fApplicationLayerReference = newReferenceValue;
return true;
}
void *
SCSITask::GetApplicationLayerReference ( void )
{
return fApplicationLayerReference;
}
#pragma mark -
#pragma mark SCSI Protocol Layer Mode methods
bool
SCSITask::SetTaskExecutionMode ( SCSITaskMode newTaskMode )
{
fTaskExecutionMode = newTaskMode;
return true;
}
SCSITaskMode
SCSITask::GetTaskExecutionMode ( void )
{
return fTaskExecutionMode;
}
bool
SCSITask::IsAutosenseRequested ( void )
{
return fAutosenseDataRequested;
}
bool
SCSITask::SetAutosenseIsValid ( bool newAutosenseState )
{
fAutoSenseDataIsValid = newAutosenseState;
return true;
}
UInt8
SCSITask::GetAutosenseCommandDescriptorBlockSize ( void )
{
return fAutosenseCDBSize;
}
bool
SCSITask::GetAutosenseCommandDescriptorBlock ( SCSICommandDescriptorBlock * cdbData )
{
bcopy ( &fAutosenseCDB, cdbData, sizeof ( SCSICommandDescriptorBlock ) );
return true;
}
UInt8
SCSITask::GetAutosenseDataTransferDirection ( void )
{
return kSCSIDataTransfer_FromTargetToInitiator;
}
UInt64
SCSITask::GetAutosenseRequestedDataTransferCount( void )
{
return sizeof ( SCSI_Sense_Data );
}
bool
SCSITask::SetAutosenseRealizedDataCount ( UInt64 realizedTransferCountInBytes )
{
fAutoSenseRealizedByteCountOfTransfer = realizedTransferCountInBytes;
return true;
}
UInt64
SCSITask::GetAutosenseRealizedDataCount ( void )
{
return fAutoSenseRealizedByteCountOfTransfer;
}
IOMemoryDescriptor *
SCSITask::GetAutosenseDataBuffer ( void )
{
return fAutosenseDescriptor;
}
bool
SCSITask::SetAutosenseCommand (
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5 )
{
fAutosenseCDB[0] = cdbByte0;
fAutosenseCDB[1] = cdbByte1;
fAutosenseCDB[2] = cdbByte2;
fAutosenseCDB[3] = cdbByte3;
fAutosenseCDB[4] = cdbByte4;
fAutosenseCDB[5] = cdbByte5;
fAutosenseCDB[6] = 0x00;
fAutosenseCDB[7] = 0x00;
fAutosenseCDB[8] = 0x00;
fAutosenseCDB[9] = 0x00;
fAutosenseCDB[10] = 0x00;
fAutosenseCDB[11] = 0x00;
fAutosenseCDB[12] = 0x00;
fAutosenseCDB[13] = 0x00;
fAutosenseCDB[14] = 0x00;
fAutosenseCDB[15] = 0x00;
fAutosenseCDBSize = kSCSICDBSize_6Byte;
fAutosenseDataRequested = true;
return true;
}
#pragma mark -
#pragma mark SCSI Task Queue Management Methods
void
SCSITask::EnqueueFollowingSCSITask ( SCSITask * followingTask )
{
fNextTaskInQueue = followingTask;
}
SCSITask *
SCSITask::GetFollowingSCSITask ( void )
{
return fNextTaskInQueue;
}
SCSITask *
SCSITask::DequeueFollowingSCSITask ( void )
{
SCSITask * returnTask;
returnTask = fNextTaskInQueue;
fNextTaskInQueue = NULL;
return returnTask;
}
SCSITask *
SCSITask::ReplaceFollowingSCSITask ( SCSITask * newFollowingTask )
{
SCSITask * returnTask;
returnTask = fNextTaskInQueue;
fNextTaskInQueue = newFollowingTask;
return returnTask;
}
OSMetaClassDefineReservedUnused( SCSITask, 1 );
OSMetaClassDefineReservedUnused( SCSITask, 2 );
OSMetaClassDefineReservedUnused( SCSITask, 3 );
OSMetaClassDefineReservedUnused( SCSITask, 4 );
OSMetaClassDefineReservedUnused( SCSITask, 5 );
OSMetaClassDefineReservedUnused( SCSITask, 6 );
OSMetaClassDefineReservedUnused( SCSITask, 7 );
OSMetaClassDefineReservedUnused( SCSITask, 8 );