diff options
author | Founder Fang <founder.fang@gmail.com> | 2012-11-21 15:20:31 +0800 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-11-26 14:18:15 +0100 |
commit | 7611e8d26d8dd0e5e132b46e905cb579daf9da1e (patch) | |
tree | 5cf31a59a211195fd15d9f6089b79fd64a1bebcf | |
parent | 1a1e8c6fada5f6dc48aa5dad453c9d9ebfdc8218 (diff) | |
download | op-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.c | 8 |
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); |