2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/irq.c
5 * PURPOSE: IRQ handling
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 /* INCLUDES *****************************************************************/
13 #include <internal/debug.h>
15 /* GLOBALS *****************************************************************/
17 #define TAG_KINTERRUPT TAG('K', 'I', 'S', 'R')
19 /* FUNCTIONS *****************************************************************/
25 IoConnectInterrupt(PKINTERRUPT
* InterruptObject
,
26 PKSERVICE_ROUTINE ServiceRoutine
,
31 KIRQL SynchronizeIrql
,
32 KINTERRUPT_MODE InterruptMode
,
34 KAFFINITY ProcessorEnableMask
,
37 * FUNCTION: Registers a driver's isr to be called when its device interrupts
39 * InterruptObject (OUT) = Points to the interrupt object created on
41 * ServiceRoutine = Routine to be called when the device interrupts
42 * ServiceContext = Parameter to be passed to ServiceRoutine
43 * SpinLock = Initalized spinlock that will be used to synchronize
44 * access between the isr and other driver routines. This is
45 * required if the isr handles more than one vector or the
46 * driver has more than one isr
47 * Vector = Interrupt vector to allocate
48 * (returned from HalGetInterruptVector)
49 * Irql = DIRQL returned from HalGetInterruptVector
50 * SynchronizeIrql = DIRQL at which the isr will execute. This must
51 * be the highest of all the DIRQLs returned from
52 * HalGetInterruptVector if the driver has multiple
54 * InterruptMode = Specifies if the interrupt is LevelSensitive or
56 * ShareVector = Specifies if the vector can be shared
57 * ProcessorEnableMask = Processors on the isr can run
58 * FloatingSave = TRUE if the floating point stack should be saved when
59 * the isr runs. Must be false for x86 drivers
64 PKINTERRUPT Interrupt
;
67 ASSERT_IRQL(PASSIVE_LEVEL
);
69 DPRINT("IoConnectInterrupt(Vector %x)\n",Vector
);
71 ProcessorEnableMask
&= ((1 << KeNumberProcessors
) - 1);
73 if (ProcessorEnableMask
== 0)
75 return STATUS_INVALID_PARAMETER
;
78 for (i
= 0, count
= 0; i
< KeNumberProcessors
; i
++)
80 if (ProcessorEnableMask
& (1 << i
))
86 * Initialize interrupt object
88 Interrupt
=ExAllocatePoolWithTag(NonPagedPool
,count
*sizeof(KINTERRUPT
),
92 return(STATUS_INSUFFICIENT_RESOURCES
);
97 SpinLock
= &Interrupt
[0].SpinLock
;
98 KeInitializeSpinLock(SpinLock
);
101 Interrupt
[0].ProcessorEnableMask
= ProcessorEnableMask
;
103 for (i
= 0, count
= 0; i
< KeNumberProcessors
; i
++)
105 if (ProcessorEnableMask
& (1 << i
))
107 KeInitializeInterrupt(&Interrupt
[count
],
118 if (!KeConnectInterrupt(&Interrupt
[count
]))
120 for (i
= 0; i
< count
; i
++)
122 KeDisconnectInterrupt(&Interrupt
[i
]);
124 ExFreePool(Interrupt
);
125 return STATUS_INVALID_PARAMETER
;
131 *InterruptObject
= Interrupt
;
133 return(STATUS_SUCCESS
);
141 IoDisconnectInterrupt(PKINTERRUPT InterruptObject
)
143 * FUNCTION: Releases a drivers isr
145 * InterruptObject = isr to release
150 for (i
= 0, count
= 0; i
< KeNumberProcessors
; i
++)
152 if (InterruptObject
[0].ProcessorEnableMask
& (1 << i
))
154 KeDisconnectInterrupt(&InterruptObject
[count
]);
158 ExFreePool(InterruptObject
);