[NDIS]
[reactos.git] / reactos / drivers / network / ndis / ndis / time.c
index 1a9fb77..0872ee7 100644 (file)
@@ -95,6 +95,32 @@ NdisInitializeTimer(
   KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext);
 }
 
+VOID DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer)
+{
+  PNDIS_MINIPORT_TIMER CurrentTimer;
+
+  ASSERT(Timer->Miniport->TimerQueue);
+
+  if (Timer->Miniport->TimerQueue == Timer)
+  {
+      Timer->Miniport->TimerQueue = Timer->NextDeferredTimer;
+  }
+  else
+  {
+      CurrentTimer = Timer->Miniport->TimerQueue;
+      while (CurrentTimer->NextDeferredTimer)
+      {
+          if (CurrentTimer->NextDeferredTimer == Timer)
+          {
+              CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer;
+              return;
+          }
+          CurrentTimer = CurrentTimer->NextDeferredTimer;
+      }
+      ASSERT(FALSE);
+  }
+}
+
 \f
 /*
  * @implemented
@@ -118,6 +144,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);
+
+  /* FIXME: We can't call this if we have a periodic timer */
+  //DequeueMiniportTimer(Timer);
 }
 
 \f
@@ -145,9 +190,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 +227,10 @@ NdisMSetPeriodicTimer(
   /* relative delays are negative, absolute are positive; resolution is 100ns */
   Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000);
 
+  /* 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 +262,10 @@ NdisMSetTimer(
   /* relative delays are negative, absolute are positive; resolution is 100ns */
   Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
 
+  /* 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);
 }
 
@@ -243,5 +301,23 @@ NdisSetTimer(
   KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc);
 }
 
+/*
+ * @implemented
+ */
+VOID
+EXPORT
+NdisSetTimerEx(
+    IN PNDIS_TIMER  Timer,
+    IN UINT  MillisecondsToDelay,
+    IN PVOID  FunctionContext)
+{
+    NDIS_DbgPrint(MAX_TRACE, ("Called. Timer is: 0x%x, Timeout is: %ld, FunctionContext is: 0x%x\n", 
+                               Timer, MillisecondsToDelay, FunctionContext));
+
+    Timer->Dpc.DeferredContext = FunctionContext;
+
+    NdisSetTimer(Timer, MillisecondsToDelay);
+}
+
 /* EOF */