The patch titled input: adapt uinput for the new force feedback interface has been removed from the -mm tree. Its filename is input-adapt-uinput-for-the-new-force-feedback-interface.patch This patch was probably dropped from -mm because it has now been merged into a subsystem tree or into Linus's tree, or because it was folded into its parent patch in the -mm tree. ------------------------------------------------------ Subject: input: adapt uinput for the new force feedback interface From: Anssi Hannula <anssi.hannula@xxxxxxxxx> Modify the uinput driver for the new force feedback interface. The userspace interface of the force feedback part is changed and documentation in uinput.h is updated accordingly. MODULE_VERSION is also added to reflect the revision. Signed-off-by: Anssi Hannula <anssi.hannula@xxxxxxxxx> Cc: Dmitry Torokhov <dtor_core@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/input/misc/uinput.c | 76 +++++++++++++++++++++++++++------- include/linux/uinput.h | 21 ++++++--- 2 files changed, 77 insertions(+), 20 deletions(-) diff -puN drivers/input/misc/uinput.c~input-adapt-uinput-for-the-new-force-feedback-interface drivers/input/misc/uinput.c --- 25/drivers/input/misc/uinput.c~input-adapt-uinput-for-the-new-force-feedback-interface Fri May 26 14:18:35 2006 +++ 25-akpm/drivers/input/misc/uinput.c Fri May 26 14:18:35 2006 @@ -20,6 +20,9 @@ * Author: Aristeu Sergio Rozanski Filho <aris@xxxxxxxxxxxxxxxxx> * * Changes/Revisions: + * 0.3 09/04/2006 (Anssi Hannula <anssi.hannula@xxxxxxxxx>) + * - updated ff support for the changes in kernel interface + * - added MODULE_VERSION * 0.2 16/10/2004 (Micah Dowty <micah@xxxxxxx>) * - added force feedback support * - added UI_SET_PHYS @@ -107,18 +110,31 @@ static int uinput_request_submit(struct return request->retval; } -static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) +static void uinput_dev_set_gain(struct input_dev *dev, u16 gain) +{ + uinput_dev_event(dev, EV_FF, FF_GAIN, gain); +} + +static void uinput_dev_set_autocenter(struct input_dev *dev, u16 magnitude) +{ + uinput_dev_event(dev, EV_FF, FF_AUTOCENTER, magnitude); +} + +static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value) +{ + return uinput_dev_event(dev, EV_FF, effect_id, value); +} + +static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) { struct uinput_request request; int retval; - if (!test_bit(EV_FF, dev->evbit)) - return -ENOSYS; - request.id = -1; init_completion(&request.done); request.code = UI_FF_UPLOAD; - request.u.effect = effect; + request.u.upload.effect = effect; + request.u.upload.old = old; retval = uinput_request_reserve_slot(dev->private, &request); if (!retval) @@ -166,6 +182,14 @@ static void uinput_destroy_device(struct udev->state = UIST_NEW_DEVICE; } +static struct ff_driver uinput_ff_driver = { + .upload = uinput_dev_upload_effect, + .erase = uinput_dev_erase_effect, + .playback = uinput_dev_playback, + .set_gain = uinput_dev_set_gain, + .set_autocenter = uinput_dev_set_autocenter +}; + static int uinput_create_device(struct uinput_device *udev) { int error; @@ -181,6 +205,14 @@ static int uinput_create_device(struct u return error; } + if (udev->dev->ff) { + error = input_ff_register(udev->dev, &uinput_ff_driver); + if (error) { + uinput_destroy_device(udev); + return error; + } + } + udev->state = UIST_CREATED; return 0; @@ -243,8 +275,6 @@ static int uinput_allocate_device(struct return -ENOMEM; udev->dev->event = uinput_dev_event; - udev->dev->upload_effect = uinput_dev_upload_effect; - udev->dev->erase_effect = uinput_dev_erase_effect; udev->dev->private = udev; return 0; @@ -296,7 +326,12 @@ static int uinput_setup_device(struct ui dev->id.vendor = user_dev->id.vendor; dev->id.product = user_dev->id.product; dev->id.version = user_dev->id.version; - dev->ff_effects_max = user_dev->ff_effects_max; + if (user_dev->ff_effects_max) { + retval = input_ff_allocate(dev); + if (retval) + goto exit; + dev->ff_effects_max = user_dev->ff_effects_max; + } size = sizeof(int) * (ABS_MAX + 1); memcpy(dev->absmax, user_dev->absmax, size); @@ -459,7 +494,12 @@ static long uinput_ioctl(struct file *fi break; case UI_SET_EVBIT: - retval = uinput_set_bit(arg, evbit, EV_MAX); + if (arg == EV_FF) + /* EV_FF shall not be touched by the driver + it is set by force feedback subsystem */ + retval = -EINVAL; + else + retval = uinput_set_bit(arg, evbit, EV_MAX); break; case UI_SET_KEYBIT: @@ -487,7 +527,10 @@ static long uinput_ioctl(struct file *fi break; case UI_SET_FFBIT: - retval = uinput_set_bit(arg, ffbit, FF_MAX); + if (!udev->dev->ff) + retval = -EINVAL; + else + retval = uinput_set_bit(arg, ff->flags, FF_MAX); break; case UI_SET_SWBIT: @@ -525,12 +568,17 @@ static long uinput_ioctl(struct file *fi break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) { retval = -EINVAL; break; } ff_up.retval = 0; - memcpy(&ff_up.effect, req->u.effect, sizeof(struct ff_effect)); + memcpy(&ff_up.effect, req->u.upload.effect, sizeof(struct ff_effect)); + if (req->u.upload.old) + memcpy(&ff_up.old, req->u.upload.old, sizeof(struct ff_effect)); + else + memset(&ff_up.old, 0, sizeof(struct ff_effect)); + if (copy_to_user(p, &ff_up, sizeof(ff_up))) { retval = -EFAULT; break; @@ -561,12 +609,11 @@ static long uinput_ioctl(struct file *fi break; } req = uinput_request_find(udev, ff_up.request_id); - if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { + if (!(req && req->code == UI_FF_UPLOAD && req->u.upload.effect)) { retval = -EINVAL; break; } req->retval = ff_up.retval; - memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect)); uinput_request_done(udev, req); break; @@ -622,6 +669,7 @@ static void __exit uinput_exit(void) MODULE_AUTHOR("Aristeu Sergio Rozanski Filho"); MODULE_DESCRIPTION("User level driver support for input subsystem"); MODULE_LICENSE("GPL"); +MODULE_VERSION("0.3"); module_init(uinput_init); module_exit(uinput_exit); diff -puN include/linux/uinput.h~input-adapt-uinput-for-the-new-force-feedback-interface include/linux/uinput.h --- 25/include/linux/uinput.h~input-adapt-uinput-for-the-new-force-feedback-interface Fri May 26 14:18:35 2006 +++ 25-akpm/include/linux/uinput.h Fri May 26 14:18:35 2006 @@ -22,12 +22,18 @@ * Author: Aristeu Sergio Rozanski Filho <aris@xxxxxxxxxxxxxxxxx> * * Changes/Revisions: + * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>) + * - update ff support for the changes in kernel interface + * - add UINPUT_VERSION * 0.2 16/10/2004 (Micah Dowty <micah@xxxxxxx>) * - added force feedback support * - added UI_SET_PHYS * 0.1 20/06/2002 * - first public version */ + +#define UINPUT_VERSION 3 + #ifdef __KERNEL__ #define UINPUT_MINOR 223 #define UINPUT_NAME "uinput" @@ -45,7 +51,10 @@ struct uinput_request { union { int effect_id; - struct ff_effect* effect; + struct { + struct ff_effect* effect; + struct ff_effect* old; + } upload; } u; }; @@ -69,6 +78,7 @@ struct uinput_ff_upload { int request_id; int retval; struct ff_effect effect; + struct ff_effect old; }; struct uinput_ff_erase { @@ -105,7 +115,7 @@ struct uinput_ff_erase { * ioctls to retrieve additional parameters and send the return code. * The callback blocks until this return code is sent. * - * The described callback mechanism is only used if EV_FF is set. + * The described callback mechanism is only used if ff_effects_max is set. * Otherwise, default implementations of upload_effect and erase_effect * are used. * @@ -116,9 +126,9 @@ struct uinput_ff_erase { * the 'value' from the EV_UINPUT event. * 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the * uinput_ff_upload struct. It will be filled in with the - * ff_effect passed to upload_effect(). - * 4. Perform the effect upload, and place the modified ff_effect - * and a return code back into the uinput_ff_upload struct. + * ff_effects passed to upload_effect(). + * 4. Perform the effect upload, and place a return code back into + the uinput_ff_upload struct. * 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the * uinput_ff_upload_effect struct. This will complete execution * of our upload_effect() handler. @@ -133,7 +143,6 @@ struct uinput_ff_erase { * effect ID passed to erase_effect(). * 4. Perform the effect erasure, and place a return code back * into the uinput_ff_erase struct. - * and a return code back into the uinput_ff_erase struct. * 5. Issue a UI_END_FF_ERASE ioctl, also giving it the * uinput_ff_erase_effect struct. This will complete execution * of our erase_effect() handler. _ Patches currently in -mm which might be from anssi.hannula@xxxxxxxxx are input-move-fixp-arithh-to-drivers-input.patch input-fix-accuracy-of-fixp-arithh.patch input-make-input-a-multi-object-module.patch input-drop-the-old-pid-driver.patch input-use-enospc-instead-of-enomem-in-iforce-when-device-full.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html