Annotation of XNU/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  *     IOSCSIParallelController.cpp
        !            24:  *
        !            25:  */
        !            26: 
        !            27: #include <IOKit/scsi/IOSCSIParallelInterface.h>
        !            28: #include <IOKit/IOSyncer.h>
        !            29: 
        !            30: #undef  super 
        !            31: #define super  IOService
        !            32: 
        !            33: OSDefineMetaClass( IOSCSIParallelController, IOService )
        !            34: OSDefineAbstractStructors( IOSCSIParallelController, IOService );
        !            35: 
        !            36: #define round(x,y) (((int)(x) + (y) - 1) & ~((y)-1))
        !            37: 
        !            38: /*
        !            39:  *
        !            40:  *
        !            41:  */
        !            42: bool IOSCSIParallelController::start( IOService *forProvider )
        !            43: {
        !            44:     provider = forProvider;
        !            45: 
        !            46:     if ( provider->open( this ) != true )
        !            47:     { 
        !            48:         return false;
        !            49:     }
        !            50: 
        !            51:     if ( createWorkLoop() != true )
        !            52:     {
        !            53:         return false;
        !            54:     }
        !            55: 
        !            56:     if ( configureController() == false )
        !            57:     {
        !            58:         provider->close( this );
        !            59:         return false;
        !            60:     }
        !            61: 
        !            62:     initQueues();
        !            63:     
        !            64:     if ( scanSCSIBus() == false ) 
        !            65:     {
        !            66:         provider->close( this );
        !            67:         return false;
        !            68:     }
        !            69: 
        !            70:     return true;
        !            71: }
        !            72: 
        !            73: /*
        !            74:  *
        !            75:  *
        !            76:  *
        !            77:  */
        !            78: bool IOSCSIParallelController::scanSCSIBus()
        !            79: {
        !            80:     SCSITargetLun              targetLun;
        !            81:     UInt32                     i;
        !            82:     
        !            83:     targetLun.lun = 0;
        !            84:     
        !            85:     for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !            86:     {
        !            87:         targetLun.target = i;
        !            88:         probeTarget( targetLun );
        !            89:     }
        !            90:     
        !            91:     return true;
        !            92: }       
        !            93: 
        !            94: /*
        !            95:  *
        !            96:  *
        !            97:  *
        !            98:  */
        !            99: bool IOSCSIParallelController::probeTarget( SCSITargetLun targetLun )
        !           100: {
        !           101:     IOSCSIParallelDevice       *device;
        !           102:     UInt32             i;
        !           103:     
        !           104:     if ( targetLun.target == controllerInfo.initiatorId )
        !           105:     {
        !           106:         return false;
        !           107:     }
        !           108: 
        !           109:     if ( workLoopRequest( kWorkLoopInitTarget, *(UInt32 *)&targetLun ) == false )
        !           110:     {
        !           111:         releaseTarget( targetLun );
        !           112:         return false;
        !           113:     }
        !           114: 
        !           115:     for ( i=0; i < controllerInfo.maxLunsSupported; i++ )
        !           116:     {
        !           117:         targetLun.lun    = i;
        !           118:         
        !           119:         device = createDevice();   
        !           120:         if ( device == 0 )
        !           121:         {
        !           122:             break;
        !           123:         }
        !           124:            
        !           125:         if ( device->init( this, targetLun ) == false )
        !           126:         {
        !           127:             releaseDevice( device );
        !           128:             break;
        !           129:         }
        !           130: 
        !           131:         if ( workLoopRequest( kWorkLoopInitDevice, (UInt32)device ) == false )
        !           132:         {
        !           133:             releaseDevice( device );
        !           134:         }
        !           135: 
        !           136: //        IOLog("Target %d Lun %d - created\n\r", targetLun.target, targetLun.lun );    
        !           137:  
        !           138:         if ( device->probeTargetLun() != kIOReturnSuccess )
        !           139:         {
        !           140: //            IOLog("Target %d Lun %d - no response\n\r", targetLun.target, targetLun.lun );
        !           141: 
        !           142:             releaseDevice( device );
        !           143: 
        !           144:             if ( i == 0 ) break;
        !           145:         }
        !           146:     }
        !           147: 
        !           148:     if ( i == 0 )
        !           149:     {
        !           150:         releaseTarget( targetLun );
        !           151:         return false;
        !           152:     }
        !           153: 
        !           154:     queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           155:     {
        !           156:         device->setupTarget();
        !           157:         device->attach( this );
        !           158:         device->registerService();
        !           159:     }
        !           160: 
        !           161:     return true;
        !           162: }            
        !           163: 
        !           164: /*
        !           165:  *
        !           166:  *
        !           167:  *
        !           168:  */
        !           169: bool IOSCSIParallelController::initTarget( SCSITargetLun targetLun )
        !           170: {
        !           171:     SCSITarget         *target;
        !           172: 
        !           173:     target = &targets[targetLun.target];
        !           174: 
        !           175:     assert ( target->clientSem == 0 );
        !           176:     assert ( target->targetSem == 0 );
        !           177: 
        !           178:     bzero( target, sizeof(SCSITarget) );
        !           179: 
        !           180:     queue_init( &targets[targetLun.target].deviceList );  
        !           181: 
        !           182:     target->clientSem = IORWLockAlloc();
        !           183:     target->targetSem = IORWLockAlloc();
        !           184:     if( (target->targetSem == 0) || (target->clientSem == 0))
        !           185:     {
        !           186:         return false;
        !           187:     }
        !           188:     target->commandLimitSave = target->commandLimit = 1;
        !           189: 
        !           190:     target->targetParmsCurrent.transferWidth = 1;
        !           191: 
        !           192:     if ( controllerInfo.targetPrivateDataSize != 0 )
        !           193:     {
        !           194:         target->targetPrivateData = IOMallocContiguous( controllerInfo.targetPrivateDataSize, 16, 0 );
        !           195:         if ( target->targetPrivateData == 0 )
        !           196:         {
        !           197:             return false;
        !           198:         }
        !           199:     }
        !           200: 
        !           201:     if ( controllerInfo.tagAllocationMethod == kTagAllocationPerTarget )
        !           202:     {
        !           203:         target->tagArray = (UInt32 *)IOMalloc( tagArraySize );
        !           204:         if ( target->tagArray == 0 )
        !           205:         {
        !           206:             return false;
        !           207:         }
        !           208:         bzero( target->tagArray, tagArraySize );
        !           209:     }
        !           210: 
        !           211:     return true;
        !           212: }
        !           213: 
        !           214: /*
        !           215:  *
        !           216:  *
        !           217:  *
        !           218:  */
        !           219: void IOSCSIParallelController::releaseTarget( SCSITargetLun targetLun )
        !           220: {
        !           221:     SCSITarget         *target;
        !           222: 
        !           223:     workLoopRequest( kWorkLoopReleaseTarget, *(UInt32 *)&targetLun );
        !           224:     
        !           225:     target = &targets[targetLun.target];
        !           226:     if ( target->tagArray != 0 )
        !           227:     {
        !           228:         IOFree( target->tagArray, tagArraySize );
        !           229:         target->tagArray = 0;
        !           230:     }
        !           231: 
        !           232:     if ( target->targetPrivateData != 0 )
        !           233:     {
        !           234:        IOFreeContiguous( target->targetPrivateData, controllerInfo.targetPrivateDataSize );
        !           235:         target->targetPrivateData = 0;
        !           236:     }
        !           237: 
        !           238:     if ( target->clientSem != 0 )
        !           239:     {
        !           240:         IORWLockFree( target->clientSem );
        !           241:     }
        !           242:     if ( target->targetSem != 0 )
        !           243:     {
        !           244:         IORWLockFree( target->targetSem );
        !           245:     }
        !           246: }
        !           247: 
        !           248: /*
        !           249:  *
        !           250:  *
        !           251:  *
        !           252:  */
        !           253: void IOSCSIParallelController::releaseDevice( IOSCSIParallelDevice *device )
        !           254: {
        !           255:     workLoopRequest( kWorkLoopReleaseDevice, (UInt32) device );
        !           256: 
        !           257:     device->release();    
        !           258: }
        !           259: 
        !           260: /*
        !           261:  *
        !           262:  *
        !           263:  *
        !           264:  */
        !           265: bool IOSCSIParallelController::workLoopRequest( WorkLoopReqType type, UInt32 p1, UInt32 p2, UInt32 p3 )
        !           266: {
        !           267:     WorkLoopRequest    workLoopReq;
        !           268: 
        !           269:     bzero( &workLoopReq, sizeof(WorkLoopRequest) );
        !           270:     workLoopReq.type = type;
        !           271:     workLoopReq.sync = IOSyncer::create();
        !           272: 
        !           273:     workLoopReqGate->runCommand( &workLoopReq, (void *)p1, (void *)p2, (void *)p3 );
        !           274: 
        !           275:     workLoopReq.sync->wait();
        !           276: 
        !           277:     return( workLoopReq.rc );
        !           278: }
        !           279: 
        !           280: 
        !           281: /*
        !           282:  *
        !           283:  *
        !           284:  *
        !           285:  */
        !           286: void IOSCSIParallelController::workLoopProcessRequest( WorkLoopRequest *workLoopReq, void *p1, void *p2, void *p3 )
        !           287: {
        !           288:     bool                       rc = true;
        !           289:     IOSCSIParallelDevice       *device;
        !           290:     SCSITargetLun              targetLun;
        !           291: 
        !           292:     switch ( workLoopReq->type )
        !           293:     {
        !           294:         case kWorkLoopInitTarget:
        !           295:             targetLun = *(SCSITargetLun *)&p1;
        !           296:             rc = initTarget( targetLun );
        !           297:             if ( rc == false )
        !           298:             { 
        !           299:                 break;
        !           300:             }
        !           301:             rc = allocateTarget( targetLun );
        !           302:             break;
        !           303:       
        !           304:         case kWorkLoopReleaseTarget:
        !           305:             targetLun = *(SCSITargetLun *) &p1;         
        !           306:             if ( queue_empty( &targets[targetLun.target].deviceList ) != true ) 
        !           307:             {
        !           308:                 IOLog("IOSCSIParallelController()::Target %d deleted with lun(s) active!\n\r",
        !           309:                            targetLun.target );
        !           310:             }
        !           311:             deallocateTarget( targetLun );
        !           312:             break;
        !           313: 
        !           314:         case kWorkLoopInitDevice:
        !           315:             device = (IOSCSIParallelDevice *) p1;
        !           316:             addDevice( device );
        !           317:             rc = allocateLun( device->targetLun );
        !           318:             break;
        !           319: 
        !           320:         case kWorkLoopReleaseDevice:
        !           321:             device = (IOSCSIParallelDevice *) p1;
        !           322:             deleteDevice( device );
        !           323:             deallocateLun( device->targetLun );
        !           324:             break;
        !           325:     }
        !           326:    
        !           327:     workLoopReq->rc = rc;
        !           328:     workLoopReq->sync->signal();
        !           329: }
        !           330: 
        !           331: /*
        !           332:  *
        !           333:  *
        !           334:  *
        !           335:  */
        !           336: void IOSCSIParallelController::addDevice( IOSCSIParallelDevice *forDevice )
        !           337: {
        !           338:     UInt32     targetID;
        !           339: 
        !           340:     targetID = forDevice->targetLun.target;
        !           341:     
        !           342:     forDevice->target = &targets[targetID];
        !           343:     queue_enter( &targets[targetID].deviceList, forDevice, IOSCSIParallelDevice *, nextDevice );
        !           344: }
        !           345: 
        !           346: /*
        !           347:  *
        !           348:  *
        !           349:  *
        !           350:  */
        !           351: void IOSCSIParallelController::deleteDevice( IOSCSIParallelDevice *forDevice )
        !           352: {
        !           353:     queue_head_t               *deviceList;
        !           354:     IOSCSIParallelDevice               *device;
        !           355:     UInt32                     targetID;
        !           356: 
        !           357:     targetID = forDevice->targetLun.target;    
        !           358: 
        !           359:     deviceList = &targets[targetID].deviceList;
        !           360: 
        !           361:     queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           362:     {
        !           363:         if ( device == forDevice )
        !           364:         {
        !           365:             queue_remove( &targets[targetID].deviceList, device, IOSCSIParallelDevice *, nextDevice );
        !           366:             break;
        !           367:         }
        !           368:     }
        !           369: }
        !           370: 
        !           371: /*
        !           372:  *
        !           373:  *
        !           374:  *
        !           375:  */
        !           376: bool IOSCSIParallelController::allocateTarget( SCSITargetLun targetLun )
        !           377: {
        !           378:     return true;
        !           379: }
        !           380: 
        !           381: /*
        !           382:  *
        !           383:  *
        !           384:  *
        !           385:  */
        !           386: void IOSCSIParallelController::deallocateTarget( SCSITargetLun targetLun )
        !           387: {
        !           388: }
        !           389: 
        !           390: /*
        !           391:  *
        !           392:  *
        !           393:  *
        !           394:  */
        !           395: bool IOSCSIParallelController::allocateLun( SCSITargetLun targetLun )
        !           396: {
        !           397:     return true;
        !           398: }
        !           399: 
        !           400: /*
        !           401:  *
        !           402:  *
        !           403:  *
        !           404:  */
        !           405: void IOSCSIParallelController::deallocateLun( SCSITargetLun targetLun )
        !           406: {
        !           407: }
        !           408: 
        !           409: 
        !           410: /*
        !           411:  *
        !           412:  *
        !           413:  *
        !           414:  */
        !           415: void *IOSCSIParallelController::getTargetData( SCSITargetLun targetLun )
        !           416: {
        !           417:     return targets[targetLun.target].targetPrivateData;
        !           418: }
        !           419: 
        !           420: /*
        !           421:  *
        !           422:  *
        !           423:  *
        !           424:  */
        !           425: void *IOSCSIParallelController::getLunData( SCSITargetLun targetLun )
        !           426: {
        !           427:     queue_head_t               *deviceList;
        !           428:     IOSCSIParallelDevice               *device;
        !           429:        
        !           430:     deviceList = &targets[targetLun.target].deviceList;
        !           431: 
        !           432:     queue_iterate( deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           433:     {
        !           434:         if ( device->targetLun.lun == targetLun.lun )
        !           435:         {
        !           436:             return device->devicePrivateData;
        !           437:         }
        !           438:     }
        !           439:     return 0;
        !           440: }
        !           441: 
        !           442: 
        !           443: 
        !           444: /*
        !           445:  *
        !           446:  *
        !           447:  *
        !           448:  */
        !           449: IOSCSIParallelDevice *IOSCSIParallelController::createDevice()
        !           450: {
        !           451:     return new IOSCSIParallelDevice;
        !           452: }
        !           453: 
        !           454: 
        !           455: /*
        !           456:  *
        !           457:  *
        !           458:  *
        !           459:  */
        !           460: void IOSCSIParallelController::initQueues()
        !           461: {
        !           462:     UInt32             i;
        !           463: 
        !           464:     for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !           465:     {
        !           466:         queue_init( &targets[i].deviceList );
        !           467:     }
        !           468: 
        !           469:     resetCmd = allocCommand( 0 );
        !           470:     resetCmd->cmdType = kSCSICommandBusReset;
        !           471: 
        !           472:     timer( timerEvent ); 
        !           473: }
        !           474: 
        !           475: /*
        !           476:  *
        !           477:  *
        !           478:  *
        !           479:  */
        !           480: void IOSCSIParallelController::reset()
        !           481: {
        !           482:     IOSCSIParallelDevice       *device;
        !           483:     UInt32                     i;
        !           484:     
        !           485:     if ( busResetState != kStateIssue )
        !           486:     {
        !           487:         return;
        !           488:     }
        !           489: 
        !           490:     busResetState = kStateActive;
        !           491: 
        !           492:     for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !           493:     {
        !           494:         queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           495:         {
        !           496:             if ( device->client != 0 )
        !           497:             {
        !           498:                 device->client->message( kSCSIClientMsgBusReset, device );
        !           499:             }
        !           500:         }
        !           501:     }
        !           502: 
        !           503:     resetCommand( resetCmd );
        !           504: }
        !           505: 
        !           506: /*
        !           507:  *
        !           508:  *
        !           509:  *
        !           510:  */
        !           511: bool IOSCSIParallelController::checkBusReset()
        !           512: {
        !           513:     if ( busResetState == kStateIdle )
        !           514:     {
        !           515:         return false;
        !           516:     }
        !           517:     if ( busResetState == kStateIssue )
        !           518:     {
        !           519:         reset();
        !           520:     }
        !           521:     return true;
        !           522: }
        !           523: 
        !           524: 
        !           525: /*
        !           526:  *
        !           527:  *
        !           528:  *
        !           529:  */
        !           530: void IOSCSIParallelController::resetOccurred()
        !           531: {
        !           532:     UInt32                     i;
        !           533:     IOSCSIParallelDevice       *device;
        !           534:     SCSITarget                 *target;
        !           535:     SCSIClientMessage          clientMsg;
        !           536: 
        !           537:     for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !           538:     {
        !           539:         target = &targets[i];
        !           540: 
        !           541:         target->commandLimit   = target->commandLimitSave;
        !           542:         target->reqSenseCount  = 0;
        !           543:         target->reqSenseState  = kStateIdle;
        !           544:         target->negotiateState = kStateIssue;
        !           545: 
        !           546:         target->targetParmsCurrent.transferPeriodpS = 0;
        !           547:         target->targetParmsCurrent.transferOffset   = 0;
        !           548:         target->targetParmsCurrent.transferWidth    = 1;
        !           549: 
        !           550:         noDisconnectCmd = 0;
        !           551: 
        !           552:         clientMsg =  ( busResetState != kStateActive ) ? kSCSIClientMsgBusReset : kSCSIClientMsgNone;
        !           553: 
        !           554:         queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           555:         {
        !           556:             device->resetOccurred( clientMsg );
        !           557:         }
        !           558:     }
        !           559: 
        !           560:     resetTimer = (kSCSIResetIntervalmS / kSCSITimerIntervalmS + 1);
        !           561: }            
        !           562: 
        !           563: 
        !           564: /*
        !           565:  *
        !           566:  *
        !           567:  */
        !           568: void IOSCSIParallelController::timer( IOTimerEventSource * /* timer */ )
        !           569: {
        !           570:     UInt32             i;
        !           571:     IOSCSIParallelDevice       *device;
        !           572: 
        !           573: 
        !           574:     if ( disableTimer )
        !           575:     {
        !           576:         if ( !--disableTimer )
        !           577:         {
        !           578:             disableTimeoutOccurred();
        !           579:         }
        !           580:     }
        !           581: 
        !           582:     if ( resetTimer )
        !           583:     {
        !           584:         if ( !--resetTimer )
        !           585:         {
        !           586:             for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !           587:             {
        !           588:                 queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           589:                 {
        !           590:                     device->resetComplete();
        !           591:                 }
        !           592:             }  
        !           593:                   
        !           594:         }
        !           595:     }
        !           596:     else
        !           597:     {
        !           598:         for (i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !           599:         {
        !           600:             queue_iterate( &targets[i].deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           601:             {
        !           602:                 device->timer();
        !           603:             }
        !           604:         }    
        !           605:     }
        !           606: 
        !           607:     timerEvent->setTimeoutMS(kSCSITimerIntervalmS);
        !           608: }
        !           609: 
        !           610: 
        !           611: /*
        !           612:  *
        !           613:  *
        !           614:  *
        !           615:  */
        !           616: void IOSCSIParallelController::completeCommand( IOSCSIParallelCommand *scsiCmd )
        !           617: {
        !           618:     switch ( scsiCmd->cmdType )
        !           619:     {
        !           620:         case kSCSICommandBusReset:
        !           621:             resetOccurred();
        !           622:             busResetState = kStateIdle;
        !           623:             break;
        !           624:         default:
        !           625:             ;
        !           626:     }
        !           627: }
        !           628: 
        !           629: 
        !           630: /*
        !           631:  *
        !           632:  *
        !           633:  *
        !           634:  */
        !           635: bool IOSCSIParallelController::createWorkLoop()
        !           636: {
        !           637:     workLoop = new IOWorkLoop;
        !           638:     if ( workLoop == NULL )
        !           639:     {
        !           640:         return false;
        !           641:     }
        !           642: 
        !           643:     if ( workLoop->init() != true )
        !           644:     {
        !           645:         return false;
        !           646:     }
        !           647: 
        !           648:     timerEvent = IOTimerEventSource::timerEventSource( this, (IOTimerEventSource::Action) &IOSCSIParallelController::timer );
        !           649:     if ( timerEvent == NULL )
        !           650:     {
        !           651:         return false;
        !           652:     }
        !           653: 
        !           654:     if ( workLoop->addEventSource( timerEvent ) != kIOReturnSuccess )
        !           655:     {
        !           656:         return false;
        !           657:     }
        !           658: 
        !           659: 
        !           660:     dispatchEvent = IOInterruptEventSource::interruptEventSource( this,
        !           661:                                                                   (IOInterruptEventAction) &IOSCSIParallelController::dispatch,
        !           662:                                                                  0 );
        !           663:     if ( dispatchEvent == 0 )
        !           664:     {
        !           665:         return false;
        !           666:     }    
        !           667: 
        !           668:     if ( workLoop->addEventSource( dispatchEvent ) != kIOReturnSuccess )
        !           669:     {
        !           670:         return false;
        !           671:     }
        !           672:      
        !           673:     workLoopReqGate = IOCommandGate::commandGate( this, (IOCommandGate::Action) &IOSCSIParallelController::workLoopProcessRequest );
        !           674:     if ( workLoopReqGate == NULL )
        !           675:     {
        !           676:         return false;
        !           677:     }
        !           678: 
        !           679:     if ( workLoop->addEventSource( workLoopReqGate ) != kIOReturnSuccess )
        !           680:     {
        !           681:         return false;
        !           682:     }
        !           683: 
        !           684: 
        !           685:    return true;
        !           686: }
        !           687: 
        !           688: /*
        !           689:  *
        !           690:  *
        !           691:  *
        !           692:  */
        !           693: IOSCSIParallelCommand *IOSCSIParallelController::findCommandWithNexus( SCSITargetLun targetLun, UInt32 tagValue = (UInt32)-1 )
        !           694: {
        !           695:     IOSCSIParallelDevice       *device;
        !           696: 
        !           697:     device = findDeviceWithTargetLun( targetLun );
        !           698:     if ( device == 0 )
        !           699:     {
        !           700:         return NULL;
        !           701:     }
        !           702: 
        !           703:     return device->findCommandWithNexus( tagValue );
        !           704: }
        !           705: 
        !           706: 
        !           707: /*
        !           708:  *
        !           709:  *
        !           710:  *
        !           711:  */
        !           712: IOSCSIParallelDevice *IOSCSIParallelController::findDeviceWithTargetLun( SCSITargetLun targetLun )
        !           713: {
        !           714:     IOSCSIParallelDevice               *device;
        !           715: 
        !           716:     if ( targetLun.target > controllerInfo.maxTargetsSupported || targetLun.lun > controllerInfo.maxLunsSupported )
        !           717:     {
        !           718:         return 0;
        !           719:     }
        !           720: 
        !           721:     queue_iterate( &targets[targetLun.target].deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           722:     {
        !           723:         if ( device->targetLun.lun == targetLun.lun )
        !           724:         {
        !           725:             return device;
        !           726:         }
        !           727:     }
        !           728:     return 0;
        !           729: }    
        !           730:     
        !           731:        
        !           732: /*
        !           733:  *
        !           734:  *
        !           735:  *
        !           736:  */
        !           737: bool IOSCSIParallelController::configureController()
        !           738: {
        !           739:     UInt32             targetsSize;
        !           740: 
        !           741:     if ( configure( provider, &controllerInfo ) == false )
        !           742:     {
        !           743:         return false;
        !           744:     }
        !           745: 
        !           746:     controllerInfo.commandPrivateDataSize = round( controllerInfo.commandPrivateDataSize, 16 );
        !           747: 
        !           748:     if ( controllerInfo.maxCommandsPerController == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1;    
        !           749:     if ( controllerInfo.maxCommandsPerTarget == 0     ) controllerInfo.maxCommandsPerTarget     = (UInt32) -1;    
        !           750:     if ( controllerInfo.maxCommandsPerLun == 0 )        controllerInfo.maxCommandsPerLun        = (UInt32) -1;    
        !           751: 
        !           752:     targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget);
        !           753:     targets = (SCSITarget *)IOMalloc( targetsSize );
        !           754:     bzero( targets, targetsSize );
        !           755: 
        !           756:     commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController;
        !           757: 
        !           758:     tagArraySize = (controllerInfo.maxTags / 32 + ((controllerInfo.maxTags % 32) ? 1 : 0)) * sizeof(UInt32);
        !           759:      
        !           760:     if ( controllerInfo.tagAllocationMethod == kTagAllocationPerController )
        !           761:     {
        !           762:         tagArray = (UInt32 *)IOMalloc( tagArraySize );
        !           763:         bzero( tagArray, tagArraySize );
        !           764:     }
        !           765: 
        !           766:     return true;
        !           767: }
        !           768: 
        !           769: /*
        !           770:  *
        !           771:  *
        !           772:  *
        !           773:  */
        !           774: void IOSCSIParallelController::setCommandLimit( UInt32 newCommandLimit )
        !           775: {
        !           776:     if ( newCommandLimit == 0 ) controllerInfo.maxCommandsPerController = (UInt32) -1;    
        !           777: 
        !           778:     commandLimit = commandLimitSave = controllerInfo.maxCommandsPerController;
        !           779: }
        !           780: 
        !           781: /*
        !           782:  *
        !           783:  *
        !           784:  *
        !           785:  */
        !           786: IOWorkLoop *IOSCSIParallelController::getWorkLoop() const
        !           787: {
        !           788:     return workLoop;
        !           789: }
        !           790: 
        !           791: /*
        !           792:  *
        !           793:  *
        !           794:  *
        !           795:  */
        !           796: void IOSCSIParallelController::disableCommands( UInt32 disableTimeoutmS )
        !           797: {
        !           798:     commandDisable = true;
        !           799: 
        !           800:     disableTimer = ( disableTimeoutmS != 0 ) ? (disableTimeoutmS / kSCSITimerIntervalmS + 1) : 0;
        !           801: }
        !           802:     
        !           803:     
        !           804: /*
        !           805:  *
        !           806:  *
        !           807:  *
        !           808:  */
        !           809: void IOSCSIParallelController::disableCommands()
        !           810: {
        !           811:     UInt32             disableTimeout;
        !           812: 
        !           813:     commandDisable = true;
        !           814: 
        !           815:     disableTimeout = kSCSIDisableTimeoutmS;
        !           816: 
        !           817:     if ( noDisconnectCmd != 0 )
        !           818:     {
        !           819:         disableTimeout = noDisconnectCmd->getTimeout();
        !           820:         if ( disableTimeout != 0 ) disableTimeout += kSCSIDisableTimeoutmS;            
        !           821:     }
        !           822: 
        !           823:     disableTimer = ( disableTimeout != 0 ) ? (disableTimeout / kSCSITimerIntervalmS + 1) : 0;
        !           824: }
        !           825: 
        !           826: /*
        !           827:  *
        !           828:  *
        !           829:  *
        !           830:  */
        !           831: void IOSCSIParallelController::disableTimeoutOccurred()
        !           832: {
        !           833:     busResetState = kStateIssue;
        !           834:     dispatchRequest();     
        !           835: }
        !           836: 
        !           837: 
        !           838: /*
        !           839:  *
        !           840:  *
        !           841:  *
        !           842:  */
        !           843: void IOSCSIParallelController::rescheduleCommand( IOSCSICommand *forSCSICmd )
        !           844: {
        !           845:     IOSCSIParallelCommand      *scsiCmd = (IOSCSIParallelCommand *)forSCSICmd;
        !           846:     IOSCSIParallelDevice       *device  = (IOSCSIParallelDevice *) scsiCmd->getDevice(kIOSCSIDevice);
        !           847: 
        !           848:     device->rescheduleCommand( scsiCmd );
        !           849: }
        !           850: 
        !           851: /*
        !           852:  *
        !           853:  *
        !           854:  *
        !           855:  */
        !           856: void IOSCSIParallelController::enableCommands()
        !           857: {
        !           858:     commandDisable = false;
        !           859: 
        !           860:     disableTimer = 0;
        !           861: 
        !           862:     dispatchRequest();
        !           863: }
        !           864: 
        !           865: /*
        !           866:  *
        !           867:  *
        !           868:  *
        !           869:  */
        !           870: void IOSCSIParallelController::dispatchRequest()
        !           871: {
        !           872:     dispatchEvent->interruptOccurred(0, 0, 0);
        !           873: }
        !           874: 
        !           875: 
        !           876: /*
        !           877:  *
        !           878:  *
        !           879:  *
        !           880:  */
        !           881: void IOSCSIParallelController::dispatch()
        !           882: {
        !           883:     SCSITarget         *target;
        !           884:     IOSCSIParallelDevice       *device;
        !           885:     UInt32              dispatchAction;
        !           886:     UInt32             lunsActive = 0;
        !           887:     UInt32             i;
        !           888: 
        !           889:     if ( checkBusReset() == true )
        !           890:     {
        !           891:         goto dispatch_Exit;
        !           892:     }
        !           893: 
        !           894:     for ( i = 0; i < controllerInfo.maxTargetsSupported; i++ )
        !           895:     {
        !           896:         target = &targets[i];
        !           897: 
        !           898:         if ( target->state == kStateActive )
        !           899:         {
        !           900:             lunsActive = 0;
        !           901: 
        !           902:             queue_iterate( &target->deviceList, device, IOSCSIParallelDevice *, nextDevice )
        !           903:             {
        !           904:                 if ( device->dispatch( &dispatchAction ) == true )
        !           905:                 {
        !           906:                     lunsActive++;
        !           907:                 }
        !           908: 
        !           909:                 switch ( dispatchAction )
        !           910:                 {
        !           911:                     case kDispatchNextLun:
        !           912:                         ;
        !           913:                     case kDispatchNextTarget:
        !           914:                         break;
        !           915:                     case kDispatchStop:
        !           916:                         goto dispatch_Exit;
        !           917:                 }     
        !           918:             }
        !           919:             if ( lunsActive == 0 )
        !           920:             {
        !           921:                 target->state = kStateIdle;
        !           922:             }
        !           923:         }        
        !           924:     }
        !           925: 
        !           926: dispatch_Exit:
        !           927:     ;
        !           928: }
        !           929: 
        !           930: /*
        !           931:  *
        !           932:  *
        !           933:  *
        !           934:  */
        !           935: IOSCSIParallelCommand *IOSCSIParallelController::allocCommand(UInt32 clientDataSize )
        !           936: {
        !           937:     IOSCSIParallelCommand      *cmd;
        !           938:     UInt32             size;
        !           939: 
        !           940:     size = controllerInfo.commandPrivateDataSize + round(clientDataSize, 16);
        !           941: 
        !           942:     cmd = new IOSCSIParallelCommand;
        !           943:     if ( !cmd )
        !           944:     {
        !           945:         return 0;
        !           946:     }
        !           947:     cmd->init();
        !           948: 
        !           949:     if ( size )
        !           950:     {
        !           951:         cmd->dataArea = (void *)IOMallocContiguous( (vm_size_t)size, 16, 0 );
        !           952:         if ( !cmd->dataArea )
        !           953:         {
        !           954:             cmd->release();
        !           955:             return 0;
        !           956:         }
        !           957:         
        !           958:         bzero( cmd->dataArea, size );
        !           959: 
        !           960:         cmd->dataSize = size;
        !           961: 
        !           962:         if ( controllerInfo.commandPrivateDataSize )
        !           963:         {
        !           964:             cmd->commandPrivateData = cmd->dataArea;
        !           965:         }
        !           966:         if ( clientDataSize )
        !           967:         {
        !           968:             cmd->clientData = (void *)((UInt8 *)cmd->dataArea + controllerInfo.commandPrivateDataSize);
        !           969:         }
        !           970:     }
        !           971: 
        !           972:     cmd->controller = this;
        !           973: 
        !           974:     return cmd;
        !           975: }
        !           976: 
        !           977: /*
        !           978:  *
        !           979:  *
        !           980:  *
        !           981:  */
        !           982: void IOSCSIParallelController::free()
        !           983: {
        !           984:     UInt32                     targetsSize;
        !           985:     UInt32                     i;
        !           986: 
        !           987:     if ( timerEvent != 0 )     timerEvent->release();
        !           988: 
        !           989:     if ( workLoopReqGate != 0 ) workLoopReqGate->release();
        !           990: 
        !           991:     if ( dispatchEvent != 0 )   dispatchEvent->release();
        !           992: 
        !           993:     if ( resetCmd != 0 )       resetCmd->release();
        !           994: 
        !           995:     if ( workLoop != 0 )       workLoop->release();
        !           996: 
        !           997:     if ( targets != 0 )
        !           998:     {
        !           999:         for ( i=0; i < controllerInfo.maxTargetsSupported; i++ )
        !          1000:         {
        !          1001:             if ( targets[i].targetPrivateData != 0 )
        !          1002:             {
        !          1003:                IOFreeContiguous( targets[i].targetPrivateData, controllerInfo.targetPrivateDataSize );
        !          1004:             }
        !          1005:         }
        !          1006: 
        !          1007:         targetsSize = controllerInfo.maxTargetsSupported * sizeof(SCSITarget);
        !          1008:         IOFree( targets, targetsSize ); 
        !          1009:     }
        !          1010: 
        !          1011:     if ( tagArray != 0 ) IOFree( tagArray, tagArraySize );
        !          1012: 
        !          1013:     super::free();
        !          1014: }
        !          1015: 
        !          1016: /*
        !          1017:  *
        !          1018:  *
        !          1019:  *
        !          1020:  */
        !          1021: void IOSCSIParallelCommand::free()
        !          1022: {
        !          1023:     if ( dataArea )
        !          1024:     {
        !          1025:         IOFreeContiguous( dataArea, dataSize );        
        !          1026:     }
        !          1027: 
        !          1028:     OSObject::free();
        !          1029: }
        !          1030:      

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.