Annotation of XNU/iokit/Kernel/IOInterruptEventSource.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: Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
                     24: 
                     25: HISTORY
                     26:     1998-7-13  Godfrey van der Linden(gvdl)
                     27:         Created.
                     28: */
                     29: #include <IOKit/IOInterruptEventSource.h>
                     30: #include <IOKit/IOLib.h>
                     31: #include <IOKit/IOService.h>
                     32: #include <IOKit/IOInterrupts.h>
                     33: #include <IOKit/IOTimeStamp.h>
                     34: #include <IOKit/IOWorkLoop.h>
                     35: 
                     36: #if KDEBUG
                     37: 
                     38: #define IOTimeTypeStampS(t)                                            \
                     39: do {                                                                   \
                     40:     IOTimeStampStart(IODBG_INTES(t),                                   \
                     41:                      (unsigned int) this, (unsigned int) owner);       \
                     42: } while(0)
                     43: 
                     44: #define IOTimeTypeStampE(t)                                            \
                     45: do {                                                                   \
                     46:     IOTimeStampEnd(IODBG_INTES(t),                                     \
                     47:                    (unsigned int) this, (unsigned int) owner);         \
                     48: } while(0)
                     49: 
                     50: #define IOTimeStampLatency()                                           \
                     51: do {                                                                   \
                     52:     IOTimeStampEnd(IODBG_INTES(IOINTES_LAT),                           \
                     53:                    (unsigned int) this, (unsigned int) owner);         \
                     54: } while(0)
                     55: 
                     56: #else /* !KDEBUG */
                     57: #define IOTimeTypeStampS(t)
                     58: #define IOTimeTypeStampE(t)
                     59: #define IOTimeStampLatency()
                     60: #endif /* KDEBUG */
                     61: 
                     62: #define super IOEventSource
                     63: 
                     64: OSDefineMetaClassAndStructors(IOInterruptEventSource, IOEventSource)
                     65: 
                     66: bool IOInterruptEventSource::init(OSObject *inOwner,
                     67:                                  Action inAction = 0,
                     68:                                  IOService *inProvider = 0,
                     69:                                  int inIntIndex = 0)
                     70: {
                     71:     bool res = true;
                     72: 
                     73:     if ( !super::init(inOwner, (IOEventSourceAction) inAction) )
                     74:         return false;
                     75: 
                     76:     provider = inProvider;
                     77:     producerCount = consumerCount = 0;
                     78:     autoDisable = explicitDisable = false;
                     79:     intIndex = -1;
                     80: 
                     81:     // Assumes inOwner holds a reference(retain) on the provider
                     82:     if (inProvider) {
                     83:         int intType;
                     84: 
                     85:         res = (kIOReturnSuccess
                     86:                     == inProvider->getInterruptType(inIntIndex, &intType));
                     87:         if (res) {
                     88:             IOInterruptAction intHandler;
                     89: 
                     90:             autoDisable = (intType == kIOInterruptTypeLevel);
                     91:             if (autoDisable) {
                     92:                 intHandler = (IOInterruptAction)
                     93:                 &IOInterruptEventSource::disableInterruptOccurred;
                     94:             }
                     95:             else
                     96:                 intHandler = (IOInterruptAction)
                     97:                     &IOInterruptEventSource::normalInterruptOccurred;
                     98: 
                     99:             res = (kIOReturnSuccess == inProvider->registerInterrupt
                    100:                                         (inIntIndex, this, intHandler));
                    101:             if (res)
                    102:                 intIndex = inIntIndex;
                    103:         }
                    104:     }
                    105: 
                    106:     return res;
                    107: }
                    108: 
                    109: IOInterruptEventSource *
                    110: IOInterruptEventSource::interruptEventSource(OSObject *inOwner,
                    111:                                             Action inAction,
                    112:                                             IOService *inProvider,
                    113:                                             int inIntIndex)
                    114: {
                    115:     IOInterruptEventSource *me = new IOInterruptEventSource;
                    116: 
                    117:     if (me && !me->init(inOwner, inAction, inProvider, inIntIndex)) {
                    118:         me->free();
                    119:         return 0;
                    120:     }
                    121: 
                    122:     return me;
                    123: }
                    124: 
                    125: void IOInterruptEventSource::free()
                    126: {
                    127:     if (provider && intIndex != -1)
                    128:         provider->unregisterInterrupt(intIndex);
                    129: 
                    130:     super::free();
                    131: }
                    132: 
                    133: void IOInterruptEventSource::enable()
                    134: {
                    135:     if (provider && intIndex != -1) {
                    136:         provider->enableInterrupt(intIndex);
                    137:         explicitDisable = false;
                    138:     }
                    139: }
                    140: 
                    141: void IOInterruptEventSource::disable()
                    142: {
                    143:     if (provider && intIndex != -1) {
                    144:         provider->disableInterrupt(intIndex);
                    145:         explicitDisable = true;
                    146:     }
                    147: }
                    148: 
                    149: const IOService *IOInterruptEventSource::getProvider() const
                    150: {
                    151:     return provider;
                    152: }
                    153: 
                    154: int IOInterruptEventSource::getIntIndex() const
                    155: {
                    156:     return intIndex;
                    157: }
                    158: 
                    159: bool IOInterruptEventSource::getAutoDisable() const
                    160: {
                    161:     return autoDisable;
                    162: }
                    163: 
                    164: bool IOInterruptEventSource::checkForWork()
                    165: {
                    166:     unsigned int cacheProdCount = producerCount;
                    167:     int numInts = cacheProdCount - consumerCount;
                    168:     IOInterruptEventAction intAction = (IOInterruptEventAction) action;
                    169: 
                    170:     if (numInts > 0) {
                    171: 
                    172:         IOTimeStampLatency();
                    173:         IOTimeTypeStampS(IOINTES_CLIENT);
                    174:             IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION),
                    175:                                 (unsigned int) intAction, (unsigned int) owner);
                    176:             (*intAction)(owner, this,  numInts);
                    177:         IOTimeTypeStampE(IOINTES_CLIENT);
                    178: 
                    179:         consumerCount = cacheProdCount;
                    180:         if (autoDisable && !explicitDisable)
                    181:             enable();
                    182:     }
                    183:     else if (numInts < 0) {
                    184:         IOTimeStampLatency();
                    185:         IOTimeTypeStampS(IOINTES_CLIENT);
                    186:             IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION),
                    187:                                 (unsigned int) intAction, (unsigned int) owner);
                    188:              (*intAction)(owner, this, -numInts);
                    189:         IOTimeTypeStampE(IOINTES_CLIENT);
                    190:     
                    191:         consumerCount = cacheProdCount;
                    192:         if (autoDisable && !explicitDisable)
                    193:             enable();
                    194:     }
                    195: 
                    196:     return false;
                    197: }
                    198: 
                    199: void IOInterruptEventSource::normalInterruptOccurred
                    200:     (void */*refcon*/, IOService */*prov*/, int /*source*/)
                    201: {
                    202: IOTimeTypeStampS(IOINTES_INTCTXT);
                    203: IOTimeStampLatency();
                    204: 
                    205:     producerCount++;
                    206: 
                    207: IOTimeTypeStampS(IOINTES_SEMA);
                    208:     workLoop->signalWorkAvailable();
                    209: IOTimeTypeStampE(IOINTES_SEMA);
                    210: 
                    211: IOTimeTypeStampE(IOINTES_INTCTXT);
                    212: }
                    213: 
                    214: void IOInterruptEventSource::disableInterruptOccurred
                    215:     (void */*refcon*/, IOService *prov, int source)
                    216: {
                    217: IOTimeTypeStampS(IOINTES_INTCTXT);
                    218: IOTimeStampLatency();
                    219: 
                    220:     prov->disableInterrupt(source);    /* disable the interrupt */
                    221: 
                    222:     producerCount++;
                    223: 
                    224: IOTimeTypeStampS(IOINTES_SEMA);
                    225:     workLoop->signalWorkAvailable();
                    226: IOTimeTypeStampE(IOINTES_SEMA);
                    227: 
                    228: IOTimeTypeStampE(IOINTES_INTCTXT);
                    229: }
                    230: 
                    231: void IOInterruptEventSource::interruptOccurred
                    232:     (void *refcon, IOService *prov, int source)
                    233: {
                    234:     if (autoDisable && prov)
                    235:         disableInterruptOccurred(refcon, prov, source);
                    236:     else
                    237:         normalInterruptOccurred(refcon, prov, source);
                    238: }

unix.superglobalmegacorp.com

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