diff options
Diffstat (limited to 'drivers/hid/hidraw.c')
-rw-r--r-- | drivers/hid/hidraw.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 47d70c523d93..e1f07483691f 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/smp_lock.h> | ||
36 | 35 | ||
37 | #include <linux/hidraw.h> | 36 | #include <linux/hidraw.h> |
38 | 37 | ||
@@ -109,6 +108,12 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t | |||
109 | int ret = 0; | 108 | int ret = 0; |
110 | 109 | ||
111 | mutex_lock(&minors_lock); | 110 | mutex_lock(&minors_lock); |
111 | |||
112 | if (!hidraw_table[minor]) { | ||
113 | ret = -ENODEV; | ||
114 | goto out; | ||
115 | } | ||
116 | |||
112 | dev = hidraw_table[minor]->hid; | 117 | dev = hidraw_table[minor]->hid; |
113 | 118 | ||
114 | if (!dev->hid_output_raw_report) { | 119 | if (!dev->hid_output_raw_report) { |
@@ -212,9 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
212 | unsigned int minor = iminor(inode); | 217 | unsigned int minor = iminor(inode); |
213 | struct hidraw *dev; | 218 | struct hidraw *dev; |
214 | struct hidraw_list *list = file->private_data; | 219 | struct hidraw_list *list = file->private_data; |
220 | int ret; | ||
215 | 221 | ||
216 | if (!hidraw_table[minor]) | 222 | mutex_lock(&minors_lock); |
217 | return -ENODEV; | 223 | if (!hidraw_table[minor]) { |
224 | ret = -ENODEV; | ||
225 | goto unlock; | ||
226 | } | ||
218 | 227 | ||
219 | list_del(&list->node); | 228 | list_del(&list->node); |
220 | dev = hidraw_table[minor]; | 229 | dev = hidraw_table[minor]; |
@@ -227,10 +236,12 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
227 | kfree(list->hidraw); | 236 | kfree(list->hidraw); |
228 | } | 237 | } |
229 | } | 238 | } |
230 | |||
231 | kfree(list); | 239 | kfree(list); |
240 | ret = 0; | ||
241 | unlock: | ||
242 | mutex_unlock(&minors_lock); | ||
232 | 243 | ||
233 | return 0; | 244 | return ret; |
234 | } | 245 | } |
235 | 246 | ||
236 | static long hidraw_ioctl(struct file *file, unsigned int cmd, | 247 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
@@ -244,6 +255,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
244 | 255 | ||
245 | mutex_lock(&minors_lock); | 256 | mutex_lock(&minors_lock); |
246 | dev = hidraw_table[minor]; | 257 | dev = hidraw_table[minor]; |
258 | if (!dev) { | ||
259 | ret = -ENODEV; | ||
260 | goto out; | ||
261 | } | ||
247 | 262 | ||
248 | switch (cmd) { | 263 | switch (cmd) { |
249 | case HIDIOCGRDESCSIZE: | 264 | case HIDIOCGRDESCSIZE: |
@@ -317,6 +332,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
317 | 332 | ||
318 | ret = -ENOTTY; | 333 | ret = -ENOTTY; |
319 | } | 334 | } |
335 | out: | ||
320 | mutex_unlock(&minors_lock); | 336 | mutex_unlock(&minors_lock); |
321 | return ret; | 337 | return ret; |
322 | } | 338 | } |
@@ -329,6 +345,7 @@ static const struct file_operations hidraw_ops = { | |||
329 | .open = hidraw_open, | 345 | .open = hidraw_open, |
330 | .release = hidraw_release, | 346 | .release = hidraw_release, |
331 | .unlocked_ioctl = hidraw_ioctl, | 347 | .unlocked_ioctl = hidraw_ioctl, |
348 | .llseek = noop_llseek, | ||
332 | }; | 349 | }; |
333 | 350 | ||
334 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) | 351 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) |