diff options
Diffstat (limited to 'drivers/hid/uhid.c')
-rw-r--r-- | drivers/hid/uhid.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 93860826d629..31e8379cfd15 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -30,6 +30,7 @@ | |||
30 | struct uhid_device { | 30 | struct uhid_device { |
31 | struct mutex devlock; | 31 | struct mutex devlock; |
32 | struct hid_device *hid; | 32 | struct hid_device *hid; |
33 | struct uhid_event input_buf; | ||
33 | 34 | ||
34 | wait_queue_head_t waitq; | 35 | wait_queue_head_t waitq; |
35 | spinlock_t qlock; | 36 | spinlock_t qlock; |
@@ -156,7 +157,35 @@ try_again: | |||
156 | static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | 157 | static ssize_t uhid_char_write(struct file *file, const char __user *buffer, |
157 | size_t count, loff_t *ppos) | 158 | size_t count, loff_t *ppos) |
158 | { | 159 | { |
159 | return 0; | 160 | struct uhid_device *uhid = file->private_data; |
161 | int ret; | ||
162 | size_t len; | ||
163 | |||
164 | /* we need at least the "type" member of uhid_event */ | ||
165 | if (count < sizeof(__u32)) | ||
166 | return -EINVAL; | ||
167 | |||
168 | ret = mutex_lock_interruptible(&uhid->devlock); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); | ||
173 | len = min(count, sizeof(uhid->input_buf)); | ||
174 | if (copy_from_user(&uhid->input_buf, buffer, len)) { | ||
175 | ret = -EFAULT; | ||
176 | goto unlock; | ||
177 | } | ||
178 | |||
179 | switch (uhid->input_buf.type) { | ||
180 | default: | ||
181 | ret = -EOPNOTSUPP; | ||
182 | } | ||
183 | |||
184 | unlock: | ||
185 | mutex_unlock(&uhid->devlock); | ||
186 | |||
187 | /* return "count" not "len" to not confuse the caller */ | ||
188 | return ret ? ret : count; | ||
160 | } | 189 | } |
161 | 190 | ||
162 | static unsigned int uhid_char_poll(struct file *file, poll_table *wait) | 191 | static unsigned int uhid_char_poll(struct file *file, poll_table *wait) |