2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: Time related routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * Vizzini 08-Oct-2003 Formatting, commenting, and ASSERTs
13 * - Although the standard kernel-mode M.O. is to trust the caller
14 * to not provide bad arguments, we have added lots of argument
15 * validation to assist in the effort to get third-party binaries
16 * working. It is easiest to track bugs when things break quickly
30 OUT PBOOLEAN TimerCancelled
)
32 * FUNCTION: Cancels a scheduled NDIS timer
34 * Timer: pointer to an NDIS_TIMER object to cancel
35 * TimerCancelled: boolean that returns cancellation status
37 * - call at IRQL <= DISPATCH_LEVEL
40 ASSERT_IRQL(DISPATCH_LEVEL
);
43 *TimerCancelled
= KeCancelTimer (&Timer
->Timer
);
50 #undef NdisGetCurrentSystemTime
53 NdisGetCurrentSystemTime (
54 IN OUT PLARGE_INTEGER pSystemTime
)
56 * FUNCTION: Retrieve the current system time
58 * pSystemTime: pointer to the returned system time
60 * - call at IRQL <= DISPATCH_LEVEL
63 ASSERT_IRQL(DISPATCH_LEVEL
);
66 KeQuerySystemTime (pSystemTime
);
76 IN OUT PNDIS_TIMER Timer
,
77 IN PNDIS_TIMER_FUNCTION TimerFunction
,
78 IN PVOID FunctionContext
)
80 * FUNCTION: Set up an NDIS_TIMER for later use
82 * Timer: pointer to caller-allocated storage to receive an NDIS_TIMER
83 * TimerFunction: function pointer to routine to run when timer expires
84 * FunctionContext: context (param 2) to be passed to the timer function when it runs
86 * - TimerFunction will be called at DISPATCH_LEVEL
87 * - call at IRQL = PASSIVE_LEVEL
93 KeInitializeTimer (&Timer
->Timer
);
95 KeInitializeDpc (&Timer
->Dpc
, (PKDEFERRED_ROUTINE
)TimerFunction
, FunctionContext
);
98 BOOLEAN
DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer
)
100 PNDIS_MINIPORT_TIMER CurrentTimer
;
102 if (!Timer
->Miniport
->TimerQueue
)
105 if (Timer
->Miniport
->TimerQueue
== Timer
)
107 Timer
->Miniport
->TimerQueue
= Timer
->NextDeferredTimer
;
108 Timer
->NextDeferredTimer
= NULL
;
113 CurrentTimer
= Timer
->Miniport
->TimerQueue
;
114 while (CurrentTimer
->NextDeferredTimer
)
116 if (CurrentTimer
->NextDeferredTimer
== Timer
)
118 CurrentTimer
->NextDeferredTimer
= Timer
->NextDeferredTimer
;
119 Timer
->NextDeferredTimer
= NULL
;
122 CurrentTimer
= CurrentTimer
->NextDeferredTimer
;
135 IN PNDIS_MINIPORT_TIMER Timer
,
136 OUT PBOOLEAN TimerCancelled
)
138 * FUNCTION: cancel a scheduled NDIS_MINIPORT_TIMER
140 * Timer: timer object to cancel
141 * TimerCancelled: status of cancel operation
143 * - call at IRQL <= DISPATCH_LEVEL
146 ASSERT_IRQL(DISPATCH_LEVEL
);
147 ASSERT(TimerCancelled
);
150 *TimerCancelled
= KeCancelTimer (&Timer
->Timer
);
152 DequeueMiniportTimer(Timer
);
156 MiniTimerDpcFunction(PKDPC Dpc
,
157 PVOID DeferredContext
,
158 PVOID SystemArgument1
,
159 PVOID SystemArgument2
)
161 PNDIS_MINIPORT_TIMER Timer
= DeferredContext
;
163 Timer
->MiniportTimerFunction(Dpc
,
164 Timer
->MiniportTimerContext
,
168 /* Only dequeue if the timer has a period of 0 */
169 if (!Timer
->Timer
.Period
) DequeueMiniportTimer(Timer
);
178 NdisMInitializeTimer(
179 IN OUT PNDIS_MINIPORT_TIMER Timer
,
180 IN NDIS_HANDLE MiniportAdapterHandle
,
181 IN PNDIS_TIMER_FUNCTION TimerFunction
,
182 IN PVOID FunctionContext
)
184 * FUNCTION: Initialize an NDIS_MINIPORT_TIMER
186 * Timer: Timer object to initialize
187 * MiniportAdapterHandle: Handle to the miniport, passed in to MiniportInitialize
188 * TimerFunction: function to be executed when the timer expires
189 * FunctionContext: argument passed to TimerFunction when it is called
191 * - TimerFunction is called at IRQL = DISPATCH_LEVEL
192 * - call at IRQL = PASSIVE_LEVEL
198 KeInitializeTimer (&Timer
->Timer
);
199 KeInitializeDpc (&Timer
->Dpc
, MiniTimerDpcFunction
, Timer
);
201 Timer
->MiniportTimerFunction
= TimerFunction
;
202 Timer
->MiniportTimerContext
= FunctionContext
;
203 Timer
->Miniport
= &((PLOGICAL_ADAPTER
)MiniportAdapterHandle
)->NdisMiniportBlock
;
204 Timer
->NextDeferredTimer
= NULL
;
213 NdisMSetPeriodicTimer(
214 IN PNDIS_MINIPORT_TIMER Timer
,
215 IN UINT MillisecondsPeriod
)
217 * FUNCTION: Set a timer to go off periodically
219 * Timer: pointer to the timer object to set
220 * MillisecondsPeriod: period of the timer
222 * - Minimum predictible interval is ~10ms
223 * - Must be called at IRQL <= DISPATCH_LEVEL
226 LARGE_INTEGER Timeout
;
228 ASSERT_IRQL(DISPATCH_LEVEL
);
231 /* relative delays are negative, absolute are positive; resolution is 100ns */
232 Timeout
.QuadPart
= Int32x32To64(MillisecondsPeriod
, -10000);
234 /* Dequeue the timer if it is queued already */
235 DequeueMiniportTimer(Timer
);
237 /* Add the timer at the head of the timer queue */
238 Timer
->NextDeferredTimer
= Timer
->Miniport
->TimerQueue
;
239 Timer
->Miniport
->TimerQueue
= Timer
;
241 KeSetTimerEx (&Timer
->Timer
, Timeout
, MillisecondsPeriod
, &Timer
->Dpc
);
252 IN PNDIS_MINIPORT_TIMER Timer
,
253 IN UINT MillisecondsToDelay
)
255 * FUNCTION: Set a NDIS_MINIPORT_TIMER so that it goes off
257 * Timer: timer object to set
258 * MillisecondsToDelay: time to wait for the timer to expire
260 * - Minimum predictible interval is ~10ms
261 * - Must be called at IRQL <= DISPATCH_LEVEL
264 LARGE_INTEGER Timeout
;
266 ASSERT_IRQL(DISPATCH_LEVEL
);
269 /* relative delays are negative, absolute are positive; resolution is 100ns */
270 Timeout
.QuadPart
= Int32x32To64(MillisecondsToDelay
, -10000);
272 /* Dequeue the timer if it is queued already */
273 DequeueMiniportTimer(Timer
);
275 /* Add the timer at the head of the timer queue */
276 Timer
->NextDeferredTimer
= Timer
->Miniport
->TimerQueue
;
277 Timer
->Miniport
->TimerQueue
= Timer
;
279 KeSetTimer (&Timer
->Timer
, Timeout
, &Timer
->Dpc
);
289 IN PNDIS_TIMER Timer
,
290 IN UINT MillisecondsToDelay
)
292 * FUNCTION: Set an NDIS_TIMER so that it goes off
294 * Timer: timer object to set
295 * MillisecondsToDelay: time to wait for the timer to expire
297 * - Minimum predictible interval is ~10ms
298 * - Must be called at IRQL <= DISPATCH_LEVEL
301 LARGE_INTEGER Timeout
;
303 ASSERT_IRQL(DISPATCH_LEVEL
);
306 NDIS_DbgPrint(MAX_TRACE
, ("Called. Timer is: 0x%x, Timeout is: %ld\n", Timer
, MillisecondsToDelay
));
308 /* relative delays are negative, absolute are positive; resolution is 100ns */
309 Timeout
.QuadPart
= Int32x32To64(MillisecondsToDelay
, -10000);
311 KeSetTimer (&Timer
->Timer
, Timeout
, &Timer
->Dpc
);
320 IN PNDIS_TIMER Timer
,
321 IN UINT MillisecondsToDelay
,
322 IN PVOID FunctionContext
)
324 NDIS_DbgPrint(MAX_TRACE
, ("Called. Timer is: 0x%x, Timeout is: %ld, FunctionContext is: 0x%x\n",
325 Timer
, MillisecondsToDelay
, FunctionContext
));
327 Timer
->Dpc
.DeferredContext
= FunctionContext
;
329 NdisSetTimer(Timer
, MillisecondsToDelay
);