Provides for cascaded, or redirected, support of the select or poll request.
#include <sys/types.h> #include <sys/errno.h> int fp_select ( fp, events, rtneventp, notify) struct file *fp; ushort events; ushort *rtneventp; void (*notify)();
Item | Description |
---|---|
fp | Points to the open instance of the device driver, socket, or pipe for which the low-level select operation is intended. |
events |
Identifies the events that are to be checked. There are three
standard event flags defined for the poll and select functions
and one informational flag. The /usr/include/sys/poll.h file
details the event bit definition. The four basic indicators are:
|
rtneventp | Indicates
the returned events pointer. This parameter, passed
by reference, is used to indicate which selected events are true
at the current time. The returned event bits include the requested
events plus an additional error event indicator:
|
notify | Points to a routine to be called when the specified object invokes the selnotify kernel service for an outstanding asynchronous select or poll event request. If no routine is to be called, this parameter must be NULL. |
The fp_select kernel service is a low-level service used by kernel extensions to perform a select operation for an open device, socket, or named pipe. The fp_select kernel service can be used for both synchronous and asynchronous select requests. Synchronous requests report on the current state of a device, and asynchronous requests allow the caller to be notified of future events on a device.
Invocation from a Device Driver's ddselect Routine
A device driver's ddselect routine can call the fp_select kernel service to pass select/poll requests to other device drivers. The ddselect routine for one device invokes the fp_select kernel service, which calls the ddselect routine for a second device, and so on. This is required when event information for the original device depends upon events occurring on other devices. A cascaded chain of select requests can be initiated that involves more than two devices, or a single device can issue fp_select calls to several other devices.
Each ddselect routine should preserve, in its call to the fp_select kernel service, the same POLLSYNC indicator that it received when previously called by the fp_select kernel service.
Invocation from Outside a Device Driver's ddselect Routine
If the fp_select kernel service is invoked outside of the device driver's ddselect routine, the fp_select kernel service sets the POLLSYNC flag, always making the request synchronous. In this case, no notification of future events for the specified device occurs, nor is a notify routine called, if specified. The fp_select kernel service can be used in this manner (unrelated to a poll or select request in progress) to check an object's current status.
Asynchronous Processing and the Use of the notify Routine
For asynchronous requests, the fp_select kernel service allows its callers to register a notify routine to be called by the kernel when specified events become true. When the relevant device driver detects that one or more pending events have become true, it invokes the selnotify kernel service. The selnotify kernel service then calls the notify routine, if one has been registered. Thus, the notify routine is called at interrupt time and must be programmed to run in an interrupt environment.
Use of a notify routine affects both the calling sequence at interrupt time and how the requested information is actually reported. Generalized asynchronous processing entails the following sequence of events:
The following example details a cascaded scenario involving several devices. Suppose that a request has been made for Device A, and Device A depends on Device B, which depends on Device C. When specified events become true at Device C, the selnotify kernel service called from Device C's device driver performs differently depending on whether a notify routine was registered at the time of the request.
Cascaded Processing without the Use of notify Routines
If no notify routine was registered from Device B, then the selnotify kernel service determines that the specified events are to be considered true for the device driver at the head of the cascading chain. (The head of the chain, in this case Device A, is the first device driver to issue the fp_select kernel service from its select routine.) The selnotify kernel service awakens all processes waiting for events that have occurred on Device A.
It is important to note that when no notify routine is used, any device driver in the calling chain that reports an event with the selnotify kernel service causes that event to appear true for the first device in the chain. As a result, any processes waiting for events that have occurred on that first device are awakened.
Cascaded Processing with notify Routines
If, on the other hand, notify routines have been registered throughout the chain, then each interrupting device (by calling the selnotify kernel service) invokes the notify routine for the device above it in the calling chain. Thus in the preceding example, the selnotify kernel service for Device C calls the notify routine registered when Device B's ddselect routine invoked the fp_select kernel service. Device B's notify routine must then decide whether to again call the selnotify kernel service to alert Device A's notify routine. If so, then Device A's notify routine is called, and makes its own determination whether to call another selnotify routine. If it does, the selnotify kernel service wakes up all the processes waiting on occurred events for Device A.
A variation on this scenario involves a cascaded chain in which only some device drivers have registered notify routines. In this case, the selnotify kernel service at each level calls the notify routine for the level above, until a level is encountered for which no notify routine was registered. At this point, all events of interest are determined to be true for the device driver at the head of the cascading chain. If any notify routines were registered in levels above the current level, they are never called.
Returning from the fp_select Kernel Service
The fp_select kernel service does not wait for any selected events to become true, but returns immediately after the call to the object's ddselect routine has completed.
If the object's select routine is successfully called, the return code for the fp_select kernel service is set to the return code provided by the object's ddselect routine.
The fp_select kernel service can be called from the process environment only.
Item | Description |
---|---|
0 | Indicates successful completion. |
EAGAIN | Indicates that the allocation of internal data structures failed. The rtneventp parameter is not updated. |
EINVAL | Indicates that the fp parameter is not a valid file pointer. The rtneventp parameter has the POLLNVAL flag set. |
The fp_select kernel service can also be set to the nonzero return code from the specified object's ddselect routine. The rtneventp parameter has the POLLERR flag set.