ReactOS 0.4.15-dev-8135-g1bc6c90
irq.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/iomgr/irq.c
5 * PURPOSE: I/O Wrappers (called Completion Ports) for Kernel Queues
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS *****************************************************************/
17
18/*
19 * @implemented
20 */
34{
36 PKINTERRUPT InterruptUsed;
37 PIO_INTERRUPT IoInterrupt;
38 BOOLEAN FirstRun;
39 CCHAR Count = 0;
41
42 PAGED_CODE();
43
44 /* Assume failure */
46
47 /* Get the affinity */
49 while (Affinity)
50 {
51 /* Increase count */
52 if (Affinity & 1) Count++;
53 Affinity >>= 1;
54 }
55
56 /* Make sure we have a valid CPU count */
58
59 /* Allocate the array of I/O interrupts */
60 IoInterrupt = ExAllocatePoolZero(NonPagedPool,
61 (Count - 1) * sizeof(KINTERRUPT) +
62 sizeof(IO_INTERRUPT),
64 if (!IoInterrupt) return STATUS_INSUFFICIENT_RESOURCES;
65
66 /* Use the structure's spinlock, if none was provided */
67 if (!SpinLock)
68 {
69 SpinLock = &IoInterrupt->SpinLock;
71 }
72
73 /* We first start with a built-in interrupt inside the I/O structure */
74 Interrupt = (PKINTERRUPT)(IoInterrupt + 1);
75 FirstRun = TRUE;
76
77 /* Now create all the interrupts */
79 for (Count = 0; Affinity; Count++, Affinity >>= 1)
80 {
81 /* Check if it's enabled for this CPU */
82 if (!(Affinity & 1))
83 continue;
84
85 /* Check which one we will use */
86 InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt;
87
88 /* Initialize it */
89 KeInitializeInterrupt(InterruptUsed,
93 Vector,
94 Irql,
98 Count,
100
101 /* Connect it */
102 if (!KeConnectInterrupt(InterruptUsed))
103 {
104 /* Check how far we got */
105 if (FirstRun)
106 {
107 /* We failed early so just free this */
108 ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT);
109 }
110 else
111 {
112 /* Far enough, so disconnect everything */
114 }
115
116 /* And fail */
118 }
119
120 /* Now we've used up our First Run */
121 if (FirstRun)
122 {
123 FirstRun = FALSE;
124 }
125 else
126 {
127 /* Move on to the next one */
128 IoInterrupt->Interrupt[(UCHAR)Count] = Interrupt++;
129 }
130 }
131
132 /* Return success */
133 *InterruptObject = &IoInterrupt->FirstInterrupt;
134 return STATUS_SUCCESS;
135}
136
137/*
138 * @implemented
139 */
140VOID
141NTAPI
143{
144 PIO_INTERRUPT IoInterrupt;
145 ULONG i;
146
147 PAGED_CODE();
148
149 /* Get the I/O interrupt */
152 FirstInterrupt);
153
154 /* Disconnect the first one */
156
157 /* Now disconnect the others */
158 for (i = 0; i < KeNumberProcessors; i++)
159 {
160 /* Make sure one was registered */
161 if (!IoInterrupt->Interrupt[i])
162 continue;
163
164 /* Disconnect it */
165 KeDisconnectInterrupt(IoInterrupt->Interrupt[i]);
166 }
167
168 /* Free the I/O interrupt */
169 ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT);
170}
171
175{
177
178 PAGED_CODE();
179
180 /* Fallback to standard IoConnectInterrupt */
181 Status = IoConnectInterrupt(Parameters->FullySpecified.InterruptObject,
182 Parameters->FullySpecified.ServiceRoutine,
183 Parameters->FullySpecified.ServiceContext,
184 Parameters->FullySpecified.SpinLock,
185 Parameters->FullySpecified.Vector,
186 Parameters->FullySpecified.Irql,
187 Parameters->FullySpecified.SynchronizeIrql,
188 Parameters->FullySpecified.InterruptMode,
189 Parameters->FullySpecified.ShareVector,
190 Parameters->FullySpecified.ProcessorEnableMask,
191 Parameters->FullySpecified.FloatingSave);
192 DPRINT("IopConnectInterruptEx_FullySpecific: has failed with status %X", Status);
193 return Status;
194}
195
197NTAPI
200{
201 PAGED_CODE();
202
203 switch (Parameters->Version)
204 {
208 //TODO: We don't do anything for the group type
211 DPRINT1("FIXME: Message based interrupts are UNIMPLEMENTED\n");
212 break;
214 DPRINT1("FIXME: Line based interrupts are UNIMPLEMENTED\n");
215 break;
216 }
217
218 return STATUS_SUCCESS;
219}
220
221VOID
222NTAPI
225{
226 PAGED_CODE();
227
228 //FIXME: This eventually will need to handle more cases
229 if (Parameters->ConnectionContext.InterruptObject)
230 IoDisconnectInterrupt(Parameters->ConnectionContext.InterruptObject);
231}
232
233/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK * PKSPIN_LOCK
Definition: env_spec_w32.h:73
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
@ InterruptObject
Definition: ketypes.h:428
int Count
Definition: noreturn.cpp:7
struct _KINTERRUPT * PKINTERRUPT
Definition: nt_native.h:32
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:142
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, 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 KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:23
NTSTATUS NTAPI IoConnectInterruptEx(_Inout_ PIO_CONNECT_INTERRUPT_PARAMETERS Parameters)
Definition: irq.c:198
VOID NTAPI IoDisconnectInterruptEx(_In_ PIO_DISCONNECT_INTERRUPT_PARAMETERS Parameters)
Definition: irq.c:223
NTSTATUS IopConnectInterruptExFullySpecific(_Inout_ PIO_CONNECT_INTERRUPT_PARAMETERS Parameters)
Definition: irq.c:173
BOOLEAN NTAPI KeDisconnectInterrupt(IN PKINTERRUPT Interrupt)
Definition: interrupt.c:165
BOOLEAN NTAPI KeConnectInterrupt(IN PKINTERRUPT Interrupt)
Definition: interrupt.c:81
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: interrupt.c:29
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
KSPIN_LOCK SpinLock
Definition: io.h:325
PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS]
Definition: io.h:324
KINTERRUPT FirstInterrupt
Definition: io.h:323
#define TAG_KINTERRUPT
Definition: tag.h:88
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:228
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN _In_ KAFFINITY ProcessorEnableMask
Definition: iofuncs.h:808
_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
#define CONNECT_FULLY_SPECIFIED_GROUP
#define CONNECT_LINE_BASED
#define CONNECT_FULLY_SPECIFIED
#define CONNECT_MESSAGE_BASED
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:512
unsigned char UCHAR
Definition: xmlstorage.h:181