+++ /dev/null
-/*
- * 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 <IOKit/scsi/IOSCSIParallelInterface.h>
-#include <IOKit/IOSyncer.h>
-
-#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();
-}
-