]> git.karo-electronics.de Git - karo-tx-linux.git/commit
poll: add poll_requested_events() function
authorHans Verkuil <hverkuil@xs4all.nl>
Mon, 24 Oct 2011 14:58:47 +0000 (01:58 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 25 Oct 2011 09:08:02 +0000 (20:08 +1100)
commit78f5357acb2875de14d01f2e881c2b6486f6a2b0
treed059673847e757ffe815108abeaceb83459bf6bd
parent5a72073c389d596656707b7dcd0d8385d7fb91f5
poll: add poll_requested_events() function

In some cases the poll() implementation in a driver has to do different
things depending on the events the caller wants to poll for.  An example
is when a driver needs to start a DMA engine if the caller polls for
POLLIN, but doesn't want to do that if POLLIN is not requested but instead
only POLLOUT or POLLPRI is requested.  This is something that can happen
in the video4linux subsystem.

Unfortunately, the current epoll/poll/select implementation doesn't
provide that information reliably.  The poll_table_struct does have it: it
has a key field with the event mask.  But once a poll() call matches one
or more bits of that mask any following poll() calls are passed a NULL
poll_table_struct pointer.

The solution is to set the qproc field to NULL in poll_table_struct once
poll() matches the events, not the poll_table_struct pointer itself.  That
way drivers can obtain the mask through a new poll_requested_events
inline.

The poll_table_struct can still be NULL since some kernel code calls it
internally (netfs_state_poll() in ./drivers/staging/pohmelfs/netfs.h).  In
that case poll_requested_events() returns ~0 (i.e.  all events).

Since eventpoll always leaves the key field at ~0 instead of using the
requested events mask, that source was changed as well to properly fill in
the key field.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Jonathan Corbet <corbet@lwn.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Davide Libenzi <davidel@xmailserver.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/eventpoll.c
fs/select.c
include/linux/poll.h