1 /*
2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
7  *
8  * This file contains Original Code and/or Modifications of Original Code
9  * as defined in and that are subject to the Apple Public Source License
10  * Version 2.0 (the 'License'). You may not use this file except in
11  * compliance with the License. Please obtain a copy of the License at
12  * http://www.opensource.apple.com/apsl/ and read it before using this
13  * file.
14  *
15  * The Original Code and all software distributed under the License are
16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20  * Please see the License for the specific language governing rights and
21  * limitations under the License.
22  *
23  * @APPLE_LICENSE_HEADER_END@
24  */
25 /*
26 Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
27 
28 HISTORY
29     1999-4-15	Godfrey van der Linden(gvdl)
30         Created.
31 */
32 #include <IOKit/IOFilterInterruptEventSource.h>
33 #include <IOKit/IOService.h>
34 #include <IOKit/IOTimeStamp.h>
35 #include <IOKit/IOWorkLoop.h>
36 
37 #if KDEBUG
38 
39 #define IOTimeTypeStampS(t)						\
40 do {									\
41     IOTimeStampStart(IODBG_INTES(t),					\
42                      (unsigned int) this, (unsigned int) owner);	\
43 } while(0)
44 
45 #define IOTimeTypeStampE(t)						\
46 do {									\
47     IOTimeStampEnd(IODBG_INTES(t),					\
48                    (unsigned int) this, (unsigned int) owner);		\
49 } while(0)
50 
51 #define IOTimeStampLatency()						\
52 do {									\
53     IOTimeStampEnd(IODBG_INTES(IOINTES_LAT),				\
54                    (unsigned int) this, (unsigned int) owner);		\
55 } while(0)
56 
57 #else /* !KDEBUG */
58 #define IOTimeTypeStampS(t)
59 #define IOTimeTypeStampE(t)
60 #define IOTimeStampLatency()
61 #endif /* KDEBUG */
62 
63 #define super IOInterruptEventSource
64 
65 OSDefineMetaClassAndStructors
66     (IOFilterInterruptEventSource, IOInterruptEventSource)
67 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 0);
68 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 1);
69 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 2);
70 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 3);
71 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 4);
72 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 5);
73 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 6);
74 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 7);
75 
76 /*
77  * Implement the call throughs for the private protection conversion
78  */
79 bool IOFilterInterruptEventSource::init(OSObject *inOwner,
80                                         Action inAction,
81                                         IOService *inProvider,
82                                         int inIntIndex)
83 {
84     return false;
85 }
86 
87 IOInterruptEventSource *
88 IOFilterInterruptEventSource::interruptEventSource(OSObject *inOwner,
89                                                    Action inAction,
90                                                    IOService *inProvider,
91                                                    int inIntIndex)
92 {
93     return 0;
94 }
95 
96 bool
97 IOFilterInterruptEventSource::init(OSObject *inOwner,
98                                    Action inAction,
99                                    Filter inFilterAction,
100                                    IOService *inProvider,
101                                    int inIntIndex)
102 {
103     if ( !super::init(inOwner, inAction, inProvider, inIntIndex) )
104         return false;
105 
106     if (!inFilterAction)
107         return false;
108 
109     filterAction = inFilterAction;
110     return true;
111 }
112 
113 IOFilterInterruptEventSource *IOFilterInterruptEventSource
114 ::filterInterruptEventSource(OSObject *inOwner,
115                              Action inAction,
116                              Filter inFilterAction,
117                              IOService *inProvider,
118                              int inIntIndex)
119 {
120     IOFilterInterruptEventSource *me = new IOFilterInterruptEventSource;
121 
122     if (me
123     && !me->init(inOwner, inAction, inFilterAction, inProvider, inIntIndex)) {
124         me->release();
125         return 0;
126     }
127 
128     return me;
129 }
130 
131 void IOFilterInterruptEventSource::signalInterrupt()
132 {
133 IOTimeStampLatency();
134 
135     producerCount++;
136 
137 IOTimeTypeStampS(IOINTES_SEMA);
138     signalWorkAvailable();
139 IOTimeTypeStampE(IOINTES_SEMA);
140 }
141 
142 
143 IOFilterInterruptEventSource::Filter
144 IOFilterInterruptEventSource::getFilterAction() const
145 {
146     return filterAction;
147 }
148 
149 
150 
151 
152 void IOFilterInterruptEventSource::normalInterruptOccurred
153     (void */*refcon*/, IOService */*prov*/, int /*source*/)
154 {
155     bool filterRes;
156 
157 IOTimeTypeStampS(IOINTES_INTCTXT);
158 
159 IOTimeTypeStampS(IOINTES_INTFLTR);
160     IOTimeStampConstant(IODBG_INTES(IOINTES_FILTER),
161                         (unsigned int) filterAction, (unsigned int) owner);
162     filterRes = (*filterAction)(owner, this);
163 IOTimeTypeStampE(IOINTES_INTFLTR);
164 
165     if (filterRes)
166         signalInterrupt();
167 
168 IOTimeTypeStampE(IOINTES_INTCTXT);
169 }
170 
171 void IOFilterInterruptEventSource::disableInterruptOccurred
172     (void */*refcon*/, IOService *prov, int source)
173 {
174     bool filterRes;
175 
176 IOTimeTypeStampS(IOINTES_INTCTXT);
177 
178 IOTimeTypeStampS(IOINTES_INTFLTR);
179     IOTimeStampConstant(IODBG_INTES(IOINTES_FILTER),
180                         (unsigned int) filterAction, (unsigned int) owner);
181     filterRes = (*filterAction)(owner, this);
182 IOTimeTypeStampE(IOINTES_INTFLTR);
183 
184     if (filterRes) {
185         prov->disableInterrupt(source);	/* disable the interrupt */
186 
187         signalInterrupt();
188     }
189 IOTimeTypeStampE(IOINTES_INTCTXT);
190 }
191