4.2 DPC Handler

Every miniport that manages a device that interrupts must have a MiniportHandleInterrupt function. Even if NDIS completely handles the interrupt, it will always queue a DPC for the miniport, causing the miniport’s MiniportHandleInterrupt handler to run. If MiniportISR processes an interrupt, it controls whether MiniportHandleInterrupt is queued by the value it returns in the InterruptRecognized and QueueMiniportHandleInterrupt arguments. If MiniportISR sets both to TRUE, MiniportHandleInterrupt is queued for execution at IRQL DISPATCH_LEVEL; if it sets InterruptRecognized to FALSE, MiniportHandleInterrupt will not be queued.

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

Assuming it uses interrupts, a miniport handles data receives and send completes in the context of MiniportHandleInterrupt. For instance, if MiniportHandleInterrupt determines that the reason for the interrupt is a receive, it will indicate the data up by calling NDIS in the context of the DPC. Section 4.6 describes how a miniport processes receives.

If the miniport determines that the reason for the interrupt is a send completion, the miniport calls NdisMSendComplete to signify the completion of a packet previously sent to MiniportSend or MiniportSendPackets which returned NDIS_STATUS_PENDING. The send operations of a miniport are described in Section 4.4.

When a miniport is processing a receive, it must not reenable interrupts until MiniportTransferData either has transferred the incoming data to a protocol driver-supplied packet if any protocol driver wants the data or has passed up an entire miniport-allocated packet or array of packets containing the received data. If a miniport-allocated packet is passed up to a protocol driver, and the protocol keeps the packet, the miniport 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 can reenable interrupts.