mirror of
https://github.com/reactos/reactos.git
synced 2025-07-05 12:01:22 +00:00
Fix definition of KINTERRUPT in ROS headers so that moving to NDK will be easier. Also fix KeDisconnectInterrupt to return the old state instead of VOID, and re-write the I/O Interrupt code to work with an array and first object for better speed
svn path=/trunk/; revision=16229
This commit is contained in:
parent
9925309a13
commit
d1258e99fa
5 changed files with 293 additions and 182 deletions
|
@ -62,7 +62,7 @@ BOOLEAN STDCALL
|
||||||
KeConnectInterrupt(
|
KeConnectInterrupt(
|
||||||
PKINTERRUPT InterruptObject);
|
PKINTERRUPT InterruptObject);
|
||||||
|
|
||||||
VOID STDCALL
|
BOOLEAN STDCALL
|
||||||
KeDisconnectInterrupt(
|
KeDisconnectInterrupt(
|
||||||
PKINTERRUPT InterruptObject);
|
PKINTERRUPT InterruptObject);
|
||||||
|
|
||||||
|
|
|
@ -1781,22 +1781,48 @@ typedef struct _LPC_PORT_BASIC_INFORMATION
|
||||||
} LPC_PORT_BASIC_INFORMATION, * PLPC_PORT_BASIC_INFORMATION;
|
} LPC_PORT_BASIC_INFORMATION, * PLPC_PORT_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct _KINTERRUPT
|
typedef struct _KINTERRUPT
|
||||||
{
|
{
|
||||||
ULONG Vector;
|
ULONG Vector; // Idem
|
||||||
KAFFINITY ProcessorEnableMask;
|
KAFFINITY ProcessorEnableMask; // not needed
|
||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock; // Idem
|
||||||
PKSPIN_LOCK ActualLock;
|
PKSPIN_LOCK ActualLock; // Idem
|
||||||
BOOLEAN Shareable;
|
BOOLEAN Shareable; // ShareVector
|
||||||
BOOLEAN FloatingSave;
|
BOOLEAN FloatingSave; // Idem
|
||||||
CHAR ProcessorNumber;
|
CHAR ProcessorNumber; // Number
|
||||||
PKSERVICE_ROUTINE ServiceRoutine;
|
PKSERVICE_ROUTINE ServiceRoutine; // Idem
|
||||||
PVOID ServiceContext;
|
PVOID ServiceContext; // Idem
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry; // InteruptListEntry
|
||||||
KIRQL Irql;
|
KIRQL Irql; // Irql
|
||||||
KIRQL SynchLevel;
|
KIRQL SynchLevel; // SynchronizeIrql
|
||||||
KINTERRUPT_MODE InterruptMode;
|
KINTERRUPT_MODE InterruptMode; // Mode
|
||||||
} KINTERRUPT;
|
} 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
|
#ifndef __USE_W32API
|
||||||
|
|
||||||
|
|
|
@ -14,23 +14,16 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* TYPES ********************************************************************/
|
||||||
|
typedef struct _IO_INTERRUPT
|
||||||
|
{
|
||||||
|
KINTERRUPT FirstInterrupt;
|
||||||
|
PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS];
|
||||||
|
KSPIN_LOCK SpinLock;
|
||||||
|
} IO_INTERRUPT, *PIO_INTERRUPT;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
* FUNCTION: Registers a driver's isr to be called when its device interrupts
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -57,106 +50,163 @@ IoConnectInterrupt(PKINTERRUPT* InterruptObject,
|
||||||
* the isr runs. Must be false for x86 drivers
|
* the isr runs. Must be false for x86 drivers
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
* IRQL: PASSIVE_LEVEL
|
* IRQL: PASSIVE_LEVEL
|
||||||
*/
|
*
|
||||||
{
|
|
||||||
PKINTERRUPT Interrupt;
|
|
||||||
ULONG i, count;
|
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
|
||||||
|
|
||||||
DPRINT("IoConnectInterrupt(Vector %x)\n",Vector);
|
|
||||||
|
|
||||||
ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID STDCALL
|
NTSTATUS
|
||||||
IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
|
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;
|
||||||
|
PKINTERRUPT InterruptUsed;
|
||||||
|
PIO_INTERRUPT IoInterrupt;
|
||||||
|
PKSPIN_LOCK SpinLockUsed;
|
||||||
|
BOOLEAN FirstRun = TRUE;
|
||||||
|
ULONG i, count;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT1("IoConnectInterrupt(Vector %x)\n",Vector);
|
||||||
|
|
||||||
|
/* Convert the Mask */
|
||||||
|
ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
|
||||||
|
|
||||||
|
/* Make sure at least one CPU is on it */
|
||||||
|
if (!ProcessorEnableMask) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* 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 Success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Releases a drivers isr
|
* FUNCTION: Releases a drivers isr
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* InterruptObject = isr to release
|
* InterruptObject = isr to release
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
*/
|
*/
|
||||||
{
|
VOID
|
||||||
ULONG i, count;
|
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]);
|
KeDisconnectInterrupt(&InterruptObject[i]);
|
||||||
count++;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ExFreePool(InterruptObject);
|
|
||||||
|
/* Free the I/O Interrupt */
|
||||||
|
ExFreePool(IoInterrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -278,7 +278,7 @@ KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
|
||||||
|
|
||||||
while (current != &CurrentIsr->ListHead)
|
while (current != &CurrentIsr->ListHead)
|
||||||
{
|
{
|
||||||
isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
|
isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
|
||||||
oldlvl = KeAcquireInterruptSpinLock(isr);
|
oldlvl = KeAcquireInterruptSpinLock(isr);
|
||||||
if (isr->ServiceRoutine(isr, isr->ServiceContext))
|
if (isr->ServiceRoutine(isr, isr->ServiceContext))
|
||||||
{
|
{
|
||||||
|
@ -401,7 +401,7 @@ KeDumpIrqList(VOID)
|
||||||
KiAcquireSpinLock(&IsrTable[i][j].Lock);
|
KiAcquireSpinLock(&IsrTable[i][j].Lock);
|
||||||
|
|
||||||
current_entry = IsrTable[i][j].ListHead.Flink;
|
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))
|
while (current_entry!=&(IsrTable[i][j].ListHead))
|
||||||
{
|
{
|
||||||
if (printed == FALSE)
|
if (printed == FALSE)
|
||||||
|
@ -411,7 +411,7 @@ KeDumpIrqList(VOID)
|
||||||
}
|
}
|
||||||
DPRINT(" Isr %x\n",current);
|
DPRINT(" Isr %x\n",current);
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
current = CONTAINING_RECORD(current_entry,KINTERRUPT,Entry);
|
current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
|
||||||
}
|
}
|
||||||
KiReleaseSpinLock(&IsrTable[i][j].Lock);
|
KiReleaseSpinLock(&IsrTable[i][j].Lock);
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,8 @@ KeDumpIrqList(VOID)
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOLEAN STDCALL
|
BOOLEAN
|
||||||
|
STDCALL
|
||||||
KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl,synch_oldlvl;
|
KIRQL oldlvl,synch_oldlvl;
|
||||||
|
@ -440,11 +441,11 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
|
|
||||||
Vector -= IRQ_BASE;
|
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);
|
KeRaiseIrql(VECTOR2IRQL(Vector + IRQ_BASE),&oldlvl);
|
||||||
KiAcquireSpinLock(&CurrentIsr->Lock);
|
KiAcquireSpinLock(&CurrentIsr->Lock);
|
||||||
|
@ -454,8 +455,8 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
*/
|
*/
|
||||||
if (!IsListEmpty(&CurrentIsr->ListHead))
|
if (!IsListEmpty(&CurrentIsr->ListHead))
|
||||||
{
|
{
|
||||||
ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,Entry);
|
ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
|
||||||
if (InterruptObject->Shareable == FALSE || ListHead->Shareable==FALSE)
|
if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
|
||||||
{
|
{
|
||||||
KiReleaseSpinLock(&CurrentIsr->Lock);
|
KiReleaseSpinLock(&CurrentIsr->Lock);
|
||||||
KeLowerIrql(oldlvl);
|
KeLowerIrql(oldlvl);
|
||||||
|
@ -468,13 +469,14 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
|
|
||||||
DPRINT("%x %x\n",CurrentIsr->ListHead.Flink, CurrentIsr->ListHead.Blink);
|
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)
|
if (Result)
|
||||||
{
|
{
|
||||||
InsertTailList(&CurrentIsr->ListHead,&InterruptObject->Entry);
|
InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
|
||||||
DPRINT("%x %x\n",InterruptObject->Entry.Flink, InterruptObject->Entry.Blink);
|
DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->Entry.Blink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InterruptObject->Connected = TRUE;
|
||||||
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
|
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -490,78 +492,112 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*
|
||||||
VOID STDCALL
|
|
||||||
KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Releases a drivers isr
|
* FUNCTION: Releases a drivers isr
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* InterruptObject = isr to release
|
* InterruptObject = isr to release
|
||||||
*/
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
STDCALL
|
||||||
|
KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl,synch_oldlvl;
|
KIRQL oldlvl,synch_oldlvl;
|
||||||
PISR_TABLE CurrentIsr;
|
PISR_TABLE CurrentIsr;
|
||||||
|
BOOLEAN State;
|
||||||
|
|
||||||
DPRINT("KeDisconnectInterrupt\n");
|
DPRINT1("KeDisconnectInterrupt\n");
|
||||||
|
ASSERT (InterruptObject->Number < KeNumberProcessors);
|
||||||
|
|
||||||
ASSERT (InterruptObject->ProcessorNumber < KeNumberProcessors);
|
/* Set the affinity */
|
||||||
|
KeSetSystemAffinityThread(1 << InterruptObject->Number);
|
||||||
|
|
||||||
KeSetSystemAffinityThread(1 << InterruptObject->ProcessorNumber);
|
/* Get the ISR Tabe */
|
||||||
|
CurrentIsr = &IsrTable[InterruptObject->Vector - IRQ_BASE]
|
||||||
|
[(ULONG)InterruptObject->Number];
|
||||||
|
|
||||||
CurrentIsr = &IsrTable[InterruptObject->Vector - IRQ_BASE][(ULONG)InterruptObject->ProcessorNumber];
|
/* Raise IRQL to required level and lock table */
|
||||||
|
KeRaiseIrql(VECTOR2IRQL(InterruptObject->Vector),&oldlvl);
|
||||||
|
KiAcquireSpinLock(&CurrentIsr->Lock);
|
||||||
|
|
||||||
KeRaiseIrql(VECTOR2IRQL(InterruptObject->Vector),&oldlvl);
|
/* Check if it's actually connected */
|
||||||
KiAcquireSpinLock(&CurrentIsr->Lock);
|
if ((State = InterruptObject->Connected))
|
||||||
|
{
|
||||||
|
/* Lock the Interrupt */
|
||||||
|
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
|
||||||
|
|
||||||
synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
|
/* 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);
|
||||||
|
|
||||||
RemoveEntryList(&InterruptObject->Entry);
|
/* Go back to default affinity */
|
||||||
if (IsListEmpty(&CurrentIsr->ListHead))
|
KeRevertToUserAffinityThread();
|
||||||
{
|
|
||||||
HalDisableSystemInterrupt(InterruptObject->Vector, 0);
|
/* Return Old Interrupt State */
|
||||||
}
|
return State;
|
||||||
KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Release the table spinlock
|
|
||||||
*/
|
|
||||||
KiReleaseSpinLock(&CurrentIsr->Lock);
|
|
||||||
KeLowerIrql(oldlvl);
|
|
||||||
|
|
||||||
KeRevertToUserAffinityThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
KeInitializeInterrupt(PKINTERRUPT InterruptObject,
|
KeInitializeInterrupt(PKINTERRUPT Interrupt,
|
||||||
PKSERVICE_ROUTINE ServiceRoutine,
|
PKSERVICE_ROUTINE ServiceRoutine,
|
||||||
PVOID ServiceContext,
|
PVOID ServiceContext,
|
||||||
PKSPIN_LOCK SpinLock,
|
PKSPIN_LOCK SpinLock,
|
||||||
ULONG Vector,
|
ULONG Vector,
|
||||||
KIRQL Irql,
|
KIRQL Irql,
|
||||||
KIRQL SynchronizeIrql,
|
KIRQL SynchronizeIrql,
|
||||||
KINTERRUPT_MODE InterruptMode,
|
KINTERRUPT_MODE InterruptMode,
|
||||||
BOOLEAN ShareVector,
|
BOOLEAN ShareVector,
|
||||||
CHAR ProcessorNumber,
|
CHAR ProcessorNumber,
|
||||||
BOOLEAN FloatingSave)
|
BOOLEAN FloatingSave)
|
||||||
{
|
{
|
||||||
InterruptObject->ServiceRoutine = ServiceRoutine;
|
/* Set the Interrupt Header */
|
||||||
InterruptObject->ServiceContext = ServiceContext;
|
Interrupt->Type = InterruptObject;
|
||||||
InterruptObject->ActualLock = SpinLock;
|
Interrupt->Size = sizeof(KINTERRUPT);
|
||||||
InterruptObject->Vector = Vector;
|
|
||||||
InterruptObject->Irql = Irql;
|
/* Check if we got a spinlock */
|
||||||
InterruptObject->SynchLevel = SynchronizeIrql;
|
if (SpinLock)
|
||||||
InterruptObject->InterruptMode = InterruptMode;
|
{
|
||||||
InterruptObject->Shareable = ShareVector;
|
Interrupt->ActualLock = SpinLock;
|
||||||
InterruptObject->ProcessorNumber = ProcessorNumber;
|
}
|
||||||
InterruptObject->FloatingSave = FloatingSave;
|
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)
|
VOID KePrintInterruptStatistic(VOID)
|
||||||
|
|
|
@ -62,8 +62,7 @@ KeAcquireInterruptSpinLock(
|
||||||
{
|
{
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
//KeRaiseIrql(Interrupt->SynchronizeIrql, &oldIrql);
|
KeRaiseIrql(Interrupt->SynchronizeIrql, &oldIrql);
|
||||||
KeRaiseIrql(Interrupt->SynchLevel, &oldIrql);
|
|
||||||
KiAcquireSpinLock(Interrupt->ActualLock);
|
KiAcquireSpinLock(Interrupt->ActualLock);
|
||||||
return oldIrql;
|
return oldIrql;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue