Loading...
iokit/Kernel/IOInterruptController.cpp xnu-1228.3.13 xnu-11417.121.6
--- xnu/xnu-1228.3.13/iokit/Kernel/IOInterruptController.cpp
+++ xnu/xnu-11417.121.6/iokit/Kernel/IOInterruptController.cpp
@@ -1,8 +1,9 @@
 /*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2007-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
@@ -11,10 +12,10 @@
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,20 +23,9 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
-/*
- * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
- *
- *  DRI: Josh de Cesare
- *
- */
-
-
-#if __ppc__
-#include <ppc/proc_reg.h> 
-#endif
 
 #include <IOKit/IOLib.h>
 #include <IOKit/IOService.h>
@@ -43,6 +33,8 @@
 #include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IOInterrupts.h>
 #include <IOKit/IOInterruptController.h>
+#include <IOKit/IOKitDebug.h>
+#include <IOKit/IOTimeStamp.h>
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -51,354 +43,467 @@
 
 OSDefineMetaClassAndAbstractStructors(IOInterruptController, IOService);
 
-OSMetaClassDefineReservedUnused(IOInterruptController, 0);
-OSMetaClassDefineReservedUnused(IOInterruptController, 1);
-OSMetaClassDefineReservedUnused(IOInterruptController, 2);
+OSMetaClassDefineReservedUsedX86(IOInterruptController, 0);
+OSMetaClassDefineReservedUsedX86(IOInterruptController, 1);
+OSMetaClassDefineReservedUsedX86(IOInterruptController, 2);
 OSMetaClassDefineReservedUnused(IOInterruptController, 3);
 OSMetaClassDefineReservedUnused(IOInterruptController, 4);
 OSMetaClassDefineReservedUnused(IOInterruptController, 5);
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source,
-						  void *target,
-						  IOInterruptHandler handler,
-						  void *refCon)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  long              wasDisabledSoft;
-  IOReturn          error;
-  OSData            *vectorData;
-  IOService         *originalNub;
-  int               originalSource;
-  IOOptionBits      options;
-  bool              canBeShared, shouldBeShared, wasAlreadyRegisterd;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  // Get the lock for this vector.
-  IOTakeLock(vector->interruptLock);
-  
-  // Check if the interrupt source can/should be shared.
-  canBeShared = vectorCanBeShared(vectorNumber, vector);
-  IODTGetInterruptOptions(nub, source, &options);
-  shouldBeShared = canBeShared && (options & kIODTInterruptShared);
-  wasAlreadyRegisterd = vector->interruptRegistered;
-  
-  // If the vector is registered and can not be shared return error.
-  if (wasAlreadyRegisterd && !canBeShared) {
-    IOUnlock(vector->interruptLock);
-    return kIOReturnNoResources;
-  }
-  
-  // If this vector is already in use, and can be shared (implied),
-  // or it is not registered and should be shared,
-  // register as a shared interrupt.
-  if (wasAlreadyRegisterd || shouldBeShared) {
-    // If this vector is not already shared, break it out.
-    if (vector->sharedController == 0) {
-      // Make the IOShareInterruptController instance
-      vector->sharedController = new IOSharedInterruptController;
-      if (vector->sharedController == 0) {
-        IOUnlock(vector->interruptLock);
-        return kIOReturnNoMemory;
-      }
-      
-      if (wasAlreadyRegisterd) {
-	// Save the nub and source for the original consumer.
-	originalNub = vector->nub;
-	originalSource = vector->source;
-	
-	// Physically disable the interrupt, but mark it as being enabled in the hardware.
-	// The interruptDisabledSoft now indicates the driver's request for enablement.
+IOReturn
+IOInterruptController::registerInterrupt(IOService *nub, int source,
+    void *target,
+    IOInterruptHandler handler,
+    void *refCon)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	int               wasDisabledSoft;
+	IOReturn          error;
+	OSData            *vectorData;
+	IOOptionBits      options;
+	bool              canBeShared, shouldBeShared, wasAlreadyRegisterd;
+
+	IOService         *originalNub = NULL;// Protected by wasAlreadyRegisterd
+	int               originalSource = 0;// Protected by wasAlreadyRegisterd
+
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	// Get the lock for this vector.
+	IOLockLock(vector->interruptLock);
+
+	// Check if the interrupt source can/should be shared.
+	canBeShared = vectorCanBeShared(vectorNumber, vector);
+	IODTGetInterruptOptions(nub, source, &options);
+#if defined(__i386__) || defined(__x86_64__)
+	int   interruptType;
+	if (OSDynamicCast(IOPlatformDevice, getProvider()) &&
+	    (getInterruptType(nub, source, &interruptType) == kIOReturnSuccess) &&
+	    (kIOInterruptTypeLevel & interruptType)) {
+		options |= kIODTInterruptShared;
+	}
+#endif
+	shouldBeShared = canBeShared && (options & kIODTInterruptShared);
+	wasAlreadyRegisterd = vector->interruptRegistered;
+
+	// If the vector is registered and can not be shared return error.
+	if (wasAlreadyRegisterd && !canBeShared) {
+		IOLockUnlock(vector->interruptLock);
+		return kIOReturnNoResources;
+	}
+
+	// If this vector is already in use, and can be shared (implied),
+	// or it is not registered and should be shared,
+	// register as a shared interrupt.
+	if (wasAlreadyRegisterd || shouldBeShared) {
+		// If this vector is not already shared, break it out.
+		if (vector->sharedController == NULL) {
+			// Make the IOShareInterruptController instance
+			vector->sharedController = new IOSharedInterruptController;
+			if (vector->sharedController == NULL) {
+				IOLockUnlock(vector->interruptLock);
+				return kIOReturnNoMemory;
+			}
+
+			if (wasAlreadyRegisterd) {
+				// Save the nub and source for the original consumer.
+				originalNub = vector->nub;
+				originalSource = vector->source;
+
+				// Physically disable the interrupt, but mark it as being enabled in the hardware.
+				// The interruptDisabledSoft now indicates the driver's request for enablement.
+				disableVectorHard(vectorNumber, vector);
+				vector->interruptDisabledHard = 0;
+			}
+
+			// Initialize the new shared interrupt controller.
+			error = vector->sharedController->initInterruptController(this, vectorData);
+			// If the IOSharedInterruptController could not be initalized,
+			// if needed, put the original consumer's interrupt back to normal and
+			// get rid of whats left of the shared controller.
+			if (error != kIOReturnSuccess) {
+				if (wasAlreadyRegisterd) {
+					enableInterrupt(originalNub, originalSource);
+				}
+				vector->sharedController->release();
+				vector->sharedController = NULL;
+				IOLockUnlock(vector->interruptLock);
+				return error;
+			}
+
+			// If there was an original consumer try to register it on the shared controller.
+			if (wasAlreadyRegisterd) {
+				error = vector->sharedController->registerInterrupt(originalNub,
+				    originalSource,
+				    vector->target,
+				    vector->handler,
+				    vector->refCon);
+				// If the original consumer could not be moved to the shared controller,
+				// put the original consumor's interrupt back to normal and
+				// get rid of whats left of the shared controller.
+				if (error != kIOReturnSuccess) {
+					// Save the driver's interrupt enablement state.
+					wasDisabledSoft = vector->interruptDisabledSoft;
+
+					// Make the interrupt really hard disabled.
+					vector->interruptDisabledSoft = 1;
+					vector->interruptDisabledHard = 1;
+
+					// Enable the original consumer's interrupt if needed.
+					if (!wasDisabledSoft) {
+						originalNub->enableInterrupt(originalSource);
+					}
+					enableInterrupt(originalNub, originalSource);
+
+					vector->sharedController->release();
+					vector->sharedController = NULL;
+					IOLockUnlock(vector->interruptLock);
+					return error;
+				}
+			}
+
+			// Fill in vector with the shared controller's info.
+			vector->handler = (IOInterruptHandler)vector->sharedController->getInterruptHandlerAddress();
+			vector->nub     = vector->sharedController;
+			vector->source  = 0;
+			vector->target  = vector->sharedController;
+			vector->refCon  = NULL;
+
+			// If the interrupt was already registered,
+			// save the driver's interrupt enablement state.
+			if (wasAlreadyRegisterd) {
+				wasDisabledSoft = vector->interruptDisabledSoft;
+			} else {
+				wasDisabledSoft = true;
+			}
+
+			// Do any specific initalization for this vector if it has not yet been used.
+			if (!wasAlreadyRegisterd) {
+				initVector(vectorNumber, vector);
+			}
+
+			// Make the interrupt really hard disabled.
+			vector->interruptDisabledSoft = 1;
+			vector->interruptDisabledHard = 1;
+			vector->interruptRegistered   = 1;
+
+			// Enable the original consumer's interrupt if needed.
+			// originalNub is protected by wasAlreadyRegisterd here (see line 184).
+			if (!wasDisabledSoft) {
+				originalNub->enableInterrupt(originalSource);
+			}
+		}
+
+		error = vector->sharedController->registerInterrupt(nub, source, target,
+		    handler, refCon);
+		IOLockUnlock(vector->interruptLock);
+		return error;
+	}
+
+	// Fill in vector with the client's info.
+	vector->handler = handler;
+	vector->nub     = nub;
+	vector->source  = source;
+	vector->target  = target;
+	vector->refCon  = refCon;
+
+	// Do any specific initalization for this vector.
+	initVector(vectorNumber, vector);
+
+	// Get the vector ready.  It starts hard disabled.
+	vector->interruptDisabledHard = 1;
+	vector->interruptDisabledSoft = 1;
+	vector->interruptRegistered   = 1;
+
+	IOLockUnlock(vector->interruptLock);
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOInterruptController::unregisterInterrupt(IOService *nub, int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	// Get the lock for this vector.
+	IOLockLock(vector->interruptLock);
+
+	// Return success if it is not already registered
+	if (!vector->interruptRegistered) {
+		IOLockUnlock(vector->interruptLock);
+		return kIOReturnSuccess;
+	}
+
+	// Soft disable the source.
+	disableInterrupt(nub, source);
+
+	// Turn the source off at hardware.
 	disableVectorHard(vectorNumber, vector);
+
+	// Clear all the storage for the vector except for interruptLock.
+	vector->interruptActive = 0;
+	vector->interruptDisabledSoft = 0;
 	vector->interruptDisabledHard = 0;
-      }
-      
-      // Initialize the new shared interrupt controller.
-      error = vector->sharedController->initInterruptController(this, vectorData);
-      // If the IOSharedInterruptController could not be initalized,
-      // if needed, put the original consumer's interrupt back to normal and
-      // get rid of whats left of the shared controller.
-      if (error != kIOReturnSuccess) {
-	if (wasAlreadyRegisterd) enableInterrupt(originalNub, originalSource);
-        vector->sharedController->release();
-        vector->sharedController = 0;
-        IOUnlock(vector->interruptLock);
-        return error;
-      }
-      
-      // If there was an original consumer try to register it on the shared controller.
-      if (wasAlreadyRegisterd) {
-	error = vector->sharedController->registerInterrupt(originalNub,
-							    originalSource,
-							    vector->target,
-							    vector->handler,
-							    vector->refCon);
-	// If the original consumer could not be moved to the shared controller,
-	// put the original consumor's interrupt back to normal and
-	// get rid of whats left of the shared controller.
-	if (error != kIOReturnSuccess) {
-	  // Save the driver's interrupt enablement state.
-	  wasDisabledSoft = vector->interruptDisabledSoft;
-	  
-	  // Make the interrupt really hard disabled.
-	  vector->interruptDisabledSoft = 1;
-	  vector->interruptDisabledHard = 1;
-	  
-	  // Enable the original consumer's interrupt if needed.
-	  if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
-	  enableInterrupt(originalNub, originalSource);
-	  
-	  vector->sharedController->release();
-	  vector->sharedController = 0;
-	  IOUnlock(vector->interruptLock);
-	  return error;
-	}
-      }
-      
-      // Fill in vector with the shared controller's info.
-      vector->handler = (IOInterruptHandler)vector->sharedController->getInterruptHandlerAddress();
-      vector->nub     = vector->sharedController;
-      vector->source  = 0;
-      vector->target  = vector->sharedController;
-      vector->refCon  = 0;
-      
-      // If the interrupt was already registered,
-      // save the driver's interrupt enablement state.
-      if (wasAlreadyRegisterd) wasDisabledSoft = vector->interruptDisabledSoft;
-      else wasDisabledSoft = true;
-      
-      // Do any specific initalization for this vector if it has not yet been used.
-      if (!wasAlreadyRegisterd) initVector(vectorNumber, vector);
-      
-      // Make the interrupt really hard disabled.
-      vector->interruptDisabledSoft = 1;
-      vector->interruptDisabledHard = 1;
-      vector->interruptRegistered   = 1;
-      
-      // Enable the original consumer's interrupt if needed.
-      if (!wasDisabledSoft) originalNub->enableInterrupt(originalSource);
-    }
-    
-    error = vector->sharedController->registerInterrupt(nub, source, target,
-                                                        handler, refCon);
-    IOUnlock(vector->interruptLock);
-    return error;
-  }
-  
-  // Fill in vector with the client's info.
-  vector->handler = handler;
-  vector->nub     = nub;
-  vector->source  = source;
-  vector->target  = target;
-  vector->refCon  = refCon;
-  
-  // Do any specific initalization for this vector.
-  initVector(vectorNumber, vector);
-  
-  // Get the vector ready.  It starts hard disabled.
-  vector->interruptDisabledHard = 1;
-  vector->interruptDisabledSoft = 1;
-  vector->interruptRegistered   = 1;
-  
-  IOUnlock(vector->interruptLock);
-  return kIOReturnSuccess;
-}
-
-IOReturn IOInterruptController::unregisterInterrupt(IOService *nub, int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  // Get the lock for this vector.
-  IOTakeLock(vector->interruptLock);
-  
-  // Return success if it is not already registered
-  if (!vector->interruptRegistered) {
-    IOUnlock(vector->interruptLock);
-    return kIOReturnSuccess;
-  }
-  
-  // Soft disable the source.
-  disableInterrupt(nub, source);
-  
-  // Turn the source off at hardware. 
-  disableVectorHard(vectorNumber, vector);
-  
-  // Clear all the storage for the vector except for interruptLock.
-  vector->interruptActive = 0;
-  vector->interruptDisabledSoft = 0;
-  vector->interruptDisabledHard = 0;
-  vector->interruptRegistered = 0;
-  vector->nub = 0;
-  vector->source = 0;
-  vector->handler = 0;
-  vector->target = 0;
-  vector->refCon = 0;
-  
-  IOUnlock(vector->interruptLock);
-  return kIOReturnSuccess;
-}
-
-IOReturn IOInterruptController::getInterruptType(IOService *nub, int source,
-						 int *interruptType)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  
-  if (interruptType == 0) return kIOReturnBadArgument;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  *interruptType = getVectorType(vectorNumber, vector);
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOInterruptController::enableInterrupt(IOService *nub, int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  if (vector->interruptDisabledSoft) {
-    vector->interruptDisabledSoft = 0;
-#if __ppc__
-    sync();
-    isync();
+	vector->interruptRegistered = 0;
+	vector->nub = NULL;
+	vector->source = 0;
+	vector->handler = NULL;
+	vector->target = NULL;
+	vector->refCon = NULL;
+
+	IOLockUnlock(vector->interruptLock);
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOInterruptController::getInterruptType(IOService *nub, int source,
+    int *interruptType)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+
+	if (interruptType == NULL) {
+		return kIOReturnBadArgument;
+	}
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	*interruptType = getVectorType(vectorNumber, vector);
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOInterruptController::enableInterrupt(IOService *nub, int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	if (vector->interruptDisabledSoft) {
+		vector->interruptDisabledSoft = 0;
+#if !defined(__i386__) && !defined(__x86_64__)
+		OSMemoryBarrier();
 #endif
-    
-    if (!getPlatform()->atInterruptLevel()) {
-      while (vector->interruptActive);
-#if __ppc__
-      isync();
+
+		if (!getPlatform()->atInterruptLevel()) {
+			while (vector->interruptActive) {
+			}
+		}
+		if (vector->interruptDisabledHard) {
+			vector->interruptDisabledHard = 0;
+
+			// A DSB ISH on ARM is needed to make sure the vector data are
+			// properly initialized before the MMIO enabling the interrupts
+			// in hardware. OSMemoryBarrier(), which maps to DMB, is not
+			// sufficient here as the CPUs are not consumers of the device
+			// write. Hence, the DMB does not guarantee the CPUs won't see an
+			// interrupt before it initalizes the vector data properly.
+			OSSynchronizeIO();
+
+			enableVector(vectorNumber, vector);
+		}
+	}
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOInterruptController::disableInterrupt(IOService *nub, int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	vector->interruptDisabledSoft = 1;
+#if !defined(__i386__) && !defined(__x86_64__)
+	OSMemoryBarrier();
 #endif
-    }
-    if (vector->interruptDisabledHard) {
-      vector->interruptDisabledHard = 0;
-      
-      enableVector(vectorNumber, vector);
-    }
-  }
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOInterruptController::disableInterrupt(IOService *nub, int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  vector->interruptDisabledSoft = 1;
-#if __ppc__
-  sync();
-  isync();
+
+	if (!getPlatform()->atInterruptLevel()) {
+		while (vector->interruptActive) {
+		}
+	}
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOInterruptController::causeInterrupt(IOService *nub, int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	causeVector(vectorNumber, vector);
+
+	return kIOReturnSuccess;
+}
+
+IOInterruptAction
+IOInterruptController::getInterruptHandlerAddress(void)
+{
+	return NULL;
+}
+
+IOReturn
+IOInterruptController::handleInterrupt(void *refCon, IOService *nub,
+    int source)
+{
+	return kIOReturnInvalid;
+}
+
+
+// Methods to be overridden for simplifed interrupt controller subclasses.
+
+bool
+IOInterruptController::vectorCanBeShared(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+	return false;
+}
+
+void
+IOInterruptController::initVector(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+}
+
+int
+IOInterruptController::getVectorType(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+	return kIOInterruptTypeEdge;
+}
+
+void
+IOInterruptController::disableVectorHard(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+}
+
+void
+IOInterruptController::enableVector(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+}
+
+void
+IOInterruptController::causeVector(IOInterruptVectorNumber /*vectorNumber*/,
+    IOInterruptVector */*vector*/)
+{
+}
+
+void
+IOInterruptController::setCPUInterruptProperties(IOService */*service*/)
+{
+}
+
+void
+IOInterruptController::sendIPI(unsigned int /*cpu_id*/, bool /*deferred*/)
+{
+}
+
+void
+IOInterruptController::cancelDeferredIPI(unsigned int /*cpu_id*/)
+{
+}
+
+void
+IOInterruptController::timeStampSpuriousInterrupt(void)
+{
+	uint64_t providerID = 0;
+	IOService * provider = getProvider();
+
+	if (provider) {
+		providerID = provider->getRegistryEntryID();
+	}
+
+	IOTimeStampConstant(IODBG_INTC(IOINTC_SPURIOUS), providerID);
+}
+
+void
+IOInterruptController::timeStampInterruptHandlerInternal(bool isStart, IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector)
+{
+	uint64_t providerID = 0;
+	vm_offset_t unslidHandler = 0;
+	vm_offset_t unslidTarget = 0;
+
+	IOService * provider = getProvider();
+
+	if (provider) {
+		providerID = provider->getRegistryEntryID();
+	}
+
+	if (vector) {
+		unslidHandler = VM_KERNEL_UNSLIDE((vm_offset_t)vector->handler);
+		unslidTarget = VM_KERNEL_UNSLIDE_OR_PERM((vm_offset_t)vector->target);
+	}
+
+
+	if (isStart) {
+#if SCHED_HYGIENE_DEBUG
+		ml_irq_debug_start((uintptr_t)vector->handler, (uintptr_t)vector);
 #endif
-  
-  if (!getPlatform()->atInterruptLevel()) {
-    while (vector->interruptActive);
-#if __ppc__
-    isync();
+		IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler,
+		    (uintptr_t)unslidTarget, (uintptr_t)providerID);
+	} else {
+		IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER), (uintptr_t)vectorNumber, (uintptr_t)unslidHandler,
+		    (uintptr_t)unslidTarget, (uintptr_t)providerID);
+#if SCHED_HYGIENE_DEBUG
+		ml_irq_debug_end();
 #endif
-  }
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOInterruptController::causeInterrupt(IOService *nub, int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  causeVector(vectorNumber, vector);
-  
-  return kIOReturnSuccess;
-}
-
-IOInterruptAction IOInterruptController::getInterruptHandlerAddress(void)
-{
-  return 0;
-}
-
-IOReturn IOInterruptController::handleInterrupt(void *refCon, IOService *nub,
-						int source)
-{
-  return kIOReturnInvalid;
-}
-
-
-// Methods to be overridden for simplifed interrupt controller subclasses.
-
-bool IOInterruptController::vectorCanBeShared(long /*vectorNumber*/,
-					      IOInterruptVector */*vector*/)
-{
-  return false;
-}
-
-void IOInterruptController::initVector(long /*vectorNumber*/,
-				       IOInterruptVector */*vector*/)
-{
-}
-
-int IOInterruptController::getVectorType(long /*vectorNumber*/,
-					  IOInterruptVector */*vector*/)
-{
-  return kIOInterruptTypeEdge;
-}
-
-void IOInterruptController::disableVectorHard(long /*vectorNumber*/,
-					      IOInterruptVector */*vector*/)
-{
-}
-
-void IOInterruptController::enableVector(long /*vectorNumber*/,
-					 IOInterruptVector */*vector*/)
-{
-}
-
-void IOInterruptController::causeVector(long /*vectorNumber*/,
-					IOInterruptVector */*vector*/)
-{
-}
-
+	}
+}
+
+void
+IOInterruptController::timeStampInterruptHandlerStart(IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector)
+{
+	timeStampInterruptHandlerInternal(true, vectorNumber, vector);
+}
+
+void
+IOInterruptController::timeStampInterruptHandlerEnd(IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector)
+{
+	timeStampInterruptHandlerInternal(false, vectorNumber, vector);
+}
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -416,306 +521,333 @@
 
 #define kIOSharedInterruptControllerDefaultVectors (128)
 
-IOReturn IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource)
-{
-  int      cnt, interruptType;
-  IOReturn error;
-  
-  if (!super::init())
-    return kIOReturnNoResources;
-  
-  // Set provider to this so enable/disable nub stuff works.
-  provider = this;
-  
-  // Allocate the IOInterruptSource so this can act like a nub.
-  _interruptSources = (IOInterruptSource *)IOMalloc(sizeof(IOInterruptSource));
-  if (_interruptSources == 0) return kIOReturnNoMemory;
-  _numInterruptSources = 1;
-  
-  // Set up the IOInterruptSource to point at this.
-  parentController->retain();
-  parentSource->retain();
-  _interruptSources[0].interruptController = parentController;
-  _interruptSources[0].vectorData = parentSource;
-  
-  sourceIsLevel = false;
-  error = provider->getInterruptType(0, &interruptType);
-  if (error == kIOReturnSuccess) {
-    if (interruptType & kIOInterruptTypeLevel)
-      sourceIsLevel = true;
-  }
-  
-  // Allocate the memory for the vectors
-  numVectors = kIOSharedInterruptControllerDefaultVectors; // For now a constant number.
-  vectors = (IOInterruptVector *)IOMalloc(numVectors * sizeof(IOInterruptVector));
-  if (vectors == NULL) {
-    IOFree(_interruptSources, sizeof(IOInterruptSource));
-    return kIOReturnNoMemory;
-  }
-  bzero(vectors, numVectors * sizeof(IOInterruptVector));
-  
-  // Allocate the lock for the controller.
-  controllerLock = IOSimpleLockAlloc();
-  if (controllerLock == 0) return kIOReturnNoResources;
-  
-  // Allocate locks for the vectors.
-  for (cnt = 0; cnt < numVectors; cnt++) {
-    vectors[cnt].interruptLock = IOLockAlloc();
-    if (vectors[cnt].interruptLock == NULL) {
-      for (cnt = 0; cnt < numVectors; cnt++) {
-	if (vectors[cnt].interruptLock != NULL)
-	  IOLockFree(vectors[cnt].interruptLock);
-      }
-      return kIOReturnNoResources;
-    }
-  }
-  
-  numVectors = 0; // reset the high water mark for used vectors
-  vectorsRegistered = 0;
-  vectorsEnabled = 0;
-  controllerDisabled = 1;
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOSharedInterruptController::registerInterrupt(IOService *nub,
-							int source,
-							void *target,
-							IOInterruptHandler handler,
-							void *refCon)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector = 0;
-  OSData            *vectorData;
-  IOInterruptState  interruptState;
-  
-  interruptSources = nub->_interruptSources;
-  
-  // Find a free vector.
-  vectorNumber = kIOSharedInterruptControllerDefaultVectors;
-  while (vectorsRegistered != kIOSharedInterruptControllerDefaultVectors) {
-    for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
-      vector = &vectors[vectorNumber];
-      
-      // Get the lock for this vector.
-      IOTakeLock(vector->interruptLock);
-      
-      // Is it unregistered?
-      if (!vector->interruptRegistered) break;
-      
-      // Move along to the next one.
-      IOUnlock(vector->interruptLock);
-    }
-    
-    if (vectorNumber != kIOSharedInterruptControllerDefaultVectors) break;
-  }
-  
-  // Could not find a free one, so give up.
-  if (vectorNumber == kIOSharedInterruptControllerDefaultVectors) {
-    return kIOReturnNoResources;
-  }
-  
-  // Create the vectorData for the IOInterruptSource.
-  vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber));
-  if (vectorData == 0) {
-    return kIOReturnNoMemory;
-  }
-  
-  // Fill in the IOInterruptSource with the controller's info.
-  interruptSources[source].interruptController = this;
-  interruptSources[source].vectorData = vectorData;
-  
-  // Fill in vector with the client's info.
-  vector->handler = handler;
-  vector->nub     = nub;
-  vector->source  = source;
-  vector->target  = target;
-  vector->refCon  = refCon;
-  
-  // Get the vector ready.  It starts off soft disabled.
-  vector->interruptDisabledSoft = 1;
-  vector->interruptRegistered   = 1;
-  
-  interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
-  // Move the high water mark if needed
-  if (++vectorsRegistered > numVectors) numVectors = vectorsRegistered;
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-  
-  IOUnlock(vector->interruptLock);
-  return kIOReturnSuccess;
-}
-
-IOReturn IOSharedInterruptController::unregisterInterrupt(IOService *nub,
-							  int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  IOInterruptState  interruptState;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  // Get the lock for this vector.
-  IOTakeLock(vector->interruptLock);
-  
-  // Return success if it is not already registered
-  if (!vector->interruptRegistered) {
-    IOUnlock(vector->interruptLock);
-    return kIOReturnSuccess;
-  }
-  
-  // Soft disable the source and the controller too.
-  disableInterrupt(nub, source);
-  
-  // Clear all the storage for the vector except for interruptLock.
-  vector->interruptActive = 0;
-  vector->interruptDisabledSoft = 0;
-  vector->interruptDisabledHard = 0;
-  vector->interruptRegistered = 0;
-  vector->nub = 0;
-  vector->source = 0;
-  vector->handler = 0;
-  vector->target = 0;
-  vector->refCon = 0;
-  
-  interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
-  vectorsRegistered--;
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-  
-  IOUnlock(vector->interruptLock);
-  
-  // Re-enable the controller if all vectors are enabled.
-  if (vectorsEnabled == vectorsRegistered) {
-    controllerDisabled = 0;
-    provider->enableInterrupt(0);
-  }
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOSharedInterruptController::getInterruptType(IOService */*nub*/,
-						       int /*source*/,
-						       int *interruptType)
-{
-  return provider->getInterruptType(0, interruptType);
-}
-
-IOReturn IOSharedInterruptController::enableInterrupt(IOService *nub,
-						      int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  IOInterruptState  interruptState;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
-  if (!vector->interruptDisabledSoft) {
-    IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-    return kIOReturnSuccess;
-  }
-  
-  vector->interruptDisabledSoft = 0;
-  vectorsEnabled++;
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-  
-  if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
-    controllerDisabled = 0;
-    provider->enableInterrupt(0);
-  }
-  
-  return kIOReturnSuccess;
-}
-
-IOReturn IOSharedInterruptController::disableInterrupt(IOService *nub,
-						       int source)
-{
-  IOInterruptSource *interruptSources;
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  OSData            *vectorData;
-  IOInterruptState  interruptState;
-  
-  interruptSources = nub->_interruptSources;
-  vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(long *)vectorData->getBytesNoCopy();
-  vector = &vectors[vectorNumber];
-  
-  interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 
-  if (!vector->interruptDisabledSoft) {
-    vector->interruptDisabledSoft = 1;
-#if __ppc__
-    sync();
-    isync();
+IOReturn
+IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource)
+{
+	int      cnt, interruptType;
+	IOReturn error;
+
+	if (!super::init()) {
+		return kIOReturnNoResources;
+	}
+
+	// Set provider to this so enable/disable nub stuff works.
+	provider = this;
+
+	// Allocate the IOInterruptSource so this can act like a nub.
+	_interruptSources = IONew(IOInterruptSource, 1);
+	if (_interruptSources == NULL) {
+		return kIOReturnNoMemory;
+	}
+	_numInterruptSources = 1;
+
+	// Set up the IOInterruptSource to point at this.
+	parentController->retain();
+	parentSource->retain();
+	_interruptSources[0].interruptController = parentController;
+	_interruptSources[0].vectorData = parentSource;
+
+	sourceIsLevel = false;
+	error = provider->getInterruptType(0, &interruptType);
+	if (error == kIOReturnSuccess) {
+		if (interruptType & kIOInterruptTypeLevel) {
+			sourceIsLevel = true;
+		}
+	}
+
+	// Allocate the memory for the vectors
+	numVectors = kIOSharedInterruptControllerDefaultVectors; // For now a constant number.
+	vectors = IONewZero(IOInterruptVector, numVectors);
+	if (vectors == NULL) {
+		IODelete(_interruptSources, IOInterruptSource, 1);
+		return kIOReturnNoMemory;
+	}
+
+	// Allocate the lock for the controller.
+	controllerLock = IOSimpleLockAlloc();
+	if (controllerLock == NULL) {
+		return kIOReturnNoResources;
+	}
+
+	// Allocate locks for the vectors.
+	for (cnt = 0; cnt < numVectors; cnt++) {
+		vectors[cnt].interruptLock = IOLockAlloc();
+		if (vectors[cnt].interruptLock == NULL) {
+			for (cnt = 0; cnt < numVectors; cnt++) {
+				if (vectors[cnt].interruptLock != NULL) {
+					IOLockFree(vectors[cnt].interruptLock);
+				}
+			}
+			return kIOReturnNoResources;
+		}
+	}
+
+	numVectors = 0; // reset the high water mark for used vectors
+	vectorsRegistered = 0;
+	vectorsEnabled = 0;
+	controllerDisabled = 1;
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOSharedInterruptController::registerInterrupt(IOService *nub,
+    int source,
+    void *target,
+    IOInterruptHandler handler,
+    void *refCon)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector = NULL;
+	OSData            *vectorData;
+	IOInterruptState  interruptState;
+
+	interruptSources = nub->_interruptSources;
+
+	// Find a free vector.
+	vectorNumber = kIOSharedInterruptControllerDefaultVectors;
+	while (vectorsRegistered != kIOSharedInterruptControllerDefaultVectors) {
+		for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
+			vector = &vectors[vectorNumber];
+
+			// Get the lock for this vector.
+			IOLockLock(vector->interruptLock);
+
+			// Is it unregistered?
+			if (!vector->interruptRegistered) {
+				break;
+			}
+
+			// Move along to the next one.
+			IOLockUnlock(vector->interruptLock);
+		}
+
+		if (vectorNumber != kIOSharedInterruptControllerDefaultVectors) {
+			break;
+		}
+	}
+
+	// Could not find a free one, so give up.
+	if (vectorNumber == kIOSharedInterruptControllerDefaultVectors) {
+		return kIOReturnNoResources;
+	}
+
+	// Create the vectorData for the IOInterruptSource.
+	vectorData = OSData::withValue(vectorNumber);
+	if (vectorData == NULL) {
+		IOLockUnlock(vector->interruptLock);
+		return kIOReturnNoMemory;
+	}
+
+	// Fill in the IOInterruptSource with the controller's info.
+	interruptSources[source].interruptController = this;
+	interruptSources[source].vectorData = vectorData;
+
+	// Fill in vector with the client's info.
+	vector->handler = handler;
+	vector->nub     = nub;
+	vector->source  = source;
+	vector->target  = target;
+	vector->refCon  = refCon;
+
+	// Get the vector ready.  It starts off soft disabled.
+	vector->interruptDisabledSoft = 1;
+	vector->interruptRegistered   = 1;
+
+	interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+	// Move the high water mark if needed
+	if (++vectorsRegistered > numVectors) {
+		numVectors = vectorsRegistered;
+	}
+	IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+
+	IOLockUnlock(vector->interruptLock);
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOSharedInterruptController::unregisterInterrupt(IOService *nub,
+    int source)
+{
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	IOInterruptState  interruptState;
+
+	for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
+		vector = &vectors[vectorNumber];
+
+		// Get the lock for this vector.
+		IOLockLock(vector->interruptLock);
+
+		// Return success if it is not already registered
+		if (!vector->interruptRegistered
+		    || (vector->nub != nub) || (vector->source != source)) {
+			IOLockUnlock(vector->interruptLock);
+			continue;
+		}
+
+		// Soft disable the source and the controller too.
+		disableInterrupt(nub, source);
+
+		// Free vectorData
+		IOInterruptSource *interruptSources = nub->_interruptSources;
+		OSSafeReleaseNULL(interruptSources[source].vectorData);
+
+		// Clear all the storage for the vector except for interruptLock.
+		vector->interruptActive = 0;
+		vector->interruptDisabledSoft = 0;
+		vector->interruptDisabledHard = 0;
+		vector->interruptRegistered = 0;
+		vector->nub = NULL;
+		vector->source = 0;
+		vector->handler = NULL;
+		vector->target = NULL;
+		vector->refCon = NULL;
+
+		interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+		vectorsRegistered--;
+		IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+
+		// Move along to the next one.
+		IOLockUnlock(vector->interruptLock);
+	}
+
+	// Re-enable the controller if all vectors are enabled.
+	if (vectorsEnabled == vectorsRegistered) {
+		controllerDisabled = 0;
+		provider->enableInterrupt(0);
+	}
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOSharedInterruptController::getInterruptType(IOService */*nub*/,
+    int /*source*/,
+    int *interruptType)
+{
+	return provider->getInterruptType(0, interruptType);
+}
+
+IOReturn
+IOSharedInterruptController::enableInterrupt(IOService *nub,
+    int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+	IOInterruptState  interruptState;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+	if (!vector->interruptDisabledSoft) {
+		IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+		return kIOReturnSuccess;
+	}
+
+	vector->interruptDisabledSoft = 0;
+	vectorsEnabled++;
+	IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+
+	if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
+		controllerDisabled = 0;
+		provider->enableInterrupt(0);
+	}
+
+	return kIOReturnSuccess;
+}
+
+IOReturn
+IOSharedInterruptController::disableInterrupt(IOService *nub,
+    int source)
+{
+	IOInterruptSource *interruptSources;
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+	OSData            *vectorData;
+	IOInterruptState  interruptState;
+
+	interruptSources = nub->_interruptSources;
+	vectorData = interruptSources[source].vectorData;
+	vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+	vector = &vectors[vectorNumber];
+
+	interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+	if (!vector->interruptDisabledSoft) {
+		vector->interruptDisabledSoft = 1;
+#if !defined(__i386__) && !defined(__x86_64__)
+		OSMemoryBarrier();
 #endif
-    vectorsEnabled--;
-  }
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-  
-  if (!getPlatform()->atInterruptLevel()) {
-    while (vector->interruptActive);
-#if __ppc__
-    isync();
+
+		vectorsEnabled--;
+	}
+	IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+
+	if (!getPlatform()->atInterruptLevel()) {
+		while (vector->interruptActive) {
+		}
+	}
+
+	return kIOReturnSuccess;
+}
+
+IOInterruptAction
+IOSharedInterruptController::getInterruptHandlerAddress(void)
+{
+	return OSMemberFunctionCast(IOInterruptAction,
+	           this, &IOSharedInterruptController::handleInterrupt);
+}
+
+IOReturn
+IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
+    IOService * nub,
+    int /*source*/)
+{
+	IOInterruptVectorNumber vectorNumber;
+	IOInterruptVector *vector;
+
+	for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
+		vector = &vectors[vectorNumber];
+
+		vector->interruptActive = 1;
+#if !defined(__i386__) && !defined(__x86_64__)
+		OSMemoryBarrier();
 #endif
-  }
-  
-  return kIOReturnSuccess;
-}
-
-IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void)
-{
-    return OSMemberFunctionCast(IOInterruptAction,
-			this, &IOSharedInterruptController::handleInterrupt);
-}
-
-IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
-						      IOService * nub,
-						      int /*source*/)
-{
-  long              vectorNumber;
-  IOInterruptVector *vector;
-  
-  for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
-    vector = &vectors[vectorNumber];
-    
-    vector->interruptActive = 1;
-#if __ppc__
-    sync();
-    isync();
-#endif
-    if (!vector->interruptDisabledSoft) {
-#if __ppc__
-      isync();
-#endif
-      
-      // Call the handler if it exists.
-      if (vector->interruptRegistered) {
-	vector->handler(vector->target, vector->refCon,
-			vector->nub, vector->source);
-      }
-    }
-    
-    vector->interruptActive = 0;
-  }
-  
-  // if any of the vectors are dissabled, then dissable this controller.
-  IOSimpleLockLock(controllerLock);
-  if (vectorsEnabled != vectorsRegistered) {
-    nub->disableInterrupt(0);
-    controllerDisabled = 1;
-  }
-  IOSimpleLockUnlock(controllerLock);
-  
-  return kIOReturnSuccess;
-}
-
+
+		if (!vector->interruptDisabledSoft) {
+			// Call the handler if it exists.
+			if (vector->interruptRegistered) {
+				bool trace = (gIOKitTrace & kIOTraceInterrupts) ? true : false;
+
+				if (trace) {
+					timeStampInterruptHandlerStart(vectorNumber, vector);
+				}
+
+				// Call handler.
+				vector->handler(vector->target, vector->refCon, vector->nub, vector->source);
+
+				if (trace) {
+					timeStampInterruptHandlerEnd(vectorNumber, vector);
+				}
+			}
+		}
+
+		vector->interruptActive = 0;
+	}
+
+	// if any of the vectors are dissabled, then dissable this controller.
+	IOSimpleLockLock(controllerLock);
+	if (vectorsEnabled != vectorsRegistered) {
+		nub->disableInterrupt(0);
+		controllerDisabled = 1;
+	}
+	IOSimpleLockUnlock(controllerLock);
+
+	return kIOReturnSuccess;
+}