Microsoft KB Archive/132690

Kernel Mode Drivers Layered Under NDIS Miniport Drivers

PSS ID Number: Q132690 Article last modified on 07-21-1995

3.51

WINDOWS NT

= 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.