aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@gmail.com>2006-07-19 01:40:22 -0400
committerDmitry Torokhov <dtor@insightbb.com>2006-07-19 01:40:22 -0400
commit509ca1a9383601fdc5612d3d3ba5b981f6eb6c8b (patch)
tree4d7b63c2b108510c11a89dc0ea45efe788fed779 /drivers/input/evdev.c
parent806d41b756fecc1b13584e2b806b76d8934b1679 (diff)
Input: implement new force feedback interface
Implement a new force feedback interface, in which all non-driver-specific operations are separated to a common module. This includes handling effect type validations, locking, etc. The effects are now file descriptor specific instead of the previous strange half-process half-fd specific behaviour. The effect memory of devices is not emptied if the root user opens and closes the device while another user is using effects. This is a minor change and most likely no force feedback aware programs are affected by this negatively. Otherwise the userspace interface is left unaltered. Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4bf48188cc91..12c7ab876c34 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -391,8 +391,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
391 struct evdev *evdev = list->evdev; 391 struct evdev *evdev = list->evdev;
392 struct input_dev *dev = evdev->handle.dev; 392 struct input_dev *dev = evdev->handle.dev;
393 struct input_absinfo abs; 393 struct input_absinfo abs;
394 struct ff_effect effect;
394 int __user *ip = (int __user *)p; 395 int __user *ip = (int __user *)p;
395 int i, t, u, v; 396 int i, t, u, v;
397 int error;
396 398
397 if (!evdev->exist) 399 if (!evdev->exist)
398 return -ENODEV; 400 return -ENODEV;
@@ -460,27 +462,22 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
460 return 0; 462 return 0;
461 463
462 case EVIOCSFF: 464 case EVIOCSFF:
463 if (dev->upload_effect) { 465 if (copy_from_user(&effect, p, sizeof(effect)))
464 struct ff_effect effect; 466 return -EFAULT;
465 int err;
466
467 if (copy_from_user(&effect, p, sizeof(effect)))
468 return -EFAULT;
469 err = dev->upload_effect(dev, &effect);
470 if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
471 return -EFAULT;
472 return err;
473 } else
474 return -ENOSYS;
475 467
476 case EVIOCRMFF: 468 error = input_ff_upload(dev, &effect, file);
477 if (!dev->erase_effect)
478 return -ENOSYS;
479 469
480 return dev->erase_effect(dev, (int)(unsigned long) p); 470 if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
471 return -EFAULT;
472
473 return error;
474
475 case EVIOCRMFF:
476 return input_ff_erase(dev, (int)(unsigned long) p, file);
481 477
482 case EVIOCGEFFECTS: 478 case EVIOCGEFFECTS:
483 if (put_user(dev->ff_effects_max, ip)) 479 i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
480 if (put_user(i, ip))
484 return -EFAULT; 481 return -EFAULT;
485 return 0; 482 return 0;
486 483
@@ -669,6 +666,7 @@ static void evdev_disconnect(struct input_handle *handle)
669 evdev->exist = 0; 666 evdev->exist = 0;
670 667
671 if (evdev->open) { 668 if (evdev->open) {
669 input_flush_device(handle, NULL);
672 input_close_device(handle); 670 input_close_device(handle);
673 wake_up_interruptible(&evdev->wait); 671 wake_up_interruptible(&evdev->wait);
674 list_for_each_entry(list, &evdev->list, node) 672 list_for_each_entry(list, &evdev->list, node)