2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
26 1998-7-13 Godfrey van der Linden(gvdl)
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>
38 #define IOTimeTypeStampS(t) \
40 IOTimeStampStart(IODBG_INTES(t), \
41 (unsigned int) this, (unsigned int) owner); \
44 #define IOTimeTypeStampE(t) \
46 IOTimeStampEnd(IODBG_INTES(t), \
47 (unsigned int) this, (unsigned int) owner); \
50 #define IOTimeStampLatency() \
52 IOTimeStampEnd(IODBG_INTES(IOINTES_LAT), \
53 (unsigned int) this, (unsigned int) owner); \
57 #define IOTimeTypeStampS(t)
58 #define IOTimeTypeStampE(t)
59 #define IOTimeStampLatency()
62 #define super IOEventSource
64 OSDefineMetaClassAndStructors(IOInterruptEventSource
, IOEventSource
)
65 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 0);
66 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 1);
67 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 2);
68 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 3);
69 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 4);
70 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 5);
71 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 6);
72 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 7);
74 bool IOInterruptEventSource::init(OSObject
*inOwner
,
76 IOService
*inProvider
= 0,
81 if ( !super::init(inOwner
, (IOEventSourceAction
) inAction
) )
84 provider
= inProvider
;
85 producerCount
= consumerCount
= 0;
86 autoDisable
= explicitDisable
= false;
89 // Assumes inOwner holds a reference(retain) on the provider
93 res
= (kIOReturnSuccess
94 == inProvider
->getInterruptType(inIntIndex
, &intType
));
96 IOInterruptAction intHandler
;
98 autoDisable
= (intType
== kIOInterruptTypeLevel
);
100 intHandler
= (IOInterruptAction
)
101 &IOInterruptEventSource::disableInterruptOccurred
;
104 intHandler
= (IOInterruptAction
)
105 &IOInterruptEventSource::normalInterruptOccurred
;
107 res
= (kIOReturnSuccess
== inProvider
->registerInterrupt
108 (inIntIndex
, this, intHandler
));
110 intIndex
= inIntIndex
;
117 IOInterruptEventSource
*
118 IOInterruptEventSource::interruptEventSource(OSObject
*inOwner
,
120 IOService
*inProvider
,
123 IOInterruptEventSource
*me
= new IOInterruptEventSource
;
125 if (me
&& !me
->init(inOwner
, inAction
, inProvider
, inIntIndex
)) {
133 void IOInterruptEventSource::free()
135 if (provider
&& intIndex
!= -1)
136 provider
->unregisterInterrupt(intIndex
);
141 void IOInterruptEventSource::enable()
143 if (provider
&& intIndex
!= -1) {
144 provider
->enableInterrupt(intIndex
);
145 explicitDisable
= false;
149 void IOInterruptEventSource::disable()
151 if (provider
&& intIndex
!= -1) {
152 provider
->disableInterrupt(intIndex
);
153 explicitDisable
= true;
157 const IOService
*IOInterruptEventSource::getProvider() const
162 int IOInterruptEventSource::getIntIndex() const
167 bool IOInterruptEventSource::getAutoDisable() const
172 bool IOInterruptEventSource::checkForWork()
174 unsigned int cacheProdCount
= producerCount
;
175 int numInts
= cacheProdCount
- consumerCount
;
176 IOInterruptEventAction intAction
= (IOInterruptEventAction
) action
;
180 IOTimeStampLatency();
181 IOTimeTypeStampS(IOINTES_CLIENT
);
182 IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
),
183 (unsigned int) intAction
, (unsigned int) owner
);
184 (*intAction
)(owner
, this, numInts
);
185 IOTimeTypeStampE(IOINTES_CLIENT
);
187 consumerCount
= cacheProdCount
;
188 if (autoDisable
&& !explicitDisable
)
191 else if (numInts
< 0) {
192 IOTimeStampLatency();
193 IOTimeTypeStampS(IOINTES_CLIENT
);
194 IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
),
195 (unsigned int) intAction
, (unsigned int) owner
);
196 (*intAction
)(owner
, this, -numInts
);
197 IOTimeTypeStampE(IOINTES_CLIENT
);
199 consumerCount
= cacheProdCount
;
200 if (autoDisable
&& !explicitDisable
)
207 void IOInterruptEventSource::normalInterruptOccurred
208 (void */
*refcon*/
, IOService */
*prov*/
, int /*source*/)
210 IOTimeTypeStampS(IOINTES_INTCTXT
);
211 IOTimeStampLatency();
215 IOTimeTypeStampS(IOINTES_SEMA
);
216 signalWorkAvailable();
217 IOTimeTypeStampE(IOINTES_SEMA
);
219 IOTimeTypeStampE(IOINTES_INTCTXT
);
222 void IOInterruptEventSource::disableInterruptOccurred
223 (void */
*refcon*/
, IOService
*prov
, int source
)
225 IOTimeTypeStampS(IOINTES_INTCTXT
);
226 IOTimeStampLatency();
228 prov
->disableInterrupt(source
); /* disable the interrupt */
232 IOTimeTypeStampS(IOINTES_SEMA
);
233 signalWorkAvailable();
234 IOTimeTypeStampE(IOINTES_SEMA
);
236 IOTimeTypeStampE(IOINTES_INTCTXT
);
239 void IOInterruptEventSource::interruptOccurred
240 (void *refcon
, IOService
*prov
, int source
)
242 if (autoDisable
&& prov
)
243 disableInterruptOccurred(refcon
, prov
, source
);
245 normalInterruptOccurred(refcon
, prov
, source
);