Skip to content

Commit

Permalink
Input: implement new force feedback interface
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Anssi Hannula authored and Dmitry Torokhov committed Jul 19, 2006
1 parent 806d41b commit 509ca1a
Show file tree
Hide file tree
Showing 5 changed files with 450 additions and 18 deletions.
2 changes: 1 addition & 1 deletion drivers/input/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Each configuration option enables a list of files.

obj-$(CONFIG_INPUT) += input-core.o
input-core-objs := input.o
input-core-objs := input.o ff-core.o

obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
Expand Down
32 changes: 15 additions & 17 deletions drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs;
struct ff_effect effect;
int __user *ip = (int __user *)p;
int i, t, u, v;
int error;

if (!evdev->exist)
return -ENODEV;
Expand Down Expand Up @@ -460,27 +462,22 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
return 0;

case EVIOCSFF:
if (dev->upload_effect) {
struct ff_effect effect;
int err;

if (copy_from_user(&effect, p, sizeof(effect)))
return -EFAULT;
err = dev->upload_effect(dev, &effect);
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
return -EFAULT;
return err;
} else
return -ENOSYS;
if (copy_from_user(&effect, p, sizeof(effect)))
return -EFAULT;

case EVIOCRMFF:
if (!dev->erase_effect)
return -ENOSYS;
error = input_ff_upload(dev, &effect, file);

return dev->erase_effect(dev, (int)(unsigned long) p);
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
return -EFAULT;

return error;

case EVIOCRMFF:
return input_ff_erase(dev, (int)(unsigned long) p, file);

case EVIOCGEFFECTS:
if (put_user(dev->ff_effects_max, ip))
i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
if (put_user(i, ip))
return -EFAULT;
return 0;

Expand Down Expand Up @@ -669,6 +666,7 @@ static void evdev_disconnect(struct input_handle *handle)
evdev->exist = 0;

if (evdev->open) {
input_flush_device(handle, NULL);
input_close_device(handle);
wake_up_interruptible(&evdev->wait);
list_for_each_entry(list, &evdev->list, node)
Expand Down
Loading

0 comments on commit 509ca1a

Please sign in to comment.