|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.