HwTimer Routine

A miniport driver that does not have a HwInterrupt routine because it manages all HBA I/O operations by polling should have a HwTimer routine. However, miniport drivers with HwInterrupt routines frequently have HwTimer routines as well.

While a miniport driver can call ScsiPortStallExecution to wait for a state change on the HBA, miniport drivers should never call this routine to wait for longer than one millisecond except, possibly, for an operation performed only when a miniport is initializing. ScsiPortStallExecution ties up the processor for the given interval, preventing other code in the system from doing useful work.

Instead of calling ScsiPortStallExecution with large input intervals and wasting many CPU cycles, a miniport driver should have a HwTimer routine. One or more HwTimer routines are particularly useful if the HBA does not generate a completion interrupt for every operation or if any commonly requested operation, such as a bus reset, takes longer than a millisecond.

After the HBA has been programmed for such an operation, the miniport driver calls ScsiPortNotification with the NotificationType RequestTimerCall, a pointer to the device extension containing context about the operation, its HwTimer routine, and a driver-determined interval.

HwTimer is called once for each such call to ScsiPortNotification, which can be called from the HwTimer routine itself. However, any call to ScsiPortNotification with the NotificationType RequestTimerCall overrides a preceding call for which the specified interval has not expired. That is, there is only one outstanding request to call a miniport's HwTimer routine at any given moment.

The interval passed in to ScsiPortNotification is in microseconds but the minimum resolution for each call is approximately ten milliseconds. An input interval of zero cancels the preceding request to call the HwTimer routine, provided it has not been called or dispatched for execution on another processor already. ScsiPortNotification calls the HwTimer routine either as a DPC or synchronized with the HwInterrupt routine so that it cannot execute concurrently while the HwTimer routine is running.