|
|
Timeouts can be used to synchronize state information between hardware and drivers. Timeouts are used under several circumstances, the most common including:
The following DDI functions are used to implement timeouts:
The following ODDI functions are used to implement timeouts:
Busy hardware may force drivers to queue up jobs and invoke timeout functions with callback functions for delayed processing of the jobs. When triggered, the status of the hardware is verified and then the callback function continues normal activity (in this case, issuing I/O requests to devices).
Drivers supplement their hardware interactions with asynchronous callbacks through a timeout mechanism. Driver processing is dependent upon hardware interrupts, and missed interrupts could complicate driver-hardware interactions by delaying, and sometimes even completely stop all further I/O. This is especially true when drivers work with job queues and job completion is indicated by hardware interrupts. In this context, callback functions verify sanity of the underlying hardware and if necessary, reset malfunctioning boards to known states before resuming normal activity. To ensure that the callback is perpetual, the callback function must be rescheduled through a call to a timeout function as the last step in the callback processing.
For those situations that require a limit on how long a process may block, timeout functions can be used in conjunction with synchronization variables to ensure that the blocked context is awakened after a certain period of time. A common situation would involve blocking a context to wait for a hardware-generated event. As a backup strategy, the driver function that suspends the context can optionally schedule a callback function through calls to one of the timeout functions. If the expected hardware events do not happen, the callback function will unblock the process.
The timeout functions take arguments that specify the function to execute, an argument to pass to the function, the number of clock ticks to wait until before calling the function, and the interrupt priority at which the function will be called. sdi_timeout( ) has an additional argument that points to the SCSI address of the HBA. Periodic timers, where the specified function is called repeatedly at a specified interval instead of just once, are implemented with a flag that is logically OR'ed into the ticks argument. The repeating timer can be canceled by untimeout(D3), just like any other timeout.
Drivers should be careful to cancel any pending timeout functions that access data structures before these structures are de-initialized or deallocated.
All timeout functions are cancelled with the untimeout(D3) or untimeout(D3oddi) function. On uniprocessor systems, if any function called by the pending timeout request is running, untimeout( ) has no effect. On multiprocessor systems, however, if untimeout( ) is called while any function called by the pending timeout request is running, untimeout( ) does not return until the function completes.
Note that any function that runs as a result of a call to a timeout function cannot use untimeout( ) to cancel itself.
A periodic timer can be canceled by untimeout( ) just like any other timeout.
The following ODDI functions are used to implement timeouts:
UDI drivers use the udi_timer_start( ) function for timeout functionality. udi_timer_start_repeating( ) is similar to a call to itimeout( ) or timeout( ) with the TO_PERIODIC flag set. udi_timer_cancel( ) is similar to untimeout( ).