|
|
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.