Annotation of XNU/iokit/Kernel/IOInterruptController.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:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
        !            24:  *
        !            25:  *  DRI: Josh de Cesare
        !            26:  *
        !            27:  */
        !            28: 
        !            29: 
        !            30: #ifdef __ppc__
        !            31: #include <ppc/proc_reg.h> 
        !            32: #endif
        !            33: 
        !            34: #include <IOKit/IOLib.h>
        !            35: #include <IOKit/IOService.h>
        !            36: #include <IOKit/IOPlatformExpert.h>
        !            37: #include <IOKit/IOInterrupts.h>
        !            38: #include <IOKit/IOInterruptController.h>
        !            39: 
        !            40: 
        !            41: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            42: 
        !            43: #define super IOService
        !            44: 
        !            45: OSDefineMetaClass(IOInterruptController, IOService);
        !            46: OSDefineAbstractStructors(IOInterruptController, IOService);
        !            47: 
        !            48: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            49: 
        !            50: IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source,
        !            51:                                                  void *target,
        !            52:                                                  IOInterruptHandler handler,
        !            53:                                                  void *refCon)
        !            54: {
        !            55:   IOInterruptSource *interruptSources;
        !            56:   long              vectorNumber;
        !            57:   IOInterruptVector *vector;
        !            58:   long              wasDisabledSoft;
        !            59:   IOReturn          error;
        !            60:   OSData            *vectorData;
        !            61:   IOService         *originalNub;
        !            62:   int               originalSource;
        !            63:   
        !            64:   interruptSources = nub->_interruptSources;
        !            65:   vectorData = interruptSources[source].vectorData;
        !            66:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !            67:   vector = &vectors[vectorNumber];
        !            68:   
        !            69:   // Get the lock for this vector.
        !            70:   IOTakeLock(vector->interruptLock);
        !            71:   
        !            72:   // If this vector is already in use, and can be shared,
        !            73:   // register as a shared interrupt.
        !            74:   if (vector->interruptRegistered) {
        !            75:     if (!vectorCanBeShared(vectorNumber, vector)) {
        !            76:       IOUnlock(vector->interruptLock);
        !            77:       return kIOReturnNoResources;
        !            78:     }
        !            79:     
        !            80:     // If this vector is not already shared, break it out.
        !            81:     if (vector->sharedController == 0) {
        !            82:       // Make the IOShareInterruptController instance
        !            83:       vector->sharedController = new IOSharedInterruptController;
        !            84:       if (vector->sharedController == 0) {
        !            85:         IOUnlock(vector->interruptLock);
        !            86:         return kIOReturnNoMemory;
        !            87:       }
        !            88:       
        !            89:       // Save the nub and source for the original consumer.
        !            90:       originalNub = vector->nub;
        !            91:       originalSource = vector->source;
        !            92:       
        !            93:       // Save the dis/enable state for the original consumer's interrupt.
        !            94:       // Then disable the source
        !            95:       wasDisabledSoft = vector->interruptDisabledSoft;
        !            96:       disableInterrupt(originalNub, originalSource);
        !            97:       
        !            98:       // Initialize the new shared interrupt controller.
        !            99:       error = vector->sharedController->initInterruptController(this,
        !           100:                                                                 vectorData);
        !           101:       // If the IOSharedInterruptController could not be initalized,
        !           102:       // put the original consumor's interrupt back to normal and
        !           103:       // get rid of whats left of the shared controller.
        !           104:       if (error != kIOReturnSuccess) {
        !           105:         enableInterrupt(originalNub, originalSource);
        !           106:         vector->sharedController->release();
        !           107:         vector->sharedController = 0;
        !           108:         IOUnlock(vector->interruptLock);
        !           109:         return error;
        !           110:       }
        !           111:       
        !           112:       // Try to register the original consumer on the shared controller.
        !           113:       error = vector->sharedController->registerInterrupt(originalNub,
        !           114:                                                           originalSource,
        !           115:                                                           vector->target,
        !           116:                                                           vector->handler,
        !           117:                                                           vector->refCon);
        !           118:       // If the original consumer could not be moved to the shared controller,
        !           119:       // put the original consumor's interrupt back to normal and
        !           120:       // get rid of whats left of the shared controller.
        !           121:       if (error != kIOReturnSuccess) {
        !           122:         enableInterrupt(originalNub, originalSource);
        !           123:         vector->sharedController->release();
        !           124:         vector->sharedController = 0;
        !           125:         IOUnlock(vector->interruptLock);
        !           126:         return error;
        !           127:       }
        !           128:       
        !           129:       // Fill in vector with the shared controller's info.
        !           130:       vector->handler = (IOInterruptHandler)vector->sharedController->getInterruptHandlerAddress();
        !           131:       vector->nub     = vector->sharedController;
        !           132:       vector->source  = 0;
        !           133:       vector->target  = vector->sharedController;
        !           134:       vector->refCon  = 0;
        !           135:       
        !           136:       // Enable the original consumer's interrupt if needed.
        !           137:       if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
        !           138:     }
        !           139:     
        !           140:     error = vector->sharedController->registerInterrupt(nub, source, target,
        !           141:                                                         handler, refCon);
        !           142:     IOUnlock(vector->interruptLock);
        !           143:     return error;
        !           144:   }
        !           145:   
        !           146:   // Fill in vector with the client's info.
        !           147:   vector->handler = handler;
        !           148:   vector->nub     = nub;
        !           149:   vector->source  = source;
        !           150:   vector->target  = target;
        !           151:   vector->refCon  = refCon;
        !           152:   
        !           153:   // Do any specific initalization for this vector.
        !           154:   initVector(vectorNumber, vector);
        !           155:   
        !           156:   // Get the vector ready.  It starts hard disabled.
        !           157:   vector->interruptDisabledHard = 1;
        !           158:   vector->interruptDisabledSoft = 1;
        !           159:   vector->interruptRegistered   = 1;
        !           160:   
        !           161:   IOUnlock(vector->interruptLock);
        !           162:   return kIOReturnSuccess;
        !           163: }
        !           164: 
        !           165: IOReturn IOInterruptController::unregisterInterrupt(IOService *nub, int source)
        !           166: {
        !           167:   IOInterruptSource *interruptSources;
        !           168:   long              vectorNumber;
        !           169:   IOInterruptVector *vector;
        !           170:   OSData            *vectorData;
        !           171:   
        !           172:   interruptSources = nub->_interruptSources;
        !           173:   vectorData = interruptSources[source].vectorData;
        !           174:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           175:   vector = &vectors[vectorNumber];
        !           176:   
        !           177:   // Get the lock for this vector.
        !           178:   IOTakeLock(vector->interruptLock);
        !           179:   
        !           180:   // Return success if it is not already registered
        !           181:   if (vector->interruptRegistered) {
        !           182:     IOUnlock(vector->interruptLock);
        !           183:     return kIOReturnSuccess;
        !           184:   }
        !           185:   
        !           186:   // Soft disable the source.
        !           187:   disableInterrupt(nub, source);
        !           188:   
        !           189:   // Turn the source off at hardware. 
        !           190:   disableVectorHard(vectorNumber, vector);
        !           191:   
        !           192:   // Clear all the storage for the vector except for interruptLock.
        !           193:   vector->interruptActive = 0;
        !           194:   vector->interruptDisabledSoft = 0;
        !           195:   vector->interruptDisabledHard = 0;
        !           196:   vector->interruptRegistered = 0;
        !           197:   vector->nub = 0;
        !           198:   vector->source = 0;
        !           199:   vector->handler = 0;
        !           200:   vector->target = 0;
        !           201:   vector->refCon = 0;
        !           202:   
        !           203:   IOUnlock(vector->interruptLock);
        !           204:   return kIOReturnSuccess;
        !           205: }
        !           206: 
        !           207: IOReturn IOInterruptController::getInterruptType(IOService *nub, int source,
        !           208:                                                 int *interruptType)
        !           209: {
        !           210:   IOInterruptSource *interruptSources;
        !           211:   long              vectorNumber;
        !           212:   IOInterruptVector *vector;
        !           213:   OSData            *vectorData;
        !           214:   
        !           215:   if (interruptType == 0) return kIOReturnBadArgument;
        !           216:   
        !           217:   interruptSources = nub->_interruptSources;
        !           218:   vectorData = interruptSources[source].vectorData;
        !           219:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           220:   vector = &vectors[vectorNumber];
        !           221:   
        !           222:   *interruptType = getVectorType(vectorNumber, vector);
        !           223:   
        !           224:   return kIOReturnSuccess;
        !           225: }
        !           226: 
        !           227: IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source)
        !           228: {
        !           229:   IOInterruptSource *interruptSources;
        !           230:   long              vectorNumber;
        !           231:   IOInterruptVector *vector;
        !           232:   OSData            *vectorData;
        !           233:   
        !           234:   interruptSources = nub->_interruptSources;
        !           235:   vectorData = interruptSources[source].vectorData;
        !           236:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           237:   vector = &vectors[vectorNumber];
        !           238:   
        !           239:   if (vector->interruptDisabledSoft) {
        !           240:     vector->interruptDisabledSoft = 0;
        !           241:     
        !           242:     if (vector->interruptDisabledHard) {
        !           243:       vector->interruptDisabledHard = 0;
        !           244:       
        !           245:       enableVector(vectorNumber, vector);
        !           246:     }
        !           247:   }
        !           248:   
        !           249:   return kIOReturnSuccess;
        !           250: }
        !           251: 
        !           252: IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source)
        !           253: {
        !           254:   IOInterruptSource *interruptSources;
        !           255:   long              vectorNumber;
        !           256:   IOInterruptVector *vector;
        !           257:   OSData            *vectorData;
        !           258:   
        !           259:   interruptSources = nub->_interruptSources;
        !           260:   vectorData = interruptSources[source].vectorData;
        !           261:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           262:   vector = &vectors[vectorNumber];
        !           263:   
        !           264:   vector->interruptDisabledSoft = 1;
        !           265: #ifdef __ppc__
        !           266:   sync();
        !           267:   isync();
        !           268: #endif
        !           269:   
        !           270:   if (!getPlatform()->atInterruptLevel()) {
        !           271:     while (vector->interruptActive);
        !           272: #ifdef __ppc__
        !           273:     isync();
        !           274: #endif
        !           275:   }
        !           276:   
        !           277:   return kIOReturnSuccess;
        !           278: }
        !           279: 
        !           280: IOReturn IOInterruptController::causeInterrupt(IOService *nub, int source)
        !           281: {
        !           282:   IOInterruptSource *interruptSources;
        !           283:   long              vectorNumber;
        !           284:   IOInterruptVector *vector;
        !           285:   OSData            *vectorData;
        !           286: 
        !           287:   interruptSources = nub->_interruptSources;
        !           288:   vectorData = interruptSources[source].vectorData;
        !           289:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           290:   vector = &vectors[vectorNumber];
        !           291:   
        !           292:   causeVector(vectorNumber, vector);
        !           293:   
        !           294:   return kIOReturnSuccess;
        !           295: }
        !           296: 
        !           297: IOInterruptAction IOInterruptController::getInterruptHandlerAddress(void)
        !           298: {
        !           299:   return 0;
        !           300: }
        !           301: 
        !           302: IOReturn IOInterruptController::handleInterrupt(void *refCon, IOService *nub,
        !           303:                                                int source)
        !           304: {
        !           305:   return kIOReturnInvalid;
        !           306: }
        !           307: 
        !           308: 
        !           309: // Methods to be overridden for simplifed interrupt controller subclasses.
        !           310: 
        !           311: bool IOInterruptController::vectorCanBeShared(long /*vectorNumber*/,
        !           312:                                              IOInterruptVector */*vector*/)
        !           313: {
        !           314:   return false;
        !           315: }
        !           316: 
        !           317: void IOInterruptController::initVector(long /*vectorNumber*/,
        !           318:                                       IOInterruptVector */*vector*/)
        !           319: {
        !           320: }
        !           321: 
        !           322: int IOInterruptController::getVectorType(long /*vectorNumber*/,
        !           323:                                          IOInterruptVector */*vector*/)
        !           324: {
        !           325:   return kIOInterruptTypeEdge;
        !           326: }
        !           327: 
        !           328: void IOInterruptController::disableVectorHard(long /*vectorNumber*/,
        !           329:                                              IOInterruptVector */*vector*/)
        !           330: {
        !           331: }
        !           332: 
        !           333: void IOInterruptController::enableVector(long /*vectorNumber*/,
        !           334:                                         IOInterruptVector */*vector*/)
        !           335: {
        !           336: }
        !           337: 
        !           338: void IOInterruptController::causeVector(long /*vectorNumber*/,
        !           339:                                        IOInterruptVector */*vector*/)
        !           340: {
        !           341: }
        !           342: 
        !           343: 
        !           344: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           345: 
        !           346: #undef  super
        !           347: #define super IOInterruptController
        !           348: 
        !           349: OSDefineMetaClassAndStructors(IOSharedInterruptController, IOInterruptController);
        !           350: 
        !           351: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           352: 
        !           353: IOReturn IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource)
        !           354: {
        !           355:   int      cnt, interruptType;
        !           356:   IOReturn error;
        !           357:   
        !           358:   if (!super::init())
        !           359:     return kIOReturnNoResources;
        !           360:   
        !           361:   // Set provider to this so enable/disable nub stuff works.
        !           362:   provider = this;
        !           363:   
        !           364:   // Allocate the IOInterruptSource so this can act like a nub.
        !           365:   _interruptSources = (IOInterruptSource *)IOMalloc(sizeof(IOInterruptSource));
        !           366:   if (_interruptSources == 0) return kIOReturnNoMemory;
        !           367:   _numInterruptSources = 1;
        !           368:   
        !           369:   // Set up the IOInterruptSource to point at this.
        !           370:   _interruptSources[0].interruptController = parentController;
        !           371:   _interruptSources[0].vectorData = parentSource;
        !           372:   
        !           373:   sourceIsLevel = false;
        !           374:   error = provider->getInterruptType(0, &interruptType);
        !           375:   if (error == kIOReturnSuccess) {
        !           376:     if (interruptType & kIOInterruptTypeLevel)
        !           377:       sourceIsLevel = true;
        !           378:   }
        !           379:   
        !           380:   // Allocate the memory for the vectors
        !           381:   numVectors = 8; // For now a constant number.
        !           382:   vectors = (IOInterruptVector *)IOMalloc(numVectors * sizeof(IOInterruptVector));
        !           383:   if (vectors == NULL) {
        !           384:     IOFree(_interruptSources, sizeof(IOInterruptSource));
        !           385:     return kIOReturnNoMemory;
        !           386:   }
        !           387:   bzero(vectors, numVectors * sizeof(IOInterruptVector));
        !           388:   
        !           389:   // Allocate locks for the
        !           390:   for (cnt = 0; cnt < numVectors; cnt++) {
        !           391:     vectors[cnt].interruptLock = IOLockAlloc();
        !           392:     if (vectors[cnt].interruptLock == NULL) {
        !           393:       for (cnt = 0; cnt < numVectors; cnt++) {
        !           394:        if (vectors[cnt].interruptLock != NULL)
        !           395:          IOLockFree(vectors[cnt].interruptLock);
        !           396:       }
        !           397:       return kIOReturnNoResources;
        !           398:     }
        !           399:   }
        !           400:   
        !           401:   vectorsRegistered = 0;
        !           402:   vectorsEnabled = 0;
        !           403:   controllerDisabled = 1;
        !           404:   
        !           405:   return kIOReturnSuccess;
        !           406: }
        !           407: 
        !           408: IOReturn IOSharedInterruptController::registerInterrupt(IOService *nub,
        !           409:                                                        int source,
        !           410:                                                        void *target,
        !           411:                                                        IOInterruptHandler handler,
        !           412:                                                        void *refCon)
        !           413: {
        !           414:   IOInterruptSource *interruptSources;
        !           415:   long              vectorNumber;
        !           416:   IOInterruptVector *vector = 0;
        !           417:   OSData            *vectorData;
        !           418:   
        !           419:   interruptSources = nub->_interruptSources;
        !           420:   
        !           421:   // Find a free vector.
        !           422:   vectorNumber = numVectors;
        !           423:   while (vectorsRegistered != numVectors) {
        !           424:     for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
        !           425:       vector = &vectors[vectorNumber];
        !           426:       
        !           427:       // Get the lock for this vector.
        !           428:       IOTakeLock(vector->interruptLock);
        !           429:       
        !           430:       // Is it unregistered?
        !           431:       if (!vector->interruptRegistered) break;
        !           432:       
        !           433:       // Move along to the next one.
        !           434:       IOUnlock(vector->interruptLock);
        !           435:     }
        !           436:     
        !           437:     if (vectorNumber != numVectors) break;
        !           438:   }
        !           439:   
        !           440:   // Could not find a free one, so give up.
        !           441:   if (vectorNumber == numVectors) {
        !           442:     return kIOReturnNoResources;
        !           443:   }
        !           444:   
        !           445:   // Create the vectorData for the IOInterruptSource.
        !           446:   vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber));
        !           447:   if (vectorData == 0) {
        !           448:     return kIOReturnNoMemory;
        !           449:   }
        !           450:   
        !           451:   // Fill in the IOInterruptSource with the controller's info.
        !           452:   interruptSources[source].interruptController = this;
        !           453:   interruptSources[source].vectorData = vectorData;
        !           454:   
        !           455:   // Fill in vector with the client's info.
        !           456:   vector->handler = handler;
        !           457:   vector->nub     = nub;
        !           458:   vector->source  = source;
        !           459:   vector->target  = target;
        !           460:   vector->refCon  = refCon;
        !           461:   
        !           462:   // Get the vector ready.  It start soft disabled.
        !           463:   vector->interruptDisabledSoft = 1;
        !           464:   vector->interruptRegistered   = 1;
        !           465:   
        !           466:   vectorsRegistered++;
        !           467:   
        !           468:   IOUnlock(vector->interruptLock);
        !           469:   return kIOReturnSuccess;
        !           470: }
        !           471: 
        !           472: IOReturn IOSharedInterruptController::unregisterInterrupt(IOService *nub,
        !           473:                                                          int source)
        !           474: {
        !           475:   IOInterruptSource *interruptSources;
        !           476:   long              vectorNumber;
        !           477:   IOInterruptVector *vector;
        !           478:   OSData            *vectorData;
        !           479:   
        !           480:   interruptSources = nub->_interruptSources;
        !           481:   vectorData = interruptSources[source].vectorData;
        !           482:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           483:   vector = &vectors[vectorNumber];
        !           484:   
        !           485:   // Get the lock for this vector.
        !           486:   IOTakeLock(vector->interruptLock);
        !           487:   
        !           488:   // Return success if it is not already registered
        !           489:   if (vector->interruptRegistered) {
        !           490:     IOUnlock(vector->interruptLock);
        !           491:     return kIOReturnSuccess;
        !           492:   }
        !           493:   
        !           494:   // Soft disable the source.
        !           495:   disableInterrupt(nub, source);
        !           496:   
        !           497:   // Clear all the storage for the vector except for interruptLock.
        !           498:   vector->interruptActive = 0;
        !           499:   vector->interruptDisabledSoft = 0;
        !           500:   vector->interruptDisabledHard = 0;
        !           501:   vector->interruptRegistered = 0;
        !           502:   vector->nub = 0;
        !           503:   vector->source = 0;
        !           504:   vector->handler = 0;
        !           505:   vector->target = 0;
        !           506:   vector->refCon = 0;
        !           507:   
        !           508:   vectorsRegistered--;
        !           509:   
        !           510:   IOUnlock(vector->interruptLock);
        !           511:   return kIOReturnSuccess;
        !           512: }
        !           513: 
        !           514: IOReturn IOSharedInterruptController::getInterruptType(IOService */*nub*/,
        !           515:                                                       int /*source*/,
        !           516:                                                       int *interruptType)
        !           517: {
        !           518:   return provider->getInterruptType(0, interruptType);
        !           519: }
        !           520: 
        !           521: IOReturn IOSharedInterruptController::enableInterrupt(IOService *nub,
        !           522:                                                      int source)
        !           523: {
        !           524:   IOInterruptSource *interruptSources;
        !           525:   long              vectorNumber;
        !           526:   IOInterruptVector *vector;
        !           527:   OSData            *vectorData;
        !           528:   
        !           529:   interruptSources = nub->_interruptSources;
        !           530:   vectorData = interruptSources[source].vectorData;
        !           531:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           532:   vector = &vectors[vectorNumber];
        !           533:   
        !           534:   if (vector->interruptDisabledSoft) {
        !           535:     vector->interruptDisabledSoft = 0;
        !           536:     
        !           537:     vectorsEnabled++;
        !           538:     
        !           539:     if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
        !           540:       controllerDisabled = 0;
        !           541:       provider->enableInterrupt(0);
        !           542:     }
        !           543:   }
        !           544:   
        !           545:   return kIOReturnSuccess;
        !           546: }
        !           547: 
        !           548: IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub,
        !           549:                                                       int source)
        !           550: {
        !           551:   IOInterruptSource *interruptSources;
        !           552:   long              vectorNumber;
        !           553:   IOInterruptVector *vector;
        !           554:   OSData            *vectorData;
        !           555:   
        !           556:   interruptSources = nub->_interruptSources;
        !           557:   vectorData = interruptSources[source].vectorData;
        !           558:   vectorNumber = *(long *)vectorData->getBytesNoCopy();
        !           559:   vector = &vectors[vectorNumber];
        !           560:   
        !           561:   if (!vector->interruptDisabledSoft) {
        !           562:     vector->interruptDisabledSoft = 1;
        !           563: #ifdef __ppc__
        !           564:     sync();
        !           565:     isync();
        !           566: #endif
        !           567:     
        !           568:     vectorsEnabled--;
        !           569:   }
        !           570:   
        !           571:   if (!getPlatform()->atInterruptLevel()) {
        !           572:     while (vector->interruptActive);
        !           573: #ifdef __ppc__
        !           574:     isync();
        !           575: #endif
        !           576:   }
        !           577:   
        !           578:   return kIOReturnSuccess;
        !           579: }
        !           580: 
        !           581: IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void)
        !           582: {
        !           583:     return (IOInterruptAction)&IOSharedInterruptController::handleInterrupt;
        !           584: }
        !           585: 
        !           586: IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
        !           587:                                                      IOService * nub,
        !           588:                                                      int /*source*/)
        !           589: {
        !           590:   long              vectorNumber;
        !           591:   IOInterruptVector *vector;
        !           592:   
        !           593:   for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
        !           594:     vector = &vectors[vectorNumber];
        !           595:     
        !           596:     vector->interruptActive = 1;
        !           597: #ifdef __ppc__
        !           598:     sync();
        !           599:     isync();
        !           600: #endif
        !           601:     if (!vector->interruptDisabledSoft) {
        !           602: #ifdef __ppc__
        !           603:       isync();
        !           604: #endif
        !           605:       
        !           606:       // Call the handler if it exists.
        !           607:       if (vector->interruptRegistered) {
        !           608:        vector->handler(vector->target, vector->refCon,
        !           609:                        vector->nub, vector->source);
        !           610:       }
        !           611:     }
        !           612:     
        !           613:     vector->interruptActive = 0;
        !           614:   }
        !           615:   
        !           616:   // if any fo the vectors are dissabled, then dissable this controller.
        !           617:   if (vectorsEnabled != vectorsRegistered) {
        !           618:     nub->disableInterrupt(0);
        !           619:     controllerDisabled = 1;
        !           620:   }
        !           621:   
        !           622:   return kIOReturnSuccess;
        !           623: }

unix.superglobalmegacorp.com

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