Annotation of XNU/iokit/Families/IOSCSIParallel/IOSCSIParallelController.cpp, revision 1.1.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.