|
@@ -98,14 +98,15 @@ static int uinput_request_reserve_slot(struct uinput_device *udev,
|
|
|
uinput_request_alloc_id(udev, request));
|
|
|
}
|
|
|
|
|
|
-static void uinput_request_done(struct uinput_device *udev,
|
|
|
- struct uinput_request *request)
|
|
|
+static void uinput_request_release_slot(struct uinput_device *udev,
|
|
|
+ unsigned int id)
|
|
|
{
|
|
|
/* Mark slot as available */
|
|
|
- udev->requests[request->id] = NULL;
|
|
|
- wake_up(&udev->requests_waitq);
|
|
|
+ spin_lock(&udev->requests_lock);
|
|
|
+ udev->requests[id] = NULL;
|
|
|
+ spin_unlock(&udev->requests_lock);
|
|
|
|
|
|
- complete(&request->done);
|
|
|
+ wake_up(&udev->requests_waitq);
|
|
|
}
|
|
|
|
|
|
static int uinput_request_send(struct uinput_device *udev,
|
|
@@ -138,20 +139,22 @@ static int uinput_request_send(struct uinput_device *udev,
|
|
|
static int uinput_request_submit(struct uinput_device *udev,
|
|
|
struct uinput_request *request)
|
|
|
{
|
|
|
- int error;
|
|
|
+ int retval;
|
|
|
|
|
|
- error = uinput_request_reserve_slot(udev, request);
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
+ retval = uinput_request_reserve_slot(udev, request);
|
|
|
+ if (retval)
|
|
|
+ return retval;
|
|
|
|
|
|
- error = uinput_request_send(udev, request);
|
|
|
- if (error) {
|
|
|
- uinput_request_done(udev, request);
|
|
|
- return error;
|
|
|
- }
|
|
|
+ retval = uinput_request_send(udev, request);
|
|
|
+ if (retval)
|
|
|
+ goto out;
|
|
|
|
|
|
wait_for_completion(&request->done);
|
|
|
- return request->retval;
|
|
|
+ retval = request->retval;
|
|
|
+
|
|
|
+ out:
|
|
|
+ uinput_request_release_slot(udev, request->id);
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -169,7 +172,7 @@ static void uinput_flush_requests(struct uinput_device *udev)
|
|
|
request = udev->requests[i];
|
|
|
if (request) {
|
|
|
request->retval = -ENODEV;
|
|
|
- uinput_request_done(udev, request);
|
|
|
+ complete(&request->done);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -957,7 +960,7 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
|
|
}
|
|
|
|
|
|
req->retval = ff_up.retval;
|
|
|
- uinput_request_done(udev, req);
|
|
|
+ complete(&req->done);
|
|
|
goto out;
|
|
|
|
|
|
case UI_END_FF_ERASE:
|
|
@@ -973,7 +976,7 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
|
|
}
|
|
|
|
|
|
req->retval = ff_erase.retval;
|
|
|
- uinput_request_done(udev, req);
|
|
|
+ complete(&req->done);
|
|
|
goto out;
|
|
|
}
|
|
|
|