From 5be16755af62069744fbe4b0533d4c951a259bf3 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 10 Jun 2012 15:16:17 +0200 Subject: [PATCH] --- yaml --- r: 316069 b: refs/heads/master c: 6664ef72a47459f883d3409ca9b2fa200015704b h: refs/heads/master i: 316067: 4c573bf90d143071906c2bd9e7434d0f1e703473 v: v3 --- [refs] | 2 +- trunk/drivers/hid/uhid.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index f72b0c2bff9a..e82cbdb21d58 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d937ae5fae17e63aaa97f029be221a6516b25475 +refs/heads/master: 6664ef72a47459f883d3409ca9b2fa200015704b diff --git a/trunk/drivers/hid/uhid.c b/trunk/drivers/hid/uhid.c index 93860826d629..31e8379cfd15 100644 --- a/trunk/drivers/hid/uhid.c +++ b/trunk/drivers/hid/uhid.c @@ -30,6 +30,7 @@ struct uhid_device { struct mutex devlock; struct hid_device *hid; + struct uhid_event input_buf; wait_queue_head_t waitq; spinlock_t qlock; @@ -156,7 +157,35 @@ static ssize_t uhid_char_read(struct file *file, char __user *buffer, static ssize_t uhid_char_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - return 0; + struct uhid_device *uhid = file->private_data; + int ret; + size_t len; + + /* we need at least the "type" member of uhid_event */ + if (count < sizeof(__u32)) + return -EINVAL; + + ret = mutex_lock_interruptible(&uhid->devlock); + if (ret) + return ret; + + memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); + len = min(count, sizeof(uhid->input_buf)); + if (copy_from_user(&uhid->input_buf, buffer, len)) { + ret = -EFAULT; + goto unlock; + } + + switch (uhid->input_buf.type) { + default: + ret = -EOPNOTSUPP; + } + +unlock: + mutex_unlock(&uhid->devlock); + + /* return "count" not "len" to not confuse the caller */ + return ret ? ret : count; } static unsigned int uhid_char_poll(struct file *file, poll_table *wait)