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