Loading...
iokit/Kernel/IOInterruptController.cpp xnu-3789.41.3 xnu-201
--- xnu/xnu-3789.41.3/iokit/Kernel/IOInterruptController.cpp
+++ xnu/xnu-201/iokit/Kernel/IOInterruptController.cpp
@@ -1,40 +1,41 @@
 /*
- * Copyright (c) 2007-2012 Apple Inc. All rights reserved.
- * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * @APPLE_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
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * 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.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * 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
+ * This 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,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * 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.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ * @APPLE_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>
 #include <IOKit/IOPlatformExpert.h>
-#include <IOKit/IODeviceTreeSupport.h>
 #include <IOKit/IOInterrupts.h>
 #include <IOKit/IOInterruptController.h>
-#include <IOKit/IOKitDebug.h>
-#include <IOKit/IOTimeStamp.h>
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -58,111 +59,77 @@
 						  void *refCon)
 {
   IOInterruptSource *interruptSources;
-  IOInterruptVectorNumber vectorNumber;
-  IOInterruptVector *vector;
-  int               wasDisabledSoft;
+  long              vectorNumber;
+  IOInterruptVector *vector;
+  long              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();
+  IOService         *originalNub;
+  int               originalSource;
+  
+  interruptSources = nub->_interruptSources;
+  vectorData = interruptSources[source].vectorData;
+  vectorNumber = *(long *)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,
+  IOTakeLock(vector->interruptLock);
+  
+  // If this vector is already in use, and can be shared,
   // register as a shared interrupt.
-  if (wasAlreadyRegisterd || shouldBeShared) {
+  if (vector->interruptRegistered) {
+    if (!vectorCanBeShared(vectorNumber, vector)) {
+      IOUnlock(vector->interruptLock);
+      return kIOReturnNoResources;
+    }
+    
     // 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) {
-        IOLockUnlock(vector->interruptLock);
+        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.
-	disableVectorHard(vectorNumber, vector);
-	vector->interruptDisabledHard = 0;
-      }
+      // Save the nub and source for the original consumer.
+      originalNub = vector->nub;
+      originalSource = vector->source;
+      
+      // Save the dis/enable state for the original consumer's interrupt.
+      // Then disable the source
+      wasDisabledSoft = vector->interruptDisabledSoft;
+      disableInterrupt(originalNub, originalSource);
       
       // Initialize the new shared interrupt controller.
-      error = vector->sharedController->initInterruptController(this, vectorData);
+      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
+      // put the original consumor's interrupt back to normal and
       // get rid of whats left of the shared controller.
       if (error != kIOReturnSuccess) {
-	if (wasAlreadyRegisterd) enableInterrupt(originalNub, originalSource);
+        enableInterrupt(originalNub, originalSource);
         vector->sharedController->release();
         vector->sharedController = 0;
-        IOLockUnlock(vector->interruptLock);
+        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;
-	  IOLockUnlock(vector->interruptLock);
-	  return error;
-	}
+      // Try to register the original consumer on the shared controller.
+      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) {
+        enableInterrupt(originalNub, originalSource);
+        vector->sharedController->release();
+        vector->sharedController = 0;
+        IOUnlock(vector->interruptLock);
+        return error;
       }
       
       // Fill in vector with the shared controller's info.
@@ -172,27 +139,13 @@
       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.
-      // 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);
+    IOUnlock(vector->interruptLock);
     return error;
   }
   
@@ -211,28 +164,28 @@
   vector->interruptDisabledSoft = 1;
   vector->interruptRegistered   = 1;
   
-  IOLockUnlock(vector->interruptLock);
+  IOUnlock(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();
+  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.
-  IOLockLock(vector->interruptLock);
+  IOTakeLock(vector->interruptLock);
   
   // Return success if it is not already registered
   if (!vector->interruptRegistered) {
-    IOLockUnlock(vector->interruptLock);
+    IOUnlock(vector->interruptLock);
     return kIOReturnSuccess;
   }
   
@@ -253,7 +206,7 @@
   vector->target = 0;
   vector->refCon = 0;
   
-  IOLockUnlock(vector->interruptLock);
+  IOUnlock(vector->interruptLock);
   return kIOReturnSuccess;
 }
 
@@ -261,7 +214,7 @@
 						 int *interruptType)
 {
   IOInterruptSource *interruptSources;
-  IOInterruptVectorNumber vectorNumber;
+  long              vectorNumber;
   IOInterruptVector *vector;
   OSData            *vectorData;
   
@@ -269,7 +222,7 @@
   
   interruptSources = nub->_interruptSources;
   vectorData = interruptSources[source].vectorData;
-  vectorNumber = *(IOInterruptVectorNumber *)vectorData->getBytesNoCopy();
+  vectorNumber = *(long *)vectorData->getBytesNoCopy();
   vector = &vectors[vectorNumber];
   
   *interruptType = getVectorType(vectorNumber, vector);
@@ -280,24 +233,27 @@
 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();
+  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 !defined(__i386__) && !defined(__x86_64__)
-    OSMemoryBarrier();
-#endif
-
+#if __ppc__
+    sync();
+    isync();
+#endif
+    
     if (!getPlatform()->atInterruptLevel()) {
-      while (vector->interruptActive)
-	{}
+      while (vector->interruptActive);
+#if __ppc__
+      isync();
+#endif
     }
     if (vector->interruptDisabledHard) {
       vector->interruptDisabledHard = 0;
@@ -312,23 +268,26 @@
 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();
+  long              vectorNumber;
+  IOInterruptVector *vector;
+  OSData            *vectorData;
+  
+  interruptSources = nub->_interruptSources;
+  vectorData = interruptSources[source].vectorData;
+  vectorNumber = *(long *)vectorData->getBytesNoCopy();
   vector = &vectors[vectorNumber];
   
   vector->interruptDisabledSoft = 1;
-#if !defined(__i386__) && !defined(__x86_64__)
-  OSMemoryBarrier();
+#if __ppc__
+  sync();
+  isync();
 #endif
   
   if (!getPlatform()->atInterruptLevel()) {
-    while (vector->interruptActive)
-	{}
+    while (vector->interruptActive);
+#if __ppc__
+    isync();
+#endif
   }
   
   return kIOReturnSuccess;
@@ -337,13 +296,13 @@
 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();
+  long              vectorNumber;
+  IOInterruptVector *vector;
+  OSData            *vectorData;
+
+  interruptSources = nub->_interruptSources;
+  vectorData = interruptSources[source].vectorData;
+  vectorNumber = *(long *)vectorData->getBytesNoCopy();
   vector = &vectors[vectorNumber];
   
   causeVector(vectorNumber, vector);
@@ -365,34 +324,34 @@
 
 // Methods to be overridden for simplifed interrupt controller subclasses.
 
-bool IOInterruptController::vectorCanBeShared(IOInterruptVectorNumber /*vectorNumber*/,
+bool IOInterruptController::vectorCanBeShared(long /*vectorNumber*/,
 					      IOInterruptVector */*vector*/)
 {
   return false;
 }
 
-void IOInterruptController::initVector(IOInterruptVectorNumber /*vectorNumber*/,
+void IOInterruptController::initVector(long /*vectorNumber*/,
 				       IOInterruptVector */*vector*/)
 {
 }
 
-int IOInterruptController::getVectorType(IOInterruptVectorNumber /*vectorNumber*/,
+int IOInterruptController::getVectorType(long /*vectorNumber*/,
 					  IOInterruptVector */*vector*/)
 {
   return kIOInterruptTypeEdge;
 }
 
-void IOInterruptController::disableVectorHard(IOInterruptVectorNumber /*vectorNumber*/,
+void IOInterruptController::disableVectorHard(long /*vectorNumber*/,
 					      IOInterruptVector */*vector*/)
 {
 }
 
-void IOInterruptController::enableVector(IOInterruptVectorNumber /*vectorNumber*/,
+void IOInterruptController::enableVector(long /*vectorNumber*/,
 					 IOInterruptVector */*vector*/)
 {
 }
 
-void IOInterruptController::causeVector(IOInterruptVectorNumber /*vectorNumber*/,
+void IOInterruptController::causeVector(long /*vectorNumber*/,
 					IOInterruptVector */*vector*/)
 {
 }
@@ -412,14 +371,10 @@
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-#define kIOSharedInterruptControllerDefaultVectors (128)
-
 IOReturn IOSharedInterruptController::initInterruptController(IOInterruptController *parentController, OSData *parentSource)
 {
   int      cnt, interruptType;
   IOReturn error;
-
-  reserved = NULL;
   
   if (!super::init())
     return kIOReturnNoResources;
@@ -433,8 +388,6 @@
   _numInterruptSources = 1;
   
   // Set up the IOInterruptSource to point at this.
-  parentController->retain();
-  parentSource->retain();
   _interruptSources[0].interruptController = parentController;
   _interruptSources[0].vectorData = parentSource;
   
@@ -446,7 +399,7 @@
   }
   
   // Allocate the memory for the vectors
-  numVectors = kIOSharedInterruptControllerDefaultVectors; // For now a constant number.
+  numVectors = 8; // For now a constant number.
   vectors = (IOInterruptVector *)IOMalloc(numVectors * sizeof(IOInterruptVector));
   if (vectors == NULL) {
     IOFree(_interruptSources, sizeof(IOInterruptSource));
@@ -470,7 +423,6 @@
     }
   }
   
-  numVectors = 0; // reset the high water mark for used vectors
   vectorsRegistered = 0;
   vectorsEnabled = 0;
   controllerDisabled = 1;
@@ -485,7 +437,7 @@
 							void *refCon)
 {
   IOInterruptSource *interruptSources;
-  IOInterruptVectorNumber vectorNumber;
+  long              vectorNumber;
   IOInterruptVector *vector = 0;
   OSData            *vectorData;
   IOInterruptState  interruptState;
@@ -493,33 +445,32 @@
   interruptSources = nub->_interruptSources;
   
   // Find a free vector.
-  vectorNumber = kIOSharedInterruptControllerDefaultVectors;
-  while (vectorsRegistered != kIOSharedInterruptControllerDefaultVectors) {
-    for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
+  vectorNumber = numVectors;
+  while (vectorsRegistered != numVectors) {
+    for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
       vector = &vectors[vectorNumber];
       
       // Get the lock for this vector.
-      IOLockLock(vector->interruptLock);
+      IOTakeLock(vector->interruptLock);
       
       // Is it unregistered?
       if (!vector->interruptRegistered) break;
       
       // Move along to the next one.
-      IOLockUnlock(vector->interruptLock);
+      IOUnlock(vector->interruptLock);
     }
     
-    if (vectorNumber != kIOSharedInterruptControllerDefaultVectors) break;
+    if (vectorNumber != numVectors) break;
   }
   
   // Could not find a free one, so give up.
-  if (vectorNumber == kIOSharedInterruptControllerDefaultVectors) {
+  if (vectorNumber == numVectors) {
     return kIOReturnNoResources;
   }
   
   // Create the vectorData for the IOInterruptSource.
   vectorData = OSData::withBytes(&vectorNumber, sizeof(vectorNumber));
   if (vectorData == 0) {
-    IOLockUnlock(vector->interruptLock);
     return kIOReturnNoMemory;
   }
   
@@ -534,67 +485,60 @@
   vector->target  = target;
   vector->refCon  = refCon;
   
-  // Get the vector ready.  It starts off soft disabled.
+  // Get the vector ready.  It start soft disabled.
   vector->interruptDisabledSoft = 1;
   vector->interruptRegistered   = 1;
   
   interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
-  // Move the high water mark if needed
-  if (++vectorsRegistered > numVectors) numVectors = vectorsRegistered;
+  vectorsRegistered++;
   IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
   
-  IOLockUnlock(vector->interruptLock);
+  IOUnlock(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);
-
-    // 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);
-
-    // 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);
-  }
-
+  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.
+  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);
   return kIOReturnSuccess;
 }
 
@@ -609,29 +553,26 @@
 						      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) {
+  long              vectorNumber;
+  IOInterruptVector *vector;
+  OSData            *vectorData;
+  IOInterruptState  interruptState;;
+  
+  interruptSources = nub->_interruptSources;
+  vectorData = interruptSources[source].vectorData;
+  vectorNumber = *(long *)vectorData->getBytesNoCopy();
+  vector = &vectors[vectorNumber];
+  
+  if (vector->interruptDisabledSoft) {
+    interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+    vector->interruptDisabledSoft = 0;
+    vectorsEnabled++;
     IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-    return kIOReturnSuccess;
-  }
-  
-  vector->interruptDisabledSoft = 0;
-  vectorsEnabled++;
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-  
-  if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
-    controllerDisabled = 0;
-    provider->enableInterrupt(0);
+    
+    if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
+      controllerDisabled = 0;
+      provider->enableInterrupt(0);
+    }
   }
   
   return kIOReturnSuccess;
@@ -641,30 +582,32 @@
 						       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); 
+  long              vectorNumber;
+  IOInterruptVector *vector;
+  OSData            *vectorData;
+  IOInterruptState  interruptState;;
+  
+  interruptSources = nub->_interruptSources;
+  vectorData = interruptSources[source].vectorData;
+  vectorNumber = *(long *)vectorData->getBytesNoCopy();
+  vector = &vectors[vectorNumber];
+  
   if (!vector->interruptDisabledSoft) {
+    interruptState = IOSimpleLockLockDisableInterrupt(controllerLock); 
     vector->interruptDisabledSoft = 1;
-#if !defined(__i386__) && !defined(__x86_64__)
-    OSMemoryBarrier();
-#endif
-
+#if __ppc__
+    sync();
+    isync();
+#endif
     vectorsEnabled--;
-  }
-  IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+    IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+  }
   
   if (!getPlatform()->atInterruptLevel()) {
-    while (vector->interruptActive)
-	{}
+    while (vector->interruptActive);
+#if __ppc__
+    isync();
+#endif
   }
   
   return kIOReturnSuccess;
@@ -672,45 +615,35 @@
 
 IOInterruptAction IOSharedInterruptController::getInterruptHandlerAddress(void)
 {
-    return OSMemberFunctionCast(IOInterruptAction,
-			this, &IOSharedInterruptController::handleInterrupt);
+    return (IOInterruptAction)&IOSharedInterruptController::handleInterrupt;
 }
 
 IOReturn IOSharedInterruptController::handleInterrupt(void * /*refCon*/,
 						      IOService * nub,
 						      int /*source*/)
 {
-  IOInterruptVectorNumber vectorNumber;
+  long              vectorNumber;
   IOInterruptVector *vector;
   
   for (vectorNumber = 0; vectorNumber < numVectors; vectorNumber++) {
     vector = &vectors[vectorNumber];
     
     vector->interruptActive = 1;
-#if !defined(__i386__) && !defined(__x86_64__)
-    OSMemoryBarrier();
-#endif
-
-	if (!vector->interruptDisabledSoft) {
-	  
-	  // Call the handler if it exists.
-	  if (vector->interruptRegistered) {
-		  
-		  bool	trace = (gIOKitTrace & kIOTraceInterrupts) ? true : false;
-		  
-		  if (trace)
-			  IOTimeStampStartConstant(IODBG_INTC(IOINTC_HANDLER),
-									   (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target);
-		  
-		  // Call handler.
-		  vector->handler(vector->target, vector->refCon, vector->nub, vector->source);
-		  
-		  if (trace)
-			  IOTimeStampEndConstant(IODBG_INTC(IOINTC_HANDLER),
-									 (uintptr_t) vectorNumber, (uintptr_t) vector->handler, (uintptr_t)vector->target);
-		  
-		}
-	}
+#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;
   }