summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFounder Fang <founder.fang@gmail.com>2012-11-21 15:20:31 +0800
committerJiri Kosina <jkosina@suse.cz>2012-11-26 14:18:15 +0100
commit7611e8d26d8dd0e5e132b46e905cb579daf9da1e (patch)
tree5cf31a59a211195fd15d9f6089b79fd64a1bebcf
parent1a1e8c6fada5f6dc48aa5dad453c9d9ebfdc8218 (diff)
downloadop-kernel-dev-7611e8d26d8dd0e5e132b46e905cb579daf9da1e.zip
op-kernel-dev-7611e8d26d8dd0e5e132b46e905cb579daf9da1e.tar.gz
HID: hidraw: fix nonblock read return EAGAIN after device removed
When nonblock read the condition check (file->f_flags & O_NONBLOCK) always be true, signal_pending and device exist checking never get a chance to run, so the user mode code always get EAGAIN even if device removed. move nonblock mode checking to the last can fix this problem. Signed-off-by: Founder Fang <founder.fang@gmail.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hidraw.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 7c47fc3..1d8c021 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -57,10 +57,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
set_current_state(TASK_INTERRUPTIBLE);
while (list->head == list->tail) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
@@ -69,6 +65,10 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
ret = -EIO;
break;
}
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }
/* allow O_NONBLOCK to work well from other threads */
mutex_unlock(&list->read_mutex);
OpenPOWER on IntegriCloud