Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1080 lines
20 KiB

/*++
Copyright (c) 1990-1995 Microsoft Corporation
Module Name:
timerm.c
Abstract:
NDIS wrapper functions for miniport isr/timer
Author:
Sean Selitrennikoff (SeanSe) 05-Oct-93
Environment:
Kernel mode, FSD
Revision History:
Jameel Hyder (JameelH) Re-organization 01-Jun-95
--*/
#include <precomp.h>
#pragma hdrstop
//
// Define the module number for debug code.
//
#define MODULE_NUMBER MODULE_TIMERM
//
// Timers
//
VOID
ndisMTimerDpc(
IN PKDPC Dpc,
IN PVOID Context,
IN PVOID SystemContext1,
IN PVOID SystemContext2
)
/*++
Routine Description:
This function services all mini-port timer interrupts. It then calls the
appropriate function that mini-port consumers have registered in the
call to NdisMInitializeTimer.
Arguments:
Dpc - Not used.
Context - A pointer to the NDIS_MINIPORT_TIMER which is bound to this DPC.
SystemContext1,2 - not used.
Return Value:
None.
--*/
{
PNDIS_MINIPORT_TIMER MiniportTimer = (PNDIS_MINIPORT_TIMER)(Context);
PNDIS_TIMER_FUNCTION TimerFunction;
PNDIS_MINIPORT_BLOCK Miniport = MiniportTimer->Miniport;
BOOLEAN LocalLock;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
do
{
//
// Attempt to acquire the local lock.
//
LOCK_MINIPORT(Miniport, LocalLock);
if (!LocalLock || MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IN_INITIALIZE))
{
//
// Unlock the miniport in the case of the in-initialize flag.
//
UNLOCK_MINIPORT(Miniport, LocalLock);
//
// Queue a work item for the timer.
//
NDISM_QUEUE_NEW_WORK_ITEM(Miniport,
NdisWorkItemTimer,
&MiniportTimer->Dpc,
NULL);
break;
}
//
// Call Miniport timer function
//
TimerFunction = MiniportTimer->MiniportTimerFunction;
(*TimerFunction)(NULL, MiniportTimer->MiniportTimerContext, NULL, NULL);
#if _SEND_PRIORITY
//
// If we are not reseting and not halting then give priority to sends
// at this point.
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_REQUESTED) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
ndisMProcessDeferredFullDuplexPrioritySends(Miniport);
}
else
{
ndisMProcessDeferredPrioritySends(Miniport);
}
}
else
#endif
{
NDISM_PROCESS_DEFERRED(Miniport);
}
UNLOCK_MINIPORT(Miniport, LocalLock);
} while (FALSE);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
}
VOID
NdisMInitializeTimer(
IN OUT PNDIS_MINIPORT_TIMER MiniportTimer,
IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_TIMER_FUNCTION TimerFunction,
IN PVOID FunctionContext
)
/*++
Routine Description:
Sets up an Miniport Timer object, initializing the DPC in the timer to
the function and context.
Arguments:
MiniportTimer - the timer object.
MiniportAdapterHandle - pointer to the mini-port block;
TimerFunction - Routine to start.
FunctionContext - Context of TimerFunction.
Return Value:
None.
--*/
{
INITIALIZE_TIMER(&(MiniportTimer->Timer));
MiniportTimer->Miniport = (PNDIS_MINIPORT_BLOCK)MiniportAdapterHandle;
MiniportTimer->MiniportTimerFunction = TimerFunction;
MiniportTimer->MiniportTimerContext = FunctionContext;
//
// Initialize our dpc. If Dpc was previously initialized, this will
// reinitialize it.
//
INITIALIZE_DPC(&MiniportTimer->Dpc,
(MiniportTimer->Miniport->Flags & fMINIPORT_IS_CO) ?
(PKDEFERRED_ROUTINE)ndisMCoTimerDpc :
(PKDEFERRED_ROUTINE)ndisMTimerDpc,
(PVOID)MiniportTimer);
SET_PROCESSOR_DPC(&MiniportTimer->Dpc,
ndisValidProcessors[ndisCurrentProcessor]);
}
VOID
NdisMCancelTimer(
IN PNDIS_MINIPORT_TIMER Timer,
OUT PBOOLEAN TimerCancelled
)
/*++
Routine Description:
Cancels a timer.
Arguments:
Timer - The timer to cancel.
TimerCancelled - TRUE if the timer was canceled, else FALSE.
Return Value:
None
--*/
{
*TimerCancelled = CANCEL_TIMER(&((((PNDIS_TIMER)(Timer))->Timer)));
}
NDIS_STATUS
NdisMRegisterInterrupt(
OUT PNDIS_MINIPORT_INTERRUPT Interrupt,
IN NDIS_HANDLE MiniportAdapterHandle,
IN UINT InterruptVector,
IN UINT InterruptLevel,
IN BOOLEAN RequestIsr,
IN BOOLEAN SharedInterrupt,
IN NDIS_INTERRUPT_MODE InterruptMode
)
{
NDIS_STATUS Status;
NdisInitializeInterrupt(&Status,
(PNDIS_INTERRUPT)Interrupt,
MiniportAdapterHandle,
NULL,
NULL,
(PNDIS_DEFERRED_PROCESSING)RequestIsr,
InterruptVector,
InterruptLevel,
SharedInterrupt,
InterruptMode);
return Status;
}
VOID
NdisMDeregisterInterrupt(
IN PNDIS_MINIPORT_INTERRUPT Interrupt
)
{
NdisRemoveInterrupt((PNDIS_INTERRUPT)Interrupt);
}
BOOLEAN
NdisMSynchronizeWithInterrupt(
IN PNDIS_MINIPORT_INTERRUPT Interrupt,
IN PVOID SynchronizeFunction,
IN PVOID SynchronizeContext
)
{
return (SYNC_WITH_ISR((Interrupt)->InterruptObject,
SynchronizeFunction,
SynchronizeContext));
}
VOID
ndisMWakeUpDpc(
IN PKDPC Dpc,
IN PVOID Context,
IN PVOID SystemContext1,
IN PVOID SystemContext2
)
/*++
Routine Description:
This function services all mini-port. It checks to see if a mini-port is
ever stalled.
Arguments:
Dpc - Not used.
Context - A pointer to the NDIS_TIMER which is bound to this DPC.
SystemContext1,2 - not used.
Return Value:
None.
--*/
{
PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(Context);
BOOLEAN Hung = FALSE;
BOOLEAN LocalLock;
PNDIS_MINIPORT_WORK_ITEM WorkItem;
PSINGLE_LIST_ENTRY Link;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
do
{
//
// If the miniport is halting then do nothing.
//
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
break;
}
//
// Does some other DPC have the miniport lock?
//
LOCK_MINIPORT(Miniport, LocalLock);
if (!LocalLock ||
MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS) ||
MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_REQUESTED))
{
//
// Release the local lock in case we are here due to
// a reset in progress.
//
UNLOCK_MINIPORT(Miniport, LocalLock);
//
// A DPC or timer is already running, assume that
// means things are fine.
//
break;
}
//
// Call Miniport stall checker.
//
if (Miniport->DriverHandle->MiniportCharacteristics.CheckForHangHandler != NULL)
{
Hung = (Miniport->DriverHandle->MiniportCharacteristics.CheckForHangHandler)(
Miniport->MiniportAdapterContext);
}
//
// Check the internal wrapper states for the miniport and
// see if we think the miniport should be reset.
//
if (!Hung) do
{
//
// Should we check the request queue?
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IGNORE_REQUEST_QUEUE))
{
//
// Did a request pend to long?
//
if (Miniport->MiniportRequest != NULL)
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_REQUEST_TIMEOUT))
{
Hung = TRUE;
break;
}
else
{
MINIPORT_SET_FLAG(Miniport, fMINIPORT_REQUEST_TIMEOUT);
}
}
}
//
// Should we ignore the packet queue's?
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IGNORE_PACKET_QUEUE))
{
//
// Grab the send lock.
//
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
NDIS_ACQUIRE_SEND_SPIN_LOCK_DPC(Miniport);
}
//
// Does the miniport have possession of any packets?
//
if (Miniport->FirstPacket != NULL)
{
//
// Has the packet timed out?
//
if (MINIPORT_TEST_PACKET_FLAG(Miniport->FirstPacket, fPACKET_HAS_TIMED_OUT))
{
//
// Reset the miniport.
//
Hung = TRUE;
}
else
{
//
// Set the packet flag and wait to see if it is still
// there next time in.
//
MINIPORT_SET_PACKET_FLAG(Miniport->FirstPacket, fPACKET_HAS_TIMED_OUT);
}
}
//
// Release the send lock.
//
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
NDIS_RELEASE_SEND_SPIN_LOCK_DPC(Miniport);
}
//
// If we are hung then we don't need to check for token ring
// errors.
//
if (Hung)
{
break;
}
}
//
// Are we ignoring token ring errors?
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IGNORE_TOKEN_RING_ERRORS))
{
//
// Token Ring reset...
//
if (Miniport->TrResetRing == 1)
{
Hung = TRUE;
break;
}
else if (Miniport->TrResetRing > 1)
{
Miniport->TrResetRing--;
}
}
} while (FALSE);
//
// If the miniport is hung then queue a workitem to reset it.
//
if (Hung)
{
//
// Queue a reset requested workitem.
//
NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemResetRequested, Miniport, NULL);
}
//
// Process any changes that have occurred.
//
NDISM_PROCESS_DEFERRED(Miniport);
UNLOCK_MINIPORT(Miniport, LocalLock);
} while (FALSE);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
}
//
// Interrupt stuff
//
BOOLEAN
ndisMIsr(
IN PKINTERRUPT KInterrupt,
IN PVOID Context
)
/*++
Routine Description:
Handles ALL Miniport interrupts, calling the appropriate Miniport ISR and DPC
depending on the context.
Arguments:
Interrupt - Interrupt object for the Mac.
Context - Really a pointer to the interrupt.
Return Value:
None.
--*/
{
//
// Get adapter from context.
//
PNDIS_MINIPORT_INTERRUPT Interrupt = (PNDIS_MINIPORT_INTERRUPT)Context;
PNDIS_MINIPORT_BLOCK Miniport = Interrupt->Miniport;
BOOLEAN InterruptRecognized;
BOOLEAN QueueDpc;
do
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_NORMAL_INTERRUPTS))
{
//
// Call to disable the interrupt
//
MINIPORT_DISABLE_INTERRUPT(Miniport);
InterruptRecognized = TRUE;
goto queue_dpc;
break;
}
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
//
// Call MiniportIsr
//
Interrupt->MiniportIsr(
&InterruptRecognized,
&QueueDpc,
Miniport->MiniportAdapterContext);
if (QueueDpc)
{
queue_dpc:
Increment((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (QUEUE_DPC(&Interrupt->InterruptDpc))
{
break;
}
//
// The DPC was already queued, so we have an extra reference (we
// do it this way to ensure that the reference is added *before*
// the DPC is queued).
//
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING) &&
(Interrupt->DpcCount == 0))
{
//
// We need to queue a DPC to set the event because we
// can't do it from the ISR. We know that the interrupt
// DPC won't fire because the refcount is 0, so we reuse it.
//
INITIALIZE_DPC(&Interrupt->InterruptDpc,
ndisLastCountRemovedFunction,
(PVOID)&Interrupt->DpcsCompletedEvent);
//
// When ndisLastCountRemovedFunction runs it will set
// the event.
//
QUEUE_DPC(&Interrupt->InterruptDpc);
}
}
break;
}
if (!Interrupt->SharedInterrupt &&
!Interrupt->IsrRequested &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IN_INITIALIZE))
{
//
// Call to disable the interrupt
//
ASSERT(Miniport->DisableInterruptHandler != NULL);
MINIPORT_DISABLE_INTERRUPT(Miniport);
InterruptRecognized = TRUE;
break;
}
//
// Call MiniportIsr, but don't queue a DPC.
//
Interrupt->MiniportIsr(
&InterruptRecognized,
&QueueDpc,
Miniport->MiniportAdapterContext);
} while (FALSE);
return(InterruptRecognized);
}
VOID
ndisMDpc(
IN PVOID SystemSpecific1,
IN PVOID InterruptContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
Handles ALL Miniport interrupt DPCs, calling the appropriate Miniport DPC
depending on the context.
Arguments:
Interrupt - Interrupt object for the Mac.
Context - Really a pointer to the Interrupt.
Return Value:
None.
--*/
{
//
// Get adapter from context.
//
PNDIS_MINIPORT_INTERRUPT Interrupt = (PNDIS_MINIPORT_INTERRUPT)(InterruptContext);
PNDIS_MINIPORT_BLOCK Miniport = Interrupt->Miniport;
BOOLEAN LocalLock;
W_HANDLE_INTERRUPT_HANDLER MiniportDpc = Interrupt->MiniportDpc;
NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
do
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (Interrupt->DpcCount==0)
{
SET_EVENT(&Interrupt->DpcsCompletedEvent);
}
break;
}
LOCK_MINIPORT(Miniport, LocalLock);
if (!LocalLock)
{
//
// A DPC is already running, queue this for later.
//
NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemDpc, &Miniport->Dpc, NULL);
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
break;
}
//
// Call MiniportDpc
//
(*MiniportDpc)(Miniport->MiniportAdapterContext);
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
//
// Enable interrupts
//
MINIPORT_SYNC_ENABLE_INTERRUPT(Miniport);
#if _SEND_PRIORITY
//
// If we are not reseting and not halting then give priority to sends
// at this point.
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_REQUESTED) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
ndisMProcessDeferredFullDuplexPrioritySends(Miniport);
}
else
{
ndisMProcessDeferredPrioritySends(Miniport);
}
}
else
#endif
{
NDISM_PROCESS_DEFERRED(Miniport);
}
}
else
{
if (Interrupt->DpcCount == 0)
{
SET_EVENT(&Interrupt->DpcsCompletedEvent);
}
}
UNLOCK_MINIPORT(Miniport, LocalLock);
} while (FALSE);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
}
VOID
ndisMDpcTimer(
IN PVOID SystemSpecific1,
IN PVOID InterruptContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
Handles a deferred interrupt dpc.
Arguments:
Context - Really a pointer to the Miniport block.
Return Value:
None.
--*/
{
//
// Get adapter from context.
//
PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(InterruptContext);
BOOLEAN LocalLock;
W_HANDLE_INTERRUPT_HANDLER MiniportDpc = Miniport->HandleInterruptHandler;
NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
do
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IN_INITIALIZE))
{
break;
}
LOCK_MINIPORT(Miniport, LocalLock);
if (!LocalLock)
{
//
// A DPC is already running, queue this for later.
//
NDISM_QUEUE_WORK_ITEM(Miniport, NdisWorkItemDpc, &Miniport->Dpc, NULL);
break;
}
//
// Disable the interrupts.
//
MINIPORT_SYNC_DISABLE_INTERRUPT(Miniport);
//
// Call MiniportDpc
//
if (MiniportDpc != NULL)
{
(*MiniportDpc)(Miniport->MiniportAdapterContext);
}
//
// Enable interrupts
//
MINIPORT_SYNC_ENABLE_INTERRUPT(Miniport);
#if _SEND_PRIORITY
//
// If we are not reseting and not halting then give priority to sends
// at this point.
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_REQUESTED) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
ndisMProcessDeferredFullDuplexPrioritySends(Miniport);
}
else
{
ndisMProcessDeferredPrioritySends(Miniport);
}
}
else
#endif
{
NDISM_PROCESS_DEFERRED(Miniport);
}
UNLOCK_MINIPORT(Miniport, LocalLock);
} while (FALSE);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
}
VOID
ndisMDeferredTimerDpc(
IN PKDPC Dpc,
IN PVOID Context,
IN PVOID SystemContext1,
IN PVOID SystemContext2
)
/*++
Routine Description:
This is a DPC routine that is queue'd by some of the [full-duplex] routines
in order to get ndisMProcessDeferred[FullDuplex] to run outside of their
context.
Arguments:
Return Value:
None.
--*/
{
PNDIS_MINIPORT_BLOCK Miniport = Context;
BOOLEAN LocalLock;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
NDIS_ACQUIRE_MINIPORT_SPIN_LOCK_DPC(Miniport);
LOCK_MINIPORT(Miniport, LocalLock);
if (!LocalLock)
{
//
// Queue this to run later.
//
NDISM_DEFER_PROCESS_DEFERRED(Miniport);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
return;
}
#if _SEND_PRIORITY
//
// If we are not reseting and not halting then give priority to sends
// at this point.
//
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_REQUESTED) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_RESET_IN_PROGRESS) &&
!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_FULL_DUPLEX))
{
ndisMProcessDeferredFullDuplexPrioritySends(Miniport);
}
else
{
ndisMProcessDeferredPrioritySends(Miniport);
}
}
else
#endif
{
NDISM_PROCESS_DEFERRED(Miniport);
}
UNLOCK_MINIPORT(Miniport, LocalLock);
NDIS_RELEASE_MINIPORT_SPIN_LOCK_DPC(Miniport);
}
VOID
ndisMCoDpc(
IN PVOID SystemSpecific1,
IN PVOID InterruptContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
Handles ALL Miniport interrupt DPCs, calling the appropriate Miniport DPC
depending on the context.
Arguments:
Interrupt - Interrupt object for the Mac.
Context - Really a pointer to the Interrupt.
Return Value:
None.
--*/
{
//
// Get adapter from context.
//
PNDIS_MINIPORT_INTERRUPT Interrupt = (PNDIS_MINIPORT_INTERRUPT)(InterruptContext);
PNDIS_MINIPORT_BLOCK Miniport = Interrupt->Miniport;
BOOLEAN LocalLock;
W_HANDLE_INTERRUPT_HANDLER MiniportDpc = Interrupt->MiniportDpc;
if (MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (Interrupt->DpcCount==0)
{
SET_EVENT(&Interrupt->DpcsCompletedEvent);
}
}
else
{
//
// Call MiniportDpc
//
(*MiniportDpc)(Miniport->MiniportAdapterContext);
Decrement((PLONG)&Interrupt->DpcCount, &Interrupt->DpcCountLock);
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_HALTING))
{
//
// Enable interrupts
//
MINIPORT_SYNC_ENABLE_INTERRUPT(Miniport);
}
else
{
if (Interrupt->DpcCount == 0)
{
SET_EVENT(&Interrupt->DpcsCompletedEvent);
}
}
}
}
VOID
ndisMCoDpcTimer(
IN PVOID SystemSpecific1,
IN PVOID InterruptContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
Handles a deferred interrupt dpc.
Arguments:
Context - Really a pointer to the Miniport block.
Return Value:
None.
--*/
{
//
// Get adapter from context.
//
PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(InterruptContext);
BOOLEAN LocalLock;
W_HANDLE_INTERRUPT_HANDLER MiniportDpc = Miniport->HandleInterruptHandler;
if (!MINIPORT_TEST_FLAG(Miniport, fMINIPORT_IN_INITIALIZE))
{
//
// Disable the interrupts.
//
MINIPORT_SYNC_DISABLE_INTERRUPT(Miniport);
//
// Call MiniportDpc
//
if (MiniportDpc != NULL)
{
(*MiniportDpc)(Miniport->MiniportAdapterContext);
}
//
// Enable interrupts
//
MINIPORT_SYNC_ENABLE_INTERRUPT(Miniport);
}
}
VOID
ndisMCoTimerDpc(
IN PKDPC Dpc,
IN PVOID Context,
IN PVOID SystemContext1,
IN PVOID SystemContext2
)
/*++
Routine Description:
This function services all mini-port timer interrupts. It then calls the
appropriate function that mini-port consumers have registered in the
call to NdisMInitializeTimer.
Arguments:
Dpc - Not used.
Context - A pointer to the NDIS_MINIPORT_TIMER which is bound to this DPC.
SystemContext1,2 - not used.
Return Value:
None.
--*/
{
PNDIS_MINIPORT_TIMER MiniportTimer = (PNDIS_MINIPORT_TIMER)(Context);
PNDIS_MINIPORT_BLOCK Miniport = MiniportTimer->Miniport;
BOOLEAN LocalLock;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemContext1);
UNREFERENCED_PARAMETER(SystemContext2);
//
// Call Miniport timer function
//
(*MiniportTimer->MiniportTimerFunction)(NULL, MiniportTimer->MiniportTimerContext, NULL, NULL);
}