| From: Jiri Kosina <jkosina@suse.cz> |
| Date: Fri, 10 Jan 2020 15:32:51 +0100 |
| Subject: HID: hidraw, uhid: Always report EPOLLOUT |
| |
| commit 9e635c2851df6caee651e589fbf937b637973c91 upstream. |
| |
| hidraw and uhid device nodes are always available for writing so we should |
| always report EPOLLOUT and EPOLLWRNORM bits, not only in the cases when |
| there is nothing to read. |
| |
| Reported-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Fixes: be54e7461ffdc ("HID: uhid: Fix returning EPOLLOUT from uhid_char_poll") |
| Fixes: 9f3b61dc1dd7b ("HID: hidraw: Fix returning EPOLLOUT from hidraw_poll") |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| [bwh: Backported to 3.16: |
| - Use unsigned int type instead of __poll_t |
| - s/EPOLL/POLL/g] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/hid/hidraw.c | 7 ++++--- |
| drivers/hid/uhid.c | 5 +++-- |
| 2 files changed, 7 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/hid/hidraw.c |
| +++ b/drivers/hid/hidraw.c |
| @@ -262,13 +262,14 @@ out: |
| static unsigned int hidraw_poll(struct file *file, poll_table *wait) |
| { |
| struct hidraw_list *list = file->private_data; |
| + unsigned int mask = POLLOUT | POLLWRNORM; /* hidraw is always writable */ |
| |
| poll_wait(file, &list->hidraw->wait, wait); |
| if (list->head != list->tail) |
| - return POLLIN | POLLRDNORM; |
| + mask |= POLLIN | POLLRDNORM; |
| if (!list->hidraw->exist) |
| - return POLLERR | POLLHUP; |
| - return POLLOUT | POLLWRNORM; |
| + mask |= POLLERR | POLLHUP; |
| + return mask; |
| } |
| |
| static int hidraw_open(struct inode *inode, struct file *file) |
| --- a/drivers/hid/uhid.c |
| +++ b/drivers/hid/uhid.c |
| @@ -720,13 +720,14 @@ unlock: |
| static unsigned int uhid_char_poll(struct file *file, poll_table *wait) |
| { |
| struct uhid_device *uhid = file->private_data; |
| + unsigned int mask = POLLOUT | POLLWRNORM; /* uhid is always writable */ |
| |
| poll_wait(file, &uhid->waitq, wait); |
| |
| if (uhid->head != uhid->tail) |
| - return POLLIN | POLLRDNORM; |
| + mask |= POLLIN | POLLRDNORM; |
| |
| - return POLLOUT | POLLWRNORM; |
| + return mask; |
| } |
| |
| static const struct file_operations uhid_fops = { |