ReactOS 0.4.16-dev-197-g92996da
interrupt.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for interrupt.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

void KiInterruptDispatch (void)
 
VOID NTAPI KeInitializeInterrupt (IN PKINTERRUPT Interrupt, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN CHAR ProcessorNumber, IN BOOLEAN FloatingSave)
 
BOOLEAN NTAPI KeConnectInterrupt (IN PKINTERRUPT Interrupt)
 
BOOLEAN NTAPI KeDisconnectInterrupt (IN PKINTERRUPT Interrupt)
 
BOOLEAN NTAPI KeSynchronizeExecution (IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
 

Variables

UCHAR KiInterruptDispatchTemplate [16]
 
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange [256]
 
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file interrupt.c.

Function Documentation

◆ KeConnectInterrupt()

BOOLEAN NTAPI KeConnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 81 of file interrupt.c.

82{
83 PVOID CurrentHandler;
84 PKINTERRUPT ConnectedInterrupt;
86
87 /* Validate the vector */
88 if ((Interrupt->Vector < PRIMARY_VECTOR_BASE) ||
89 (Interrupt->Vector > MAXIMUM_IDTVECTOR))
90 {
91 DPRINT1("Invalid interrupt vector: %lu\n", Interrupt->Vector);
92 return FALSE;
93 }
94
96 ASSERT(Interrupt->Irql <= HIGH_LEVEL);
97 ASSERT(Interrupt->SynchronizeIrql >= Interrupt->Irql);
98 ASSERT(Interrupt->Irql == (Interrupt->Vector >> 4));
99
100 /* Check if its already connected */
101 if (Interrupt->Connected) return TRUE;
102
103 /* Set the system affinity and acquire the dispatcher lock */
104 KeSetSystemAffinityThread(1ULL << Interrupt->Number);
106
107 /* Query the current handler */
108 CurrentHandler = KeQueryInterruptHandler(Interrupt->Vector);
109
110 /* Check if the vector is unused */
111 if ((CurrentHandler >= (PVOID)KiUnexpectedRange) &&
112 (CurrentHandler <= (PVOID)KiUnexpectedRangeEnd))
113 {
114 /* Initialize the list for chained interrupts */
115 InitializeListHead(&Interrupt->InterruptListEntry);
116
117 /* Set normal dispatch address */
118 Interrupt->DispatchAddress = KiInterruptDispatch;
119
120 /* Set the new handler */
122 Interrupt->DispatchCode);
123
124 /* Enable the interrupt */
126 Interrupt->Irql,
127 Interrupt->Mode))
128 {
129 /* Didn't work, restore old handler */
130 DPRINT1("HalEnableSystemInterrupt failed\n");
131 KeRegisterInterruptHandler(Interrupt->Vector, CurrentHandler);
132 goto Cleanup;
133 }
134 }
135 else
136 {
137 /* Get the connected interrupt */
138 ConnectedInterrupt = CONTAINING_RECORD(CurrentHandler, KINTERRUPT, DispatchCode);
139
140 /* Check if sharing is ok */
141 if ((Interrupt->ShareVector == 0) ||
142 (ConnectedInterrupt->ShareVector == 0) ||
143 (Interrupt->Mode != ConnectedInterrupt->Mode))
144 {
145 goto Cleanup;
146 }
147
148 /* Insert the new interrupt into the connected interrupt's list */
149 InsertTailList(&ConnectedInterrupt->InterruptListEntry,
150 &Interrupt->InterruptListEntry);
151 }
152
153 /* Mark as connected */
154 Interrupt->Connected = TRUE;
155
156Cleanup:
157 /* Release the dispatcher lock and restore the thread affinity */
160 return Interrupt->Connected;
161}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOLEAN NTAPI HalEnableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode)
Definition: pic.c:295
#define PRIMARY_VECTOR_BASE
Definition: halp.h:16
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ASSERT(a)
Definition: mode.c:44
#define MAXIMUM_IDTVECTOR
Definition: asm.h:280
FORCEINLINE PVOID KeQueryInterruptHandler(IN ULONG Vector)
Definition: ke.h:327
FORCEINLINE VOID KeRegisterInterruptHandler(IN ULONG Vector, IN PVOID Handler)
Definition: ke.h:301
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
void KiInterruptDispatch(void)
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd[]
KINTERRUPT_MODE Mode
Definition: ketypes.h:955
BOOLEAN ShareVector
Definition: ketypes.h:954
LIST_ENTRY InterruptListEntry
Definition: ketypes.h:937
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1107
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1021
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by IoConnectInterrupt().

◆ KeDisconnectInterrupt()

BOOLEAN NTAPI KeDisconnectInterrupt ( IN PKINTERRUPT  Interrupt)

Definition at line 165 of file interrupt.c.

166{
168 PVOID VectorHandler, UnexpectedHandler;
169 PKINTERRUPT VectorFirstInterrupt, NextInterrupt;
170 PLIST_ENTRY HandlerHead;
171
172 /* Set the system affinity and acquire the dispatcher lock */
173 KeSetSystemAffinityThread(1ULL << Interrupt->Number);
175
176 /* Check if the interrupt was connected - otherwise there's nothing to do */
177 if (Interrupt->Connected)
178 {
179 /* Get the handler for this interrupt vector */
180 VectorHandler = KeQueryInterruptHandler(Interrupt->Vector);
181
182 /* Get the first interrupt for this handler */
183 VectorFirstInterrupt = CONTAINING_RECORD(VectorHandler, KINTERRUPT, DispatchCode);
184
185 /* The first interrupt list entry is the interrupt list head */
186 HandlerHead = &VectorFirstInterrupt->InterruptListEntry;
187
188 /* If the list is empty, this is the only interrupt for this vector */
189 if (IsListEmpty(HandlerHead))
190 {
191 /* If the list is empty, and the head is not from this interrupt,
192 * this interrupt is somehow incorrectly connected */
193 ASSERT(VectorFirstInterrupt == Interrupt);
194
195 UnexpectedHandler = &KiUnexpectedRange[Interrupt->Vector]._Op_push;
196
197 /* This is the only interrupt, the handler can be disconnected */
199 KeRegisterInterruptHandler(Interrupt->Vector, UnexpectedHandler);
200 }
201 /* If the interrupt to be disconnected is the list head, but some others follow */
202 else if (VectorFirstInterrupt == Interrupt)
203 {
204 /* Relocate the head to the next element */
205 HandlerHead = HandlerHead->Flink;
206 RemoveTailList(HandlerHead);
207
208 /* Get the next interrupt from the list head */
209 NextInterrupt = CONTAINING_RECORD(HandlerHead,
211 InterruptListEntry);
212
213 /* Set the next interrupt as the handler for this vector */
215 NextInterrupt->DispatchCode);
216 }
217 /* If the interrupt to be disconnected is not the list head */
218 else
219 {
220 /* Remove the to be disconnected interrupt from the interrupt list */
221 RemoveEntryList(&Interrupt->InterruptListEntry);
222 }
223
224 /* Mark as not connected */
225 Interrupt->Connected = FALSE;
226 }
227
228 /* Release the dispatcher lock and restore the thread affinity */
231
232 return TRUE;
233}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975
VOID NTAPI HalDisableSystemInterrupt(IN ULONG Vector, IN KIRQL Irql)
Definition: pic.c:309
ULONG DispatchCode[DISPATCH_LENGTH]
Definition: ketypes.h:968
UCHAR _Op_push
Definition: ke.h:105
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by IoDisconnectInterrupt().

◆ KeInitializeInterrupt()

VOID NTAPI KeInitializeInterrupt ( IN PKINTERRUPT  Interrupt,
IN PKSERVICE_ROUTINE  ServiceRoutine,
IN PVOID  ServiceContext,
IN PKSPIN_LOCK  SpinLock,
IN ULONG  Vector,
IN KIRQL  Irql,
IN KIRQL  SynchronizeIrql,
IN KINTERRUPT_MODE  InterruptMode,
IN BOOLEAN  ShareVector,
IN CHAR  ProcessorNumber,
IN BOOLEAN  FloatingSave 
)

Definition at line 29 of file interrupt.c.

41{
42
43 /* Initialize the header */
45 Interrupt->Size = sizeof(KINTERRUPT);
46
47 /* If no Spinlock is given, use the internal */
48 if (!SpinLock) SpinLock = &Interrupt->SpinLock;
50
51 /* Set the given parameters */
52 Interrupt->ServiceRoutine = ServiceRoutine;
53 Interrupt->ServiceContext = ServiceContext;
54 Interrupt->ActualLock = SpinLock;
55 Interrupt->Vector = Vector;
56 Interrupt->Irql = Irql;
57 Interrupt->SynchronizeIrql = SynchronizeIrql;
59 Interrupt->ShareVector = ShareVector;
60 Interrupt->Number = ProcessorNumber;
61 Interrupt->FloatingSave = FloatingSave;
62
63 /* Set initial values */
64 Interrupt->TickCount = 0;
65 Interrupt->Connected = FALSE;
66 Interrupt->ServiceCount = 0;
67 Interrupt->DispatchCount = 0;
68 Interrupt->TrapFrame = NULL;
69 Interrupt->Reserved = 0;
70
71 /* Copy the dispatch code (its location independent, no need to patch it) */
72 RtlCopyMemory(Interrupt->DispatchCode,
74 sizeof(Interrupt->DispatchCode));
75
76 Interrupt->DispatchAddress = 0;
77}
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
struct _KINTERRUPT KINTERRUPT
@ InterruptObject
Definition: ketypes.h:428
UCHAR KiInterruptDispatchTemplate[16]
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:228
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:800
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL SynchronizeIrql
Definition: iofuncs.h:805
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN _In_ KAFFINITY _In_ BOOLEAN FloatingSave
Definition: iofuncs.h:809
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN ShareVector
Definition: iofuncs.h:807
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801

Referenced by IoConnectInterrupt().

◆ KeSynchronizeExecution()

BOOLEAN NTAPI KeSynchronizeExecution ( IN OUT PKINTERRUPT  Interrupt,
IN PKSYNCHRONIZE_ROUTINE  SynchronizeRoutine,
IN PVOID SynchronizeContext  OPTIONAL 
)

Definition at line 237 of file interrupt.c.

240{
243
244 /* Raise IRQL */
245 OldIrql = KfRaiseIrql(Interrupt->SynchronizeIrql);
246
247 /* Acquire interrupt spinlock */
249
250 /* Call the routine */
252
253 /* Release lock */
255
256 /* Lower IRQL */
258
259 /* Return status */
260 return Success;
261}
static KSYNCHRONIZE_ROUTINE SynchronizeRoutine
Definition: IoInterrupt.c:30
unsigned char BOOLEAN
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
@ Success
Definition: eventcreate.c:712
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:525

Referenced by _SynchronizeExecution(), FdoCallHWInitialize(), InPortRemoveDevice(), InPortStartDevice(), KspSynchronizedEventRoutine(), NdisMSynchronizeWithInterrupt(), ScsiPortAllocateAdapterChannel(), ScsiPortDpcForIsr(), ScsiPortIoTimer(), ScsiPortStartIo(), SerialDeviceControl(), SpiAdapterControl(), StreamClassStartDevice(), TestSynchronizeExecution(), and VideoPortSynchronizeExecution().

◆ KiInterruptDispatch()

void KiInterruptDispatch ( void  )

Variable Documentation

◆ KiInterruptDispatchTemplate

UCHAR KiInterruptDispatchTemplate[16]
extern

Referenced by KeInitializeInterrupt().

◆ KiUnexpectedRange

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
extern

◆ KiUnexpectedRangeEnd

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRangeEnd[]
extern

Referenced by KeConnectInterrupt().