Fixed prototype for MmSetAddressRangeModified().
[reactos.git] / ntoskrnl / ke / kqueue.c
1 /*
2  * COPYRIGHT:            See COPYING in the top level directory
3  * PURPOSE:              ReactOS kernel
4  * FILE:                 ntoskrnl/ke/kqueue.c
5  * PURPOSE:              Implement device queues
6  * PROGRAMMER:           David Welch (welch@mcmail.com)
7  * REVISION HISTORY:
8  *               08/07/98: Created
9  */
10
11 /* INCLUDES ****************************************************************/
12
13 #include <ddk/ntddk.h>
14
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* FUNCTIONS *****************************************************************/
19
20 #ifndef LIBCAPTIVE
21
22 VOID 
23 InsertBeforeEntryInList(PLIST_ENTRY Head, PLIST_ENTRY After, PLIST_ENTRY Entry)
24 {
25    InsertHeadList(After, Entry);
26 }
27
28 /*
29  * @implemented
30  */
31 BOOLEAN STDCALL
32 KeInsertByKeyDeviceQueue (PKDEVICE_QUEUE                DeviceQueue,
33                           PKDEVICE_QUEUE_ENTRY  DeviceQueueEntry,
34                           ULONG                 SortKey)
35 {
36    KIRQL oldlvl;
37    PLIST_ENTRY current;
38    PKDEVICE_QUEUE_ENTRY entry;
39    
40    DPRINT("KeInsertByKeyDeviceQueue()\n");
41    
42    DeviceQueueEntry->SortKey=SortKey;
43
44    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
45    
46    if (!DeviceQueue->Busy)
47      {
48         DeviceQueue->Busy=TRUE;
49         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
50         return(FALSE);
51      }
52       
53    current=DeviceQueue->DeviceListHead.Flink;
54    while (current!=(&DeviceQueue->DeviceListHead))
55      {
56         entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
57         if (entry->SortKey < SortKey)
58           {
59              InsertBeforeEntryInList(&DeviceQueue->DeviceListHead,
60                                      &DeviceQueueEntry->DeviceListEntry,
61                                      current);
62              KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
63              return(TRUE);
64           }
65         current = current->Flink;
66      }   
67    InsertTailList(&DeviceQueue->DeviceListHead,&DeviceQueueEntry->DeviceListEntry);
68    
69    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
70    return(TRUE);
71 }
72
73 /*
74  * @implemented
75  */
76 PKDEVICE_QUEUE_ENTRY
77 STDCALL
78 KeRemoveByKeyDeviceQueue (
79         PKDEVICE_QUEUE  DeviceQueue,
80         ULONG           SortKey
81         )
82 {
83    KIRQL oldlvl;
84    PLIST_ENTRY current;
85    PKDEVICE_QUEUE_ENTRY entry;   
86    
87    assert_irql(DISPATCH_LEVEL);
88    assert(DeviceQueue!=NULL);
89    assert(DeviceQueue->Busy);
90    
91    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
92    
93    current = DeviceQueue->DeviceListHead.Flink;
94    while (current != &DeviceQueue->DeviceListHead)
95      {
96         entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
97         if (entry->SortKey < SortKey ||
98             current->Flink == &DeviceQueue->DeviceListHead)
99           {
100              RemoveEntryList(current);
101              KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
102              return(entry);
103           }
104         current = current->Flink;
105      }
106    DeviceQueue->Busy = FALSE;
107    KeReleaseSpinLock(&DeviceQueue->Lock, oldlvl);
108    return(NULL);
109 }
110
111 /*
112  * @implemented
113  */
114 PKDEVICE_QUEUE_ENTRY
115 STDCALL
116 KeRemoveDeviceQueue (
117         PKDEVICE_QUEUE  DeviceQueue
118         )
119 /*
120  * FUNCTION: Removes an entry from a device queue
121  * ARGUMENTS:
122  *        DeviceQueue = Queue to remove the entry
123  * RETURNS: The removed entry
124  */
125 {
126    KIRQL oldlvl;
127    PLIST_ENTRY list_entry;
128    PKDEVICE_QUEUE_ENTRY entry;
129    
130    DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue);
131    
132    assert_irql(DISPATCH_LEVEL);
133    assert(DeviceQueue!=NULL);
134    assert(DeviceQueue->Busy);
135    
136    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
137    
138    list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead);
139    if (list_entry==(&DeviceQueue->DeviceListHead))
140      {
141         DeviceQueue->Busy=FALSE;
142         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
143         return(NULL);
144      }
145    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
146    
147    entry = CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
148    return(entry);
149 }
150
151 #endif /* LIBCAPTIVE */
152
153 /*
154  * @implemented
155  */
156 VOID
157 STDCALL
158 KeInitializeDeviceQueue (
159         PKDEVICE_QUEUE  DeviceQueue
160         )
161 /*
162  * FUNCTION: Intializes a device queue
163  * ARGUMENTS:
164  *       DeviceQueue = Device queue to initialize
165  */
166 {
167    assert(DeviceQueue!=NULL);
168    InitializeListHead(&DeviceQueue->DeviceListHead);
169    DeviceQueue->Busy=FALSE;
170    KeInitializeSpinLock(&DeviceQueue->Lock);
171 }
172
173 #ifndef LIBCAPTIVE
174
175 /*
176  * @implemented
177  */
178 BOOLEAN
179 STDCALL
180 KeInsertDeviceQueue (
181         PKDEVICE_QUEUE          DeviceQueue,
182         PKDEVICE_QUEUE_ENTRY    DeviceQueueEntry
183         )
184 /*
185  * FUNCTION: Inserts an entry in a device queue
186  * ARGUMENTS:
187  *        DeviceQueue = Queue to insert the entry in
188  *        DeviceQueueEntry = Entry to insert
189  * RETURNS: False is the device queue wasn't busy
190  *          True otherwise
191  */
192 {
193    KIRQL oldlvl;
194    
195    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
196    
197    if (!DeviceQueue->Busy)
198      {
199         DeviceQueue->Busy=TRUE;
200         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
201         return(FALSE);
202      }
203    
204    InsertTailList(&DeviceQueue->DeviceListHead,
205                   &DeviceQueueEntry->DeviceListEntry);
206    DeviceQueueEntry->SortKey=0;
207    
208    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
209    return(TRUE);
210 }
211
212
213 /*
214  * @unimplemented
215  */
216 BOOLEAN STDCALL
217 KeRemoveEntryDeviceQueue(PKDEVICE_QUEUE DeviceQueue,
218                          PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
219 {
220   UNIMPLEMENTED;
221   return(FALSE);
222 }
223
224 #endif /* LIBCAPTIVE */