diff options
Diffstat (limited to 'drivers/hid/hidraw.c')
-rw-r--r-- | drivers/hid/hidraw.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 36fa77b40ffb..3b6f7bf5a77e 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -96,6 +96,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
96 | } | 96 | } |
97 | 97 | ||
98 | kfree(list->buffer[list->tail].value); | 98 | kfree(list->buffer[list->tail].value); |
99 | list->buffer[list->tail].value = NULL; | ||
99 | list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); | 100 | list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); |
100 | } | 101 | } |
101 | out: | 102 | out: |
@@ -300,6 +301,7 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
300 | struct hidraw *dev; | 301 | struct hidraw *dev; |
301 | struct hidraw_list *list = file->private_data; | 302 | struct hidraw_list *list = file->private_data; |
302 | int ret; | 303 | int ret; |
304 | int i; | ||
303 | 305 | ||
304 | mutex_lock(&minors_lock); | 306 | mutex_lock(&minors_lock); |
305 | if (!hidraw_table[minor]) { | 307 | if (!hidraw_table[minor]) { |
@@ -317,6 +319,9 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
317 | kfree(list->hidraw); | 319 | kfree(list->hidraw); |
318 | } | 320 | } |
319 | } | 321 | } |
322 | |||
323 | for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) | ||
324 | kfree(list->buffer[i].value); | ||
320 | kfree(list); | 325 | kfree(list); |
321 | ret = 0; | 326 | ret = 0; |
322 | unlock: | 327 | unlock: |
@@ -446,12 +451,17 @@ int hidraw_report_event(struct hid_device *hid, u8 *data, int len) | |||
446 | int ret = 0; | 451 | int ret = 0; |
447 | 452 | ||
448 | list_for_each_entry(list, &dev->list, node) { | 453 | list_for_each_entry(list, &dev->list, node) { |
454 | int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1); | ||
455 | |||
456 | if (new_head == list->tail) | ||
457 | continue; | ||
458 | |||
449 | if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) { | 459 | if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) { |
450 | ret = -ENOMEM; | 460 | ret = -ENOMEM; |
451 | break; | 461 | break; |
452 | } | 462 | } |
453 | list->buffer[list->head].len = len; | 463 | list->buffer[list->head].len = len; |
454 | list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1); | 464 | list->head = new_head; |
455 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 465 | kill_fasync(&list->fasync, SIGIO, POLL_IN); |
456 | } | 466 | } |
457 | 467 | ||