+ 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;
+
+ request.id = -1;
+ init_completion(&request.done);
+ request.code = UI_FF_UPLOAD;
+ request.u.upload.effect = effect;
+ request.u.upload.old = old;
+
+ retval = uinput_request_reserve_slot(dev->private, &request);
+ if (!retval)
+ retval = uinput_request_submit(dev, &request);
+
+ return retval;
+}
+
+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
+{
+ 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_ERASE;
+ request.u.effect_id = effect_id;
+
+ retval = uinput_request_reserve_slot(dev->private, &request);
+ if (!retval)
+ retval = uinput_request_submit(dev, &request);
+
+ return retval;
+}
+
+static void uinput_destroy_device(struct uinput_device *udev)
+{
+ const char *name, *phys;
+
+ if (udev->dev) {
+ name = udev->dev->name;
+ phys = udev->dev->phys;
+ if (udev->state == UIST_CREATED)
+ input_unregister_device(udev->dev);
+ else
+ input_free_device(udev->dev);
+ kfree(name);
+ kfree(phys);
+ udev->dev = NULL;
+ }
+
+ udev->state = UIST_NEW_DEVICE;
+}
+
+static int uinput_create_device(struct uinput_device *udev)
+{
+ struct input_dev *dev = udev->dev;
+ int error;
+
+ if (udev->state != UIST_SETUP_COMPLETE) {
+ printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);