--- x/drivers/input/misc/uinput.c +++ y/drivers/input/misc/uinput.c @@ -157,8 +157,6 @@ static int uinput_request_send(struct ui goto out; } - init_completion(&request->done); - /* * Tell our userspace application about this new request * by queueing an input event. @@ -175,6 +173,8 @@ static int uinput_request_submit(struct { int retval; + init_completion(&request->done); + retval = uinput_request_reserve_slot(udev, request); if (retval) return retval; @@ -311,8 +311,11 @@ static int uinput_create_device(struct u struct input_dev *dev = udev->dev; int error, nslot; + lockdep_assert_held(&udev->mutex); + if (udev->state != UIST_SETUP_COMPLETE) { printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME); + mutex_unlock(&udev->mutex); return -EINVAL; } @@ -362,9 +365,12 @@ static int uinput_create_device(struct u input_set_drvdata(udev->dev, udev); + mutex_unlock(&udev->mutex); error = input_register_device(udev->dev); - if (error) + if (error) { + mutex_lock(&udev->mutex); goto fail2; + } udev->state = UIST_CREATED; @@ -372,6 +378,7 @@ static int uinput_create_device(struct u fail2: input_ff_destroy(dev); fail1: uinput_destroy_device(udev); + mutex_unlock(&udev->mutex); return error; } @@ -901,8 +908,7 @@ static long uinput_ioctl_handler(struct goto out; case UI_DEV_CREATE: - retval = uinput_create_device(udev); - goto out; + return uinput_create_device(udev); case UI_DEV_DESTROY: uinput_destroy_device(udev);