Kernel Mode Drivers Layered Under NDIS Miniport Drivers
  
PSS ID Number: Q132690
Article last modified on 07-21-1995
 
3.51
 
WINDOWS NT
 

------------------------------------------------------------------------
The information in this article applies to:
 
 - Microsoft Win32 Device Development Kit (DDK), version 3.51
------------------------------------------------------------------------
 
SUMMARY
=======
 
The NDIS wrapper is designed to provide both the upper edge interface and
the lower edge interface to an NDIS Miniport driver.
 
In some cases it may be desirable to layer in another driver that
interfaces with the lower edge of a Miniport driver, for example when the
NDIS Miniport driver is communicating with a virtual adapter, rather than
actual hardware. This is sometimes the case when the adapter's driver is
being developed in parallel with the adapter hardware. The layered driver
simulates the hardware, allowing the driver development to proceed. When
the hardware is completed, the layered driver is removed, and the hardware
inserted.
 
A problem with layering a driver under an NDIS Miniport is that the NDIS
wrapper expects to be the caller of the Miniport's DPC routine. This is the
DPC routine that the Miniport registered with the wrapper in the Miniport
NdisMRegisterMiniport(...) call. This problem is described below.
 
MORE INFORMATION
================
 
In normal Miniport driver operation, when an interrupt fires, the ISR that
is associated with that interrupt, (and the ISR registered with the
wrapper), is called. This ISR simply clears the interrupt, and asks the
wrapper to queue the registered DPC routine. The queued DPC routine is
activated by the scheduler, through the NDIS wrapper.
 
The wrapper acquires certain Miniport spinlocks before actually calling the
registered DPC. Many of the subsequent NDIS function calls require these
spinlocks be held in order to function properly.
 
Considering the case of a layered driver, residing below the NDIS Miniport,
the problem becomes apparent. Neither the driver's ISR or the driver's DPC
have been registered with the NDIS wrapper. The interrupt fires, and the
ISR is called. The ISR clears the interrupt, and queues the DPC with a
call to IoRequestDpc(...). The DPC, when activated by the scheduler, then
attempts to make an NDIS call, to pass the received packet up the stack.
Because the DPC was not registered with NDIS, and the Miniport spinlocks
have not been acquired, the results of these NDIS call will be
unpredictable.
 
One solution is to set up a timer function in your Miniport initialization
routine [NdisMInitializeTimer(... )]. This timer function will provide the
same functionality that the Miniport DPC routine would have provided. This
function is initialized with NdisMInitializeTimer(...) in the Miniport's
Driver Entry(...) routine. When the DPC routine, queued by the ISR, is
executed, it calls NdisMSetTimer(...) with a value of 0. This causes the
wrapper to queue a DPC routine, which will most likely run immediately
after the current DPC finishes. The wrapper's DPC routine then acquires the
required spinlocks, and immediately calls the registered timer function.
The timer function may then complete the request, initiated by the ISR, by
using the appropriate NDIS calls.
 
IMPORTANT NOTE
==============
 
The resulting NDIS Miniport does not lose any compatibility as a result of
this approach. Any other kernel mode drivers, however, may require
modification, possibly extensive, to function on other NDIS compatible
operating systems or Windows NT platforms.
 
Additional reference words: 3.51 miniports
KBCategory: kbprg
KBSubcategory: NDIS WAN ntddkndis
=============================================================================
Copyright Microsoft Corporation 1995.
