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