1 /* 2 * Copyright (c) 1998-2010 Apple 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 #include <IOKit/IOFilterInterruptEventSource.h> 30 #include <IOKit/IOService.h> 31 #include <IOKit/IOKitDebug.h> 32 #include <IOKit/IOTimeStamp.h> 33 #include <IOKit/IOWorkLoop.h> 34 35 #if IOKITSTATS 36 37 #define IOStatisticsInitializeCounter() \ 38 do { \ 39 IOStatistics::setCounterType(IOEventSource::reserved->counter, kIOStatisticsFilterInterruptEventSourceCounter); \ 40 } while (0) 41 42 #define IOStatisticsInterrupt() \ 43 do { \ 44 IOStatistics::countInterrupt(IOEventSource::reserved->counter); \ 45 } while (0) 46 47 #else 48 49 #define IOStatisticsInitializeCounter() 50 #define IOStatisticsInterrupt() 51 52 #endif /* IOKITSTATS */ 53 54 #define super IOInterruptEventSource 55 56 OSDefineMetaClassAndStructors 57 (IOFilterInterruptEventSource, IOInterruptEventSource) 58 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 0); 59 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 1); 60 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 2); 61 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 3); 62 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 4); 63 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 5); 64 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 6); 65 OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 7); 66 67 /* 68 * Implement the call throughs for the private protection conversion 69 */ 70 bool IOFilterInterruptEventSource::init(OSObject *inOwner, 71 Action inAction, 72 IOService *inProvider, 73 int inIntIndex) 74 { 75 return false; 76 } 77 78 IOInterruptEventSource * 79 IOFilterInterruptEventSource::interruptEventSource(OSObject *inOwner, 80 Action inAction, 81 IOService *inProvider, 82 int inIntIndex) 83 { 84 return 0; 85 } 86 87 bool 88 IOFilterInterruptEventSource::init(OSObject *inOwner, 89 Action inAction, 90 Filter inFilterAction, 91 IOService *inProvider, 92 int inIntIndex) 93 { 94 if ( !super::init(inOwner, inAction, inProvider, inIntIndex) ) 95 return false; 96 97 if (!inFilterAction) 98 return false; 99 100 filterAction = inFilterAction; 101 102 IOStatisticsInitializeCounter(); 103 104 return true; 105 } 106 107 IOFilterInterruptEventSource *IOFilterInterruptEventSource 108 ::filterInterruptEventSource(OSObject *inOwner, 109 Action inAction, 110 Filter inFilterAction, 111 IOService *inProvider, 112 int inIntIndex) 113 { 114 IOFilterInterruptEventSource *me = new IOFilterInterruptEventSource; 115 116 if (me 117 && !me->init(inOwner, inAction, inFilterAction, inProvider, inIntIndex)) { 118 me->release(); 119 return 0; 120 } 121 122 return me; 123 } 124 125 void IOFilterInterruptEventSource::signalInterrupt() 126 { 127 bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false; 128 129 IOStatisticsInterrupt(); 130 producerCount++; 131 132 if (trace) 133 IOTimeStampStartConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner); 134 135 signalWorkAvailable(); 136 137 if (trace) 138 IOTimeStampEndConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner); 139 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 bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false; 157 158 if (trace) 159 IOTimeStampStartConstant(IODBG_INTES(IOINTES_FILTER), 160 VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); 161 162 // Call the filter. 163 filterRes = (*filterAction)(owner, this); 164 165 if (trace) 166 IOTimeStampEndConstant(IODBG_INTES(IOINTES_FILTER), 167 VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); 168 169 if (filterRes) 170 signalInterrupt(); 171 } 172 173 void IOFilterInterruptEventSource::disableInterruptOccurred 174 (void */*refcon*/, IOService *prov, int source) 175 { 176 bool filterRes; 177 bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false; 178 179 if (trace) 180 IOTimeStampStartConstant(IODBG_INTES(IOINTES_FILTER), 181 VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); 182 183 // Call the filter. 184 filterRes = (*filterAction)(owner, this); 185 186 if (trace) 187 IOTimeStampEndConstant(IODBG_INTES(IOINTES_FILTER), 188 VM_KERNEL_UNSLIDE(filterAction), (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop); 189 190 if (filterRes) { 191 prov->disableInterrupt(source); /* disable the interrupt */ 192 signalInterrupt(); 193 } 194 } 195