Forgot to remove this ASSERT for r47636
[reactos.git] / reactos / drivers / network / ndis / ndis / time.c
index 75a65f3..772557f 100644 (file)
@@ -95,6 +95,36 @@ NdisInitializeTimer(
   KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext);
 }
 
+BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer)
+{
+  PNDIS_MINIPORT_TIMER CurrentTimer;
+
+  if (!Timer->Miniport->TimerQueue)
+      return FALSE;
+
+  if (Timer->Miniport->TimerQueue == Timer)
+  {
+      Timer->Miniport->TimerQueue = Timer->NextDeferredTimer;
+      Timer->NextDeferredTimer = NULL;
+      return TRUE;
+  }
+  else
+  {
+      CurrentTimer = Timer->Miniport->TimerQueue;
+      while (CurrentTimer->NextDeferredTimer)
+      {
+          if (CurrentTimer->NextDeferredTimer == Timer)
+          {
+              CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer;
+              Timer->NextDeferredTimer = NULL;
+              return TRUE;
+          }
+          CurrentTimer = CurrentTimer->NextDeferredTimer;
+      }
+      return FALSE;
+  }
+}
+
 \f
 /*
  * @implemented
@@ -118,6 +148,25 @@ NdisMCancelTimer(
   ASSERT(Timer);
 
   *TimerCancelled = KeCancelTimer (&Timer->Timer);
+
+  DequeueMiniportTimer(Timer);
+}
+
+VOID NTAPI
+MiniTimerDpcFunction(PKDPC Dpc,
+                     PVOID DeferredContext,
+                     PVOID SystemArgument1,
+                     PVOID SystemArgument2)
+{
+  PNDIS_MINIPORT_TIMER Timer = DeferredContext;
+
+  Timer->MiniportTimerFunction(Dpc,
+                               Timer->MiniportTimerContext,
+                               SystemArgument1,
+                               SystemArgument2);
+
+  /* Only dequeue if the timer has a period of 0 */
+  if (!Timer->Timer.Period) DequeueMiniportTimer(Timer);
 }
 
 \f
@@ -145,9 +194,14 @@ NdisMInitializeTimer(
 {
   PAGED_CODE();
   ASSERT(Timer);
+
   KeInitializeTimer (&Timer->Timer);
+  KeInitializeDpc (&Timer->Dpc, MiniTimerDpcFunction, Timer);
 
-  KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext);
+  Timer->MiniportTimerFunction = TimerFunction;
+  Timer->MiniportTimerContext = FunctionContext;
+  Timer->Miniport = &((PLOGICAL_ADAPTER)MiniportAdapterHandle)->NdisMiniportBlock;
+  Timer->NextDeferredTimer = NULL;
 }
 
 \f
@@ -177,6 +231,13 @@ NdisMSetPeriodicTimer(
   /* relative delays are negative, absolute are positive; resolution is 100ns */
   Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000);
 
+  /* Dequeue the timer if it is queued already */
+  DequeueMiniportTimer(Timer);
+
+  /* Add the timer at the head of the timer queue */
+  Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
+  Timer->Miniport->TimerQueue = Timer;
+
   KeSetTimerEx (&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc);
 }
 
@@ -208,6 +269,13 @@ NdisMSetTimer(
   /* relative delays are negative, absolute are positive; resolution is 100ns */
   Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
 
+  /* Dequeue the timer if it is queued already */
+  DequeueMiniportTimer(Timer);
+
+  /* Add the timer at the head of the timer queue */
+  Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
+  Timer->Miniport->TimerQueue = Timer;
+
   KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc);
 }