Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 328517
b: refs/heads/master
c: 00ce756
h: refs/heads/master
i:
  328515: 7c99865
v: v3
  • Loading branch information
Dmitry Torokhov committed Aug 22, 2012
1 parent cbe4af4 commit bced5ac
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 22ae19c6e3c22b390952e90f452f26adad9b8687
refs/heads/master: 00ce756ce53acdb82d408346e6a7b734ca9e5bad
78 changes: 40 additions & 38 deletions trunk/drivers/input/misc/uinput.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,25 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i
}

/* Atomically allocate an ID for the given request. Returns 0 on success. */
static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request)
static bool uinput_request_alloc_id(struct uinput_device *udev,
struct uinput_request *request)
{
int id;
int err = -1;
bool reserved = false;

spin_lock(&udev->requests_lock);

for (id = 0; id < UINPUT_NUM_REQUESTS; id++) {
if (!udev->requests[id]) {
request->id = id;
udev->requests[id] = request;
err = 0;
reserved = true;
break;
}
}

spin_unlock(&udev->requests_lock);
return err;
return reserved;
}

static struct uinput_request *uinput_request_find(struct uinput_device *udev, int id)
Expand All @@ -85,11 +86,12 @@ static struct uinput_request *uinput_request_find(struct uinput_device *udev, in
return udev->requests[id];
}

static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request)
static int uinput_request_reserve_slot(struct uinput_device *udev,
struct uinput_request *request)
{
/* Allocate slot. If none are available right away, wait. */
return wait_event_interruptible(udev->requests_waitq,
!uinput_request_alloc_id(udev, request));
uinput_request_alloc_id(udev, request));
}

static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request)
Expand All @@ -101,14 +103,11 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques
complete(&request->done);
}

static int uinput_request_submit(struct uinput_device *udev, struct uinput_request *request)
static int uinput_request_send(struct uinput_device *udev,
struct uinput_request *request)
{
int retval;

retval = uinput_request_reserve_slot(udev, request);
if (retval)
return retval;

retval = mutex_lock_interruptible(&udev->mutex);
if (retval)
return retval;
Expand All @@ -118,14 +117,38 @@ static int uinput_request_submit(struct uinput_device *udev, struct uinput_reque
goto out;
}

/* Tell our userspace app about this new request by queueing an input event */
init_completion(&request->done);

/*
* Tell our userspace application about this new request
* by queueing an input event.
*/
uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id);

out:
mutex_unlock(&udev->mutex);
return retval;
}

static int uinput_request_submit(struct uinput_device *udev,
struct uinput_request *request)
{
int error;

error = uinput_request_reserve_slot(udev, request);
if (error)
return error;

error = uinput_request_send(udev, request);
if (error) {
uinput_request_done(udev, request);
return error;
}

wait_for_completion(&request->done);
return request->retval;
}

/*
* Fail all ouitstanding requests so handlers don't wait for the userspace
* to finish processing them.
Expand Down Expand Up @@ -167,7 +190,6 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
{
struct uinput_device *udev = input_get_drvdata(dev);
struct uinput_request request;
int retval;

/*
* uinput driver does not currently support periodic effects with
Expand All @@ -180,42 +202,25 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
effect->u.periodic.waveform == FF_CUSTOM)
return -EINVAL;

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_submit(udev, &request);
if (!retval) {
wait_for_completion(&request.done);
retval = request.retval;
}

return retval;
return uinput_request_submit(udev, &request);
}

static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
{
struct uinput_device *udev = input_get_drvdata(dev);
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_submit(udev, &request);
if (!retval) {
wait_for_completion(&request.done);
retval = request.retval;
}

return retval;
return uinput_request_submit(udev, &request);
}

static void uinput_destroy_device(struct uinput_device *udev)
Expand Down Expand Up @@ -478,20 +483,17 @@ static ssize_t uinput_events_to_user(struct uinput_device *udev,
{
struct input_event event;
size_t read = 0;
int error = 0;

while (read + input_event_size() <= count &&
uinput_fetch_next_event(udev, &event)) {

if (input_event_to_user(buffer + read, &event)) {
error = -EFAULT;
break;
}
if (input_event_to_user(buffer + read, &event))
return -EFAULT;

read += input_event_size();
}

return read ?: error;
return read;
}

static ssize_t uinput_read(struct file *file, char __user *buffer,
Expand Down

0 comments on commit bced5ac

Please sign in to comment.