The select() function is generally most useful with character devices. It is usually used to multiplex reads without polling --- the application calls the select() system call, giving it a list of file descriptors to watch, and the kernel reports back to the program on which file descriptor has woken it up. It is also used as a timer. However, the select() function in your device driver is not directly called by the system call select(), and so the file_operations select() only needs to do a few things. Its arguments are:
If the calling program wants to wait until one of the devices upon
which it is selecting becomes available for the operation it is
interested in, the process will have to be put to sleep until one of
those operations becomes available. This does not require use
of a sleep_on*() function, however. Instead the
select_wait() function is used. (See section
for the definition of the select_wait() function). The sleep
state that select_wait() will cause is the same as that of
sleep_on_interruptible(), and, in fact,
wake_up_interruptible() is used to wake up the process.
However, select_wait() will not make the process go to sleep right away. It returns directly, and the select() function you wrote should then return. The process isn't put to sleep until the system call sys_select(), which originally called your select() function, uses the information given to it by the select_wait() function to put the process to sleep. select_wait() adds the process to the wait queue, but do_select() (called from sys_select()) actually puts the process to sleep by changing the process state to TASK_INTERRUPTIBLE and calling schedule().
The first argument to select_wait() is the same wait_queue that should be used for a sleep_on(), and the second is the select_table that was passed to your select() function.
After having explained all this in excruciating detail, here are two rules to follow:
If you provide a select() function, do not provide timeouts by
setting current->timeout, as the select() mechanism uses
current->timeout, and the two methods cannot co-exist, as there is
only one timeout for each process. Instead, consider using a
timer to provide timeouts. See the description of the
add_timer() function in section for
details.