2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. 
   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 
  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. 
  23  * @APPLE_LICENSE_HEADER_END@ 
  26 Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
  29     1998-7-13   Godfrey van der Linden(gvdl) 
  32 #include <IOKit/IOInterruptEventSource.h> 
  33 #include <IOKit/IOLib.h> 
  34 #include <IOKit/IOService.h> 
  35 #include <IOKit/IOInterrupts.h> 
  36 #include <IOKit/IOTimeStamp.h> 
  37 #include <IOKit/IOWorkLoop.h> 
  41 #define IOTimeTypeStampS(t)                                             \ 
  43     IOTimeStampStart(IODBG_INTES(t),                                    \ 
  44                      (unsigned int) this, (unsigned int) owner);        \ 
  47 #define IOTimeTypeStampE(t)                                             \ 
  49     IOTimeStampEnd(IODBG_INTES(t),                                      \ 
  50                    (unsigned int) this, (unsigned int) owner);          \ 
  53 #define IOTimeStampLatency()                                            \ 
  55     IOTimeStampEnd(IODBG_INTES(IOINTES_LAT),                            \ 
  56                    (unsigned int) this, (unsigned int) owner);          \ 
  60 #define IOTimeTypeStampS(t) 
  61 #define IOTimeTypeStampE(t) 
  62 #define IOTimeStampLatency() 
  65 #define super IOEventSource 
  67 OSDefineMetaClassAndStructors(IOInterruptEventSource
, IOEventSource
) 
  68 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 0); 
  69 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 1); 
  70 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 2); 
  71 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 3); 
  72 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 4); 
  73 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 5); 
  74 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 6); 
  75 OSMetaClassDefineReservedUnused(IOInterruptEventSource
, 7); 
  77 bool IOInterruptEventSource::init(OSObject 
*inOwner
, 
  79                                   IOService 
*inProvider 
= 0, 
  84     if ( !super::init(inOwner
, (IOEventSourceAction
) inAction
) ) 
  87     provider 
= inProvider
; 
  88     producerCount 
= consumerCount 
= 0; 
  89     autoDisable 
= explicitDisable 
= false; 
  92     // Assumes inOwner holds a reference(retain) on the provider 
  96         res 
= (kIOReturnSuccess
 
  97                     == inProvider
->getInterruptType(inIntIndex
, &intType
)); 
  99             IOInterruptAction intHandler
; 
 101             autoDisable 
= (intType 
== kIOInterruptTypeLevel
); 
 103                 intHandler 
= (IOInterruptAction
) 
 104                 &IOInterruptEventSource::disableInterruptOccurred
; 
 107                 intHandler 
= (IOInterruptAction
) 
 108                     &IOInterruptEventSource::normalInterruptOccurred
; 
 110             res 
= (kIOReturnSuccess 
== inProvider
->registerInterrupt
 
 111                                         (inIntIndex
, this, intHandler
)); 
 113                 intIndex 
= inIntIndex
; 
 120 IOInterruptEventSource 
* 
 121 IOInterruptEventSource::interruptEventSource(OSObject 
*inOwner
, 
 123                                              IOService 
*inProvider
, 
 126     IOInterruptEventSource 
*me 
= new IOInterruptEventSource
; 
 128     if (me 
&& !me
->init(inOwner
, inAction
, inProvider
, inIntIndex
)) { 
 136 void IOInterruptEventSource::free() 
 138     if (provider 
&& intIndex 
!= -1) 
 139         provider
->unregisterInterrupt(intIndex
); 
 144 void IOInterruptEventSource::enable() 
 146     if (provider 
&& intIndex 
!= -1) { 
 147         provider
->enableInterrupt(intIndex
); 
 148         explicitDisable 
= false; 
 152 void IOInterruptEventSource::disable() 
 154     if (provider 
&& intIndex 
!= -1) { 
 155         provider
->disableInterrupt(intIndex
); 
 156         explicitDisable 
= true; 
 160 const IOService 
*IOInterruptEventSource::getProvider() const 
 165 int IOInterruptEventSource::getIntIndex() const 
 170 bool IOInterruptEventSource::getAutoDisable() const 
 175 bool IOInterruptEventSource::checkForWork() 
 177     unsigned int cacheProdCount 
= producerCount
; 
 178     int numInts 
= cacheProdCount 
- consumerCount
; 
 179     IOInterruptEventAction intAction 
= (IOInterruptEventAction
) action
; 
 183         IOTimeStampLatency(); 
 184         IOTimeTypeStampS(IOINTES_CLIENT
); 
 185             IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
), 
 186                                 (unsigned int) intAction
, (unsigned int) owner
); 
 187             (*intAction
)(owner
, this,  numInts
); 
 188         IOTimeTypeStampE(IOINTES_CLIENT
); 
 190         consumerCount 
= cacheProdCount
; 
 191         if (autoDisable 
&& !explicitDisable
) 
 194     else if (numInts 
< 0) { 
 195         IOTimeStampLatency(); 
 196         IOTimeTypeStampS(IOINTES_CLIENT
); 
 197             IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION
), 
 198                                 (unsigned int) intAction
, (unsigned int) owner
); 
 199              (*intAction
)(owner
, this, -numInts
); 
 200         IOTimeTypeStampE(IOINTES_CLIENT
); 
 202         consumerCount 
= cacheProdCount
; 
 203         if (autoDisable 
&& !explicitDisable
) 
 210 void IOInterruptEventSource::normalInterruptOccurred
 
 211     (void */
*refcon*/
, IOService */
*prov*/
, int /*source*/) 
 213 IOTimeTypeStampS(IOINTES_INTCTXT
); 
 214 IOTimeStampLatency(); 
 218 IOTimeTypeStampS(IOINTES_SEMA
); 
 219     signalWorkAvailable(); 
 220 IOTimeTypeStampE(IOINTES_SEMA
); 
 222 IOTimeTypeStampE(IOINTES_INTCTXT
); 
 225 void IOInterruptEventSource::disableInterruptOccurred
 
 226     (void */
*refcon*/
, IOService 
*prov
, int source
) 
 228 IOTimeTypeStampS(IOINTES_INTCTXT
); 
 229 IOTimeStampLatency(); 
 231     prov
->disableInterrupt(source
);     /* disable the interrupt */ 
 235 IOTimeTypeStampS(IOINTES_SEMA
); 
 236     signalWorkAvailable(); 
 237 IOTimeTypeStampE(IOINTES_SEMA
); 
 239 IOTimeTypeStampE(IOINTES_INTCTXT
); 
 242 void IOInterruptEventSource::interruptOccurred
 
 243     (void *refcon
, IOService 
*prov
, int source
) 
 245     if (autoDisable 
&& prov
) 
 246         disableInterruptOccurred(refcon
, prov
, source
); 
 248         normalInterruptOccurred(refcon
, prov
, source
);