X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d52fe63fc81f7e44faaae711812a211a78434976..9bccf70c0258c7cac2dcb80011b2a964d884c552:/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp diff --git a/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp b/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp deleted file mode 100644 index a2b386386..000000000 --- a/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * IOSCSIParallelController.cpp - * - */ - -#include -#include - -#undef super -#define super IOService - -OSDefineMetaClass( IOSCSIParallelController, IOService ) -OSDefineAbstractStructors( IOSCSIParallelController, IOService ); - -#define round(x,y) (((int)(x) + (y) - 1) & ~((y)-1)) - -/* - * - * - */ -bool IOSCSIParallelController::start( IOService *forProvider ) -{ - provider = forProvider; - - if ( provider->open( this ) != true ) - { - return false; - } - - if ( createWorkLoop() != true ) - { - return false; - } - - if ( configureController() == false ) - { - provider->close( this ); - return false; - } - - initQueues(); - - if ( scanSCSIBus() == false ) - { - provider->close( this ); - return false; - } - - return true; -} - -/* - * - * - * - */ -bool IOSCSIParallelController::scanSCSIBus() -{ - SCSITargetLun targetLun; - UInt32 i; - - targetLun.lun = 0; - - for ( i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - targetLun.target = i; - probeTarget( targetLun ); - } - - return true; -} - -/* - * - * - * - */ -bool IOSCSIParallelController::probeTarget( SCSITargetLun targetLun ) -{ - IOSCSIParallelDevice *device; - UInt32 i; - - if ( targetLun.target == controllerInfo.initiatorId ) - { - return false; - } - - if ( initTarget( targetLun ) == false ) - { - releaseTarget( targetLun ); - return false; - } - - for ( i=0; i < controllerInfo.maxLunsSupported; i++ ) - { - targetLun.lun = i; - - device = createDevice(); - if ( device == 0 ) - { - break; - } - - if ( device->init( this, targetLun ) == false ) - { - releaseDevice( device ); - break; - } - - if ( initDevice( device ) == false ) - { - releaseDevice( device ); - continue; - } - - if ( device->probeTargetLun() != kIOReturnSuccess ) - { - releaseDevice( device ); - if ( i == 0 ) break; - } - } - - if ( i == 0 ) - { - releaseTarget( targetLun ); - return false; - } - - queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - device->setupTarget(); - device->attach( this ); - device->registerService(); - } - - return true; -} - -/* - * - * - * - */ -bool IOSCSIParallelController::initTargetGated( SCSITargetLun *targetLun ) -{ - return initTarget( *targetLun ); -} - -bool IOSCSIParallelController::initTarget( SCSITargetLun targetLun ) -{ - SCSITarget *target; - UInt32 number; - - if ( getWorkLoop()->inGate() == false ) - { - return controllerGate->runAction( (IOCommandGate::Action)&IOSCSIParallelController::initTargetGated, (void *)&targetLun ); - } - - target = &targets[targetLun.target]; - - target->clientSem = IORWLockAlloc(); - target->targetSem = IORWLockAlloc(); - if( (target->targetSem == 0) || (target->clientSem == 0)) - { - return false; - } - target->commandLimitSave = target->commandLimit = 1; - - target->targetParmsCurrent.transferWidth = 1; - - if ( controllerInfo.targetPrivateDataSize != 0 ) - { - target->targetPrivateData = IOMallocContiguous( controllerInfo.targetPrivateDataSize, 16, 0 ); - if ( target->targetPrivateData == 0 ) - { - return false; - } - } - - if ( controllerInfo.tagAllocationMethod == kTagAllocationPerTarget ) - { - target->tagArray = (UInt32 *)IOMalloc( tagArraySize ); - if ( target->tagArray == 0 ) - { - return false; - } - bzero( target->tagArray, tagArraySize ); - } - - number = 0; - target->regObjTransferPeriod = OSNumber::withNumber( number, 32 ); - if ( target->regObjTransferPeriod == 0 ) - { - return false; - } - - number = 0; - target->regObjTransferOffset = OSNumber::withNumber( number, 32 ); - if ( target->regObjTransferOffset == 0 ) - { - return false; - } - - number = 1; - target->regObjTransferWidth = OSNumber::withNumber( number, 32 ); - if ( target->regObjTransferWidth == 0 ) - { - return false; - } - - number = 0; - target->regObjTransferOptions = OSNumber::withNumber( number, 32 ); - if ( target->regObjTransferOptions == 0 ) - { - return false; - } - - number = 0; - target->regObjCmdQueue = OSNumber::withNumber( number, 32 ); - if ( target->regObjCmdQueue == 0 ) - { - return false; - } - - target->targetAllocated = allocateTarget( targetLun ); - - return target->targetAllocated; -} - -/* - * - * - * - */ -void IOSCSIParallelController::releaseTargetGated( SCSITargetLun *targetLun ) -{ - releaseTarget( *targetLun ); -} - -void IOSCSIParallelController::releaseTarget( SCSITargetLun targetLun ) -{ - SCSITarget *target; - - if ( getWorkLoop()->inGate() == false ) - { - controllerGate->runAction( (IOCommandGate::Action)&IOSCSIParallelController::releaseTargetGated, (void *)&targetLun ); - return; - } - - target = &targets[targetLun.target]; - - if ( queue_empty( &target->deviceList ) != true ) - { - IOLog("IOSCSIParallelController()::Target %d deleted with lun(s) active!\n\r", - targetLun.target ); - } - - if ( target->targetAllocated == true ) - { - deallocateTarget( targetLun ); - - target->targetAllocated = false; - } - - if ( target->tagArray != 0 ) - { - IOFree( target->tagArray, tagArraySize ); - target->tagArray = 0; - } - - if ( target->targetPrivateData != 0 ) - { - IOFreeContiguous( target->targetPrivateData, controllerInfo.targetPrivateDataSize ); - target->targetPrivateData = 0; - } - - if ( target->clientSem != 0 ) - { - IORWLockFree( target->clientSem ); - } - if ( target->targetSem != 0 ) - { - IORWLockFree( target->targetSem ); - } - - if ( target->regObjTransferPeriod != 0 ) - { - target->regObjTransferPeriod->release(); - target->regObjTransferPeriod = 0; - } - if ( target->regObjTransferOffset != 0 ) - { - target->regObjTransferOffset->release(); - target->regObjTransferOffset = 0; - } - if ( target->regObjTransferWidth != 0 ) - { - target->regObjTransferWidth->release(); - target->regObjTransferWidth = 0; - } - if ( target->regObjCmdQueue != 0 ) - { - target->regObjCmdQueue->release(); - target->regObjCmdQueue = 0; - } - -} - -/* - * - * - * - */ -bool IOSCSIParallelController::initDeviceGated( IOSCSIParallelDevice *device ) -{ - return initDevice( device ); -} - -bool IOSCSIParallelController::initDevice( IOSCSIParallelDevice *device ) -{ - if ( getWorkLoop()->inGate() == false ) - { - return controllerGate->runAction( (IOCommandGate::Action)&IOSCSIParallelController::initDeviceGated, (void *)device ); - } - - addDevice( device ); - device->lunAllocated = allocateLun( device->targetLun ); - - return device->lunAllocated; -} - -/* - * - * - * - */ -void IOSCSIParallelController::releaseDeviceGated( IOSCSIParallelDevice *device ) -{ - releaseDevice( device ); - return; -} - -void IOSCSIParallelController::releaseDevice( IOSCSIParallelDevice *device ) -{ - if ( getWorkLoop()->inGate() == false ) - { - controllerGate->runAction( (IOCommandGate::Action)&IOSCSIParallelController::releaseDeviceGated, (void *)device ); - return; - } - - deleteDevice( device ); - if ( device->lunAllocated == true ) - { - deallocateLun( device->targetLun ); - } - - device->release(); -} - - -/* - * - * - * - */ -void IOSCSIParallelController::addDevice( IOSCSIParallelDevice *forDevice ) -{ - UInt32 targetID; - - targetID = forDevice->targetLun.target; - - forDevice->target = &targets[targetID]; - queue_enter( &targets[targetID].deviceList, forDevice, IOSCSIParallelDevice *, nextDevice ); -} - -/* - * - * - * - */ -void IOSCSIParallelController::deleteDevice( IOSCSIParallelDevice *forDevice ) -{ - queue_head_t *deviceList; - IOSCSIParallelDevice *device; - UInt32 targetID; - - targetID = forDevice->targetLun.target; - - deviceList = &targets[targetID].deviceList; - - queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - if ( device == forDevice ) - { - queue_remove( &targets[targetID].deviceList, device, IOSCSIParallelDevice *, nextDevice ); - break; - } - } -} - -/* - * - * - * - */ -bool IOSCSIParallelController::allocateTarget( SCSITargetLun targetLun ) -{ - return true; -} - -/* - * - * - * - */ -void IOSCSIParallelController::deallocateTarget( SCSITargetLun targetLun ) -{ -} - -/* - * - * - * - */ -bool IOSCSIParallelController::allocateLun( SCSITargetLun targetLun ) -{ - return true; -} - -/* - * - * - * - */ -void IOSCSIParallelController::deallocateLun( SCSITargetLun targetLun ) -{ -} - - -/* - * - * - * - */ -void *IOSCSIParallelController::getTargetData( SCSITargetLun targetLun ) -{ - return targets[targetLun.target].targetPrivateData; -} - -/* - * - * - * - */ -void *IOSCSIParallelController::getLunData( SCSITargetLun targetLun ) -{ - queue_head_t *deviceList; - IOSCSIParallelDevice *device; - - deviceList = &targets[targetLun.target].deviceList; - - queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - if ( device->targetLun.lun == targetLun.lun ) - { - return device->devicePrivateData; - } - } - return 0; -} - - - -/* - * - * - * - */ -IOSCSIParallelDevice *IOSCSIParallelController::createDevice() -{ - return new IOSCSIParallelDevice; -} - - -/* - * - * - * - */ -void IOSCSIParallelController::initQueues() -{ - UInt32 i; - - for ( i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - queue_init( &targets[i].deviceList ); - } - - resetCmd = allocCommand( 0 ); - resetCmd->cmdType = kSCSICommandBusReset; - - timer( timerEvent ); -} - -/* - * - * - * - */ -void IOSCSIParallelController::reset() -{ - IOSCSIParallelDevice *device; - UInt32 i; - - if ( busResetState != kStateIssue ) - { - return; - } - - busResetState = kStateActive; - - for (i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - if ( device->client != 0 ) - { - device->client->message( kSCSIClientMsgBusReset, device ); - } - } - } - - resetCommand( resetCmd ); -} - -/* - * - * - * - */ -bool IOSCSIParallelController::checkBusReset() -{ - if ( busResetState == kStateIdle ) - { - return false; - } - if ( busResetState == kStateIssue ) - { - reset(); - } - return true; -} - - -/* - * - * - * - */ -void IOSCSIParallelController::resetOccurred() -{ - UInt32 i; - IOSCSIParallelDevice *device; - SCSITarget *target; - SCSIClientMessage clientMsg; - - for (i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - target = &targets[i]; - - target->commandLimit = target->commandLimitSave; - target->reqSenseCount = 0; - target->reqSenseState = kStateIdle; - target->negotiateState = kStateIssue; - - target->targetParmsCurrent.transferPeriodpS = 0; - target->targetParmsCurrent.transferOffset = 0; - target->targetParmsCurrent.transferWidth = 1; - - noDisconnectCmd = 0; - - clientMsg = ( busResetState != kStateActive ) ? kSCSIClientMsgBusReset : kSCSIClientMsgNone; - - queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - device->resetOccurred( clientMsg ); - } - } - - resetTimer = (kSCSIResetIntervalmS / kSCSITimerIntervalmS + 1); -} - - -/* - * - * - */ -void IOSCSIParallelController::timer( IOTimerEventSource * /* timer */ ) -{ - UInt32 i; - IOSCSIParallelDevice *device; - - - if ( disableTimer ) - { - if ( !--disableTimer ) - { - disableTimeoutOccurred(); - } - } - - if ( resetTimer ) - { - if ( !--resetTimer ) - { - for (i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - device->resetComplete(); - } - } - - } - } - else - { - for (i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - device->timer(); - } - } - } - - timerEvent->setTimeoutMS(kSCSITimerIntervalmS); -} - - -/* - * - * - * - */ -void IOSCSIParallelController::completeCommand( IOSCSIParallelCommand *scsiCmd ) -{ - switch ( scsiCmd->cmdType ) - { - case kSCSICommandBusReset: - resetOccurred(); - busResetState = kStateIdle; - break; - default: - ; - } -} - - -/* - * - * - * - */ -bool IOSCSIParallelController::createWorkLoop() -{ - workLoop = getWorkLoop(); - if ( workLoop == 0 ) - { - workLoop = IOWorkLoop::workLoop(); - if ( workLoop == 0 ) - { - return false; - } - } - - timerEvent = IOTimerEventSource::timerEventSource( this, (IOTimerEventSource::Action) &IOSCSIParallelController::timer ); - if ( timerEvent == 0 ) - { - return false; - } - - if ( workLoop->addEventSource( timerEvent ) != kIOReturnSuccess ) - { - return false; - } - - - dispatchEvent = IOInterruptEventSource::interruptEventSource( this, - (IOInterruptEventAction) &IOSCSIParallelController::dispatch, - 0 ); - if ( dispatchEvent == 0 ) - { - return false; - } - - if ( workLoop->addEventSource( dispatchEvent ) != kIOReturnSuccess ) - { - return false; - } - - controllerGate = IOCommandGate::commandGate( this, (IOCommandGate::Action) 0 ); - if ( controllerGate == 0 ) - { - return false; - } - - if ( workLoop->addEventSource( controllerGate ) != kIOReturnSuccess ) - { - return false; - } - - return true; -} - -/* - * - * - * - */ -IOSCSIParallelCommand *IOSCSIParallelController::findCommandWithNexus( SCSITargetLun targetLun, UInt32 tagValue = (UInt32)-1 ) -{ - IOSCSIParallelDevice *device; - - device = findDeviceWithTargetLun( targetLun ); - if ( device == 0 ) - { - return 0; - } - - return device->findCommandWithNexus( tagValue ); -} - - -/* - * - * - * - */ -IOSCSIParallelDevice *IOSCSIParallelController::findDeviceWithTargetLun( SCSITargetLun targetLun ) -{ - IOSCSIParallelDevice *device; - - if ( targetLun.target > controllerInfo.maxTargetsSupported || targetLun.lun > controllerInfo.maxLunsSupported ) - { - return 0; - } - - queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - if ( device->targetLun.lun == targetLun.lun ) - { - return device; - } - } - return 0; -} - - -/* - * - * - * - */ -bool IOSCSIParallelController::configureController() -{ - UInt32 targetsSize; - - if ( configure( provider, &controllerInfo ) == false ) - { - return false; - } - - controllerInfo.commandPrivateDataSize = round( controllerInfo.commandPrivateDataSize, 16 ); - - if ( controllerInfo.maxCommandsPerController == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1; - if ( controllerInfo.maxCommandsPerTarget == 0 ) controllerInfo.maxCommandsPerTarget = (UInt32) -1; - if ( controllerInfo.maxCommandsPerLun == 0 ) controllerInfo.maxCommandsPerLun = (UInt32) -1; - - targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget); - targets = (SCSITarget *)IOMalloc( targetsSize ); - bzero( targets, targetsSize ); - - commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController; - - tagArraySize = (controllerInfo.maxTags / 32 + ((controllerInfo.maxTags % 32) ? 1 : 0)) * sizeof(UInt32); - - if ( controllerInfo.tagAllocationMethod == kTagAllocationPerController ) - { - tagArray = (UInt32 *)IOMalloc( tagArraySize ); - bzero( tagArray, tagArraySize ); - } - - return true; -} - -/* - * - * - * - */ -void IOSCSIParallelController::setCommandLimit( UInt32 newCommandLimit ) -{ - if ( newCommandLimit == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1; - - commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController; -} - -/* - * - * - * - */ -IOWorkLoop *IOSCSIParallelController::getWorkLoop() const -{ - return workLoop; -} - -/* - * - * - * - */ -void IOSCSIParallelController::disableCommands( UInt32 disableTimeoutmS ) -{ - commandDisable = true; - - disableTimer = ( disableTimeoutmS != 0 ) ? (disableTimeoutmS / kSCSITimerIntervalmS + 1) : 0; -} - - -/* - * - * - * - */ -void IOSCSIParallelController::disableCommands() -{ - UInt32 disableTimeout; - - commandDisable = true; - - disableTimeout = kSCSIDisableTimeoutmS; - - if ( noDisconnectCmd != 0 ) - { - disableTimeout = noDisconnectCmd->getTimeout(); - if ( disableTimeout != 0 ) disableTimeout += kSCSIDisableTimeoutmS; - } - - disableTimer = ( disableTimeout != 0 ) ? (disableTimeout / kSCSITimerIntervalmS + 1) : 0; -} - -/* - * - * - * - */ -void IOSCSIParallelController::disableTimeoutOccurred() -{ - busResetState = kStateIssue; - dispatchRequest(); -} - -/* - * - * - * - */ -void IOSCSIParallelController::rescheduleCommand( IOSCSIParallelCommand *forSCSICmd ) -{ - forSCSICmd->getDevice(kIOSCSIParallelDevice)->rescheduleCommand( forSCSICmd ); -} - -/* - * - * - * - */ -void IOSCSIParallelController::enableCommands() -{ - commandDisable = false; - - disableTimer = 0; - - dispatchRequest(); -} - -/* - * - * - * - */ -void IOSCSIParallelController::dispatchRequest() -{ - dispatchEvent->interruptOccurred(0, 0, 0); -} - - -/* - * - * - * - */ -void IOSCSIParallelController::dispatch() -{ - SCSITarget *target; - IOSCSIParallelDevice *device; - UInt32 dispatchAction; - UInt32 lunsActive = 0; - UInt32 i; - - if ( !targets || checkBusReset() ) - { - goto dispatch_Exit; - } - - for ( i = 0; i < controllerInfo.maxTargetsSupported; i++ ) - { - target = &targets[i]; - - if ( target->state == kStateActive ) - { - lunsActive = 0; - - queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice ) - { - if ( device->dispatch( &dispatchAction ) == true ) - { - lunsActive++; - } - - switch ( dispatchAction ) - { - case kDispatchNextLun: - ; - case kDispatchNextTarget: - break; - case kDispatchStop: - goto dispatch_Exit; - } - } - if ( lunsActive == 0 ) - { - target->state = kStateIdle; - } - } - } - -dispatch_Exit: - ; -} - -/* - * - * - * - */ -IOSCSIParallelCommand *IOSCSIParallelController::allocCommand(UInt32 clientDataSize ) -{ - IOSCSIParallelCommand *cmd; - UInt32 size; - - size = controllerInfo.commandPrivateDataSize + round(clientDataSize, 16); - - cmd = new IOSCSIParallelCommand; - if ( !cmd ) - { - return 0; - } - cmd->init(); - - if ( size ) - { - cmd->dataArea = (void *)IOMallocContiguous( (vm_size_t)size, 16, 0 ); - if ( !cmd->dataArea ) - { - cmd->release(); - return 0; - } - - bzero( cmd->dataArea, size ); - - cmd->dataSize = size; - - if ( controllerInfo.commandPrivateDataSize ) - { - cmd->commandPrivateData = cmd->dataArea; - } - if ( clientDataSize ) - { - cmd->clientData = (void *)((UInt8 *)cmd->dataArea + controllerInfo.commandPrivateDataSize); - } - } - - cmd->controller = this; - - return cmd; -} - -/* - * - * - * - */ -void IOSCSIParallelController::free() -{ - UInt32 targetsSize; - UInt32 i; - - if ( controllerGate != 0 ) - { - workLoop->removeEventSource( controllerGate ); - controllerGate->release(); - } - - if ( timerEvent != 0 ) timerEvent->release(); - - if ( dispatchEvent != 0 ) dispatchEvent->release(); - - if ( resetCmd != 0 ) resetCmd->release(); - - if ( workLoop != 0 ) workLoop->release(); - - if ( targets != 0 ) - { - for ( i=0; i < controllerInfo.maxTargetsSupported; i++ ) - { - if ( targets[i].targetPrivateData != 0 ) - { - IOFreeContiguous( targets[i].targetPrivateData, controllerInfo.targetPrivateDataSize ); - } - } - - targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget); - IOFree( targets, targetsSize ); - } - - if ( tagArray != 0 ) IOFree( tagArray, tagArraySize ); - - super::free(); -} - -/* - * - * - * - */ -void IOSCSIParallelCommand::free() -{ - if ( dataArea ) - { - IOFreeContiguous( dataArea, dataSize ); - } - - OSObject::free(); -} -