strip whitespace from end of lines
[reactos.git] / reactos / ntoskrnl / io / irq.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/irq.c
6 * PURPOSE: IRQ handling
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS *****************************************************************/
18
19 #define TAG_KINTERRUPT TAG('K', 'I', 'S', 'R')
20
21 /* FUNCTIONS *****************************************************************/
22
23 /*
24 * @implemented
25 */
26 NTSTATUS STDCALL
27 IoConnectInterrupt(PKINTERRUPT* InterruptObject,
28 PKSERVICE_ROUTINE ServiceRoutine,
29 PVOID ServiceContext,
30 PKSPIN_LOCK SpinLock,
31 ULONG Vector,
32 KIRQL Irql,
33 KIRQL SynchronizeIrql,
34 KINTERRUPT_MODE InterruptMode,
35 BOOLEAN ShareVector,
36 KAFFINITY ProcessorEnableMask,
37 BOOLEAN FloatingSave)
38 /*
39 * FUNCTION: Registers a driver's isr to be called when its device interrupts
40 * ARGUMENTS:
41 * InterruptObject (OUT) = Points to the interrupt object created on
42 * return
43 * ServiceRoutine = Routine to be called when the device interrupts
44 * ServiceContext = Parameter to be passed to ServiceRoutine
45 * SpinLock = Initalized spinlock that will be used to synchronize
46 * access between the isr and other driver routines. This is
47 * required if the isr handles more than one vector or the
48 * driver has more than one isr
49 * Vector = Interrupt vector to allocate
50 * (returned from HalGetInterruptVector)
51 * Irql = DIRQL returned from HalGetInterruptVector
52 * SynchronizeIrql = DIRQL at which the isr will execute. This must
53 * be the highest of all the DIRQLs returned from
54 * HalGetInterruptVector if the driver has multiple
55 * isrs
56 * InterruptMode = Specifies if the interrupt is LevelSensitive or
57 * Latched
58 * ShareVector = Specifies if the vector can be shared
59 * ProcessorEnableMask = Processors on the isr can run
60 * FloatingSave = TRUE if the floating point stack should be saved when
61 * the isr runs. Must be false for x86 drivers
62 * RETURNS: Status
63 * IRQL: PASSIVE_LEVEL
64 */
65 {
66 PKINTERRUPT Interrupt;
67 ULONG i, count;
68
69 ASSERT_IRQL(PASSIVE_LEVEL);
70
71 DPRINT("IoConnectInterrupt(Vector %x)\n",Vector);
72
73 ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
74
75 if (ProcessorEnableMask == 0)
76 {
77 return STATUS_INVALID_PARAMETER;
78 }
79
80 for (i = 0, count = 0; i < KeNumberProcessors; i++)
81 {
82 if (ProcessorEnableMask & (1 << i))
83 {
84 count++;
85 }
86 }
87 /*
88 * Initialize interrupt object
89 */
90 Interrupt=ExAllocatePoolWithTag(NonPagedPool,count*sizeof(KINTERRUPT),
91 TAG_KINTERRUPT);
92 if (Interrupt==NULL)
93 {
94 return(STATUS_INSUFFICIENT_RESOURCES);
95 }
96
97 if (SpinLock == NULL)
98 {
99 SpinLock = &Interrupt[0].SpinLock;
100 KeInitializeSpinLock(SpinLock);
101 }
102
103 Interrupt[0].ProcessorEnableMask = ProcessorEnableMask;
104
105 for (i = 0, count = 0; i < KeNumberProcessors; i++)
106 {
107 if (ProcessorEnableMask & (1 << i))
108 {
109 KeInitializeInterrupt(&Interrupt[count],
110 ServiceRoutine,
111 ServiceContext,
112 SpinLock,
113 Vector,
114 Irql,
115 SynchronizeIrql,
116 InterruptMode,
117 ShareVector,
118 i,
119 FloatingSave);
120 if (!KeConnectInterrupt(&Interrupt[count]))
121 {
122 for (i = 0; i < count; i++)
123 {
124 if (ProcessorEnableMask & (1 << i))
125 {
126 KeDisconnectInterrupt(&Interrupt[i]);
127 }
128 }
129 ExFreePool(Interrupt);
130 return STATUS_INVALID_PARAMETER;
131 }
132 count++;
133 }
134 }
135
136 *InterruptObject = Interrupt;
137
138 return(STATUS_SUCCESS);
139 }
140
141
142 /*
143 * @implemented
144 */
145 VOID STDCALL
146 IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
147 /*
148 * FUNCTION: Releases a drivers isr
149 * ARGUMENTS:
150 * InterruptObject = isr to release
151 */
152 {
153 ULONG i, count;
154
155 for (i = 0, count = 0; i < KeNumberProcessors; i++)
156 {
157 if (InterruptObject[0].ProcessorEnableMask & (1 << i))
158 {
159 KeDisconnectInterrupt(&InterruptObject[count]);
160 count++;
161 }
162 }
163 ExFreePool(InterruptObject);
164 }
165
166 /* EOF */