Loading...
iokit/Kernel/IOInterruptEventSource.cpp xnu-1228 xnu-1504.15.3
--- xnu/xnu-1228/iokit/Kernel/IOInterruptEventSource.cpp
+++ xnu/xnu-1504.15.3/iokit/Kernel/IOInterruptEventSource.cpp
@@ -33,37 +33,12 @@
         Created.
 */
 #include <IOKit/IOInterruptEventSource.h>
+#include <IOKit/IOKitDebug.h>
 #include <IOKit/IOLib.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOInterrupts.h>
 #include <IOKit/IOTimeStamp.h>
 #include <IOKit/IOWorkLoop.h>
-
-#if KDEBUG
-
-#define IOTimeTypeStampS(t)						\
-do {									\
-    IOTimeStampStart(IODBG_INTES(t),					\
-                     (unsigned int) this, (unsigned int) owner);	\
-} while(0)
-
-#define IOTimeTypeStampE(t)						\
-do {									\
-    IOTimeStampEnd(IODBG_INTES(t),					\
-                   (unsigned int) this, (unsigned int) owner);		\
-} while(0)
-
-#define IOTimeStampLatency()						\
-do {									\
-    IOTimeStampEnd(IODBG_INTES(IOINTES_LAT),				\
-                   (unsigned int) this, (unsigned int) owner);		\
-} while(0)
-
-#else /* !KDEBUG */
-#define IOTimeTypeStampS(t)
-#define IOTimeTypeStampE(t)
-#define IOTimeStampLatency()
-#endif /* KDEBUG */
 
 #define super IOEventSource
 
@@ -90,34 +65,41 @@
     provider = inProvider;
     producerCount = consumerCount = 0;
     autoDisable = explicitDisable = false;
-    intIndex = -1;
+    intIndex = ~inIntIndex;
 
     // Assumes inOwner holds a reference(retain) on the provider
     if (inProvider) {
-        int intType;
-
-        res = (kIOReturnSuccess
-                    == inProvider->getInterruptType(inIntIndex, &intType));
-        if (res) {
-            IOInterruptAction intHandler;
-
-            autoDisable = (intType == kIOInterruptTypeLevel);
-            if (autoDisable) {
-                intHandler = OSMemberFunctionCast(IOInterruptAction,
-		    this, &IOInterruptEventSource::disableInterruptOccurred);
-            }
-            else
-                intHandler = OSMemberFunctionCast(IOInterruptAction,
-		    this, &IOInterruptEventSource::normalInterruptOccurred);
-
-            res = (kIOReturnSuccess == inProvider->registerInterrupt
-                                        (inIntIndex, this, intHandler));
-            if (res)
-                intIndex = inIntIndex;
-        }
+        res = (kIOReturnSuccess == registerInterruptHandler(inProvider, inIntIndex));
+	if (res)
+	    intIndex = inIntIndex;
     }
 
     return res;
+}
+
+IOReturn IOInterruptEventSource::registerInterruptHandler(IOService *inProvider,
+				  int inIntIndex)
+{
+    IOReturn ret;
+    int intType;
+    IOInterruptAction intHandler;
+
+    ret = inProvider->getInterruptType(inIntIndex, &intType);
+    if (kIOReturnSuccess != ret)
+	return (ret);
+
+    autoDisable = (intType == kIOInterruptTypeLevel);
+    if (autoDisable) {
+	intHandler = OSMemberFunctionCast(IOInterruptAction,
+	    this, &IOInterruptEventSource::disableInterruptOccurred);
+    }
+    else
+	intHandler = OSMemberFunctionCast(IOInterruptAction,
+	    this, &IOInterruptEventSource::normalInterruptOccurred);
+
+    ret = provider->registerInterrupt(inIntIndex, this, intHandler);
+
+    return (ret);
 }
 
 IOInterruptEventSource *
@@ -138,7 +120,7 @@
 
 void IOInterruptEventSource::free()
 {
-    if (provider && intIndex != -1)
+    if (provider && intIndex >= 0)
         provider->unregisterInterrupt(intIndex);
 
     super::free();
@@ -146,7 +128,7 @@
 
 void IOInterruptEventSource::enable()
 {
-    if (provider && intIndex != -1) {
+    if (provider && intIndex >= 0) {
         provider->enableInterrupt(intIndex);
         explicitDisable = false;
         enabled = true;
@@ -155,13 +137,30 @@
 
 void IOInterruptEventSource::disable()
 {
-    if (provider && intIndex != -1) {
+    if (provider && intIndex >= 0) {
         provider->disableInterrupt(intIndex);
         explicitDisable = true;
         enabled = false;
     }
 }
 
+void IOInterruptEventSource::setWorkLoop(IOWorkLoop *inWorkLoop)
+{
+    super::setWorkLoop(inWorkLoop);
+
+    if (!provider)
+    	return;
+
+    if ( !inWorkLoop ) {
+	if (intIndex >= 0) {
+	    provider->unregisterInterrupt(intIndex);
+	    intIndex = ~intIndex;
+	}
+    } else if ((intIndex < 0) && (kIOReturnSuccess == registerInterruptHandler(provider, ~intIndex))) {
+	intIndex = ~intIndex;
+    }
+}
+
 const IOService *IOInterruptEventSource::getProvider() const
 {
     return provider;
@@ -182,27 +181,38 @@
     unsigned int cacheProdCount = producerCount;
     int numInts = cacheProdCount - consumerCount;
     IOInterruptEventAction intAction = (IOInterruptEventAction) action;
-
-    if (numInts > 0) {
-
-        IOTimeStampLatency();
-        IOTimeTypeStampS(IOINTES_CLIENT);
-            IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION),
-                                (unsigned int) intAction, (unsigned int) owner);
-            (*intAction)(owner, this,  numInts);
-        IOTimeTypeStampE(IOINTES_CLIENT);
+	bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false;
+
+	if ( numInts > 0 )
+	{
+		if (trace)
+			IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
+									 (uintptr_t) intAction, (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop);
+
+		// Call the handler
+        (*intAction)(owner, this,  numInts);
+		
+		if (trace)
+			IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
+								   (uintptr_t) intAction, (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop);
 
         consumerCount = cacheProdCount;
         if (autoDisable && !explicitDisable)
             enable();
     }
-    else if (numInts < 0) {
-        IOTimeStampLatency();
-        IOTimeTypeStampS(IOINTES_CLIENT);
-            IOTimeStampConstant(IODBG_INTES(IOINTES_ACTION),
-                                (unsigned int) intAction, (unsigned int) owner);
-             (*intAction)(owner, this, -numInts);
-        IOTimeTypeStampE(IOINTES_CLIENT);
+	
+	else if ( numInts < 0 )
+	{
+		if (trace)
+			IOTimeStampStartConstant(IODBG_INTES(IOINTES_ACTION),
+									 (uintptr_t) intAction, (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop);
+		
+		// Call the handler
+    	(*intAction)(owner, this, -numInts);
+		
+		if (trace)
+			IOTimeStampEndConstant(IODBG_INTES(IOINTES_ACTION),
+								   (uintptr_t) intAction, (uintptr_t) owner, (uintptr_t) this, (uintptr_t) workLoop);
     
         consumerCount = cacheProdCount;
         if (autoDisable && !explicitDisable)
@@ -215,33 +225,35 @@
 void IOInterruptEventSource::normalInterruptOccurred
     (void */*refcon*/, IOService */*prov*/, int /*source*/)
 {
-IOTimeTypeStampS(IOINTES_INTCTXT);
-IOTimeStampLatency();
+	bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false;
 
     producerCount++;
 
-IOTimeTypeStampS(IOINTES_SEMA);
+	if (trace)
+	    IOTimeStampStartConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner);
+	
     signalWorkAvailable();
-IOTimeTypeStampE(IOINTES_SEMA);
-
-IOTimeTypeStampE(IOINTES_INTCTXT);
+
+	if (trace)
+	    IOTimeStampEndConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner);
 }
 
 void IOInterruptEventSource::disableInterruptOccurred
     (void */*refcon*/, IOService *prov, int source)
 {
-IOTimeTypeStampS(IOINTES_INTCTXT);
-IOTimeStampLatency();
+	bool trace = (gIOKitTrace & kIOTraceIntEventSource) ? true : false;
 
     prov->disableInterrupt(source);	/* disable the interrupt */
 
     producerCount++;
 
-IOTimeTypeStampS(IOINTES_SEMA);
+	if (trace)
+	    IOTimeStampStartConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner);
+    
     signalWorkAvailable();
-IOTimeTypeStampE(IOINTES_SEMA);
-
-IOTimeTypeStampE(IOINTES_INTCTXT);
+
+	if (trace)
+	    IOTimeStampEndConstant(IODBG_INTES(IOINTES_SEMA), (uintptr_t) this, (uintptr_t) owner);
 }
 
 void IOInterruptEventSource::interruptOccurred