IOSCSIPrimaryCommandsDevice.cpp [plain text]
#include <libkern/OSByteOrder.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOKitKeys.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/scsi/SCSICommandOperationCodes.h>
#include "IOSCSIPrimaryCommandsDevice.h"
#include "SCSIPrimaryCommands.h"
#define DEBUG 0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "SPC"
#if DEBUG
#define SCSI_SPC_DEVICE_DEBUGGING_LEVEL 0
#endif
#include "IOSCSIArchitectureModelFamilyDebugging.h"
#if ( SCSI_SPC_DEVICE_DEBUGGING_LEVEL >= 1 )
#define PANIC_NOW(x) IOPanic x
#else
#define PANIC_NOW(x)
#endif
#if ( SCSI_SPC_DEVICE_DEBUGGING_LEVEL >= 2 )
#define ERROR_LOG(x) IOLog x
#else
#define ERROR_LOG(x)
#endif
#if ( SCSI_SPC_DEVICE_DEBUGGING_LEVEL >= 3 )
#define STATUS_LOG(x) IOLog x
#else
#define STATUS_LOG(x)
#endif
#define super IOSCSIProtocolInterface
OSDefineMetaClass ( IOSCSIPrimaryCommandsDevice, IOSCSIProtocolInterface );
OSDefineAbstractStructors ( IOSCSIPrimaryCommandsDevice, IOSCSIProtocolInterface );
enum
{
kSecondsInAMinute = 60
};
#define kPowerConditionsModePage 0x1A
#define kPowerConditionsModePageSize 12
#define kIOPropertyPowerConditionsSupportedKey "PowerConditionsSupported"
#define kAppleKeySwitchProperty "AppleKeyswitch"
#define kKeySwitchProperty "Keyswitch"
#define fKeySwitchNotifier fIOSCSIPrimaryCommandsDeviceReserved->fKeySwitchNotifier
#define fANSIVersion fIOSCSIPrimaryCommandsDeviceReserved->fANSIVersion
#define fCMDQUE fIOSCSIPrimaryCommandsDeviceReserved->fCMDQUE
#define fTaskID fIOSCSIPrimaryCommandsDeviceReserved->fTaskID
#define fTaskIDLock fIOSCSIPrimaryCommandsDeviceReserved->fTaskIDLock
#if 0
#pragma mark -
#pragma mark ₯ Public Methods
#pragma mark -
#endif
bool
IOSCSIPrimaryCommandsDevice::init ( OSDictionary * propTable )
{
bool result = false;
require ( super::init ( propTable ), ErrorExit );
result = true;
ErrorExit:
return result;
}
bool
IOSCSIPrimaryCommandsDevice::start ( IOService * provider )
{
bool result = false;
bool supported = false;
UInt64 maxByteCount = 0;
OSIterator * iterator = NULL;
OSObject * obj = NULL;
OSDictionary * dict = NULL;
OSString * string = NULL;
OSNumber * value = NULL;
require ( super::start ( provider ), ErrorExit );
fDeviceAccessEnabled = false;
fDeviceAccessSuspended = false;
fDeviceSupportsPowerConditions = false;
fNumCommandsOutstanding = 0;
fIOSCSIPrimaryCommandsDeviceReserved = IONew ( IOSCSIPrimaryCommandsDeviceExpansionData, 1 );
require_nonzero ( fIOSCSIPrimaryCommandsDeviceReserved, ErrorExit );
bzero ( fIOSCSIPrimaryCommandsDeviceReserved,
sizeof ( IOSCSIPrimaryCommandsDeviceExpansionData ) );
fANSIVersion = kINQUIRY_ANSI_VERSION_NoClaimedConformance;
fTaskIDLock = IOSimpleLockAlloc ( );
require_nonzero ( fTaskIDLock, FreeReservedMemory );
fProtocolDriver = OSDynamicCast ( IOSCSIProtocolInterface, provider );
require_nonzero ( fProtocolDriver, FreeTaskIDLock );
fDeviceCharacteristicsDictionary = OSDictionary::withCapacity ( 1 );
require_nonzero ( fDeviceCharacteristicsDictionary, FreeTaskIDLock );
string = ( OSString * ) GetProtocolDriver ( )->getProperty ( kIOPropertySCSIVendorIdentification );
check ( string );
fDeviceCharacteristicsDictionary->setObject ( kIOPropertyVendorNameKey, string );
string = ( OSString * ) GetProtocolDriver ( )->getProperty ( kIOPropertySCSIProductIdentification );
check ( string );
fDeviceCharacteristicsDictionary->setObject ( kIOPropertyProductNameKey, string );
string = ( OSString * ) GetProtocolDriver ( )->getProperty ( kIOPropertySCSIProductRevisionLevel );
check ( string );
fDeviceCharacteristicsDictionary->setObject ( kIOPropertyProductRevisionLevelKey, string );
value = ( OSNumber * ) GetProtocolDriver ( )->getProperty ( kIOPropertyReadTimeOutDurationKey );
if ( value != NULL );
{
fDeviceCharacteristicsDictionary->setObject ( kIOPropertyReadTimeOutDurationKey, value );
}
value = ( OSNumber * ) GetProtocolDriver ( )->getProperty ( kIOPropertyWriteTimeOutDurationKey );
if ( value != NULL );
{
fDeviceCharacteristicsDictionary->setObject ( kIOPropertyWriteTimeOutDurationKey, value );
}
require ( CreateCommandSetObjects ( ), FreeDeviceDictionary );
GetProtocolDriver ( )->open ( this );
STATUS_LOG ( ( "%s: Check for the SCSI Device Characteristics property from provider.\n", getName ( ) ) );
if ( ( GetProtocolDriver ( )->getProperty ( kIOPropertySCSIDeviceCharacteristicsKey ) ) == NULL )
{
STATUS_LOG ( ( "%s: No SCSI Device Characteristics property, set defaults.\n", getName ( ) ) );
fDefaultInquiryCount = 0;
}
else
{
OSDictionary * characterDict;
STATUS_LOG ( ( "%s: Get the SCSI Device Characteristics property from provider.\n", getName ( ) ) );
characterDict = OSDynamicCast ( OSDictionary, ( GetProtocolDriver ( )->getProperty ( kIOPropertySCSIDeviceCharacteristicsKey ) ) );
STATUS_LOG ( ( "%s: set this SCSI Device Characteristics property.\n", getName ( ) ) );
setProperty ( kIOPropertySCSIDeviceCharacteristicsKey, characterDict );
STATUS_LOG ( ( "%s: check for the Inquiry Length property.\n", getName ( ) ) );
if ( characterDict->getObject ( kIOPropertySCSIInquiryLengthKey ) == NULL )
{
STATUS_LOG ( ( "%s: No Inquiry Length property, use default.\n", getName ( ) ) );
fDefaultInquiryCount = 0;
}
else
{
OSNumber * defaultInquiry;
STATUS_LOG ( ( "%s: Get Inquiry Length property.\n", getName ( ) ) );
defaultInquiry = OSDynamicCast ( OSNumber, characterDict->getObject ( kIOPropertySCSIInquiryLengthKey ) );
fDefaultInquiryCount = defaultInquiry->unsigned32BitValue ( );
}
}
fProtocolAccessEnabled = true;
require ( InitializeDeviceSupport ( ), CloseProvider );
iterator = getMatchingServices ( nameMatching ( kAppleKeySwitchProperty ) );
if ( iterator != NULL )
{
while ( obj = iterator->getNextObject ( ) )
{
IOService * service = ( IOService * ) obj;
OSBoolean * boolKey = NULL;
boolKey = OSDynamicCast (
OSBoolean,
service->getProperty ( kKeySwitchProperty ) );
dict = GetProtocolCharacteristicsDictionary ( );
OSString * protocol = OSDynamicCast ( OSString, dict->getObject ( kIOPropertyPhysicalInterconnectTypeKey ) );
if ( ( protocol == NULL ) ||
( protocol->isEqualTo ( kIOPropertyPhysicalInterconnectTypeUSB ) ) ||
( protocol->isEqualTo ( kIOPropertyPhysicalInterconnectTypeFireWire ) ) ||
( protocol->isEqualTo ( kIOPropertyPhysicalInterconnectTypeATAPI ) ) )
{
setProperty ( kAppleKeySwitchProperty, boolKey );
fKeySwitchNotifier = addNotification (
gIOMatchedNotification,
nameMatching ( kAppleKeySwitchProperty ),
( IOServiceNotificationHandler ) &IOSCSIPrimaryCommandsDevice::ServerKeyswitchCallback,
this,
0 );
}
}
iterator->release ( );
iterator = NULL;
}
fReadTimeoutDuration = 0;
fWriteTimeoutDuration = 0;
dict = GetProtocolCharacteristicsDictionary ( );
if ( dict != NULL )
{
value = OSDynamicCast ( OSNumber, dict->getObject ( kIOPropertyReadTimeOutDurationKey ) );
if ( value != NULL )
{
fReadTimeoutDuration = value->unsigned32BitValue ( );
}
value = OSDynamicCast ( OSNumber, dict->getObject ( kIOPropertyWriteTimeOutDurationKey ) );
if ( value != NULL )
{
fWriteTimeoutDuration = value->unsigned32BitValue ( );
}
}
dict = GetDeviceCharacteristicsDictionary ( );
if ( dict != NULL )
{
value = OSDynamicCast ( OSNumber, dict->getObject ( kIOPropertyReadTimeOutDurationKey ) );
if ( value != NULL )
{
fReadTimeoutDuration = value->unsigned32BitValue ( );
}
value = OSDynamicCast ( OSNumber, dict->getObject ( kIOPropertyWriteTimeOutDurationKey ) );
if ( value != NULL )
{
fWriteTimeoutDuration = value->unsigned32BitValue ( );
}
}
supported = GetProtocolDriver ( )->IsProtocolServiceSupported (
kSCSIProtocolFeature_MaximumReadTransferByteCount,
&maxByteCount );
if ( supported == true )
{
setProperty ( kIOMaximumByteCountReadKey, maxByteCount, 64 );
}
supported = GetProtocolDriver ( )->IsProtocolServiceSupported (
kSCSIProtocolFeature_MaximumWriteTransferByteCount,
&maxByteCount );
if ( supported == true )
{
setProperty ( kIOMaximumByteCountWriteKey, maxByteCount, 64 );
}
fDeviceAccessEnabled = true;
StartDeviceSupport ( );
result = true;
return result;
CloseProvider:
GetProtocolDriver ( )->close ( this );
FreeDeviceDictionary:
require_nonzero ( fDeviceCharacteristicsDictionary, FreeTaskIDLock );
fDeviceCharacteristicsDictionary->release ( );
fDeviceCharacteristicsDictionary = NULL;
FreeTaskIDLock:
require_nonzero ( fTaskIDLock, FreeReservedMemory );
IOSimpleLockFree ( fTaskIDLock );
fTaskIDLock = NULL;
FreeReservedMemory:
require_nonzero ( fIOSCSIPrimaryCommandsDeviceReserved, ErrorExit );
IODelete ( fIOSCSIPrimaryCommandsDeviceReserved, IOSCSIPrimaryCommandsDeviceExpansionData, 1 );
fIOSCSIPrimaryCommandsDeviceReserved = NULL;
ErrorExit:
return result;
}
void
IOSCSIPrimaryCommandsDevice::stop ( IOService * provider )
{
fProtocolAccessEnabled = false;
if ( fDeviceAccessEnabled == true )
{
fDeviceAccessEnabled = false;
StopDeviceSupport ( );
}
if ( ( fProtocolDriver != NULL ) && ( fProtocolDriver == provider ) )
{
fProtocolDriver->close ( this );
fProtocolDriver = NULL;
super::stop ( provider );
}
}
void
IOSCSIPrimaryCommandsDevice::free ( void )
{
FreeCommandSetObjects ( );
if ( fIOSCSIPrimaryCommandsDeviceReserved != NULL )
{
if ( fTaskIDLock != NULL )
{
IOSimpleLockFree ( fTaskIDLock );
fTaskIDLock = NULL;
}
IODelete ( fIOSCSIPrimaryCommandsDeviceReserved, IOSCSIPrimaryCommandsDeviceExpansionData, 1 );
fIOSCSIPrimaryCommandsDeviceReserved = NULL;
}
if ( fDeviceCharacteristicsDictionary != NULL )
{
fDeviceCharacteristicsDictionary->release ( );
fDeviceCharacteristicsDictionary = NULL;
}
super::free ( );
}
IOReturn
IOSCSIPrimaryCommandsDevice::message ( UInt32 type,
IOService * nub,
void * arg )
{
IOReturn status;
switch ( type )
{
case kIOMessageServiceIsRequestingClose:
{
STATUS_LOG ( ( "%s: kIOMessageServiceIsRequestingClose Received\n", getName ( ) ) );
fProtocolAccessEnabled = false;
if ( fDeviceAccessEnabled == true )
{
fDeviceAccessEnabled = false;
StopDeviceSupport ( );
}
if ( fKeySwitchNotifier != NULL )
{
fKeySwitchNotifier->remove ( );
fKeySwitchNotifier = NULL;
}
TerminateDeviceSupport ( );
if ( fProtocolDriver != NULL )
{
fProtocolDriver->close ( this );
}
status = kIOReturnSuccess;
}
break;
case kSCSIServicesNotification_Suspend:
{
ERROR_LOG ( ( "type = kSCSIServicesNotification_Suspend, nub = %p\n", nub ) );
fDeviceAccessSuspended = true;
SuspendDeviceSupport ( );
status = kIOReturnSuccess;
}
break;
case kSCSIServicesNotification_Resume:
{
ERROR_LOG ( ( "type = kSCSIServicesNotification_Resume, nub = %p\n", nub ) );
fDeviceAccessSuspended = false;
ResumeDeviceSupport ( );
status = kIOReturnSuccess;
}
break;
case kSCSIProtocolNotification_VerifyDeviceState:
{
STATUS_LOG ( ("%s: kSCSIProtocolNotification_VerifyDeviceState Received\n", getName ( ) ) );
status = VerifyDeviceState ( );
}
break;
default:
{
status = super::message ( type, nub, arg );
}
break;
}
return status;
}
IOReturn
IOSCSIPrimaryCommandsDevice::VerifyDeviceState ( void )
{
return kIOReturnSuccess;
}
bool
IOSCSIPrimaryCommandsDevice::IsProtocolAccessEnabled ( void )
{
return fProtocolAccessEnabled;
}
bool
IOSCSIPrimaryCommandsDevice::IsDeviceAccessEnabled ( void )
{
return fDeviceAccessEnabled;
}
bool
IOSCSIPrimaryCommandsDevice::IsDeviceAccessSuspended ( void )
{
return fDeviceAccessSuspended;
}
#if 0
#pragma mark -
#pragma mark ₯ Power Management Methods
#pragma mark -
#endif
IOReturn
IOSCSIPrimaryCommandsDevice::setAggressiveness ( UInt32 type, UInt32 minutes )
{
UInt32 numStateTransitions = 0;
if ( type == kPMMinutesToSpinDown )
{
STATUS_LOG ( ( "IOSCSIPrimaryCommandsDevice: setting idle timer to %ld min\n", minutes ) );
numStateTransitions = GetNumberOfPowerStateTransitions ( );
if ( numStateTransitions != 0 )
{
setIdleTimerPeriod ( minutes * ( kSecondsInAMinute / numStateTransitions ) );
}
else
{
setIdleTimerPeriod ( 0 );
}
}
return ( super::setAggressiveness ( type, minutes ) );
}
bool
IOSCSIPrimaryCommandsDevice::ClearPowerOnReset ( void )
{
SCSI_Sense_Data senseBuffer = { 0 };
IOMemoryDescriptor * bufferDesc = NULL;
SCSITaskIdentifier request = NULL;
bool driveReady = false;
bool result = true;
SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
bufferDesc = IOMemoryDescriptor::withAddress ( ( void * ) &senseBuffer,
kSenseDefaultSize,
kIODirectionIn );
request = GetSCSITask ( );
do
{
if ( TEST_UNIT_READY ( request, 0 ) == true )
{
serviceResponse = SendCommand ( request, kTenSecondTimeoutInMS );
}
else
{
PANIC_NOW ( ( "IOSCSIPrimaryCommandsDevice::ClearPowerOnReset malformed command" ) );
}
if ( serviceResponse == kSCSIServiceResponse_TASK_COMPLETE )
{
bool validSense = false;
if ( GetTaskStatus ( request ) == kSCSITaskStatus_CHECK_CONDITION )
{
validSense = GetAutoSenseData ( request, &senseBuffer, sizeof ( senseBuffer ) );
if ( validSense == false )
{
if ( REQUEST_SENSE ( request, bufferDesc, kSenseDefaultSize, 0 ) == true )
{
serviceResponse = SendCommand ( request, kTenSecondTimeoutInMS );
}
else
{
PANIC_NOW ( ( "IOSCSIPrimaryCommandsDevice::ClearPowerOnReset REQUEST_SENSE malformed command" ) );
}
if ( serviceResponse == kSCSIServiceResponse_TASK_COMPLETE )
{
validSense = true;
}
else
{
IOSleep ( 200 );
}
}
if ( validSense == true )
{
if ( ( ( ( senseBuffer.SENSE_KEY & kSENSE_KEY_Mask ) == kSENSE_KEY_UNIT_ATTENTION ) &&
( senseBuffer.ADDITIONAL_SENSE_CODE == 0x29 ) &&
( senseBuffer.ADDITIONAL_SENSE_CODE_QUALIFIER == 0x00 ) ) ||
( ( ( senseBuffer.SENSE_KEY & kSENSE_KEY_Mask ) == kSENSE_KEY_UNIT_ATTENTION ) &&
( senseBuffer.ADDITIONAL_SENSE_CODE == 0x28 ) &&
( senseBuffer.ADDITIONAL_SENSE_CODE_QUALIFIER == 0x00 ) ) )
{
STATUS_LOG ( ( "%s::drive NOT READY\n", getName ( ) ) );
driveReady = false;
IOSleep ( 200 );
}
else
{
driveReady = true;
STATUS_LOG ( ( "%s::drive READY\n", getName ( ) ) );
}
STATUS_LOG ( ( "sense data: %01x, %02x, %02x\n",
( senseBuffer.SENSE_KEY & kSENSE_KEY_Mask ),
senseBuffer.ADDITIONAL_SENSE_CODE,
senseBuffer.ADDITIONAL_SENSE_CODE_QUALIFIER ) );
}
}
else
{
driveReady = true;
}
}
else
{
IOSleep ( 200 );
}
} while ( ( driveReady == false ) && ( isInactive ( ) == false ) );
bufferDesc->release ( );
ReleaseSCSITask ( request );
result = isInactive ( ) ? false : true;
return result;
}
void
IOSCSIPrimaryCommandsDevice::CheckPowerConditionsModePage ( void )
{
UInt8 buffer[kPowerConditionsModePageSize];
IOMemoryDescriptor * bufferDesc;
IOReturn status;
bool use10Byte = true;
STATUS_LOG ( ( "%s::%s called\n", getName ( ), __FUNCTION__ ) );
bufferDesc = IOMemoryDescriptor::withAddress ( ( void * ) buffer,
kPowerConditionsModePageSize,
kIODirectionIn );
if ( bufferDesc != NULL )
{
status = GetModeSense ( bufferDesc,
kPowerConditionsModePage,
kPowerConditionsModePageSize,
&use10Byte );
if ( status == kIOReturnSuccess )
{
if ( ( buffer[8] & 0x3F ) == kPowerConditionsModePage )
{
STATUS_LOG ( ( "Device supports power conditions page\n" ) );
fDeviceSupportsPowerConditions = true;
}
}
bufferDesc->release ( );
}
#if ( SCSI_SPC_DEVICE_DEBUGGING_LEVEL > 0 )
setProperty ( kIOPropertyPowerConditionsSupportedKey, fDeviceSupportsPowerConditions );
#endif
}
void
IOSCSIPrimaryCommandsDevice::IncrementOutstandingCommandsCount ( void )
{
fCommandGate->runAction ( ( IOCommandGate::Action )
&IOSCSIPrimaryCommandsDevice::sIncrementOutstandingCommandsCount );
}
void
IOSCSIPrimaryCommandsDevice::sIncrementOutstandingCommandsCount (
IOSCSIPrimaryCommandsDevice * self )
{
self->HandleIncrementOutstandingCommandsCount ( );
}
void
IOSCSIPrimaryCommandsDevice::HandleIncrementOutstandingCommandsCount ( void )
{
fNumCommandsOutstanding++;
}
#if 0
#pragma mark -
#pragma mark ₯ΚSCSI Task Get and Release
#pragma mark -
#endif
SCSITaskIdentifier
IOSCSIPrimaryCommandsDevice::GetSCSITask ( void )
{
SCSITask * newTask = OSTypeAlloc ( SCSITask );
check ( newTask );
newTask->SetTaskOwner ( this );
IncrementOutstandingCommandsCount ( );
retain ( );
return ( SCSITaskIdentifier ) newTask;
}
void
IOSCSIPrimaryCommandsDevice::ReleaseSCSITask ( SCSITaskIdentifier request )
{
require_nonzero ( request, Exit );
fNumCommandsOutstanding--;
request->release ( );
release ( );
Exit:
return;
}
SCSITaggedTaskIdentifier
IOSCSIPrimaryCommandsDevice::GetUniqueTagID ( void )
{
SCSITaggedTaskIdentifier taskID = kSCSIUntaggedTaskIdentifier;
IOSimpleLockLock ( fTaskIDLock );
taskID = ++fTaskID;
IOSimpleLockUnlock ( fTaskIDLock );
return taskID;
}
#if 0
#pragma mark -
#pragma mark ₯ Supporting Object Accessor Methods
#pragma mark -
#endif
IOSCSIProtocolInterface *
IOSCSIPrimaryCommandsDevice::GetProtocolDriver ( void )
{
check ( fProtocolDriver );
return fProtocolDriver;
}
SCSIPrimaryCommands *
IOSCSIPrimaryCommandsDevice::GetSCSIPrimaryCommandObject ( void )
{
STATUS_LOG ( ( "%s: getSCSIPrimaryCommandObject called.\n", getName ( ) ) );
return fSCSIPrimaryCommandObject;
}
bool
IOSCSIPrimaryCommandsDevice::CreateCommandSetObjects ( void )
{
bool result = false;
fSCSIPrimaryCommandObject =
SCSIPrimaryCommands::CreateSCSIPrimaryCommandObject ( );
require_nonzero ( fSCSIPrimaryCommandObject, ErrorExit );
result = true;
ErrorExit:
return result;
}
void
IOSCSIPrimaryCommandsDevice::FreeCommandSetObjects ( void )
{
if ( fSCSIPrimaryCommandObject != NULL )
{
fSCSIPrimaryCommandObject->release( );
fSCSIPrimaryCommandObject = NULL;
}
}
#if 0
#pragma mark -
#pragma mark ₯ Task Execution Support Methods
#pragma mark -
#endif
void
IOSCSIPrimaryCommandsDevice::TaskCallback ( SCSITaskIdentifier completedTask )
{
SCSITask * scsiRequest = NULL;
IOSCSIPrimaryCommandsDevice * owner = NULL;
scsiRequest = OSDynamicCast ( SCSITask, completedTask );
require_nonzero ( scsiRequest, ErrorExit );
owner = ( IOSCSIPrimaryCommandsDevice * ) scsiRequest->GetTaskOwner ( );
require_nonzero ( owner, ErrorExit );
owner->TaskCompletion ( scsiRequest );
ErrorExit:
return;
}
void
IOSCSIPrimaryCommandsDevice::TaskCompletion ( SCSITaskIdentifier completedTask )
{
fCommandGate->commandWakeup ( completedTask, true );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::SendCommand (
SCSITaskIdentifier request,
UInt32 timeoutDuration )
{
SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
require ( IsProtocolAccessEnabled ( ), ProtocolAccessDisabledError );
SetTimeoutDuration ( request, timeoutDuration );
SetTaskCompletionCallback ( request, &IOSCSIPrimaryCommandsDevice::TaskCallback );
SetAutosenseCommand ( request,
kSCSICmd_REQUEST_SENSE,
0x00,
0x00,
0x00,
sizeof ( SCSI_Sense_Data ),
0x00 );
GetProtocolDriver ( )->ExecuteCommand ( request );
fCommandGate->runAction ( ( IOCommandGate::Action )
&IOSCSIPrimaryCommandsDevice::sWaitForTask,
request );
serviceResponse = GetServiceResponse ( request );
return serviceResponse;
ProtocolAccessDisabledError:
SetServiceResponse ( request, serviceResponse );
SetTaskStatus ( request, kSCSITaskStatus_No_Status );
return serviceResponse;
}
void
IOSCSIPrimaryCommandsDevice::SendCommand (
SCSITaskIdentifier request,
UInt32 timeoutDuration,
SCSITaskCompletion taskCompletion )
{
SetTaskCompletionCallback ( request, taskCompletion );
require ( IsProtocolAccessEnabled ( ), ProtocolAccessDisabledError );
SetTimeoutDuration ( request, timeoutDuration );
SetAutosenseCommand ( request,
kSCSICmd_REQUEST_SENSE,
0x00,
0x00,
0x00,
sizeof ( SCSI_Sense_Data ),
0x00 );
GetProtocolDriver ( )->ExecuteCommand ( request );
return;
ProtocolAccessDisabledError:
SetServiceResponse ( request,
kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE );
SetTaskStatus ( request, kSCSITaskStatus_No_Status );
TaskCompletedNotification ( request );
return;
}
IOReturn
IOSCSIPrimaryCommandsDevice::GatedWaitForTask ( SCSITaskIdentifier request )
{
SCSITask * task = OSDynamicCast ( SCSITask, request );
IOReturn result = kIOReturnBadArgument;
if ( task != NULL )
{
while ( task->GetTaskState ( ) != kSCSITaskState_ENDED )
{
result = fCommandGate->commandSleep ( task, THREAD_UNINT );
}
}
if ( result == THREAD_AWAKENED )
result = kIOReturnSuccess;
return result;
}
#if 0
#pragma mark -
#pragma mark ₯ SCSI Task Field Accessors
#pragma mark -
#endif
bool
IOSCSIPrimaryCommandsDevice::ResetForNewTask (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->ResetForNewTask ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTaskAttribute (
SCSITaskIdentifier request,
SCSITaskAttribute newAttribute )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTaskAttribute ( newAttribute );
}
SCSITaskAttribute
IOSCSIPrimaryCommandsDevice::GetTaskAttribute ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetTaskAttribute ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTaggedTaskIdentifier (
SCSITaskIdentifier request,
SCSITaggedTaskIdentifier taggedTaskIdentifier )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTaggedTaskIdentifier ( taggedTaskIdentifier );
}
SCSITaggedTaskIdentifier
IOSCSIPrimaryCommandsDevice::GetTaggedTaskIdentifier (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetTaggedTaskIdentifier ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTaskState ( SCSITaskIdentifier request,
SCSITaskState newTaskState )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTaskState ( newTaskState );
}
SCSITaskState
IOSCSIPrimaryCommandsDevice::GetTaskState ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
return scsiRequest->GetTaskState( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTaskStatus ( SCSITaskIdentifier request,
SCSITaskStatus newStatus )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTaskStatus ( newStatus );
}
SCSITaskStatus
IOSCSIPrimaryCommandsDevice::GetTaskStatus ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetTaskStatus ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetCommandDescriptorBlock (
SCSITaskIdentifier request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5 )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5 );
}
bool
IOSCSIPrimaryCommandsDevice::SetCommandDescriptorBlock (
SCSITaskIdentifier request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5,
UInt8 cdbByte6,
UInt8 cdbByte7,
UInt8 cdbByte8,
UInt8 cdbByte9 )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9 );
}
bool
IOSCSIPrimaryCommandsDevice::SetCommandDescriptorBlock (
SCSITaskIdentifier 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 )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9,
cdbByte10,
cdbByte11 );
}
bool
IOSCSIPrimaryCommandsDevice::SetCommandDescriptorBlock (
SCSITaskIdentifier 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 )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetCommandDescriptorBlock (
cdbByte0,
cdbByte1,
cdbByte2,
cdbByte3,
cdbByte4,
cdbByte5,
cdbByte6,
cdbByte7,
cdbByte8,
cdbByte9,
cdbByte10,
cdbByte11,
cdbByte12,
cdbByte13,
cdbByte14,
cdbByte15 );
}
bool
IOSCSIPrimaryCommandsDevice::SetDataTransferDirection (
SCSITaskIdentifier request,
UInt8 newDirection )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetDataTransferDirection ( newDirection );
}
UInt8
IOSCSIPrimaryCommandsDevice::GetDataTransferDirection (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetDataTransferDirection ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetRequestedDataTransferCount (
SCSITaskIdentifier request,
UInt64 newRequestedCount )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetRequestedDataTransferCount ( newRequestedCount );
}
UInt64
IOSCSIPrimaryCommandsDevice::GetRequestedDataTransferCount (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetRequestedDataTransferCount ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetRealizedDataTransferCount (
SCSITaskIdentifier request,
UInt64 newRealizedDataCount )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetRealizedDataTransferCount ( newRealizedDataCount );
}
UInt64
IOSCSIPrimaryCommandsDevice::GetRealizedDataTransferCount (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetRealizedDataTransferCount ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetDataBuffer ( SCSITaskIdentifier request,
IOMemoryDescriptor * newBuffer )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetDataBuffer ( newBuffer );
}
IOMemoryDescriptor *
IOSCSIPrimaryCommandsDevice::GetDataBuffer ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetDataBuffer ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTimeoutDuration (
SCSITaskIdentifier request,
UInt32 newTimeout )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTimeoutDuration ( newTimeout );
}
UInt32
IOSCSIPrimaryCommandsDevice::GetTimeoutDuration ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetTimeoutDuration ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetTaskCompletionCallback (
SCSITaskIdentifier request,
SCSITaskCompletion newCallback )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetTaskCompletionCallback ( newCallback );
}
void
IOSCSIPrimaryCommandsDevice::TaskCompletedNotification (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->TaskCompletedNotification ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetServiceResponse (
SCSITaskIdentifier request,
SCSIServiceResponse serviceResponse )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetServiceResponse ( serviceResponse );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::GetServiceResponse (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetServiceResponse ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetAutosenseCommand (
SCSITaskIdentifier request,
UInt8 cdbByte0,
UInt8 cdbByte1,
UInt8 cdbByte2,
UInt8 cdbByte3,
UInt8 cdbByte4,
UInt8 cdbByte5 )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetAutosenseCommand ( cdbByte0, cdbByte1, cdbByte2,
cdbByte3, cdbByte4, cdbByte5 );
}
bool
IOSCSIPrimaryCommandsDevice::GetAutoSenseData ( SCSITaskIdentifier request,
SCSI_Sense_Data * senseData )
{
return GetAutoSenseData ( request, senseData, sizeof ( SCSI_Sense_Data ) );
}
bool
IOSCSIPrimaryCommandsDevice::GetAutoSenseData ( SCSITaskIdentifier request,
SCSI_Sense_Data * senseData,
UInt8 senseDataSize )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetAutoSenseData ( senseData, senseDataSize );
}
UInt8
IOSCSIPrimaryCommandsDevice::GetAutoSenseDataSize ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetAutoSenseDataSize ( );
}
bool
IOSCSIPrimaryCommandsDevice::SetApplicationLayerReference (
SCSITaskIdentifier request,
void * newReferenceValue )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->SetApplicationLayerReference ( newReferenceValue );
}
void *
IOSCSIPrimaryCommandsDevice::GetApplicationLayerReference (
SCSITaskIdentifier request )
{
SCSITask * scsiRequest;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetApplicationLayerReference ( );
}
OSObject *
IOSCSIPrimaryCommandsDevice::sGetOwnerForTask ( SCSITaskIdentifier request )
{
SCSITask * scsiRequest = NULL;
scsiRequest = OSDynamicCast ( SCSITask, request );
check ( scsiRequest );
return scsiRequest->GetTaskOwner ( );
}
#if 0
#pragma mark -
#pragma mark ₯ Device Information Methods
#pragma mark -
#endif
char *
IOSCSIPrimaryCommandsDevice::GetVendorString ( void )
{
OSString * vendorString;
vendorString = ( OSString * ) GetProtocolDriver ( )->getProperty (
kIOPropertySCSIVendorIdentification );
if ( vendorString != NULL )
{
return ( ( char * ) vendorString->getCStringNoCopy ( ) );
}
else
{
return "NULL STRING";
}
}
char *
IOSCSIPrimaryCommandsDevice::GetProductString ( void )
{
OSString * productString;
productString = ( OSString * ) GetProtocolDriver ( )->getProperty (
kIOPropertySCSIProductIdentification );
if ( productString != NULL )
{
return ( ( char * ) productString->getCStringNoCopy ( ) );
}
else
{
return "NULL STRING";
}
}
char *
IOSCSIPrimaryCommandsDevice::GetRevisionString ( void )
{
OSString * revisionString;
STATUS_LOG ( ( "%s::%s\n", getName ( ), __FUNCTION__ ) );
revisionString = ( OSString * ) GetProtocolDriver ( )->getProperty (
kIOPropertySCSIProductRevisionLevel );
if ( revisionString != NULL )
{
return ( ( char * ) revisionString->getCStringNoCopy ( ) );
}
else
{
return "NULL STRING";
}
}
OSDictionary *
IOSCSIPrimaryCommandsDevice::GetProtocolCharacteristicsDictionary ( void )
{
return ( OSDictionary * ) GetProtocolDriver ( )->getProperty (
kIOPropertyProtocolCharacteristicsKey );
}
OSDictionary *
IOSCSIPrimaryCommandsDevice::GetDeviceCharacteristicsDictionary ( void )
{
check ( fDeviceCharacteristicsDictionary );
return fDeviceCharacteristicsDictionary;
}
UInt8
IOSCSIPrimaryCommandsDevice::GetANSIVersion ( void )
{
return fANSIVersion;
}
void
IOSCSIPrimaryCommandsDevice::SetANSIVersion ( UInt8 newVersion )
{
fANSIVersion = newVersion;
}
bool
IOSCSIPrimaryCommandsDevice::GetCMDQUE ( void )
{
return fCMDQUE;
}
void
IOSCSIPrimaryCommandsDevice::SetCMDQUE ( bool value )
{
fCMDQUE = value;
}
IOReturn
IOSCSIPrimaryCommandsDevice::GetModeSense (
IOMemoryDescriptor * dataBuffer,
SCSICmdField6Bit PAGE_CODE,
SCSICmdField2Byte ALLOCATION_LENGTH,
bool * use10ByteModeSense )
{
SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
SCSITaskIdentifier request = NULL;
SCSICmdField1Bit DBD = 0;
IOReturn status = kIOReturnNoResources;
bool commandOK = false;
request = GetSCSITask ( );
require_nonzero ( request, ErrorExit );
OUTERLOOP:
DBD = 1;
INNERLOOP:
if ( *use10ByteModeSense )
{
commandOK = MODE_SENSE_10 ( request,
dataBuffer,
0x00,
DBD,
0x00,
PAGE_CODE,
ALLOCATION_LENGTH,
0 );
}
else
{
commandOK = MODE_SENSE_6 ( request,
dataBuffer,
DBD,
0x00,
PAGE_CODE,
ALLOCATION_LENGTH & 0xFF,
0 );
}
if ( commandOK )
{
serviceResponse = SendCommand ( request, kThirtySecondTimeoutInMS );
}
if ( ( serviceResponse == kSCSIServiceResponse_TASK_COMPLETE ) &&
( GetTaskStatus ( request ) == kSCSITaskStatus_GOOD ) )
{
if ( GetRealizedDataTransferCount ( request ) == GetRequestedDataTransferCount ( request ) )
{
status = kIOReturnSuccess;
}
else if ( GetRealizedDataTransferCount ( request ) < GetRequestedDataTransferCount ( request ) )
{
status = kIOReturnUnderrun;
}
else
{
status = kIOReturnIOError;
}
}
else
{
if ( DBD == 1 )
{
ERROR_LOG ( ( "Trying again with DBD=0\n" ) );
DBD = 0;
goto INNERLOOP;
}
ERROR_LOG ( ( "Modes sense returned error\n" ) );
}
if ( status != kIOReturnSuccess )
{
if ( *use10ByteModeSense )
{
ERROR_LOG ( ( "Trying again with MODE_SENSE_6 command\n" ) );
*use10ByteModeSense = false;
goto OUTERLOOP;
}
ERROR_LOG ( ( "Mode sense returned error\n" ) );
}
ReleaseSCSITask ( request );
ErrorExit:
return status;
}
#if 0
#pragma mark -
#pragma mark ₯ SCSI Protocol Interface Implementations
#pragma mark -
#endif
void
IOSCSIPrimaryCommandsDevice::ExecuteCommand ( SCSITaskIdentifier request )
{
GetProtocolDriver ( )->ExecuteCommand ( request );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::AbortCommand ( SCSITaskIdentifier request )
{
return GetProtocolDriver ( )->AbortCommand ( request );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::AbortTask (
UInt8 theLogicalUnit,
SCSITaggedTaskIdentifier theTag )
{
return GetProtocolDriver ( )->AbortTask ( theLogicalUnit, theTag );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::AbortTaskSet ( UInt8 theLogicalUnit )
{
return GetProtocolDriver ( )->AbortTaskSet ( theLogicalUnit );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::ClearACA ( UInt8 theLogicalUnit )
{
return GetProtocolDriver ( )->ClearACA ( theLogicalUnit );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::ClearTaskSet ( UInt8 theLogicalUnit )
{
return GetProtocolDriver ( )->ClearTaskSet ( theLogicalUnit );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::LogicalUnitReset ( UInt8 theLogicalUnit )
{
return GetProtocolDriver ( )->LogicalUnitReset ( theLogicalUnit );
}
SCSIServiceResponse
IOSCSIPrimaryCommandsDevice::TargetReset ( void )
{
return GetProtocolDriver ( )->TargetReset ( );
}
bool
IOSCSIPrimaryCommandsDevice::IsProtocolServiceSupported (
SCSIProtocolFeature feature,
void * serviceValue )
{
return GetProtocolDriver ( )->IsProtocolServiceSupported ( feature, serviceValue );
}
bool
IOSCSIPrimaryCommandsDevice::HandleProtocolServiceFeature (
SCSIProtocolFeature feature,
void * serviceValue )
{
return GetProtocolDriver ( )->HandleProtocolServiceFeature ( feature, serviceValue );
}
#if 0
#pragma mark -
#pragma mark ₯ Static Methods C->C++ Glue
#pragma mark -
#endif
bool
IOSCSIPrimaryCommandsDevice::ServerKeyswitchCallback (
void * target,
void * refCon,
IOService * newDevice )
{
OSBoolean * keySwitchLocked = NULL;
IOSCSIPrimaryCommandsDevice * device = NULL;
device = OSDynamicCast ( IOSCSIPrimaryCommandsDevice, ( OSObject * ) target );
keySwitchLocked = OSDynamicCast (
OSBoolean,
newDevice->getProperty ( kKeySwitchProperty ) );
if ( ( keySwitchLocked != NULL ) && ( device != NULL ) )
{
device->setProperty ( kAppleKeySwitchProperty, keySwitchLocked );
}
return true;
}
IOReturn
IOSCSIPrimaryCommandsDevice::sWaitForTask (
void * object,
SCSITaskIdentifier request )
{
IOSCSIPrimaryCommandsDevice * device = NULL;
device = OSDynamicCast ( IOSCSIPrimaryCommandsDevice, ( OSObject * ) object );
return device->GatedWaitForTask ( request );
}
#if 0
#pragma mark -
#pragma mark ₯ VTable Padding
#pragma mark -
#endif
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 1 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 2 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 3 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 4 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 5 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 6 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 7 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 8 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 9 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 10 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 11 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 12 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 13 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 14 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 15 );
OSMetaClassDefineReservedUnused ( IOSCSIPrimaryCommandsDevice, 16 );