Fix definition of KINTERRUPT in ROS headers so that moving to NDK will be easier...
authorAlex Ionescu <aionescu@gmail.com>
Wed, 22 Jun 2005 23:10:15 +0000 (23:10 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Wed, 22 Jun 2005 23:10:15 +0000 (23:10 +0000)
svn path=/trunk/; revision=16229

reactos/include/ntos/kefuncs.h
reactos/include/ntos/zwtypes.h
reactos/ntoskrnl/io/irq.c
reactos/ntoskrnl/ke/i386/irq.c
reactos/ntoskrnl/ke/spinlock.c

index 17c7feb..33af624 100644 (file)
@@ -62,7 +62,7 @@ BOOLEAN STDCALL
 KeConnectInterrupt(
   PKINTERRUPT  InterruptObject);
 
-VOID STDCALL
+BOOLEAN STDCALL
 KeDisconnectInterrupt(
   PKINTERRUPT  InterruptObject);
 
index e166f72..ce9e2f8 100755 (executable)
@@ -1781,22 +1781,48 @@ typedef struct _LPC_PORT_BASIC_INFORMATION
 } LPC_PORT_BASIC_INFORMATION, * PLPC_PORT_BASIC_INFORMATION;
 
 
+#if 0
 typedef struct _KINTERRUPT
 {
-   ULONG Vector;
-   KAFFINITY ProcessorEnableMask;
-   KSPIN_LOCK SpinLock;
-   PKSPIN_LOCK ActualLock;
-   BOOLEAN Shareable;
-   BOOLEAN FloatingSave;
-   CHAR ProcessorNumber;
-   PKSERVICE_ROUTINE ServiceRoutine;
-   PVOID ServiceContext;
-   LIST_ENTRY Entry;
-   KIRQL Irql;
-   KIRQL SynchLevel;
-   KINTERRUPT_MODE InterruptMode;
+   ULONG Vector; // Idem
+   KAFFINITY ProcessorEnableMask; // not needed
+   KSPIN_LOCK SpinLock; // Idem
+   PKSPIN_LOCK ActualLock; // Idem
+   BOOLEAN Shareable; // ShareVector
+   BOOLEAN FloatingSave; // Idem
+   CHAR ProcessorNumber; // Number
+   PKSERVICE_ROUTINE ServiceRoutine; // Idem
+   PVOID ServiceContext; // Idem
+   LIST_ENTRY Entry; // InteruptListEntry
+   KIRQL Irql; // Irql
+   KIRQL SynchLevel; // SynchronizeIrql
+   KINTERRUPT_MODE InterruptMode; // Mode
 } KINTERRUPT;
+#endif
+
+typedef struct _KINTERRUPT 
+{
+    CSHORT              Type;
+    CSHORT              Size;
+    LIST_ENTRY          InterruptListEntry;
+    PKSERVICE_ROUTINE   ServiceRoutine;
+    PVOID               ServiceContext;
+    KSPIN_LOCK          SpinLock;
+    ULONG               TickCount;
+    PKSPIN_LOCK         ActualLock;
+    PVOID               DispatchAddress;
+    ULONG               Vector;
+    KIRQL               Irql;
+    KIRQL               SynchronizeIrql;
+    BOOLEAN             FloatingSave;
+    BOOLEAN             Connected;
+    CHAR                Number;
+    UCHAR               ShareVector;
+    KINTERRUPT_MODE     Mode;
+    ULONG               ServiceCount;
+    ULONG               DispatchCount;
+    ULONG               DispatchCode[106];
+} KINTERRUPT, *PKINTERRUPT;
 
 #ifndef __USE_W32API
 
index d80f7c0..7f9ebb2 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
+/* TYPES ********************************************************************/
+typedef struct _IO_INTERRUPT
+{
+    KINTERRUPT FirstInterrupt;
+    PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS];
+    KSPIN_LOCK SpinLock;
+} IO_INTERRUPT, *PIO_INTERRUPT;
+
 /* FUNCTIONS *****************************************************************/
 
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-IoConnectInterrupt(PKINTERRUPT* InterruptObject,
-                  PKSERVICE_ROUTINE ServiceRoutine,
-                  PVOID ServiceContext,
-                  PKSPIN_LOCK SpinLock,
-                  ULONG Vector,
-                  KIRQL Irql,
-                  KIRQL SynchronizeIrql,
-                  KINTERRUPT_MODE InterruptMode,
-                  BOOLEAN ShareVector,
-                  KAFFINITY ProcessorEnableMask,
-                  BOOLEAN FloatingSave)
 /*
  * FUNCTION: Registers a driver's isr to be called when its device interrupts
  * ARGUMENTS:
@@ -57,106 +50,163 @@ IoConnectInterrupt(PKINTERRUPT* InterruptObject,
  *                       the isr runs. Must be false for x86 drivers
  * RETURNS: Status
  * IRQL: PASSIVE_LEVEL
+ *
+ * @implemented
  */
+NTSTATUS 
+STDCALL
+IoConnectInterrupt(PKINTERRUPT* InterruptObject,
+                   PKSERVICE_ROUTINE ServiceRoutine,
+                   PVOID ServiceContext,
+                   PKSPIN_LOCK SpinLock,
+                   ULONG Vector,
+                   KIRQL Irql,
+                   KIRQL SynchronizeIrql,
+                   KINTERRUPT_MODE InterruptMode,
+                   BOOLEAN ShareVector,
+                   KAFFINITY ProcessorEnableMask,
+                   BOOLEAN FloatingSave)
 {
-   PKINTERRUPT Interrupt;
-   ULONG i, count;
+    PKINTERRUPT Interrupt;
+    PKINTERRUPT InterruptUsed;
+    PIO_INTERRUPT IoInterrupt;
+    PKSPIN_LOCK SpinLockUsed;
+    BOOLEAN FirstRun = TRUE;
+    ULONG i, count;
+    
+    PAGED_CODE();
 
-   ASSERT_IRQL(PASSIVE_LEVEL);
+    DPRINT1("IoConnectInterrupt(Vector %x)\n",Vector);
 
-   DPRINT("IoConnectInterrupt(Vector %x)\n",Vector);
+    /* Convert the Mask */
+    ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
 
-   ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
+    /* Make sure at least one CPU is on it */
+    if (!ProcessorEnableMask) return STATUS_INVALID_PARAMETER;
 
-   if (ProcessorEnableMask == 0)
-     {
-       return STATUS_INVALID_PARAMETER;
-     }
-
-   for (i = 0, count = 0; i < KeNumberProcessors; i++)
-     {
-       if (ProcessorEnableMask & (1 << i))
-         {
-          count++;
-        }
-     }
-   /*
-    * Initialize interrupt object
-    */
-   Interrupt=ExAllocatePoolWithTag(NonPagedPool,count*sizeof(KINTERRUPT),
-                                  TAG_KINTERRUPT);
-   if (Interrupt==NULL)
-     {
-       return(STATUS_INSUFFICIENT_RESOURCES);
-     }
-
-   if (SpinLock == NULL)
-     {
-       SpinLock = &Interrupt[0].SpinLock;
-       KeInitializeSpinLock(SpinLock);
-     }
-
-   Interrupt[0].ProcessorEnableMask = ProcessorEnableMask;
-
-   for (i = 0, count = 0; i < KeNumberProcessors; i++)
-     {
-       if (ProcessorEnableMask & (1 << i))
-         {
-           KeInitializeInterrupt(&Interrupt[count],
-                                ServiceRoutine,
-                                ServiceContext,
-                                SpinLock,
-                                Vector,
-                                Irql,
-                                SynchronizeIrql,
-                                InterruptMode,
-                                ShareVector,
-                                i,
-                                FloatingSave);
-           if (!KeConnectInterrupt(&Interrupt[count]))
-             {
-              for (i = 0; i < count; i++)
-                {
-                  if (ProcessorEnableMask & (1 << i))
-                    {
-                      KeDisconnectInterrupt(&Interrupt[i]);
-                    }
-                }
-              ExFreePool(Interrupt);
-              return STATUS_INVALID_PARAMETER;
-            }
-          count++;
-        }
-     }
-
-   *InterruptObject = Interrupt;
+    /* Determine the allocation */
+    for (i = 0, count = 0; i < KeNumberProcessors; i++)
+    {
+        if (ProcessorEnableMask & (1 << i)) count++;
+    }
+    
+    /* Allocate the array of I/O Interrupts */
+    IoInterrupt = ExAllocatePoolWithTag(NonPagedPool,
+                                        (count - 1)* sizeof(KINTERRUPT) +
+                                        sizeof(IO_INTERRUPT),
+                                        TAG_KINTERRUPT);
+    if (!Interrupt) return(STATUS_INSUFFICIENT_RESOURCES);
+
+    /* Select which Spinlock to use */
+    if (SpinLock)
+    {
+        SpinLockUsed = SpinLock;
+    }
+    else
+    {
+        SpinLockUsed = &IoInterrupt->SpinLock;
+    }
+    
+    /* We first start with a built-in Interrupt inside the I/O Structure */
+    *InterruptObject = &IoInterrupt->FirstInterrupt;
+    Interrupt = (PKINTERRUPT)(IoInterrupt + 1);
+    FirstRun = TRUE;
+    
+    /* Start with a fresh structure */
+    RtlZeroMemory(IoInterrupt, sizeof(IO_INTERRUPT));
+    
+    /* Now create all the interrupts */
+    for (i = 0; i < KeNumberProcessors; i++)
+    {
+        /* Check if it's enabled for this CPU */
+        if (ProcessorEnableMask & (1 << i))
+        {
+            /* Check which one we will use */
+            InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt;
+            
+            /* Initialize it */
+            KeInitializeInterrupt(InterruptUsed,
+                                  ServiceRoutine,
+                                  ServiceContext,
+                                  SpinLockUsed,
+                                  Vector,
+                                  Irql,
+                                  SynchronizeIrql,
+                                  InterruptMode,
+                                  ShareVector,
+                                  i,
+                                  FloatingSave);
+                                  
+            /* Connect it */
+            if (!KeConnectInterrupt(InterruptUsed))
+            {
+                /* Check how far we got */
+                if (FirstRun)
+                {
+                    /* We failed early so just free this */
+                    ExFreePool(IoInterrupt);
+                }
+                else
+                {
+                    /* Far enough, so disconnect everything */
+                    IoDisconnectInterrupt(&IoInterrupt->FirstInterrupt);
+                }
+                return STATUS_INVALID_PARAMETER;
+            }
+            
+            /* Now we've used up our First Run */
+            if (FirstRun)
+            {
+                FirstRun = FALSE;
+            }
+            else
+            {
+                /* Move on to the next one */
+                IoInterrupt->Interrupt[i] = Interrupt++;
+            }
+        }
+    }
 
-   return(STATUS_SUCCESS);
+    /* Return Success */
+    return STATUS_SUCCESS;
 }
 
-
-/*
- * @implemented
- */
-VOID STDCALL
-IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
 /*
  * FUNCTION: Releases a drivers isr
  * ARGUMENTS:
  *        InterruptObject = isr to release
+ *
+ * @implemented
  */
-{
-  ULONG i, count;
+VOID 
+STDCALL
+IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
 
-  for (i = 0, count = 0; i < KeNumberProcessors; i++)
+{
+    ULONG i;
+    PIO_INTERRUPT IoInterrupt;
+    
+    PAGED_CODE();
+    
+    /* Get the I/O Interrupt */
+    IoInterrupt = CONTAINING_RECORD(InterruptObject, 
+                                    IO_INTERRUPT, 
+                                    FirstInterrupt);
+                                    
+    /* Disconnect the first one */
+    KeDisconnectInterrupt(&IoInterrupt->FirstInterrupt);
+
+    /* Now disconnect the others */
+    for (i = 0; i < KeNumberProcessors; i++)
     {
-      if (InterruptObject[0].ProcessorEnableMask & (1 << i))
+        if (IoInterrupt->Interrupt[i])
         {
-          KeDisconnectInterrupt(&InterruptObject[count]);
-         count++;
-       }
+            KeDisconnectInterrupt(&InterruptObject[i]);
+        }
     }
-  ExFreePool(InterruptObject);
+    
+    /* Free the I/O Interrupt */
+    ExFreePool(IoInterrupt);
 }
 
 /* EOF */
index 59bbf0f..5b72804 100644 (file)
@@ -278,7 +278,7 @@ KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
 
   while (current != &CurrentIsr->ListHead)
     {
-      isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
+      isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
       oldlvl = KeAcquireInterruptSpinLock(isr);
       if (isr->ServiceRoutine(isr, isr->ServiceContext))
         {
@@ -401,7 +401,7 @@ KeDumpIrqList(VOID)
            KiAcquireSpinLock(&IsrTable[i][j].Lock);
 
            current_entry = IsrTable[i][j].ListHead.Flink;
-           current = CONTAINING_RECORD(current_entry,KINTERRUPT,Entry);
+           current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
            while (current_entry!=&(IsrTable[i][j].ListHead))
              {
                if (printed == FALSE)
@@ -411,7 +411,7 @@ KeDumpIrqList(VOID)
                  }
                DPRINT("   Isr %x\n",current);
                current_entry = current_entry->Flink;
-               current = CONTAINING_RECORD(current_entry,KINTERRUPT,Entry);
+               current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
              }
            KiReleaseSpinLock(&IsrTable[i][j].Lock);
          }
@@ -422,7 +422,8 @@ KeDumpIrqList(VOID)
 /*
  * @implemented
  */
-BOOLEAN STDCALL
+BOOLEAN 
+STDCALL
 KeConnectInterrupt(PKINTERRUPT InterruptObject)
 {
    KIRQL oldlvl,synch_oldlvl;
@@ -440,11 +441,11 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
 
    Vector -= IRQ_BASE;
 
-   ASSERT (InterruptObject->ProcessorNumber < KeNumberProcessors);
+   ASSERT (InterruptObject->Number < KeNumberProcessors);
 
-   KeSetSystemAffinityThread(1 << InterruptObject->ProcessorNumber);
+   KeSetSystemAffinityThread(1 << InterruptObject->Number);
 
-   CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->ProcessorNumber];
+   CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->Number];
 
    KeRaiseIrql(VECTOR2IRQL(Vector + IRQ_BASE),&oldlvl);
    KiAcquireSpinLock(&CurrentIsr->Lock);
@@ -454,8 +455,8 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
     */
    if (!IsListEmpty(&CurrentIsr->ListHead))
    {
-      ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,Entry);
-      if (InterruptObject->Shareable == FALSE || ListHead->Shareable==FALSE)
+      ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
+      if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
       {
          KiReleaseSpinLock(&CurrentIsr->Lock);
          KeLowerIrql(oldlvl);
@@ -468,13 +469,14 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
 
    DPRINT("%x %x\n",CurrentIsr->ListHead.Flink, CurrentIsr->ListHead.Blink);
 
-   Result = HalEnableSystemInterrupt(Vector + IRQ_BASE, InterruptObject->Irql, InterruptObject->InterruptMode);
+   Result = HalEnableSystemInterrupt(Vector + IRQ_BASE, InterruptObject->Irql, InterruptObject->Mode);
    if (Result)
    {
-      InsertTailList(&CurrentIsr->ListHead,&InterruptObject->Entry);
-      DPRINT("%x %x\n",InterruptObject->Entry.Flink, InterruptObject->Entry.Blink);
+      InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
+      DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->Entry.Blink);
    }
 
+   InterruptObject->Connected = TRUE;
    KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
 
    /*
@@ -490,78 +492,112 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
    return Result;
 }
 
-
 /*
  * @implemented
- */
-VOID STDCALL
-KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
-/*
+ *
  * FUNCTION: Releases a drivers isr
  * ARGUMENTS:
  *        InterruptObject = isr to release
  */
+BOOLEAN 
+STDCALL
+KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
 {
-   KIRQL oldlvl,synch_oldlvl;
-   PISR_TABLE CurrentIsr;
-
-   DPRINT("KeDisconnectInterrupt\n");
-
-   ASSERT (InterruptObject->ProcessorNumber < KeNumberProcessors);
+    KIRQL oldlvl,synch_oldlvl;
+    PISR_TABLE CurrentIsr;
+    BOOLEAN State;
 
-   KeSetSystemAffinityThread(1 << InterruptObject->ProcessorNumber);
+    DPRINT1("KeDisconnectInterrupt\n");
+    ASSERT (InterruptObject->Number < KeNumberProcessors);
 
-   CurrentIsr = &IsrTable[InterruptObject->Vector - IRQ_BASE][(ULONG)InterruptObject->ProcessorNumber];
+    /* Set the affinity */
+    KeSetSystemAffinityThread(1 << InterruptObject->Number);
 
-   KeRaiseIrql(VECTOR2IRQL(InterruptObject->Vector),&oldlvl);
-   KiAcquireSpinLock(&CurrentIsr->Lock);
+    /* Get the ISR Tabe */
+    CurrentIsr = &IsrTable[InterruptObject->Vector - IRQ_BASE]
+                          [(ULONG)InterruptObject->Number];
 
-   synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
+    /* Raise IRQL to required level and lock table */
+    KeRaiseIrql(VECTOR2IRQL(InterruptObject->Vector),&oldlvl);
+    KiAcquireSpinLock(&CurrentIsr->Lock);
 
-   RemoveEntryList(&InterruptObject->Entry);
-   if (IsListEmpty(&CurrentIsr->ListHead))
-   {
-      HalDisableSystemInterrupt(InterruptObject->Vector, 0);
-   }
-   KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
-
-   /*
-    * Release the table spinlock
-    */
-   KiReleaseSpinLock(&CurrentIsr->Lock);
-   KeLowerIrql(oldlvl);
+    /* Check if it's actually connected */
+    if ((State = InterruptObject->Connected))
+    {
+        /* Lock the Interrupt */
+        synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
 
-   KeRevertToUserAffinityThread();
+        /* Remove this one, and check if all are gone */
+        RemoveEntryList(&InterruptObject->InterruptListEntry);
+        if (IsListEmpty(&CurrentIsr->ListHead))
+        {
+            /* Completely Disable the Interrupt */
+            HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql);
+        }
+        
+        /* Disconnect it */
+        InterruptObject->Connected = FALSE;
+    
+        /* Release the interrupt lock */
+        KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
+    }
+    /* Release the table spinlock */
+    KiReleaseSpinLock(&CurrentIsr->Lock);
+    KeLowerIrql(oldlvl);
+
+    /* Go back to default affinity */
+    KeRevertToUserAffinityThread();
+    
+    /* Return Old Interrupt State */
+    return State;
 }
 
-
 /*
  * @implemented
  */
 VOID
 STDCALL
-KeInitializeInterrupt(PKINTERRUPT InterruptObject,
-                     PKSERVICE_ROUTINE ServiceRoutine,
-                     PVOID ServiceContext,
-                     PKSPIN_LOCK SpinLock,
-                     ULONG Vector,
-                     KIRQL Irql,
-                     KIRQL SynchronizeIrql,
-                     KINTERRUPT_MODE InterruptMode,
-                     BOOLEAN ShareVector,
-                     CHAR ProcessorNumber,
-                     BOOLEAN FloatingSave)
+KeInitializeInterrupt(PKINTERRUPT Interrupt,
+                      PKSERVICE_ROUTINE ServiceRoutine,
+                      PVOID ServiceContext,
+                      PKSPIN_LOCK SpinLock,
+                      ULONG Vector,
+                      KIRQL Irql,
+                      KIRQL SynchronizeIrql,
+                      KINTERRUPT_MODE InterruptMode,
+                      BOOLEAN ShareVector,
+                      CHAR ProcessorNumber,
+                      BOOLEAN FloatingSave)
 {
-   InterruptObject->ServiceRoutine = ServiceRoutine;
-   InterruptObject->ServiceContext = ServiceContext;
-   InterruptObject->ActualLock = SpinLock;
-   InterruptObject->Vector = Vector;
-   InterruptObject->Irql = Irql;
-   InterruptObject->SynchLevel = SynchronizeIrql;
-   InterruptObject->InterruptMode = InterruptMode;
-   InterruptObject->Shareable = ShareVector;
-   InterruptObject->ProcessorNumber = ProcessorNumber;
-   InterruptObject->FloatingSave = FloatingSave;
+    /* Set the Interrupt Header */
+    Interrupt->Type = InterruptObject;
+    Interrupt->Size = sizeof(KINTERRUPT);
+    
+    /* Check if we got a spinlock */
+    if (SpinLock)
+    {
+        Interrupt->ActualLock = SpinLock;
+    }
+    else
+    {
+        /* This means we'll be usin the built-in one */
+        KeInitializeSpinLock(&Interrupt->SpinLock);
+        Interrupt->ActualLock = &Interrupt->SpinLock;
+    }
+    
+    /* Set the other settings */
+    Interrupt->ServiceRoutine = ServiceRoutine;
+    Interrupt->ServiceContext = ServiceContext;
+    Interrupt->Vector = Vector;
+    Interrupt->Irql = Irql;
+    Interrupt->SynchronizeIrql = SynchronizeIrql;
+    Interrupt->Mode = InterruptMode;
+    Interrupt->ShareVector = ShareVector;
+    Interrupt->Number = ProcessorNumber;
+    Interrupt->FloatingSave = FloatingSave;
+    
+    /* Disconnect it at first */
+    Interrupt->Connected = FALSE;
 }
 
 VOID KePrintInterruptStatistic(VOID)
index 969d4fa..59d2492 100644 (file)
@@ -62,8 +62,7 @@ KeAcquireInterruptSpinLock(
 {
    KIRQL oldIrql;
 
-   //KeRaiseIrql(Interrupt->SynchronizeIrql, &oldIrql);
-   KeRaiseIrql(Interrupt->SynchLevel, &oldIrql);
+   KeRaiseIrql(Interrupt->SynchronizeIrql, &oldIrql);
    KiAcquireSpinLock(Interrupt->ActualLock);
    return oldIrql;
 }