fixes and changes to support IDE driver
[reactos.git] / reactos / ntoskrnl / ke / dpc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/dpc.c
5 * PURPOSE: Handle DPCs (Delayed Procedure Calls)
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * 28/05/98: Created
9 */
10
11 /*
12 * NOTE: See also the higher level support routines in ntoskrnl/io/dpc.c
13 */
14
15 /* INCLUDES ***************************************************************/
16
17 #include <ddk/ntddk.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22 /* TYPES *******************************************************************/
23
24 /* GLOBALS ******************************************************************/
25
26 static LIST_ENTRY DpcQueueHead={NULL,NULL};
27 static KSPIN_LOCK DpcQueueLock={0,};
28
29 /* FUNCTIONS ****************************************************************/
30
31 VOID KeInitializeDpc(PKDPC Dpc, PKDEFERRED_ROUTINE DeferredRoutine,
32 PVOID DeferredContext)
33 /*
34 * FUNCTION: Initalizes a DPC
35 * ARGUMENTS:
36 * Dpc = Caller supplied DPC to be initialized
37 * DeferredRoutine = Associated DPC callback
38 * DeferredContext = Parameter to be passed to the callback
39 * NOTE: Callers must be running at IRQL PASSIVE_LEVEL
40 */
41 {
42 Dpc->Type=0;
43 Dpc->DeferredRoutine=DeferredRoutine;
44 Dpc->DeferredContext=DeferredContext;
45 Dpc->Lock=0;
46 }
47
48 void KeDrainDpcQueue(void)
49 /*
50 * FUNCTION: Called to execute queued dpcs
51 */
52 {
53 PLIST_ENTRY current_entry;
54 PKDPC current;
55
56
57 KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
58 current_entry = RemoveHeadList(&DpcQueueHead);
59 current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
60 while (current_entry!=(&DpcQueueHead))
61 {
62 CHECKPOINT;
63 current->DeferredRoutine(current,current->DeferredContext,
64 current->SystemArgument1,
65 current->SystemArgument2);
66 current->Lock=FALSE;
67 current_entry = RemoveHeadList(&DpcQueueHead);
68 current = CONTAINING_RECORD(&current_entry,KDPC,DpcListEntry);
69 }
70 KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
71 // DPRINT("Finished KeDrainDpcQueue()\n",0);
72 }
73
74 BOOLEAN KeRemoveQueueDpc(PKDPC Dpc)
75 /*
76 * FUNCTION: Removes DPC object from the system dpc queue
77 * ARGUMENTS:
78 * Dpc = DPC to remove
79 * RETURNS: TRUE if the DPC was in the queue
80 * FALSE otherwise
81 */
82 {
83 if (!Dpc->Lock)
84 {
85 return(FALSE);
86 }
87 RemoveEntryList(&Dpc->DpcListEntry);
88 Dpc->Lock=0;
89 return(TRUE);
90 }
91
92 BOOLEAN KeInsertQueueDpc(PKDPC dpc, PVOID SystemArgument1,
93 PVOID SystemArgument2)
94 /*
95 * FUNCTION: Queues a DPC for execution when the IRQL of a processor
96 * drops below DISPATCH_LEVEL
97 * ARGUMENTS:
98 * Dpc = Initalizes DPC
99 * SystemArguments[1-2] = Undocumented
100 * RETURNS: TRUE if the DPC object wasn't already in the queue
101 * FALSE otherwise
102 */
103 {
104 DPRINT("KeInsertQueueDpc()\n",0);
105 assert(KeGetCurrentIrql()>=DISPATCH_LEVEL);
106
107 dpc->Number=0;
108 dpc->Importance=Medium;
109 dpc->SystemArgument1=SystemArgument1;
110 dpc->SystemArgument2=SystemArgument2;
111 if (dpc->Lock)
112 {
113 return(FALSE);
114 }
115 KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
116 InsertHeadList(&DpcQueueHead,&dpc->DpcListEntry);
117 KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
118 dpc->Lock=(PULONG)1;
119 DPRINT("DpcQueueHead.Flink %x\n",DpcQueueHead.Flink);
120 DPRINT("Leaving KeInsertQueueDpc()\n",0);
121 return(TRUE);
122 }
123
124 void KeInitDpc(void)
125 /*
126 * FUNCTION: Initialize DPC handling
127 */
128 {
129 InitializeListHead(&DpcQueueHead);
130 }
131
132