HOWTO: Ndis Intermediate Driver Models

ID: Q214455


The information in this article applies to:


SUMMARY

Before Microsoft introduced Ndis Miniports, IHVs (Independent Hardware Vendors) had to develop Full-MAC Ndis drivers. A Full-MAC driver is the piece of code that allows the operating system to interface with the adapter hardware.

Microsoft quickly realized that there was a lot of common code among Full-MAC drivers. Microsoft optimized this common code, and moved it into the Ndis wrapper, creating the Ndis Miniport model. With the Miniport model, IHVs only develop the code that is specific to their hardware.

The Ndis wrapper handles all common issues, such as synchronization and serialization. Access to the adapters under a Miniport are serialized and controlled by a Miniport Spin Lock acquired by the wrapper. The net result is that developing Ndis drivers for new adapters is greatly simplified. The drawback of this model is that it requires developers to strictly adhere to the Ndis Miniport API set.

Because the wrapper handles the serialization issues, nonNdis, kernel-mode calls can not be used. This is fine for most of the Ndis development community. There are some cases, however, where nonstandard hardware requires certain features and services not provided in the Ndis Miniport API set. To address these cases Microsoft developed the Intermediate driver model.


MORE INFORMATION

The original Intermediate driver model

: The original Intermediate driver model was introduced with Windows NT 4.0. A driver was identified to the Ndis wrapper as an intermediate driver by setting the appropriate bit in the NdisMSetAttributesEx(…) call in the driver's InitializeHandler. The following example is the NdisMSetAttributesEx(…) call for an Ndis 4.0 Intermediate driver:

Sample Code


NdisMSetAttributesEx(MiniportAdapterHandle,
                      AdapterInList,
                      0,
                      _ATTRIBUTE_INTERMEDIATE_DRIVER|
                      NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT|
                      NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT,
                      0); 
The fourth parameter in this call specifies that this is an intermediate driver.

The Intermediate driver model provides developers with a method of switching into and out of "Miniport" mode; Miniport mode being identified as anytime the Ndis wrapper holds the Miniport Spin Lock. This allowed the driver developer to perform nonNdis functions, such as calls into the kernel (Ke…) or the IoManager (Io…), when not in Miniport mode, and to use the Ndis Miniport API set when in Miniport mode. When in the Miniport mode, access to the adapter(s) is still serialized.

A normal sequence of operation is for a driver to call one of the Ndis Intermediate synchronization functions, such as NdisIMSwitchToMiniport (…), perform the required NdisM… functions, and then call NdisIMRevertBack(…) to switch back out of Miniport mode.

This model has been incorrectly referred to in the past as the "Full Duplex" model. This reference is incorrect. It is true that all Intermediate drivers are considered to be full duplex; however, a full duplex driver is not necessarily an Intermediate driver. Full Duplex drivers are drivers that can simultaneously send and receive packets. Full Duplex only affects performance when running on SMP machines. The Full Duplex capability of Ndis is documented in the Windows NT DDK.

In addition to the overhead of adding another component to the network stack, Microsoft also determined that the process of switching into and out of Miniport mode was very expensive in terms of performance. Because of this performance hit, Microsoft has introduced another driver model, the Deserialized model. The Deserialized model provides the same capabilities as the Intermediate driver model, without incurring the performance hit of switching into and out of Miniport mode.

Ndis Deserialized Miniports

The Deserialized driver model is introduced with Windows NT 4.0 Service pack 3, and is intended to replace the Ndis Intermediate model described above. The following paragraphs describe the Deserialized model.

Most of the Miniport API set [NdisM…(…) functions] perform a check to make sure the Miniport Spin Lock is held before they execute. If the lock is not held, then an assert is raised. This is usually caused by an NdisM…. call from a nonMiniport driver. As mentioned above, the Ndis wrapper provides necessary serialization through a Miniport. The Deserialized model provides a way for a driver to inform the wrapper that the Ndis-supplied serialization is not required. This means that a Deserialized driver is reentrant, and the driver's developer must now include the necessary synchronization and shared resource protection mechanisms in the driver code. A driver is identified to the Ndis wrapper as a Deserialized driver by setting the appropriate bit in the NdisMSetAttributesEx(…) call in the driver's InitializeHandler. The following example is the NdisMSetAttributesEx(…) call for a Deserialized driver:

NdisMSetAttributesEx(MiniportAdapterHandle,
                       AdapterInList,
                       0,
                       NDIS_ATTRIBUTE_DESERIALIZE |
                       NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT|
                       NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT  ,
                       0);
 
The fourth parameter in this call specifies that this is a Deserialized driver.

Because the wrapper does not first check to see if the Miniport Lock is held before executing NdisM… code in a Deserialized driver, it is possible to intermix NdisM… calls and nonNdisM… calls in the same driver. It is the responsibility of the Deserialized driver developer to ensure the necessary synchronization mechanisms are in place.

Conclusion

Microsoft has determined that the performance penalties incurred in an Ndis Intermediate driver are unacceptable, and has abandoned the Intermediate model. All development in this area should follow the Ndis Deserialized model.

Additional query words:


Keywords          : kbDDK kbKMode kbNDIS kbNTOS400 
Version           : winnt:4.0
Platform          : winnt 
Issue type        : kbhowto 

Last Reviewed: April 7, 1999