From f44eee190b536ee0362aa20d9ba9d6d271ba3d4f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 6 Jun 2010 18:09:25 +0000 Subject: [PATCH] [NDIS] - Implement miniport timer queuing - Add some BUGCODE_ID_DRIVER bug check cases for missing interrupt deregistration, missing timer cancellation, and invalid IRQL when calling NdisMAllocateSharedMemory svn path=/trunk/; revision=47630 --- reactos/drivers/network/ndis/ndis/memory.c | 9 +++ reactos/drivers/network/ndis/ndis/miniport.c | 25 ++++++++ reactos/drivers/network/ndis/ndis/time.c | 60 +++++++++++++++++++- 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/network/ndis/ndis/memory.c b/reactos/drivers/network/ndis/ndis/memory.c index 7696389e876..3d96170ea4c 100644 --- a/reactos/drivers/network/ndis/ndis/memory.c +++ b/reactos/drivers/network/ndis/ndis/memory.c @@ -171,6 +171,15 @@ NdisMAllocateSharedMemory( NDIS_DbgPrint(MAX_TRACE,("Called.\n")); + if (KeGetCurrentIrql() != PASSIVE_LEVEL) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + Length, + 0, + 1); + } + *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer( Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached); } diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index daaf7cac1b1..4492caffe32 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -365,6 +365,15 @@ MiniResetComplete( KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + if (Adapter->NdisMiniportBlock.ResetStatus != NDIS_STATUS_PENDING) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)MiniportAdapterHandle, + (ULONG_PTR)Status, + (ULONG_PTR)AddressingReset, + 0); + } + Adapter->NdisMiniportBlock.ResetStatus = Status; CurrentEntry = Adapter->ProtocolListHead.Flink; @@ -1959,6 +1968,22 @@ NdisIPnPStartDevice( { NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); + if (Adapter->NdisMiniportBlock.Interrupt) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } + if (Adapter->NdisMiniportBlock.TimerQueue) + { + KeBugCheckEx(BUGCODE_ID_DRIVER, + (ULONG_PTR)Adapter, + (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt, + (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue, + 1); + } return NdisStatus; } diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index 75a65f3b24f..0872ee70458 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -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); + } +} + /* * @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); } @@ -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; } @@ -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); } -- 2.17.1