3.2.5 Polling Timers

Some miniports control devices that do not generate interrupts, that is, devices that must be polled. Such a miniport does not call NdisMRegisterInterrupt. Rather, the miniport allocates one or more timer objects that will be used to poll the device.

Some miniports for NICs that interrupt choose to turn off some or all interrupts and poll their device instead. Such a miniport must also set up a timer or timers.

MiniportInitialize calls NdisMInitializeTimer to initialize a timer object for each timer the miniport will require. NdisMInitializeTimer associates a miniport-supplied timer function with the timer being initialized. When the timer expires, this MiniportTimer function is called.

NDIS provides two types of timers, one-shot timers and periodic timers. When a one-shot timer is set by calling NdisMSetTimer, and the timer expires, it must be reset by a call to NdisMSetTimer. This requirement can cause the wait time to drift due to the time it takes on each expiration to reset the timer. A periodic timer, once set, continues to expire every requested time interval. Such a periodic timer is well suited to polling within a miniport. Once set with a call to NdisMSetPeriodicTimer, the timer will continue to expire causing the associated timer function to be called until the timer is reset in a subsequent call to NdisMSetPeriodicTimer or cleared with a call to NdisMCancelTimer.

If a timer function shares resources with any other miniport function, access must be protected.

If the function(s) with which a timer function shares resources runs at the same IRQL (DISPATCH_LEVEL), access to those resources is synchronized with a spin lock. Any function that needs to acquire the previously initialized spin lock does so by calling NdisDprAcquireSpinLock and NdisDprReleaseSpinLock, both of which are faster than calling NdisAcquireSpinLock and NdisReleaseSpinLock.

If the timer function shares resources with MiniportISR or MiniportDisableInterrupt, access must be synchronized by calling NdisMSynchronizeWithInterrupt. The miniport performs any timer-related operations on the shared resources, typically device registers, within its MiniportSynchronizeISR function, whose address is passed to NdisMSynchronizeWithInterrupt.