aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hidraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hidraw.c')
-rw-r--r--drivers/hid/hidraw.c27
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;
241unlock:
242 mutex_unlock(&minors_lock);
232 243
233 return 0; 244 return ret;
234} 245}
235 246
236static long hidraw_ioctl(struct file *file, unsigned int cmd, 247static 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 }
335out:
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
334void hidraw_report_event(struct hid_device *hid, u8 *data, int len) 351void hidraw_report_event(struct hid_device *hid, u8 *data, int len)