AppleSCSIEmulatorAdapter.cpp [plain text]
#include <libkern/c++/OSArray.h>
#include <libkern/c++/OSData.h>
#include <libkern/c++/OSString.h>
#include <IOKit/IOTypes.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
#include <IOKit/scsi/spi/IOSCSIParallelInterfaceController.h>
#include "AppleSCSITargetEmulator.h"
#include "AppleSCSIEmulatorAdapter.h"
#include "AppleSCSIEmulatorEventSource.h"
typedef struct AdapterTargetStruct
{
AppleSCSITargetEmulator * emulator;
} AdapterTargetStruct;
#define DEBUG 1
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "Adapter"
#if DEBUG
#define EMULATOR_ADAPTER_DEBUGGING_LEVEL 2
#endif
#include "DebugSupport.h"
#if ( EMULATOR_ADAPTER_DEBUGGING_LEVEL >= 1 )
#define PANIC_NOW(x) panic x
#else
#define PANIC_NOW(x)
#endif
#if ( EMULATOR_ADAPTER_DEBUGGING_LEVEL >= 2 )
#define ERROR_LOG(x) IOLog x; IOSleep(1)
#else
#define ERROR_LOG(x)
#endif
#if ( EMULATOR_ADAPTER_DEBUGGING_LEVEL >= 3 )
#define STATUS_LOG(x) IOLog x; IOSleep(1)
#else
#define STATUS_LOG(x)
#endif
#define super IOSCSIParallelInterfaceController
OSDefineMetaClassAndStructors ( AppleSCSIEmulatorAdapter, IOSCSIParallelInterfaceController );
#define kMaxTargetID 256
void
AppleSCSIEmulatorAdapter::ReportHBAConstraints (
OSDictionary * constraints )
{
super::ReportHBAConstraints ( constraints );
#if USE_LUN_BYTES
constraints->setObject ( kIOHierarchicalLogicalUnitSupportKey, kOSBooleanTrue );
#endif
}
SCSILogicalUnitNumber
AppleSCSIEmulatorAdapter::ReportHBAHighestLogicalUnitNumber ( void )
{
SCSILogicalUnitNumber maxLUN = 0x3FFF;
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportHBAHighestLogicalUnitNumber, maxLUN = %qd\n", maxLUN ) );
return maxLUN;
}
bool
AppleSCSIEmulatorAdapter::DoesHBASupportSCSIParallelFeature ( SCSIParallelFeature theFeature )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::DoesHBASupportSCSIParallelFeature\n" ) );
return false;
}
bool
AppleSCSIEmulatorAdapter::InitializeTargetForID ( SCSITargetIdentifier targetID )
{
UInt32 index = 0;
UInt32 count = 0;
AppleSCSITargetEmulator * emulator = NULL;
AdapterTargetStruct * targetStruct = NULL;
bool found = false;
count = fTargetEmulators->getCount ( );
for ( index = 0; index < count; index++ )
{
emulator = OSDynamicCast ( AppleSCSITargetEmulator, fTargetEmulators->getObject ( index ) );
if ( emulator->GetTargetID ( ) == targetID )
{
targetStruct = ( AdapterTargetStruct * ) GetHBATargetDataPointer ( targetID );
targetStruct->emulator = emulator;
found = true;
}
}
return found;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::AbortTaskRequest (
SCSITargetIdentifier theT,
SCSILogicalUnitNumber theL,
SCSITaggedTaskIdentifier theQ )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::AbortTaskSetRequest (
SCSITargetIdentifier theT,
SCSILogicalUnitNumber theL )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::ClearACARequest (
SCSITargetIdentifier theT,
SCSILogicalUnitNumber theL )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::ClearTaskSetRequest (
SCSITargetIdentifier theT,
SCSILogicalUnitNumber theL )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::LogicalUnitResetRequest (
SCSITargetIdentifier theT,
SCSILogicalUnitNumber theL )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::TargetResetRequest (
SCSITargetIdentifier theT )
{
return kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
SCSIInitiatorIdentifier
AppleSCSIEmulatorAdapter::ReportInitiatorIdentifier ( void )
{
SCSIInitiatorIdentifier ourIdentity = kInitiatorID;
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportInitiatorIdentifier, ourIdentity = %qd\n", ourIdentity ) );
return ourIdentity;
}
SCSIDeviceIdentifier
AppleSCSIEmulatorAdapter::ReportHighestSupportedDeviceID ( void )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportHighestSupportedDeviceID, kMaxTargetID = %d\n", ( int ) kMaxTargetID ) );
return kMaxTargetID;
}
UInt32
AppleSCSIEmulatorAdapter::ReportMaximumTaskCount ( void )
{
UInt32 maxTasks = 512;
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportHighestSupportedDeviceID, maxTasks = %ld\n", maxTasks ) );
return maxTasks;
}
UInt32
AppleSCSIEmulatorAdapter::ReportHBASpecificTaskDataSize ( void )
{
UInt32 taskDataSize = 0;
taskDataSize = sizeof ( SCSIEmulatorRequestBlock );
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportHBASpecificTaskDataSize, taskDataSize = %ld\n", taskDataSize ) );
return taskDataSize;
}
UInt32
AppleSCSIEmulatorAdapter::ReportHBASpecificDeviceDataSize ( void )
{
UInt32 hbaDataSize = 0;
hbaDataSize = sizeof ( AdapterTargetStruct );
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::ReportHBASpecificDeviceDataSize, hbaDataSize = %ld\n", hbaDataSize ) );
return hbaDataSize;
}
bool
AppleSCSIEmulatorAdapter::DoesHBAPerformDeviceManagement ( void )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::DoesHBAPerformDeviceManagement\n" ) );
return true;
}
void
AppleSCSIEmulatorAdapter::SetControllerProperties ( void )
{
OSString * string = NULL;
OSData * data = NULL;
UInt8 wwn[8];
UInt8 addressID[3];
string = OSString::withCString ( "Apple" );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyVendorNameKey, string );
string->release ( );
string = NULL;
}
string = OSString::withCString ( "SCSI HBA Emulator" );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyProductNameKey, string );
string->release ( );
string = NULL;
}
string = OSString::withCString ( "1.0" );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyProductRevisionLevelKey, string );
string->release ( );
string = NULL;
}
string = OSString::withCString ( "Port 0" );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyPortDescriptionKey, string );
string->release ( );
string = NULL;
}
string = OSString::withCString ( kIOPropertyPortSpeedAutomatic4GigabitKey );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyPortSpeedKey, string );
string->release ( );
string = NULL;
}
string = OSString::withCString ( kIOPropertyPortTopologyAutomaticNPortKey );
if ( string != NULL )
{
SetHBAProperty ( kIOPropertyPortTopologyKey, string );
string->release ( );
string = NULL;
}
wwn[0] = 0x10;
wwn[1] = 0x00;
wwn[2] = 0x00;
wwn[3] = 0x40;
wwn[4] = 0x50;
wwn[5] = 0x60;
wwn[6] = 0xBB;
wwn[7] = 0xA0;
data = OSData::withBytes ( wwn, sizeof ( wwn ) );
if ( data != NULL )
{
SetHBAProperty ( kIOPropertyFibreChannelPortWorldWideNameKey, data );
data->release ( );
data = NULL;
}
wwn[0] = 0x20;
wwn[1] = 0x00;
wwn[2] = 0x00;
wwn[3] = 0x40;
wwn[4] = 0x50;
wwn[5] = 0x60;
wwn[6] = 0xBB;
wwn[7] = 0xA0;
data = OSData::withBytes ( wwn, sizeof ( wwn ) );
if ( data != NULL )
{
SetHBAProperty ( kIOPropertyFibreChannelNodeWorldWideNameKey, data );
data->release ( );
data = NULL;
}
addressID[0] = 0;
addressID[1] = 0;
addressID[2] = 1;
data = OSData::withBytes ( addressID, sizeof ( addressID ) );
if ( data != NULL )
{
SetHBAProperty ( kIOPropertyFibreChannelAddressIdentifierKey, data );
data->release ( );
data = NULL;
}
}
bool
AppleSCSIEmulatorAdapter::InitializeController ( void )
{
IOReturn status = kIOReturnSuccess;
STATUS_LOG ( ( "+AppleSCSIEmulatorAdapter::InitializeController\n" ) );
SetControllerProperties ( );
fEventSource = AppleSCSIEmulatorEventSource::Create (
this,
OSMemberFunctionCast (
AppleSCSIEmulatorEventSource::Action,
this,
&AppleSCSIEmulatorAdapter::TaskComplete ) );
require_nonzero ( fEventSource, ErrorExit );
status = GetWorkLoop ( )->addEventSource ( fEventSource );
require_success ( status, ReleaseEventSource );
fTargetEmulators = OSArray::withCapacity ( 1 );
require_nonzero ( fTargetEmulators, RemoveEventSource );
STATUS_LOG ( ( "-AppleSCSIEmulatorAdapter::InitializeController\n" ) );
return true;
RemoveEventSource:
GetWorkLoop ( )->removeEventSource ( fEventSource );
ReleaseEventSource:
fEventSource->release ( );
fEventSource = NULL;
ErrorExit:
STATUS_LOG ( ( "-AppleSCSIEmulatorAdapter::InitializeController failed\n" ) );
return false;
}
void
AppleSCSIEmulatorAdapter::TerminateController ( void )
{
STATUS_LOG ( ( "+AppleSCSIEmulatorAdapter::TerminateController\n" ) );
if ( fEventSource != NULL )
{
if ( GetWorkLoop ( )->removeEventSource ( fEventSource ) != kIOReturnSuccess )
{
ERROR_LOG ( ( "TerminateController: failed to de-register eventsource?\n" ) );
}
fEventSource->release ( );
fEventSource = NULL;
}
if ( fTargetEmulators != NULL )
{
fTargetEmulators->release ( );
fTargetEmulators = NULL;
}
STATUS_LOG ( ( "-AppleSCSIEmulatorAdapter::TerminateController\n" ) );
}
bool
AppleSCSIEmulatorAdapter::StartController ( void )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::StartController\n" ) );
return true;
}
void
AppleSCSIEmulatorAdapter::StopController ( void )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::StopController\n" ) );
}
void
AppleSCSIEmulatorAdapter::HandleInterruptRequest ( void )
{
ERROR_LOG ( ( "HandleInterruptRequest: captured interrupt?" ) );
}
IOInterruptEventSource *
AppleSCSIEmulatorAdapter::CreateDeviceInterrupt (
IOInterruptEventSource::Action action,
IOFilterInterruptEventSource::Filter filter,
IOService * provider )
{
STATUS_LOG ( ( "AppleSCSIEmulatorAdapter::CreateDeviceInterrupt\n" ) );
return NULL;
}
SCSIServiceResponse
AppleSCSIEmulatorAdapter::ProcessParallelTask ( SCSIParallelTaskIdentifier parallelRequest )
{
SCSIServiceResponse ret = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
UInt8 transferDir = GetDataTransferDirection ( parallelRequest );
IOMemoryDescriptor * transferMemDesc = GetDataBuffer ( parallelRequest );
UInt8 cdbLength = GetCommandDescriptorBlockSize ( parallelRequest );
SCSICommandDescriptorBlock cdbData = { 0 };
SCSITaskStatus scsiStatus = kSCSITaskStatus_No_Status;
UInt64 dataLen = 0;
SCSI_Sense_Data senseDataBuffer = { 0 };
UInt8 senseLength = sizeof ( SCSI_Sense_Data );
AdapterTargetStruct * targetStruct = NULL;
SCSITargetIdentifier targetID = 0;
SCSILogicalUnitNumber logicalUnitNumber = 0;
#if USE_LUN_BYTES
SCSILogicalUnitBytes logicalUnitBytes = { 0 };
GetLogicalUnitBytes ( parallelRequest, &logicalUnitBytes );
#endif
targetID = GetTargetIdentifier ( parallelRequest );
targetStruct = ( AdapterTargetStruct * ) GetHBATargetDataPointer ( targetID );
GetCommandDescriptorBlock ( parallelRequest, &cdbData );
if ( transferMemDesc && ( transferDir != kSCSIDataTransfer_NoDataTransfer ) )
{
dataLen = GetRequestedDataTransferCount ( parallelRequest );
}
#if USE_LUN_BYTES
targetStruct->emulator->SendCommand ( cdbData, cdbLength, transferMemDesc, &dataLen, logicalUnitBytes, &scsiStatus, &senseDataBuffer, &senseLength );
#else
logicalUnitNumber = GetLogicalUnitNumber ( parallelRequest );
targetStruct->emulator->SendCommand ( cdbData, cdbLength, transferMemDesc, &dataLen, logicalUnitNumber, &scsiStatus, &senseDataBuffer, &senseLength );
#endif
CompleteTaskOnWorkloopThread ( parallelRequest, true, scsiStatus, dataLen, &senseDataBuffer, senseLength );
ret = kSCSIServiceResponse_Request_In_Process;
return ret;
}
void
AppleSCSIEmulatorAdapter::CompleteTaskOnWorkloopThread (
SCSIParallelTaskIdentifier parallelRequest,
bool transportSuccessful,
SCSITaskStatus scsiStatus,
UInt64 actuallyTransferred,
SCSI_Sense_Data * senseBuffer,
UInt8 senseLength )
{
UInt8 transferDir = GetDataTransferDirection ( parallelRequest );
UInt64 transferSizeMax = GetRequestedDataTransferCount ( parallelRequest );
SCSIEmulatorRequestBlock * srb = ( SCSIEmulatorRequestBlock * ) GetHBADataPointer ( parallelRequest );
if ( transportSuccessful && ( scsiStatus != kSCSITaskStatus_TASK_SET_FULL ) )
{
switch ( transferDir )
{
case kSCSIDataTransfer_FromTargetToInitiator:
{
if ( actuallyTransferred > transferSizeMax )
{
actuallyTransferred = transferSizeMax;
}
if ( !SetRealizedDataTransferCount ( parallelRequest, actuallyTransferred ) )
{
ERROR_LOG ( ( "CompleteTaskOnWorkloopThread: SetRealizedDataTransferCount (%llu bytes) returned FAIL", actuallyTransferred ) );
}
break;
}
case kSCSIDataTransfer_FromInitiatorToTarget:
{
if ( actuallyTransferred > transferSizeMax )
{
actuallyTransferred = transferSizeMax;
}
if ( !SetRealizedDataTransferCount ( parallelRequest, actuallyTransferred ) )
{
ERROR_LOG ( ( "CompleteTaskOnWorkloopThread: SetRealizedDataTransferCount (%llu bytes) returned FAIL", actuallyTransferred ) );
}
break;
}
case kSCSIDataTransfer_NoDataTransfer:
default:
{
break;
}
}
}
if ( !transportSuccessful )
{
ERROR_LOG ( ( "CompleteTaskOnWorkloopThread: Failed transport - task = %p, transferDir = %d, transferSize = %lld, scsiStatus = 0x%X", parallelRequest, transferDir, transferSizeMax, scsiStatus ) );
srb->fServiceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
}
else
{
srb->fServiceResponse = kSCSIServiceResponse_TASK_COMPLETE;
if ( senseLength > 0 )
{
if ( !SetAutoSenseData ( parallelRequest, ( SCSI_Sense_Data * ) senseBuffer, senseLength ) )
{
ERROR_LOG ( ( "CompleteTaskOnWorkloopThread: Could not set sense data in parallel task" ) );
}
}
}
queue_init ( &srb->fQueueChain );
srb->fParallelRequest = parallelRequest;
srb->fTaskStatus = scsiStatus;
fEventSource->AddItemToQueue ( srb );
}
void
AppleSCSIEmulatorAdapter::TaskComplete (
SCSIParallelTaskIdentifier parallelRequest )
{
SCSIEmulatorRequestBlock * srb = ( SCSIEmulatorRequestBlock * ) GetHBADataPointer ( parallelRequest );
if ( srb != NULL )
{
CompleteParallelTask ( parallelRequest, srb->fTaskStatus, srb->fServiceResponse );
}
}
IOReturn
AppleSCSIEmulatorAdapter::CreateLUN (
EmulatorTargetParamsStruct * targetParameters,
task_t task )
{
IOReturn status = kIOReturnBadArgument;
bool result = false;
AppleSCSITargetEmulator * target = NULL;
AdapterTargetStruct * targetStruct = NULL;
IOMemoryDescriptor * inquiryBuffer = NULL;
IOMemoryDescriptor * inquiryPage00Buffer = NULL;
IOMemoryDescriptor * inquiryPage80Buffer = NULL;
IOMemoryDescriptor * inquiryPage83Buffer = NULL;
ERROR_LOG ( ( "AppleSCSIEmulatorAdapter::CreateTargetEmulator, targetID = %qd\n", targetParameters->targetID ) );
require ( ( targetParameters->targetID != kInitiatorID ), ErrorExit );
targetStruct = ( AdapterTargetStruct * ) GetHBATargetDataPointer ( targetParameters->targetID );
if ( targetStruct == NULL )
{
target = AppleSCSITargetEmulator::Create ( targetParameters->targetID );
require_nonzero_action ( target, ErrorExit, status = kIOReturnNoResources );
}
else
{
target = targetStruct->emulator;
}
ERROR_LOG ( ( "logicalUnit = %qd, capacity = %qd\n", targetParameters->lun.logicalUnit, targetParameters->lun.capacity ) );
ERROR_LOG ( ( "lun.inquiryData = %qx\n", targetParameters->lun.inquiryData ) );
ERROR_LOG ( ( "lun.inquiryPage00Data = %qx\n", targetParameters->lun.inquiryPage00Data ) );
ERROR_LOG ( ( "lun.inquiryPage80Data = %qx\n", targetParameters->lun.inquiryPage80Data ) );
ERROR_LOG ( ( "lun.inquiryPage83Data = %qx\n", targetParameters->lun.inquiryPage83Data ) );
ERROR_LOG ( ( "lun.inquiryDataLength = %d\n", targetParameters->lun.inquiryDataLength ) );
ERROR_LOG ( ( "lun.inquiryPage00DataLength = %d\n", targetParameters->lun.inquiryPage00DataLength ) );
ERROR_LOG ( ( "lun.inquiryPage80DataLength = %d\n", targetParameters->lun.inquiryPage80DataLength ) );
ERROR_LOG ( ( "lun.inquiryPage83DataLength = %d\n", targetParameters->lun.inquiryPage83DataLength ) );
inquiryBuffer = IOMemoryDescriptor::withAddressRange (
targetParameters->lun.inquiryData,
targetParameters->lun.inquiryDataLength,
0,
task );
inquiryPage00Buffer = IOMemoryDescriptor::withAddressRange (
targetParameters->lun.inquiryPage00Data,
targetParameters->lun.inquiryPage00DataLength,
0,
task );
inquiryPage80Buffer = IOMemoryDescriptor::withAddressRange (
targetParameters->lun.inquiryPage80Data,
targetParameters->lun.inquiryPage80DataLength,
0,
task );
inquiryPage83Buffer = IOMemoryDescriptor::withAddressRange (
targetParameters->lun.inquiryPage83Data,
targetParameters->lun.inquiryPage83DataLength,
0,
task );
if ( inquiryBuffer != NULL )
{
inquiryBuffer->prepare ( );
}
if ( inquiryPage00Buffer != NULL )
{
inquiryPage00Buffer->prepare ( );
}
if ( inquiryPage80Buffer != NULL )
{
inquiryPage80Buffer->prepare ( );
}
if ( inquiryPage83Buffer != NULL )
{
inquiryPage83Buffer->prepare ( );
}
result = target->AddLogicalUnit (
targetParameters->lun.logicalUnit,
targetParameters->lun.capacity,
inquiryBuffer,
inquiryPage00Buffer,
inquiryPage80Buffer,
inquiryPage83Buffer );
if ( inquiryBuffer != NULL )
{
inquiryBuffer->complete ( );
inquiryBuffer->release ( );
}
if ( inquiryPage00Buffer != NULL )
{
inquiryPage00Buffer->complete ( );
inquiryPage00Buffer->release ( );
}
if ( inquiryPage80Buffer != NULL )
{
inquiryPage80Buffer->complete ( );
inquiryPage80Buffer->release ( );
}
if ( inquiryPage83Buffer != NULL )
{
inquiryPage83Buffer->complete ( );
inquiryPage83Buffer->release ( );
}
if ( targetStruct == NULL )
{
OSDictionary * dict = NULL;
fTargetEmulators->setObject ( target );
dict = OSDictionary::withCapacity ( 3 );
if ( dict != NULL )
{
OSData * data = NULL;
UInt8 nodeWWN[] = { 0x60, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78 };
UInt8 portWWN[] = { 0x50, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78 };
nodeWWN[1] = ( targetParameters->targetID >> 16 ) & 0xFF;
nodeWWN[2] = ( targetParameters->targetID >> 8 ) & 0xFF;
nodeWWN[3] = ( targetParameters->targetID >> 0 ) & 0xFF;
data = OSData::withBytes ( nodeWWN, sizeof ( nodeWWN ) );
if ( data != NULL )
{
dict->setObject ( kIOPropertyFibreChannelNodeWorldWideNameKey, data );
data->release ( );
data = NULL;
}
data = OSData::withBytes ( portWWN, sizeof ( portWWN ) );
if ( data != NULL )
{
dict->setObject ( kIOPropertyFibreChannelPortWorldWideNameKey, data );
data->release ( );
data = NULL;
}
}
result = CreateTargetForID ( targetParameters->targetID, dict );
target->release ( );
target = NULL;
dict->release ( );
dict = NULL;
}
if ( result == true )
status = kIOReturnSuccess;
else
status = kIOReturnError;
ErrorExit:
return status;
}
IOReturn
AppleSCSIEmulatorAdapter::DestroyLUN (
SCSITargetIdentifier targetID,
SCSILogicalUnitNumber logicalUnit )
{
AppleSCSITargetEmulator * emulator = NULL;
AdapterTargetStruct * targetStruct = NULL;
ERROR_LOG ( ( "AppleSCSIEmulatorAdapter::DestroyLUN, targetID = %qd, logicalUnit = %qd\n", targetID, logicalUnit ) );
targetStruct = ( AdapterTargetStruct * ) GetHBATargetDataPointer ( targetID );
require_nonzero ( targetStruct, ErrorExit );
emulator = targetStruct->emulator;
emulator->RemoveLogicalUnit ( logicalUnit );
return kIOReturnSuccess;
ErrorExit:
return kIOReturnError;
}
IOReturn
AppleSCSIEmulatorAdapter::DestroyTarget (
SCSITargetIdentifier targetID )
{
int index = 0;
int count = 0;
AppleSCSITargetEmulator * emulator = NULL;
ERROR_LOG ( ( "AppleSCSIEmulatorAdapter::DestroyTarget, targetID = %qd\n", targetID ) );
DestroyTargetForID ( targetID );
count = fTargetEmulators->getCount ( );
for ( index = 0; index < count; index++ )
{
emulator = OSDynamicCast ( AppleSCSITargetEmulator, fTargetEmulators->getObject ( index ) );
if ( emulator->GetTargetID ( ) == targetID )
{
fTargetEmulators->removeObject ( index );
break;
}
}
return kIOReturnSuccess;
ErrorExit:
return kIOReturnError;
}
void
AppleSCSIEmulatorDebugAssert (
const char * componentNameString,
const char * assertionString,
const char * exceptionLabelString,
const char * errorString,
const char * fileName,
long lineNumber,
int errorCode )
{
IOLog ( "%s Assert failed: %s ", componentNameString, assertionString );
if ( exceptionLabelString != NULL )
IOLog ( "%s ", exceptionLabelString );
if ( errorString != NULL )
IOLog ( "%s ", errorString );
if ( fileName != NULL )
IOLog ( "file: %s ", fileName );
if ( lineNumber != 0 )
IOLog ( "line: %ld ", lineNumber );
if ( ( long ) errorCode != 0 )
IOLog ( "error: %ld ", ( long ) errorCode );
IOLog ( "\n" );
IOSleep ( 1 );
}