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() \ 38do { \ 39 IOStatistics::setCounterType(IOEventSource::reserved->counter, kIOStatisticsFilterInterruptEventSourceCounter); \ 40} while (0) 41 42#define IOStatisticsInterrupt() \ 43do { \ 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 56OSDefineMetaClassAndStructors 57 (IOFilterInterruptEventSource, IOInterruptEventSource) 58OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 0); 59OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 1); 60OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 2); 61OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 3); 62OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 4); 63OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 5); 64OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 6); 65OSMetaClassDefineReservedUnused(IOFilterInterruptEventSource, 7); 66 67/* 68 * Implement the call throughs for the private protection conversion 69 */ 70bool IOFilterInterruptEventSource::init(OSObject *inOwner, 71 Action inAction, 72 IOService *inProvider, 73 int inIntIndex) 74{ 75 return false; 76} 77 78IOInterruptEventSource * 79IOFilterInterruptEventSource::interruptEventSource(OSObject *inOwner, 80 Action inAction, 81 IOService *inProvider, 82 int inIntIndex) 83{ 84 return 0; 85} 86 87bool 88IOFilterInterruptEventSource::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 107IOFilterInterruptEventSource *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 125void 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 143IOFilterInterruptEventSource::Filter 144IOFilterInterruptEventSource::getFilterAction() const 145{ 146 return filterAction; 147} 148 149 150 151 152void 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 173void 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