2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
27 1998-7-13 Godfrey van der Linden(gvdl)
30 #include <IOKit/IOInterruptEventSource.h>
31 #include <IOKit/IOLib.h>
32 #include <IOKit/IOService.h>
33 #include <IOKit/IOInterrupts.h>
34 #include <IOKit/IOTimeStamp.h>
35 #include <IOKit/IOWorkLoop.h>
39 #define IOTimeTypeStampS(t) \
41 IOTimeStampStart(IODBG_INTES(t), \
42 (unsigned int) this, (unsigned int) owner); \
45 #define IOTimeTypeStampE(t) \
47 IOTimeStampEnd(IODBG_INTES(t), \
48 (unsigned int) this, (unsigned int) owner); \
51 #define IOTimeStampLatency() \
53 IOTimeStampEnd(IODBG_INTES(IOINTES_LAT), \
54 (unsigned int) this, (unsigned int) owner); \
58 #define IOTimeTypeStampS(t)
59 #define IOTimeTypeStampE(t)
60 #define IOTimeStampLatency()
63 #define super IOEventSource
65 OSDefineMetaClassAndStructors(IOInterruptEventSource
, IOEventSource
)
66 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 0);
67 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 1);
68 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 2);
69 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 3);
70 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 4);
71 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 5);
72 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 6);
73 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 7);
75 bool IOInterruptEventSource::init(OSObject
*inOwner
,
77 IOService
*inProvider
,
82 if ( !super::init(inOwner
, (IOEventSourceAction
) inAction
) )
85 provider
= inProvider
;
86 producerCount
= consumerCount
= 0;
87 autoDisable
= explicitDisable
= false;
90 // Assumes inOwner holds a reference(retain) on the provider
94 res
= (kIOReturnSuccess
95 == inProvider
->getInterruptType(inIntIndex
, &intType
));
97 IOInterruptAction intHandler
;
99 autoDisable
= (intType
== kIOInterruptTypeLevel
);
101 intHandler
= OSMemberFunctionCast(IOInterruptAction
,
102 this, &IOInterruptEventSource::disableInterruptOccurred
);
105 intHandler
= OSMemberFunctionCast(IOInterruptAction
,
106 this, &IOInterruptEventSource::normalInterruptOccurred
);
108 res
= (kIOReturnSuccess
== inProvider
->registerInterrupt
109 (inIntIndex
, this, intHandler
));
111 intIndex
= inIntIndex
;
118 IOInterruptEventSource
*
119 IOInterruptEventSource::interruptEventSource(OSObject
*inOwner
,
121 IOService
*inProvider
,
124 IOInterruptEventSource
*me
= new IOInterruptEventSource
;
126 if (me
&& !me
->init(inOwner
, inAction
, inProvider
, inIntIndex
)) {
134 void IOInterruptEventSource::free()
136 if (provider
&& intIndex
!= -1)
137 provider
->unregisterInterrupt(intIndex
);
142 void IOInterruptEventSource::enable()
144 if (provider
&& intIndex
!= -1) {
145 provider
->enableInterrupt(intIndex
);
146 explicitDisable
= false;
150 void IOInterruptEventSource::disable()
152 if (provider
&& intIndex
!= -1) {
153 provider
->disableInterrupt(intIndex
);
154 explicitDisable
= true;
158 const IOService
*IOInterruptEventSource::getProvider() const
163 int IOInterruptEventSource::getIntIndex() const
168 bool IOInterruptEventSource::getAutoDisable() const
173 bool IOInterruptEventSource::checkForWork()
175 unsigned int cacheProdCount
= producerCount
;
176 int numInts
= cacheProdCount
- consumerCount
;
177 IOInterruptEventAction intAction
= (IOInterruptEventAction
) action
;
181 IOTimeStampLatency();
182 IOTimeTypeStampS(IOINTES_CLIENT
);
183 IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
),
184 (unsigned int) intAction
, (unsigned int) owner
);
185 (*intAction
)(owner
, this, numInts
);
186 IOTimeTypeStampE(IOINTES_CLIENT
);
188 consumerCount
= cacheProdCount
;
189 if (autoDisable
&& !explicitDisable
)
192 else if (numInts
< 0) {
193 IOTimeStampLatency();
194 IOTimeTypeStampS(IOINTES_CLIENT
);
195 IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
),
196 (unsigned int) intAction
, (unsigned int) owner
);
197 (*intAction
)(owner
, this, -numInts
);
198 IOTimeTypeStampE(IOINTES_CLIENT
);
200 consumerCount
= cacheProdCount
;
201 if (autoDisable
&& !explicitDisable
)
208 void IOInterruptEventSource::normalInterruptOccurred
209 (void */
*refcon*/
, IOService */
*prov*/
, int /*source*/)
211 IOTimeTypeStampS(IOINTES_INTCTXT
);
212 IOTimeStampLatency();
216 IOTimeTypeStampS(IOINTES_SEMA
);
217 signalWorkAvailable();
218 IOTimeTypeStampE(IOINTES_SEMA
);
220 IOTimeTypeStampE(IOINTES_INTCTXT
);
223 void IOInterruptEventSource::disableInterruptOccurred
224 (void */
*refcon*/
, IOService
*prov
, int source
)
226 IOTimeTypeStampS(IOINTES_INTCTXT
);
227 IOTimeStampLatency();
229 prov
->disableInterrupt(source
); /* disable the interrupt */
233 IOTimeTypeStampS(IOINTES_SEMA
);
234 signalWorkAvailable();
235 IOTimeTypeStampE(IOINTES_SEMA
);
237 IOTimeTypeStampE(IOINTES_INTCTXT
);
240 void IOInterruptEventSource::interruptOccurred
241 (void *refcon
, IOService
*prov
, int source
)
243 if (autoDisable
&& prov
)
244 disableInterruptOccurred(refcon
, prov
, source
);
246 normalInterruptOccurred(refcon
, prov
, source
);