Поделиться через


Minimizing Miniport Driver Initialization Time (NDIS 5.1)

Note   NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.

The time spent in driver initialization can significantly impact the total time required to boot the operating system. It is therefore important to minimize driver initialization time. Driver initialization time should be in the 10s of milliseconds or less.

To reduce initialization time, an NDIS miniport driver should do the following:

  • Perform media detection before checking the link speed. If media detection fails (for example, because a network cable is not connected to the NIC), the miniport driver should not attempt to check the link speed.

  • If media detection is successful, the miniport driver should defer link-speed detection to a timer function. Network protocols are not loaded until after the miniport driver is loaded; therefore, the miniport driver should have sufficient time to obtain the link speed before a protocol requests the link speed.

If a miniport driver receives one of these requests: OID_GEN_LINK_SPEED, OID_GEN_CO_LINK_SPEED, OID_GEN_MEDIA_CONNECT_STATUS, or OID_GEN_CO_MEDIA_CONNECT_STATUS, or a request to send a packet before it obtains the media connect status or the link speed, the driver should delay the completion of the request or send operation. The driver should complete the request or send operation after it obtains the media connection status or the link speed. The driver should not fail such a request or a send operation. In Windows XP and later, NDIS allows for three times the normal time-out period for queries of OID_GEN(_CO)_LINK_SPEED and OID_GEN(_CO)_MEDIA_CONNECT_STATUS. Miniport drivers running under earlier versions of the operating system can use NdisMSetAttributesExto set an appropriate time-out interval for queries.

The following pseudocode examples illustrate how to:

  • Handle media detection and link-speed detection during initialization

  • Use a timer function to obtain the link speed and to complete any pending OID requests and send operations

  • Delay completion of OID_GEN(_CO)_LINK_SPEED and OID_GEN(_CO)_MEDIA_CONNECT_STATUS requests if detection of link-speed or media connection status is not finished

  • Schedule send operations if link-speed detection is not finished

The following pseudocode illustrates how to handle media detection and link-speed detection in the context of MiniportInitialize:

If (there is no link pulse on the physical layer interface)
  // The cable is not connected to NIC.
{
  // Do not do link-speed detection.
}
else
{
  Adapter->NegotiationDone = FALSE;
  Command NIC to start the link-speed negotiation.
  Start a timer to check for completion of link-speed detection.
  }

To minimize the time it spends in initialization, the miniport driver should defer link-speed detection to a timer function. The following pseudocode illustrates how to use a timer function to obtain the link speed. After the timer function obtains the link speed, it should complete any pending OID requests and restart any pending send operations.

If (NIC has finished link-speed negotiation)
{
  Adapter->NegotiationDone = TRUE;
  if (Adapter->QueryPending)
  {
    // Complete the pending OID request after getting the link speed.
    NdisMQueryInformationComplete();   // If the miniport driver exports an
// NdisMCoRequestComplete
// function, call
// NdisMCoRequestComplete
// instead.
  }
  if (Adapter->SetPending)
  {
    Send the set filter down to the adapter;
    // The NIC generates an interrupt to indicate the completion
// of the set-filter operation.
  NdisMSendResourcesAvailable();    // Restarts any pending send
                          // operations.
  // This timer does not fire again.
}
else
{
  Restart timer;
}

If a miniport driver has not completed link-speed detection, it should schedule an OID_GEN_LINK_SPEED request or an OID_GEN_CURRENT_PACKET_FILTER request that it receives. The miniport driver should complete such a pending OID request asynchronously in its timer function (see above) after the timer function has completed link-speed detection.

The following pseudocode shows how to schedule an OID_GEN_LINK_SPEED request in MiniportQueryInformationor MiniportCoRequestif link-speed detection is not finished:

if (!Adapter->NegotiationDone && (OID == OID_GEN_LINK_SPEED))
{
  // Save the current OID request.
  Adapter->QueryPending = TRUE;  //Timer function tests this value.
  return NDIS_STATUS_PENDING;

The following pseudocode shows how to schedule an OID_GEN_CURRENT_PACKET_FILTER request in MiniportQueryInformationor MiniportCoRequestif link-speed detection is not finished:

if (!Adapter->NegotiationDone && (OID == OID_GEN_CURRENT_PACKET_FILTER))
{
  // Save the current OID request.
  Adapter->SetPending = TRUE;  //Timer function tests this value.
  return NDIS_STATUS_PENDING;
}

If a serialized miniport driver has not completed link-speed detection, it should schedule any send operations that it receives and restart such operations in a timer function (see above) after the timer function has completed link-speed detection.

The following pseudocode illustrates how to schedule send operations in MiniportSendif link-speed detection is not finished:

if (!Adapter_>NegotiationDone)
return NDIS_STATUS_RESOURCES;  // Force NDIS to resubmit the send
// when link-speed negotiation is
// finished.

The following pseudocode illustrates how to schedule send operations in MiniportSendPacketsif link-speed detection is not finished:

if (!Adapter_>NegotiationDone)
Set the Status member of the NDIS_PACKET_OOB_DATA block
associated with the packet descriptor to NDIS_STATUS_RESOURCES;
return;

A deserialized or connection-oriented miniport driver must queue such send operations internally and complete the send operations after link-speed detection is finished.

 

 

Send comments about this topic to Microsoft