[kernel] generic-2.6/2.6.28: add missing Kconfig option
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 1050-fix-EVIOCGRAB-semantics.patch.patch
1 From 6294c84872b0d26111bdd1b9e5fec41c8a087443 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 25 Jul 2008 22:21:23 +0100
4 Subject: [PATCH] fix-EVIOCGRAB-semantics.patch
5
6 ---
7 drivers/input/evdev.c | 32 +++++++++++++++-----------------
8 1 files changed, 15 insertions(+), 17 deletions(-)
9
10 diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
11 index b32984b..499ffe1 100644
12 --- a/drivers/input/evdev.c
13 +++ b/drivers/input/evdev.c
14 @@ -28,7 +28,7 @@ struct evdev {
15 char name[16];
16 struct input_handle handle;
17 wait_queue_head_t wait;
18 - struct evdev_client *grab;
19 + int *grab;
20 struct list_head client_list;
21 spinlock_t client_lock; /* protects client_list */
22 struct mutex mutex;
23 @@ -39,6 +39,7 @@ struct evdev_client {
24 struct input_event buffer[EVDEV_BUFFER_SIZE];
25 int head;
26 int tail;
27 + int grab;
28 spinlock_t buffer_lock; /* protects access to buffer, head and tail */
29 struct fasync_struct *fasync;
30 struct evdev *evdev;
31 @@ -79,12 +80,8 @@ static void evdev_event(struct input_handle *handle,
32
33 rcu_read_lock();
34
35 - client = rcu_dereference(evdev->grab);
36 - if (client)
37 + list_for_each_entry_rcu(client, &evdev->client_list, node)
38 evdev_pass_event(client, &event);
39 - else
40 - list_for_each_entry_rcu(client, &evdev->client_list, node)
41 - evdev_pass_event(client, &event);
42
43 rcu_read_unlock();
44
45 @@ -136,14 +133,15 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
46 {
47 int error;
48
49 - if (evdev->grab)
50 + if (client->grab)
51 return -EBUSY;
52
53 - error = input_grab_device(&evdev->handle);
54 - if (error)
55 - return error;
56 -
57 - rcu_assign_pointer(evdev->grab, client);
58 + if (!evdev->grab++) {
59 + error = input_grab_device(&evdev->handle);
60 + if (error)
61 + return error;
62 + }
63 + client->grab = 1;
64 synchronize_rcu();
65
66 return 0;
67 @@ -151,12 +149,12 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
68
69 static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client)
70 {
71 - if (evdev->grab != client)
72 + if (!client->grab)
73 return -EINVAL;
74
75 - rcu_assign_pointer(evdev->grab, NULL);
76 - synchronize_rcu();
77 - input_release_device(&evdev->handle);
78 + if (!--evdev->grab && evdev->exist)
79 + input_release_device(&evdev->handle);
80 + client->grab = 0;
81
82 return 0;
83 }
84 @@ -231,7 +229,7 @@ static int evdev_release(struct inode *inode, struct file *file)
85 struct evdev *evdev = client->evdev;
86
87 mutex_lock(&evdev->mutex);
88 - if (evdev->grab == client)
89 + if (client->grab)
90 evdev_ungrab(evdev, client);
91 mutex_unlock(&evdev->mutex);
92
93 --
94 1.5.6.3
95
This page took 0.042478 seconds and 5 git commands to generate.