VOID
MiniportISR(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext
);
MiniportISR is a required function if the driver’s NIC generates interrupts.
If its NIC shares an IRQ with other devices on the same bus, MiniportISR
should return FALSE as quickly as possible whenever it determines that the NIC
did not interrupt.
If the variable at InterruptRecognized is set to FALSE, the value of
this variable is irrelevant because MiniportHandleInterrupt will not be
called.
Any NIC driver should do as little work as possible in its MiniportISR function, deferring I/O operations for each interrupt the NIC generates to the MiniportHandleInterrupt function. A NIC driver’s ISR is not re-entrant, although two instantiations of a MiniportISR function can execute concurrently in SMP machines, particularly if the miniport supports full-duplex sends and receives.
Miniport ISR is called under the following conditions:
If the NIC shares an IRQ with other devices, that miniport’s ISR must be called on every interrupt to determine whether its NIC actually generated the interrupt. If not, MiniportISR should return FALSE immediately so the driver of the device that actually generated the interrupt is called quickly. This strategy maximizes I/O throughput for every device on the same bus.
Miniports that do not provide MiniportDisable/EnableInterrupt functionality must have their ISRs called on every interrupt.
MiniportISR dismisses the interrupt on the NIC, saves whatever state it must about the interrupt, and defers as much of the I/O processing for each interrupt as possible to the MiniportHandleInterrupt function.
After MiniportISR returns control with the variables at InterruptRecognized and QueueMiniportHandleInterrupt set to TRUE, the corresponding MiniportHandleInterrupt function runs at a lower hardware priority (IRQL DISPATCH_LEVEL) than that of the ISR (DIRQL). As a general rule, MiniportHandleInterrupt should do all the work for interrupt-driven I/O operations except for determining whether the NIC actually generated the interrupt, and, if necessary, preserving the type (receive, send, reset...) of interrupt.
However, a driver writer should not rely on a one-to-one correspondence between the execution of MiniportISR and MiniportHandleInterrupt. A MiniportHandleInterrupt function should be written to handle the I/O processing for more than one NIC interrupt. Its MiniportISR and MiniportHandleInterrupt functions can run concurrently in SMP machines. Moreover, as soon as MiniportISR acknowledges a NIC interrupt, the NIC can generate another interrupt, while the MiniportHandleInterrupt DPC can be queued for execution once for such a sequence of interrupts.
The MiniportHandleInterrupt function is not queued if the driver’s MiniportHalt or MiniportInitialize function is currently executing.
If MiniportISR shares resources, such as NIC registers or state variables, with another MiniportXxx that runs at lower IRQL, that MiniportXxx must call NdisMSychronizeWithInterrupt so the driver’s MiniportSynchronizeISR function will access those shared resources in a synchronized and multiprocessor-safe manner. Otherwise, while it is accessing the shared resources, that MiniportXxx function can be pre-empted by MiniportISR, possibly undoing the work just done by MiniportXxx.
By default, MiniportISR runs at DIRQL, in particular at the DIRQL assigned when the driver initialized the interrupt object with NdisMRegisterInterrupt. Therefore, MiniportIsr can call only a subset of the NDIS library functions, such as the NdisRawXxx or NdisRead/WriteRegisterXxx functions that are safe to call at any IRQL.
MiniportDisableInterrupt, MiniportEnableInterrupt, MiniportHalt, MiniportHandleInterrupt, MiniportInitialize, MiniportSynchronizeISR, NdisMRegisterInterrupt, NdisMSynchronizeWithInterrupt, NdisRawReadPortBufferUchar, NdisRawReadPortBufferUlong, NdisRawReadPortBufferUshort, NdisRawReadPortUchar, NdisRawReadPortUlong, NdisRawReadPortUshort, NdisRawWritePortBufferUchar, NdisRawWritePortBufferUlong, NdisRawWritePortBufferUshort, NdisRawWritePortUchar, NdisRawWritePortUlong, NdisRawWritePortUshort, NdisReadRegisterUchar, NdisReadRegisterUlong, NdisReadRegisterUshort, NdisWriteRegisterUchar, NdisWriteRegisterUlong, NdisWriteRegisterUshort