aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/uinput.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/input/misc/uinput.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/input/misc/uinput.c')
-rw-r--r--drivers/input/misc/uinput.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 360698553eb5..736056897e50 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
37#include <linux/fs.h> 37#include <linux/fs.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39#include <linux/uinput.h> 39#include <linux/uinput.h>
40#include <linux/input/mt.h>
40#include "../input-compat.h" 41#include "../input-compat.h"
41 42
42static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 43static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -301,10 +302,14 @@ static int uinput_validate_absbits(struct input_dev *dev)
301 int retval = 0; 302 int retval = 0;
302 303
303 for (cnt = 0; cnt < ABS_CNT; cnt++) { 304 for (cnt = 0; cnt < ABS_CNT; cnt++) {
305 int min, max;
304 if (!test_bit(cnt, dev->absbit)) 306 if (!test_bit(cnt, dev->absbit))
305 continue; 307 continue;
306 308
307 if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { 309 min = input_abs_get_min(dev, cnt);
310 max = input_abs_get_max(dev, cnt);
311
312 if ((min != 0 || max != 0) && max <= min) {
308 printk(KERN_DEBUG 313 printk(KERN_DEBUG
309 "%s: invalid abs[%02x] min:%d max:%d\n", 314 "%s: invalid abs[%02x] min:%d max:%d\n",
310 UINPUT_NAME, cnt, 315 UINPUT_NAME, cnt,
@@ -346,8 +351,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
346{ 351{
347 struct uinput_user_dev *user_dev; 352 struct uinput_user_dev *user_dev;
348 struct input_dev *dev; 353 struct input_dev *dev;
349 char *name; 354 int i;
350 int i, size;
351 int retval; 355 int retval;
352 356
353 if (count != sizeof(struct uinput_user_dev)) 357 if (count != sizeof(struct uinput_user_dev))
@@ -361,30 +365,25 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
361 365
362 dev = udev->dev; 366 dev = udev->dev;
363 367
364 user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); 368 user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev));
365 if (!user_dev) 369 if (IS_ERR(user_dev))
366 return -ENOMEM; 370 return PTR_ERR(user_dev);
367
368 if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
369 retval = -EFAULT;
370 goto exit;
371 }
372 371
373 udev->ff_effects_max = user_dev->ff_effects_max; 372 udev->ff_effects_max = user_dev->ff_effects_max;
374 373
375 size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; 374 /* Ensure name is filled in */
376 if (!size) { 375 if (!user_dev->name[0]) {
377 retval = -EINVAL; 376 retval = -EINVAL;
378 goto exit; 377 goto exit;
379 } 378 }
380 379
381 kfree(dev->name); 380 kfree(dev->name);
382 dev->name = name = kmalloc(size, GFP_KERNEL); 381 dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE,
383 if (!name) { 382 GFP_KERNEL);
383 if (!dev->name) {
384 retval = -ENOMEM; 384 retval = -ENOMEM;
385 goto exit; 385 goto exit;
386 } 386 }
387 strlcpy(name, user_dev->name, size);
388 387
389 dev->id.bustype = user_dev->id.bustype; 388 dev->id.bustype = user_dev->id.bustype;
390 dev->id.vendor = user_dev->id.vendor; 389 dev->id.vendor = user_dev->id.vendor;
@@ -406,8 +405,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
406 goto exit; 405 goto exit;
407 if (test_bit(ABS_MT_SLOT, dev->absbit)) { 406 if (test_bit(ABS_MT_SLOT, dev->absbit)) {
408 int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; 407 int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
409 input_mt_create_slots(dev, nslot); 408 input_mt_init_slots(dev, nslot);
410 input_set_events_per_packet(dev, 6 * nslot);
411 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { 409 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
412 input_set_events_per_packet(dev, 60); 410 input_set_events_per_packet(dev, 60);
413 } 411 }
@@ -622,7 +620,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
622 struct uinput_ff_upload ff_up; 620 struct uinput_ff_upload ff_up;
623 struct uinput_ff_erase ff_erase; 621 struct uinput_ff_erase ff_erase;
624 struct uinput_request *req; 622 struct uinput_request *req;
625 int length;
626 char *phys; 623 char *phys;
627 624
628 retval = mutex_lock_interruptible(&udev->mutex); 625 retval = mutex_lock_interruptible(&udev->mutex);
@@ -680,29 +677,24 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
680 retval = uinput_set_bit(arg, swbit, SW_MAX); 677 retval = uinput_set_bit(arg, swbit, SW_MAX);
681 break; 678 break;
682 679
680 case UI_SET_PROPBIT:
681 retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
682 break;
683
683 case UI_SET_PHYS: 684 case UI_SET_PHYS:
684 if (udev->state == UIST_CREATED) { 685 if (udev->state == UIST_CREATED) {
685 retval = -EINVAL; 686 retval = -EINVAL;
686 goto out; 687 goto out;
687 } 688 }
688 length = strnlen_user(p, 1024); 689
689 if (length <= 0) { 690 phys = strndup_user(p, 1024);
690 retval = -EFAULT; 691 if (IS_ERR(phys)) {
691 break; 692 retval = PTR_ERR(phys);
693 goto out;
692 } 694 }
695
693 kfree(udev->dev->phys); 696 kfree(udev->dev->phys);
694 udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); 697 udev->dev->phys = phys;
695 if (!phys) {
696 retval = -ENOMEM;
697 break;
698 }
699 if (copy_from_user(phys, p, length)) {
700 udev->dev->phys = NULL;
701 kfree(phys);
702 retval = -EFAULT;
703 break;
704 }
705 phys[length - 1] = '\0';
706 break; 698 break;
707 699
708 case UI_BEGIN_FF_UPLOAD: 700 case UI_BEGIN_FF_UPLOAD:
@@ -811,6 +803,7 @@ static const struct file_operations uinput_fops = {
811#ifdef CONFIG_COMPAT 803#ifdef CONFIG_COMPAT
812 .compat_ioctl = uinput_compat_ioctl, 804 .compat_ioctl = uinput_compat_ioctl,
813#endif 805#endif
806 .llseek = no_llseek,
814}; 807};
815 808
816static struct miscdevice uinput_misc = { 809static struct miscdevice uinput_misc = {