Previous Next

DPC Handler

Every miniport driver that manages a network interface card (NIC) that interrupts must have a MiniportHandleInterrupt function. Even if NDIS completely handles the interrupt, it always queues a deferred procedure call (DPC) for the miniport driver, causing the miniport driver’s MiniportHandleInterrupt handler to run. If MiniportISR processes an interrupt, it controls whether MiniportHandleInterrupt is queued by the value MiniportISR returns in the InterruptRecognized and QueueMiniportHandleInterrupt arguments. If MiniportISR sets QueueMiniportHandleInterrupt to TRUE, MiniportHandleInterrupt is queued for execution at IRQL = DISPATCH_LEVEL.

MiniportHandleInterrupt is called after interrupts have been disabled on the NIC by the MiniportISR or MiniportDisableInterrupt function. MiniportHandleInterrupt should read whatever data it needs to finish processing the interrupt-driven I/O operation. MiniportHandleInterrupt then reenables interrupts on the NIC, either by letting NDIS call the miniport driver’s MiniportEnableInterrupt function after MiniportHandleInterrupt returns control or by enabling the interrupt from within MiniportHandleInterrupt, which is faster. Until interrupts are reenabled, no further interrupts can occur on the NIC. To ensure that no receive data is missed, MiniportHandleInterrupt should reenable interrupts as quickly as possible.

A miniport driver that processes interrupts handles data receives and send completes in the context of its MiniportHandleInterrupt function. For example, if MiniportHandleInterrupt determines that the reason for the interrupt is a receive, it indicates the data up by calling NdisMIndicateReceivePacket, NdisMCoIndicateReceivePacket, or NdisMXxxIndicateReceive in the context of the DPC. For more information about how a miniport driver processes receives, see Receiving Data.

If a connectionless miniport driver determines that the reason for the interrupt is a send completion, it calls NdisMSendComplete to signal the completion of a packet previously sent to MiniportSend or MiniportSendPackets. Similarly, if a connection-oriented miniport driver determines that the reason for the interrupt is a send completion, it calls NdisMCoSendComplete to signal the completion of a packet that was previously sent to MiniportCoSendPackets, which returned NDIS_STATUS_PENDING. The send operations of a miniport driver are described in Sending Packets.

Sustained bursts of network activity, which are typically data receives, can force a miniport driver's MiniportHandleInterrupt function to run for a long time, handling outstanding receive and send-completion events from the NIC. However, MiniportHandleInterrupt should not continue to run indefinitely to handle such outstanding events because MiniportHandleInterrupt runs at DISPATCH_LEVEL and thus prevents all other threads that run at DISPATCH_LEVEL or lower from running on a particular processor. Therefore, MiniportHandleInterrupt should limit the time it spends handling outstanding events. For example, MiniportHandleInterrupt might limit the number of iterations it executes based on the total number of receive descriptors on the NIC.

When a miniport driver processes a receive, it must not reenable interrupts until either of the following has occurred:

If a miniport driver-allocated packet is passed up to a protocol driver and the protocol keeps the packet, the miniport driver must supply a new empty packet for the next receive. After it has completely processed the receive and is prepared for the next receive, the miniport driver can reenable interrupts.