ReactOS  0.4.13-dev-242-g611e6d7
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 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 /*
18  * @implemented
19  */
21 NTAPI
26  IN ULONG Vector,
27  IN KIRQL Irql,
33 {
34  PKINTERRUPT Interrupt;
35  PKINTERRUPT InterruptUsed;
36  PIO_INTERRUPT IoInterrupt;
37  PKSPIN_LOCK SpinLockUsed;
38  BOOLEAN FirstRun;
39  CCHAR Count = 0;
41  PAGED_CODE();
42 
43  /* Assume failure */
45 
46  /* Get the affinity */
48  while (Affinity)
49  {
50  /* Increase count */
51  if (Affinity & 1) Count++;
52  Affinity >>= 1;
53  }
54 
55  /* Make sure we have a valid CPU count */
56  if (!Count) return STATUS_INVALID_PARAMETER;
57 
58  /* Allocate the array of I/O Interrupts */
59  IoInterrupt = ExAllocatePoolWithTag(NonPagedPool,
60  (Count - 1) * sizeof(KINTERRUPT) +
61  sizeof(IO_INTERRUPT),
63  if (!IoInterrupt) return STATUS_INSUFFICIENT_RESOURCES;
64 
65  /* Select which Spinlock to use */
66  SpinLockUsed = SpinLock ? SpinLock : &IoInterrupt->SpinLock;
67 
68  /* We first start with a built-in Interrupt inside the I/O Structure */
69  *InterruptObject = &IoInterrupt->FirstInterrupt;
70  Interrupt = (PKINTERRUPT)(IoInterrupt + 1);
71  FirstRun = TRUE;
72 
73  /* Start with a fresh structure */
74  RtlZeroMemory(IoInterrupt, sizeof(IO_INTERRUPT));
75 
76  /* Now create all the interrupts */
78  for (Count = 0; Affinity; Count++, Affinity >>= 1)
79  {
80  /* Check if it's enabled for this CPU */
81  if (Affinity & 1)
82  {
83  /* Check which one we will use */
84  InterruptUsed = FirstRun ? &IoInterrupt->FirstInterrupt : Interrupt;
85 
86  /* Initialize it */
87  KeInitializeInterrupt(InterruptUsed,
90  SpinLockUsed,
91  Vector,
92  Irql,
96  Count,
97  FloatingSave);
98 
99  /* Connect it */
100  if (!KeConnectInterrupt(InterruptUsed))
101  {
102  /* Check how far we got */
103  if (FirstRun)
104  {
105  /* We failed early so just free this */
106  ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT);
107  }
108  else
109  {
110  /* Far enough, so disconnect everything */
111  IoDisconnectInterrupt(&IoInterrupt->FirstInterrupt);
112  }
113 
114  /* And fail */
116  }
117 
118  /* Now we've used up our First Run */
119  if (FirstRun)
120  {
121  FirstRun = FALSE;
122  }
123  else
124  {
125  /* Move on to the next one */
126  IoInterrupt->Interrupt[(UCHAR)Count] = Interrupt++;
127  }
128  }
129  }
130 
131  /* Return Success */
132  return STATUS_SUCCESS;
133 }
134 
135 /*
136  * @implemented
137  */
138 VOID
139 NTAPI
141 {
142  LONG i;
143  PIO_INTERRUPT IoInterrupt;
144  PAGED_CODE();
145 
146  /* Get the I/O Interrupt */
147  IoInterrupt = CONTAINING_RECORD(InterruptObject,
148  IO_INTERRUPT,
149  FirstInterrupt);
150 
151  /* Disconnect the first one */
152  KeDisconnectInterrupt(&IoInterrupt->FirstInterrupt);
153 
154  /* Now disconnect the others */
155  for (i = 0; i < KeNumberProcessors; i++)
156  {
157  /* Make sure one was registered */
158  if (IoInterrupt->Interrupt[i])
159  {
160  /* Disconnect it */
162  }
163  }
164 
165  /* Free the I/O Interrupt */
166  ExFreePool(IoInterrupt); // ExFreePoolWithTag(IoInterrupt, TAG_KINTERRUPT);
167 }
168 
169 /* EOF */
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
KINTERRUPT FirstInterrupt
Definition: io.h:319
_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:798
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
KSPIN_LOCK * PKSPIN_LOCK
Definition: env_spec_w32.h:73
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
_Out_ PKIRQL Irql
Definition: csq.h:179
#define PAGED_CODE()
Definition: video.h:57
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:500
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK SpinLock
Definition: iofuncs.h:798
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
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:22
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL SynchronizeIrql
Definition: iofuncs.h:798
_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:798
struct _KINTERRUPT * PKINTERRUPT
Definition: nt_native.h:32
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
char CCHAR
Definition: typedefs.h:50
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
BOOLEAN NTAPI KeConnectInterrupt(IN PKINTERRUPT Interrupt)
Definition: interrupt.c:81
KSPIN_LOCK SpinLock
Definition: io.h:321
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TAG_KINTERRUPT
Definition: tag.h:83
_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:798
BOOLEAN NTAPI KeDisconnectInterrupt(IN PKINTERRUPT Interrupt)
Definition: interrupt.c:133
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
ULONG_PTR KAFFINITY
Definition: compat.h:75
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS]
Definition: io.h:320
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:798