diff options
Diffstat (limited to 'target/linux/s3c24xx/patches/0050-fix-EVIOCGRAB-semantics.patch.patch')
-rwxr-xr-x | target/linux/s3c24xx/patches/0050-fix-EVIOCGRAB-semantics.patch.patch | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches/0050-fix-EVIOCGRAB-semantics.patch.patch b/target/linux/s3c24xx/patches/0050-fix-EVIOCGRAB-semantics.patch.patch new file mode 100755 index 0000000000..5ef328b2f0 --- /dev/null +++ b/target/linux/s3c24xx/patches/0050-fix-EVIOCGRAB-semantics.patch.patch @@ -0,0 +1,95 @@ +From 6294c84872b0d26111bdd1b9e5fec41c8a087443 Mon Sep 17 00:00:00 2001 +From: mokopatches <mokopatches@openmoko.org> +Date: Fri, 25 Jul 2008 22:21:23 +0100 +Subject: [PATCH] fix-EVIOCGRAB-semantics.patch + +--- + drivers/input/evdev.c | 32 +++++++++++++++----------------- + 1 files changed, 15 insertions(+), 17 deletions(-) + +diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c +index b32984b..499ffe1 100644 +--- a/drivers/input/evdev.c ++++ b/drivers/input/evdev.c +@@ -28,7 +28,7 @@ struct evdev { + char name[16]; + struct input_handle handle; + wait_queue_head_t wait; +- struct evdev_client *grab; ++ int *grab; + struct list_head client_list; + spinlock_t client_lock; /* protects client_list */ + struct mutex mutex; +@@ -39,6 +39,7 @@ struct evdev_client { + struct input_event buffer[EVDEV_BUFFER_SIZE]; + int head; + int tail; ++ int grab; + spinlock_t buffer_lock; /* protects access to buffer, head and tail */ + struct fasync_struct *fasync; + struct evdev *evdev; +@@ -79,12 +80,8 @@ static void evdev_event(struct input_handle *handle, + + rcu_read_lock(); + +- client = rcu_dereference(evdev->grab); +- if (client) ++ list_for_each_entry_rcu(client, &evdev->client_list, node) + evdev_pass_event(client, &event); +- else +- list_for_each_entry_rcu(client, &evdev->client_list, node) +- evdev_pass_event(client, &event); + + rcu_read_unlock(); + +@@ -136,14 +133,15 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) + { + int error; + +- if (evdev->grab) ++ if (client->grab) + return -EBUSY; + +- error = input_grab_device(&evdev->handle); +- if (error) +- return error; +- +- rcu_assign_pointer(evdev->grab, client); ++ if (!evdev->grab++) { ++ error = input_grab_device(&evdev->handle); ++ if (error) ++ return error; ++ } ++ client->grab = 1; + synchronize_rcu(); + + return 0; +@@ -151,12 +149,12 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) + + static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) + { +- if (evdev->grab != client) ++ if (!client->grab) + return -EINVAL; + +- rcu_assign_pointer(evdev->grab, NULL); +- synchronize_rcu(); +- input_release_device(&evdev->handle); ++ if (!--evdev->grab && evdev->exist) ++ input_release_device(&evdev->handle); ++ client->grab = 0; + + return 0; + } +@@ -231,7 +229,7 @@ static int evdev_release(struct inode *inode, struct file *file) + struct evdev *evdev = client->evdev; + + mutex_lock(&evdev->mutex); +- if (evdev->grab == client) ++ if (client->grab) + evdev_ungrab(evdev, client); + mutex_unlock(&evdev->mutex); + +-- +1.5.6.3 + |