diff options
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 716 |
1 files changed, 476 insertions, 240 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index f1c3d6cebd58..27026f7d3c03 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -30,6 +30,8 @@ struct evdev { | |||
30 | wait_queue_head_t wait; | 30 | wait_queue_head_t wait; |
31 | struct evdev_client *grab; | 31 | struct evdev_client *grab; |
32 | struct list_head client_list; | 32 | struct list_head client_list; |
33 | spinlock_t client_lock; /* protects client_list */ | ||
34 | struct mutex mutex; | ||
33 | struct device dev; | 35 | struct device dev; |
34 | }; | 36 | }; |
35 | 37 | ||
@@ -37,39 +39,53 @@ struct evdev_client { | |||
37 | struct input_event buffer[EVDEV_BUFFER_SIZE]; | 39 | struct input_event buffer[EVDEV_BUFFER_SIZE]; |
38 | int head; | 40 | int head; |
39 | int tail; | 41 | int tail; |
42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | ||
40 | struct fasync_struct *fasync; | 43 | struct fasync_struct *fasync; |
41 | struct evdev *evdev; | 44 | struct evdev *evdev; |
42 | struct list_head node; | 45 | struct list_head node; |
43 | }; | 46 | }; |
44 | 47 | ||
45 | static struct evdev *evdev_table[EVDEV_MINORS]; | 48 | static struct evdev *evdev_table[EVDEV_MINORS]; |
49 | static DEFINE_MUTEX(evdev_table_mutex); | ||
46 | 50 | ||
47 | static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 51 | static void evdev_pass_event(struct evdev_client *client, |
52 | struct input_event *event) | ||
53 | { | ||
54 | /* | ||
55 | * Interrupts are disabled, just acquire the lock | ||
56 | */ | ||
57 | spin_lock(&client->buffer_lock); | ||
58 | client->buffer[client->head++] = *event; | ||
59 | client->head &= EVDEV_BUFFER_SIZE - 1; | ||
60 | spin_unlock(&client->buffer_lock); | ||
61 | |||
62 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Pass incoming event to all connected clients. Note that we are | ||
67 | * caleld under a spinlock with interrupts off so we don't need | ||
68 | * to use rcu_read_lock() here. Writers will be using syncronize_sched() | ||
69 | * instead of synchrnoize_rcu(). | ||
70 | */ | ||
71 | static void evdev_event(struct input_handle *handle, | ||
72 | unsigned int type, unsigned int code, int value) | ||
48 | { | 73 | { |
49 | struct evdev *evdev = handle->private; | 74 | struct evdev *evdev = handle->private; |
50 | struct evdev_client *client; | 75 | struct evdev_client *client; |
76 | struct input_event event; | ||
51 | 77 | ||
52 | if (evdev->grab) { | 78 | do_gettimeofday(&event.time); |
53 | client = evdev->grab; | 79 | event.type = type; |
54 | 80 | event.code = code; | |
55 | do_gettimeofday(&client->buffer[client->head].time); | 81 | event.value = value; |
56 | client->buffer[client->head].type = type; | ||
57 | client->buffer[client->head].code = code; | ||
58 | client->buffer[client->head].value = value; | ||
59 | client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); | ||
60 | |||
61 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | ||
62 | } else | ||
63 | list_for_each_entry(client, &evdev->client_list, node) { | ||
64 | |||
65 | do_gettimeofday(&client->buffer[client->head].time); | ||
66 | client->buffer[client->head].type = type; | ||
67 | client->buffer[client->head].code = code; | ||
68 | client->buffer[client->head].value = value; | ||
69 | client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); | ||
70 | 82 | ||
71 | kill_fasync(&client->fasync, SIGIO, POLL_IN); | 83 | client = rcu_dereference(evdev->grab); |
72 | } | 84 | if (client) |
85 | evdev_pass_event(client, &event); | ||
86 | else | ||
87 | list_for_each_entry_rcu(client, &evdev->client_list, node) | ||
88 | evdev_pass_event(client, &event); | ||
73 | 89 | ||
74 | wake_up_interruptible(&evdev->wait); | 90 | wake_up_interruptible(&evdev->wait); |
75 | } | 91 | } |
@@ -88,38 +104,145 @@ static int evdev_flush(struct file *file, fl_owner_t id) | |||
88 | { | 104 | { |
89 | struct evdev_client *client = file->private_data; | 105 | struct evdev_client *client = file->private_data; |
90 | struct evdev *evdev = client->evdev; | 106 | struct evdev *evdev = client->evdev; |
107 | int retval; | ||
108 | |||
109 | retval = mutex_lock_interruptible(&evdev->mutex); | ||
110 | if (retval) | ||
111 | return retval; | ||
91 | 112 | ||
92 | if (!evdev->exist) | 113 | if (!evdev->exist) |
93 | return -ENODEV; | 114 | retval = -ENODEV; |
115 | else | ||
116 | retval = input_flush_device(&evdev->handle, file); | ||
94 | 117 | ||
95 | return input_flush_device(&evdev->handle, file); | 118 | mutex_unlock(&evdev->mutex); |
119 | return retval; | ||
96 | } | 120 | } |
97 | 121 | ||
98 | static void evdev_free(struct device *dev) | 122 | static void evdev_free(struct device *dev) |
99 | { | 123 | { |
100 | struct evdev *evdev = container_of(dev, struct evdev, dev); | 124 | struct evdev *evdev = container_of(dev, struct evdev, dev); |
101 | 125 | ||
102 | evdev_table[evdev->minor] = NULL; | ||
103 | kfree(evdev); | 126 | kfree(evdev); |
104 | } | 127 | } |
105 | 128 | ||
129 | /* | ||
130 | * Grabs an event device (along with underlying input device). | ||
131 | * This function is called with evdev->mutex taken. | ||
132 | */ | ||
133 | static int evdev_grab(struct evdev *evdev, struct evdev_client *client) | ||
134 | { | ||
135 | int error; | ||
136 | |||
137 | if (evdev->grab) | ||
138 | return -EBUSY; | ||
139 | |||
140 | error = input_grab_device(&evdev->handle); | ||
141 | if (error) | ||
142 | return error; | ||
143 | |||
144 | rcu_assign_pointer(evdev->grab, client); | ||
145 | /* | ||
146 | * We don't use synchronize_rcu() here because read-side | ||
147 | * critical section is protected by a spinlock instead | ||
148 | * of rcu_read_lock(). | ||
149 | */ | ||
150 | synchronize_sched(); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) | ||
156 | { | ||
157 | if (evdev->grab != client) | ||
158 | return -EINVAL; | ||
159 | |||
160 | rcu_assign_pointer(evdev->grab, NULL); | ||
161 | synchronize_sched(); | ||
162 | input_release_device(&evdev->handle); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static void evdev_attach_client(struct evdev *evdev, | ||
168 | struct evdev_client *client) | ||
169 | { | ||
170 | spin_lock(&evdev->client_lock); | ||
171 | list_add_tail_rcu(&client->node, &evdev->client_list); | ||
172 | spin_unlock(&evdev->client_lock); | ||
173 | synchronize_sched(); | ||
174 | } | ||
175 | |||
176 | static void evdev_detach_client(struct evdev *evdev, | ||
177 | struct evdev_client *client) | ||
178 | { | ||
179 | spin_lock(&evdev->client_lock); | ||
180 | list_del_rcu(&client->node); | ||
181 | spin_unlock(&evdev->client_lock); | ||
182 | synchronize_sched(); | ||
183 | } | ||
184 | |||
185 | static int evdev_open_device(struct evdev *evdev) | ||
186 | { | ||
187 | int retval; | ||
188 | |||
189 | retval = mutex_lock_interruptible(&evdev->mutex); | ||
190 | if (retval) | ||
191 | return retval; | ||
192 | |||
193 | if (!evdev->exist) | ||
194 | retval = -ENODEV; | ||
195 | else if (!evdev->open++) { | ||
196 | retval = input_open_device(&evdev->handle); | ||
197 | if (retval) | ||
198 | evdev->open--; | ||
199 | } | ||
200 | |||
201 | mutex_unlock(&evdev->mutex); | ||
202 | return retval; | ||
203 | } | ||
204 | |||
205 | static void evdev_close_device(struct evdev *evdev) | ||
206 | { | ||
207 | mutex_lock(&evdev->mutex); | ||
208 | |||
209 | if (evdev->exist && !--evdev->open) | ||
210 | input_close_device(&evdev->handle); | ||
211 | |||
212 | mutex_unlock(&evdev->mutex); | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | * Wake up users waiting for IO so they can disconnect from | ||
217 | * dead device. | ||
218 | */ | ||
219 | static void evdev_hangup(struct evdev *evdev) | ||
220 | { | ||
221 | struct evdev_client *client; | ||
222 | |||
223 | spin_lock(&evdev->client_lock); | ||
224 | list_for_each_entry(client, &evdev->client_list, node) | ||
225 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); | ||
226 | spin_unlock(&evdev->client_lock); | ||
227 | |||
228 | wake_up_interruptible(&evdev->wait); | ||
229 | } | ||
230 | |||
106 | static int evdev_release(struct inode *inode, struct file *file) | 231 | static int evdev_release(struct inode *inode, struct file *file) |
107 | { | 232 | { |
108 | struct evdev_client *client = file->private_data; | 233 | struct evdev_client *client = file->private_data; |
109 | struct evdev *evdev = client->evdev; | 234 | struct evdev *evdev = client->evdev; |
110 | 235 | ||
111 | if (evdev->grab == client) { | 236 | mutex_lock(&evdev->mutex); |
112 | input_release_device(&evdev->handle); | 237 | if (evdev->grab == client) |
113 | evdev->grab = NULL; | 238 | evdev_ungrab(evdev, client); |
114 | } | 239 | mutex_unlock(&evdev->mutex); |
115 | 240 | ||
116 | evdev_fasync(-1, file, 0); | 241 | evdev_fasync(-1, file, 0); |
117 | list_del(&client->node); | 242 | evdev_detach_client(evdev, client); |
118 | kfree(client); | 243 | kfree(client); |
119 | 244 | ||
120 | if (!--evdev->open && evdev->exist) | 245 | evdev_close_device(evdev); |
121 | input_close_device(&evdev->handle); | ||
122 | |||
123 | put_device(&evdev->dev); | 246 | put_device(&evdev->dev); |
124 | 247 | ||
125 | return 0; | 248 | return 0; |
@@ -127,41 +250,44 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
127 | 250 | ||
128 | static int evdev_open(struct inode *inode, struct file *file) | 251 | static int evdev_open(struct inode *inode, struct file *file) |
129 | { | 252 | { |
130 | struct evdev_client *client; | ||
131 | struct evdev *evdev; | 253 | struct evdev *evdev; |
254 | struct evdev_client *client; | ||
132 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 255 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
133 | int error; | 256 | int error; |
134 | 257 | ||
135 | if (i >= EVDEV_MINORS) | 258 | if (i >= EVDEV_MINORS) |
136 | return -ENODEV; | 259 | return -ENODEV; |
137 | 260 | ||
261 | error = mutex_lock_interruptible(&evdev_table_mutex); | ||
262 | if (error) | ||
263 | return error; | ||
138 | evdev = evdev_table[i]; | 264 | evdev = evdev_table[i]; |
265 | if (evdev) | ||
266 | get_device(&evdev->dev); | ||
267 | mutex_unlock(&evdev_table_mutex); | ||
139 | 268 | ||
140 | if (!evdev || !evdev->exist) | 269 | if (!evdev) |
141 | return -ENODEV; | 270 | return -ENODEV; |
142 | 271 | ||
143 | get_device(&evdev->dev); | ||
144 | |||
145 | client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); | 272 | client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); |
146 | if (!client) { | 273 | if (!client) { |
147 | error = -ENOMEM; | 274 | error = -ENOMEM; |
148 | goto err_put_evdev; | 275 | goto err_put_evdev; |
149 | } | 276 | } |
150 | 277 | ||
278 | spin_lock_init(&client->buffer_lock); | ||
151 | client->evdev = evdev; | 279 | client->evdev = evdev; |
152 | list_add_tail(&client->node, &evdev->client_list); | 280 | evdev_attach_client(evdev, client); |
153 | 281 | ||
154 | if (!evdev->open++ && evdev->exist) { | 282 | error = evdev_open_device(evdev); |
155 | error = input_open_device(&evdev->handle); | 283 | if (error) |
156 | if (error) | 284 | goto err_free_client; |
157 | goto err_free_client; | ||
158 | } | ||
159 | 285 | ||
160 | file->private_data = client; | 286 | file->private_data = client; |
161 | return 0; | 287 | return 0; |
162 | 288 | ||
163 | err_free_client: | 289 | err_free_client: |
164 | list_del(&client->node); | 290 | evdev_detach_client(evdev, client); |
165 | kfree(client); | 291 | kfree(client); |
166 | err_put_evdev: | 292 | err_put_evdev: |
167 | put_device(&evdev->dev); | 293 | put_device(&evdev->dev); |
@@ -197,12 +323,14 @@ static inline size_t evdev_event_size(void) | |||
197 | sizeof(struct input_event_compat) : sizeof(struct input_event); | 323 | sizeof(struct input_event_compat) : sizeof(struct input_event); |
198 | } | 324 | } |
199 | 325 | ||
200 | static int evdev_event_from_user(const char __user *buffer, struct input_event *event) | 326 | static int evdev_event_from_user(const char __user *buffer, |
327 | struct input_event *event) | ||
201 | { | 328 | { |
202 | if (COMPAT_TEST) { | 329 | if (COMPAT_TEST) { |
203 | struct input_event_compat compat_event; | 330 | struct input_event_compat compat_event; |
204 | 331 | ||
205 | if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat))) | 332 | if (copy_from_user(&compat_event, buffer, |
333 | sizeof(struct input_event_compat))) | ||
206 | return -EFAULT; | 334 | return -EFAULT; |
207 | 335 | ||
208 | event->time.tv_sec = compat_event.time.tv_sec; | 336 | event->time.tv_sec = compat_event.time.tv_sec; |
@@ -219,7 +347,8 @@ static int evdev_event_from_user(const char __user *buffer, struct input_event * | |||
219 | return 0; | 347 | return 0; |
220 | } | 348 | } |
221 | 349 | ||
222 | static int evdev_event_to_user(char __user *buffer, const struct input_event *event) | 350 | static int evdev_event_to_user(char __user *buffer, |
351 | const struct input_event *event) | ||
223 | { | 352 | { |
224 | if (COMPAT_TEST) { | 353 | if (COMPAT_TEST) { |
225 | struct input_event_compat compat_event; | 354 | struct input_event_compat compat_event; |
@@ -230,7 +359,8 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev | |||
230 | compat_event.code = event->code; | 359 | compat_event.code = event->code; |
231 | compat_event.value = event->value; | 360 | compat_event.value = event->value; |
232 | 361 | ||
233 | if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat))) | 362 | if (copy_to_user(buffer, &compat_event, |
363 | sizeof(struct input_event_compat))) | ||
234 | return -EFAULT; | 364 | return -EFAULT; |
235 | 365 | ||
236 | } else { | 366 | } else { |
@@ -248,7 +378,8 @@ static inline size_t evdev_event_size(void) | |||
248 | return sizeof(struct input_event); | 378 | return sizeof(struct input_event); |
249 | } | 379 | } |
250 | 380 | ||
251 | static int evdev_event_from_user(const char __user *buffer, struct input_event *event) | 381 | static int evdev_event_from_user(const char __user *buffer, |
382 | struct input_event *event) | ||
252 | { | 383 | { |
253 | if (copy_from_user(event, buffer, sizeof(struct input_event))) | 384 | if (copy_from_user(event, buffer, sizeof(struct input_event))) |
254 | return -EFAULT; | 385 | return -EFAULT; |
@@ -256,7 +387,8 @@ static int evdev_event_from_user(const char __user *buffer, struct input_event * | |||
256 | return 0; | 387 | return 0; |
257 | } | 388 | } |
258 | 389 | ||
259 | static int evdev_event_to_user(char __user *buffer, const struct input_event *event) | 390 | static int evdev_event_to_user(char __user *buffer, |
391 | const struct input_event *event) | ||
260 | { | 392 | { |
261 | if (copy_to_user(buffer, event, sizeof(struct input_event))) | 393 | if (copy_to_user(buffer, event, sizeof(struct input_event))) |
262 | return -EFAULT; | 394 | return -EFAULT; |
@@ -266,37 +398,71 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev | |||
266 | 398 | ||
267 | #endif /* CONFIG_COMPAT */ | 399 | #endif /* CONFIG_COMPAT */ |
268 | 400 | ||
269 | static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 401 | static ssize_t evdev_write(struct file *file, const char __user *buffer, |
402 | size_t count, loff_t *ppos) | ||
270 | { | 403 | { |
271 | struct evdev_client *client = file->private_data; | 404 | struct evdev_client *client = file->private_data; |
272 | struct evdev *evdev = client->evdev; | 405 | struct evdev *evdev = client->evdev; |
273 | struct input_event event; | 406 | struct input_event event; |
274 | int retval = 0; | 407 | int retval; |
275 | 408 | ||
276 | if (!evdev->exist) | 409 | retval = mutex_lock_interruptible(&evdev->mutex); |
277 | return -ENODEV; | 410 | if (retval) |
411 | return retval; | ||
412 | |||
413 | if (!evdev->exist) { | ||
414 | retval = -ENODEV; | ||
415 | goto out; | ||
416 | } | ||
278 | 417 | ||
279 | while (retval < count) { | 418 | while (retval < count) { |
280 | 419 | ||
281 | if (evdev_event_from_user(buffer + retval, &event)) | 420 | if (evdev_event_from_user(buffer + retval, &event)) { |
282 | return -EFAULT; | 421 | retval = -EFAULT; |
283 | input_inject_event(&evdev->handle, event.type, event.code, event.value); | 422 | goto out; |
423 | } | ||
424 | |||
425 | input_inject_event(&evdev->handle, | ||
426 | event.type, event.code, event.value); | ||
284 | retval += evdev_event_size(); | 427 | retval += evdev_event_size(); |
285 | } | 428 | } |
286 | 429 | ||
430 | out: | ||
431 | mutex_unlock(&evdev->mutex); | ||
287 | return retval; | 432 | return retval; |
288 | } | 433 | } |
289 | 434 | ||
290 | static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 435 | static int evdev_fetch_next_event(struct evdev_client *client, |
436 | struct input_event *event) | ||
437 | { | ||
438 | int have_event; | ||
439 | |||
440 | spin_lock_irq(&client->buffer_lock); | ||
441 | |||
442 | have_event = client->head != client->tail; | ||
443 | if (have_event) { | ||
444 | *event = client->buffer[client->tail++]; | ||
445 | client->tail &= EVDEV_BUFFER_SIZE - 1; | ||
446 | } | ||
447 | |||
448 | spin_unlock_irq(&client->buffer_lock); | ||
449 | |||
450 | return have_event; | ||
451 | } | ||
452 | |||
453 | static ssize_t evdev_read(struct file *file, char __user *buffer, | ||
454 | size_t count, loff_t *ppos) | ||
291 | { | 455 | { |
292 | struct evdev_client *client = file->private_data; | 456 | struct evdev_client *client = file->private_data; |
293 | struct evdev *evdev = client->evdev; | 457 | struct evdev *evdev = client->evdev; |
458 | struct input_event event; | ||
294 | int retval; | 459 | int retval; |
295 | 460 | ||
296 | if (count < evdev_event_size()) | 461 | if (count < evdev_event_size()) |
297 | return -EINVAL; | 462 | return -EINVAL; |
298 | 463 | ||
299 | if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK)) | 464 | if (client->head == client->tail && evdev->exist && |
465 | (file->f_flags & O_NONBLOCK)) | ||
300 | return -EAGAIN; | 466 | return -EAGAIN; |
301 | 467 | ||
302 | retval = wait_event_interruptible(evdev->wait, | 468 | retval = wait_event_interruptible(evdev->wait, |
@@ -307,14 +473,12 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, | |||
307 | if (!evdev->exist) | 473 | if (!evdev->exist) |
308 | return -ENODEV; | 474 | return -ENODEV; |
309 | 475 | ||
310 | while (client->head != client->tail && retval + evdev_event_size() <= count) { | 476 | while (retval + evdev_event_size() <= count && |
477 | evdev_fetch_next_event(client, &event)) { | ||
311 | 478 | ||
312 | struct input_event *event = (struct input_event *) client->buffer + client->tail; | 479 | if (evdev_event_to_user(buffer + retval, &event)) |
313 | |||
314 | if (evdev_event_to_user(buffer + retval, event)) | ||
315 | return -EFAULT; | 480 | return -EFAULT; |
316 | 481 | ||
317 | client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1); | ||
318 | retval += evdev_event_size(); | 482 | retval += evdev_event_size(); |
319 | } | 483 | } |
320 | 484 | ||
@@ -409,8 +573,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
409 | return copy_to_user(p, str, len) ? -EFAULT : len; | 573 | return copy_to_user(p, str, len) ? -EFAULT : len; |
410 | } | 574 | } |
411 | 575 | ||
412 | static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | 576 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
413 | void __user *p, int compat_mode) | 577 | void __user *p, int compat_mode) |
414 | { | 578 | { |
415 | struct evdev_client *client = file->private_data; | 579 | struct evdev_client *client = file->private_data; |
416 | struct evdev *evdev = client->evdev; | 580 | struct evdev *evdev = client->evdev; |
@@ -421,215 +585,289 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
421 | int i, t, u, v; | 585 | int i, t, u, v; |
422 | int error; | 586 | int error; |
423 | 587 | ||
424 | if (!evdev->exist) | ||
425 | return -ENODEV; | ||
426 | |||
427 | switch (cmd) { | 588 | switch (cmd) { |
428 | 589 | ||
429 | case EVIOCGVERSION: | 590 | case EVIOCGVERSION: |
430 | return put_user(EV_VERSION, ip); | 591 | return put_user(EV_VERSION, ip); |
431 | 592 | ||
432 | case EVIOCGID: | 593 | case EVIOCGID: |
433 | if (copy_to_user(p, &dev->id, sizeof(struct input_id))) | 594 | if (copy_to_user(p, &dev->id, sizeof(struct input_id))) |
434 | return -EFAULT; | 595 | return -EFAULT; |
435 | return 0; | 596 | return 0; |
436 | 597 | ||
437 | case EVIOCGREP: | 598 | case EVIOCGREP: |
438 | if (!test_bit(EV_REP, dev->evbit)) | 599 | if (!test_bit(EV_REP, dev->evbit)) |
439 | return -ENOSYS; | 600 | return -ENOSYS; |
440 | if (put_user(dev->rep[REP_DELAY], ip)) | 601 | if (put_user(dev->rep[REP_DELAY], ip)) |
441 | return -EFAULT; | 602 | return -EFAULT; |
442 | if (put_user(dev->rep[REP_PERIOD], ip + 1)) | 603 | if (put_user(dev->rep[REP_PERIOD], ip + 1)) |
443 | return -EFAULT; | 604 | return -EFAULT; |
444 | return 0; | 605 | return 0; |
445 | 606 | ||
446 | case EVIOCSREP: | 607 | case EVIOCSREP: |
447 | if (!test_bit(EV_REP, dev->evbit)) | 608 | if (!test_bit(EV_REP, dev->evbit)) |
448 | return -ENOSYS; | 609 | return -ENOSYS; |
449 | if (get_user(u, ip)) | 610 | if (get_user(u, ip)) |
450 | return -EFAULT; | 611 | return -EFAULT; |
451 | if (get_user(v, ip + 1)) | 612 | if (get_user(v, ip + 1)) |
452 | return -EFAULT; | 613 | return -EFAULT; |
453 | 614 | ||
454 | input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u); | 615 | input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u); |
455 | input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v); | 616 | input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v); |
456 | 617 | ||
457 | return 0; | 618 | return 0; |
458 | 619 | ||
459 | case EVIOCGKEYCODE: | 620 | case EVIOCGKEYCODE: |
460 | if (get_user(t, ip)) | 621 | if (get_user(t, ip)) |
461 | return -EFAULT; | 622 | return -EFAULT; |
462 | 623 | ||
463 | error = dev->getkeycode(dev, t, &v); | 624 | error = dev->getkeycode(dev, t, &v); |
464 | if (error) | 625 | if (error) |
465 | return error; | 626 | return error; |
466 | 627 | ||
467 | if (put_user(v, ip + 1)) | 628 | if (put_user(v, ip + 1)) |
468 | return -EFAULT; | 629 | return -EFAULT; |
469 | 630 | ||
470 | return 0; | 631 | return 0; |
471 | 632 | ||
472 | case EVIOCSKEYCODE: | 633 | case EVIOCSKEYCODE: |
473 | if (get_user(t, ip) || get_user(v, ip + 1)) | 634 | if (get_user(t, ip) || get_user(v, ip + 1)) |
474 | return -EFAULT; | 635 | return -EFAULT; |
475 | 636 | ||
476 | return dev->setkeycode(dev, t, v); | 637 | return dev->setkeycode(dev, t, v); |
477 | 638 | ||
478 | case EVIOCSFF: | 639 | case EVIOCSFF: |
479 | if (copy_from_user(&effect, p, sizeof(effect))) | 640 | if (copy_from_user(&effect, p, sizeof(effect))) |
480 | return -EFAULT; | 641 | return -EFAULT; |
481 | 642 | ||
482 | error = input_ff_upload(dev, &effect, file); | 643 | error = input_ff_upload(dev, &effect, file); |
483 | 644 | ||
484 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | 645 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
485 | return -EFAULT; | 646 | return -EFAULT; |
486 | 647 | ||
487 | return error; | 648 | return error; |
488 | 649 | ||
489 | case EVIOCRMFF: | 650 | case EVIOCRMFF: |
490 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 651 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
491 | 652 | ||
492 | case EVIOCGEFFECTS: | 653 | case EVIOCGEFFECTS: |
493 | i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0; | 654 | i = test_bit(EV_FF, dev->evbit) ? |
494 | if (put_user(i, ip)) | 655 | dev->ff->max_effects : 0; |
495 | return -EFAULT; | 656 | if (put_user(i, ip)) |
496 | return 0; | 657 | return -EFAULT; |
497 | 658 | return 0; | |
498 | case EVIOCGRAB: | ||
499 | if (p) { | ||
500 | if (evdev->grab) | ||
501 | return -EBUSY; | ||
502 | if (input_grab_device(&evdev->handle)) | ||
503 | return -EBUSY; | ||
504 | evdev->grab = client; | ||
505 | return 0; | ||
506 | } else { | ||
507 | if (evdev->grab != client) | ||
508 | return -EINVAL; | ||
509 | input_release_device(&evdev->handle); | ||
510 | evdev->grab = NULL; | ||
511 | return 0; | ||
512 | } | ||
513 | 659 | ||
514 | default: | 660 | case EVIOCGRAB: |
661 | if (p) | ||
662 | return evdev_grab(evdev, client); | ||
663 | else | ||
664 | return evdev_ungrab(evdev, client); | ||
515 | 665 | ||
516 | if (_IOC_TYPE(cmd) != 'E') | 666 | default: |
517 | return -EINVAL; | ||
518 | 667 | ||
519 | if (_IOC_DIR(cmd) == _IOC_READ) { | 668 | if (_IOC_TYPE(cmd) != 'E') |
669 | return -EINVAL; | ||
520 | 670 | ||
521 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { | 671 | if (_IOC_DIR(cmd) == _IOC_READ) { |
522 | 672 | ||
523 | unsigned long *bits; | 673 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { |
524 | int len; | ||
525 | 674 | ||
526 | switch (_IOC_NR(cmd) & EV_MAX) { | 675 | unsigned long *bits; |
527 | case 0: bits = dev->evbit; len = EV_MAX; break; | 676 | int len; |
528 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | ||
529 | case EV_REL: bits = dev->relbit; len = REL_MAX; break; | ||
530 | case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; | ||
531 | case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; | ||
532 | case EV_LED: bits = dev->ledbit; len = LED_MAX; break; | ||
533 | case EV_SND: bits = dev->sndbit; len = SND_MAX; break; | ||
534 | case EV_FF: bits = dev->ffbit; len = FF_MAX; break; | ||
535 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; | ||
536 | default: return -EINVAL; | ||
537 | } | ||
538 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | ||
539 | } | ||
540 | 677 | ||
541 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | 678 | switch (_IOC_NR(cmd) & EV_MAX) { |
542 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), | ||
543 | p, compat_mode); | ||
544 | 679 | ||
545 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) | 680 | case 0: bits = dev->evbit; len = EV_MAX; break; |
546 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), | 681 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; |
547 | p, compat_mode); | 682 | case EV_REL: bits = dev->relbit; len = REL_MAX; break; |
683 | case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; | ||
684 | case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; | ||
685 | case EV_LED: bits = dev->ledbit; len = LED_MAX; break; | ||
686 | case EV_SND: bits = dev->sndbit; len = SND_MAX; break; | ||
687 | case EV_FF: bits = dev->ffbit; len = FF_MAX; break; | ||
688 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; | ||
689 | default: return -EINVAL; | ||
690 | } | ||
691 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | ||
692 | } | ||
548 | 693 | ||
549 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) | 694 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) |
550 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), | 695 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), |
551 | p, compat_mode); | 696 | p, compat_mode); |
552 | 697 | ||
553 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) | 698 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) |
554 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), | 699 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), |
555 | p, compat_mode); | 700 | p, compat_mode); |
556 | 701 | ||
557 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 702 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) |
558 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); | 703 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), |
704 | p, compat_mode); | ||
559 | 705 | ||
560 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 706 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) |
561 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 707 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), |
708 | p, compat_mode); | ||
562 | 709 | ||
563 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) | 710 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) |
564 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); | 711 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); |
565 | 712 | ||
566 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | 713 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) |
714 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | ||
567 | 715 | ||
568 | t = _IOC_NR(cmd) & ABS_MAX; | 716 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) |
717 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); | ||
569 | 718 | ||
570 | abs.value = dev->abs[t]; | 719 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { |
571 | abs.minimum = dev->absmin[t]; | ||
572 | abs.maximum = dev->absmax[t]; | ||
573 | abs.fuzz = dev->absfuzz[t]; | ||
574 | abs.flat = dev->absflat[t]; | ||
575 | 720 | ||
576 | if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) | 721 | t = _IOC_NR(cmd) & ABS_MAX; |
577 | return -EFAULT; | ||
578 | 722 | ||
579 | return 0; | 723 | abs.value = dev->abs[t]; |
580 | } | 724 | abs.minimum = dev->absmin[t]; |
725 | abs.maximum = dev->absmax[t]; | ||
726 | abs.fuzz = dev->absfuzz[t]; | ||
727 | abs.flat = dev->absflat[t]; | ||
581 | 728 | ||
729 | if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) | ||
730 | return -EFAULT; | ||
731 | |||
732 | return 0; | ||
582 | } | 733 | } |
583 | 734 | ||
584 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | 735 | } |
585 | 736 | ||
586 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | 737 | if (_IOC_DIR(cmd) == _IOC_WRITE) { |
587 | 738 | ||
588 | t = _IOC_NR(cmd) & ABS_MAX; | 739 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
589 | 740 | ||
590 | if (copy_from_user(&abs, p, sizeof(struct input_absinfo))) | 741 | t = _IOC_NR(cmd) & ABS_MAX; |
591 | return -EFAULT; | ||
592 | 742 | ||
593 | dev->abs[t] = abs.value; | 743 | if (copy_from_user(&abs, p, |
594 | dev->absmin[t] = abs.minimum; | 744 | sizeof(struct input_absinfo))) |
595 | dev->absmax[t] = abs.maximum; | 745 | return -EFAULT; |
596 | dev->absfuzz[t] = abs.fuzz; | ||
597 | dev->absflat[t] = abs.flat; | ||
598 | 746 | ||
599 | return 0; | 747 | /* |
600 | } | 748 | * Take event lock to ensure that we are not |
749 | * changing device parameters in the middle | ||
750 | * of event. | ||
751 | */ | ||
752 | spin_lock_irq(&dev->event_lock); | ||
753 | |||
754 | dev->abs[t] = abs.value; | ||
755 | dev->absmin[t] = abs.minimum; | ||
756 | dev->absmax[t] = abs.maximum; | ||
757 | dev->absfuzz[t] = abs.fuzz; | ||
758 | dev->absflat[t] = abs.flat; | ||
759 | |||
760 | spin_unlock_irq(&dev->event_lock); | ||
761 | |||
762 | return 0; | ||
601 | } | 763 | } |
764 | } | ||
602 | } | 765 | } |
603 | return -EINVAL; | 766 | return -EINVAL; |
604 | } | 767 | } |
605 | 768 | ||
769 | static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | ||
770 | void __user *p, int compat_mode) | ||
771 | { | ||
772 | struct evdev_client *client = file->private_data; | ||
773 | struct evdev *evdev = client->evdev; | ||
774 | int retval; | ||
775 | |||
776 | retval = mutex_lock_interruptible(&evdev->mutex); | ||
777 | if (retval) | ||
778 | return retval; | ||
779 | |||
780 | if (!evdev->exist) { | ||
781 | retval = -ENODEV; | ||
782 | goto out; | ||
783 | } | ||
784 | |||
785 | retval = evdev_do_ioctl(file, cmd, p, compat_mode); | ||
786 | |||
787 | out: | ||
788 | mutex_unlock(&evdev->mutex); | ||
789 | return retval; | ||
790 | } | ||
791 | |||
606 | static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 792 | static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
607 | { | 793 | { |
608 | return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0); | 794 | return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0); |
609 | } | 795 | } |
610 | 796 | ||
611 | #ifdef CONFIG_COMPAT | 797 | #ifdef CONFIG_COMPAT |
612 | static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) | 798 | static long evdev_ioctl_compat(struct file *file, |
799 | unsigned int cmd, unsigned long arg) | ||
613 | { | 800 | { |
614 | return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1); | 801 | return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1); |
615 | } | 802 | } |
616 | #endif | 803 | #endif |
617 | 804 | ||
618 | static const struct file_operations evdev_fops = { | 805 | static const struct file_operations evdev_fops = { |
619 | .owner = THIS_MODULE, | 806 | .owner = THIS_MODULE, |
620 | .read = evdev_read, | 807 | .read = evdev_read, |
621 | .write = evdev_write, | 808 | .write = evdev_write, |
622 | .poll = evdev_poll, | 809 | .poll = evdev_poll, |
623 | .open = evdev_open, | 810 | .open = evdev_open, |
624 | .release = evdev_release, | 811 | .release = evdev_release, |
625 | .unlocked_ioctl = evdev_ioctl, | 812 | .unlocked_ioctl = evdev_ioctl, |
626 | #ifdef CONFIG_COMPAT | 813 | #ifdef CONFIG_COMPAT |
627 | .compat_ioctl = evdev_ioctl_compat, | 814 | .compat_ioctl = evdev_ioctl_compat, |
628 | #endif | 815 | #endif |
629 | .fasync = evdev_fasync, | 816 | .fasync = evdev_fasync, |
630 | .flush = evdev_flush | 817 | .flush = evdev_flush |
631 | }; | 818 | }; |
632 | 819 | ||
820 | static int evdev_install_chrdev(struct evdev *evdev) | ||
821 | { | ||
822 | /* | ||
823 | * No need to do any locking here as calls to connect and | ||
824 | * disconnect are serialized by the input core | ||
825 | */ | ||
826 | evdev_table[evdev->minor] = evdev; | ||
827 | return 0; | ||
828 | } | ||
829 | |||
830 | static void evdev_remove_chrdev(struct evdev *evdev) | ||
831 | { | ||
832 | /* | ||
833 | * Lock evdev table to prevent race with evdev_open() | ||
834 | */ | ||
835 | mutex_lock(&evdev_table_mutex); | ||
836 | evdev_table[evdev->minor] = NULL; | ||
837 | mutex_unlock(&evdev_table_mutex); | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * Mark device non-existent. This disables writes, ioctls and | ||
842 | * prevents new users from opening the device. Already posted | ||
843 | * blocking reads will stay, however new ones will fail. | ||
844 | */ | ||
845 | static void evdev_mark_dead(struct evdev *evdev) | ||
846 | { | ||
847 | mutex_lock(&evdev->mutex); | ||
848 | evdev->exist = 0; | ||
849 | mutex_unlock(&evdev->mutex); | ||
850 | } | ||
851 | |||
852 | static void evdev_cleanup(struct evdev *evdev) | ||
853 | { | ||
854 | struct input_handle *handle = &evdev->handle; | ||
855 | |||
856 | evdev_mark_dead(evdev); | ||
857 | evdev_hangup(evdev); | ||
858 | evdev_remove_chrdev(evdev); | ||
859 | |||
860 | /* evdev is marked dead so no one else accesses evdev->open */ | ||
861 | if (evdev->open) { | ||
862 | input_flush_device(handle, NULL); | ||
863 | input_close_device(handle); | ||
864 | } | ||
865 | } | ||
866 | |||
867 | /* | ||
868 | * Create new evdev device. Note that input core serializes calls | ||
869 | * to connect and disconnect so we don't need to lock evdev_table here. | ||
870 | */ | ||
633 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | 871 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, |
634 | const struct input_device_id *id) | 872 | const struct input_device_id *id) |
635 | { | 873 | { |
@@ -637,7 +875,10 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
637 | int minor; | 875 | int minor; |
638 | int error; | 876 | int error; |
639 | 877 | ||
640 | for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); | 878 | for (minor = 0; minor < EVDEV_MINORS; minor++) |
879 | if (!evdev_table[minor]) | ||
880 | break; | ||
881 | |||
641 | if (minor == EVDEV_MINORS) { | 882 | if (minor == EVDEV_MINORS) { |
642 | printk(KERN_ERR "evdev: no more free evdev devices\n"); | 883 | printk(KERN_ERR "evdev: no more free evdev devices\n"); |
643 | return -ENFILE; | 884 | return -ENFILE; |
@@ -648,38 +889,44 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
648 | return -ENOMEM; | 889 | return -ENOMEM; |
649 | 890 | ||
650 | INIT_LIST_HEAD(&evdev->client_list); | 891 | INIT_LIST_HEAD(&evdev->client_list); |
892 | spin_lock_init(&evdev->client_lock); | ||
893 | mutex_init(&evdev->mutex); | ||
651 | init_waitqueue_head(&evdev->wait); | 894 | init_waitqueue_head(&evdev->wait); |
652 | 895 | ||
896 | snprintf(evdev->name, sizeof(evdev->name), "event%d", minor); | ||
653 | evdev->exist = 1; | 897 | evdev->exist = 1; |
654 | evdev->minor = minor; | 898 | evdev->minor = minor; |
899 | |||
655 | evdev->handle.dev = dev; | 900 | evdev->handle.dev = dev; |
656 | evdev->handle.name = evdev->name; | 901 | evdev->handle.name = evdev->name; |
657 | evdev->handle.handler = handler; | 902 | evdev->handle.handler = handler; |
658 | evdev->handle.private = evdev; | 903 | evdev->handle.private = evdev; |
659 | snprintf(evdev->name, sizeof(evdev->name), "event%d", minor); | ||
660 | 904 | ||
661 | snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id), | 905 | strlcpy(evdev->dev.bus_id, evdev->name, sizeof(evdev->dev.bus_id)); |
662 | "event%d", minor); | 906 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); |
663 | evdev->dev.class = &input_class; | 907 | evdev->dev.class = &input_class; |
664 | evdev->dev.parent = &dev->dev; | 908 | evdev->dev.parent = &dev->dev; |
665 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); | ||
666 | evdev->dev.release = evdev_free; | 909 | evdev->dev.release = evdev_free; |
667 | device_initialize(&evdev->dev); | 910 | device_initialize(&evdev->dev); |
668 | 911 | ||
669 | evdev_table[minor] = evdev; | 912 | error = input_register_handle(&evdev->handle); |
670 | |||
671 | error = device_add(&evdev->dev); | ||
672 | if (error) | 913 | if (error) |
673 | goto err_free_evdev; | 914 | goto err_free_evdev; |
674 | 915 | ||
675 | error = input_register_handle(&evdev->handle); | 916 | error = evdev_install_chrdev(evdev); |
917 | if (error) | ||
918 | goto err_unregister_handle; | ||
919 | |||
920 | error = device_add(&evdev->dev); | ||
676 | if (error) | 921 | if (error) |
677 | goto err_delete_evdev; | 922 | goto err_cleanup_evdev; |
678 | 923 | ||
679 | return 0; | 924 | return 0; |
680 | 925 | ||
681 | err_delete_evdev: | 926 | err_cleanup_evdev: |
682 | device_del(&evdev->dev); | 927 | evdev_cleanup(evdev); |
928 | err_unregister_handle: | ||
929 | input_unregister_handle(&evdev->handle); | ||
683 | err_free_evdev: | 930 | err_free_evdev: |
684 | put_device(&evdev->dev); | 931 | put_device(&evdev->dev); |
685 | return error; | 932 | return error; |
@@ -688,21 +935,10 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
688 | static void evdev_disconnect(struct input_handle *handle) | 935 | static void evdev_disconnect(struct input_handle *handle) |
689 | { | 936 | { |
690 | struct evdev *evdev = handle->private; | 937 | struct evdev *evdev = handle->private; |
691 | struct evdev_client *client; | ||
692 | 938 | ||
693 | input_unregister_handle(handle); | ||
694 | device_del(&evdev->dev); | 939 | device_del(&evdev->dev); |
695 | 940 | evdev_cleanup(evdev); | |
696 | evdev->exist = 0; | 941 | input_unregister_handle(handle); |
697 | |||
698 | if (evdev->open) { | ||
699 | input_flush_device(handle, NULL); | ||
700 | input_close_device(handle); | ||
701 | list_for_each_entry(client, &evdev->client_list, node) | ||
702 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); | ||
703 | wake_up_interruptible(&evdev->wait); | ||
704 | } | ||
705 | |||
706 | put_device(&evdev->dev); | 942 | put_device(&evdev->dev); |
707 | } | 943 | } |
708 | 944 | ||
@@ -714,13 +950,13 @@ static const struct input_device_id evdev_ids[] = { | |||
714 | MODULE_DEVICE_TABLE(input, evdev_ids); | 950 | MODULE_DEVICE_TABLE(input, evdev_ids); |
715 | 951 | ||
716 | static struct input_handler evdev_handler = { | 952 | static struct input_handler evdev_handler = { |
717 | .event = evdev_event, | 953 | .event = evdev_event, |
718 | .connect = evdev_connect, | 954 | .connect = evdev_connect, |
719 | .disconnect = evdev_disconnect, | 955 | .disconnect = evdev_disconnect, |
720 | .fops = &evdev_fops, | 956 | .fops = &evdev_fops, |
721 | .minor = EVDEV_MINOR_BASE, | 957 | .minor = EVDEV_MINOR_BASE, |
722 | .name = "evdev", | 958 | .name = "evdev", |
723 | .id_table = evdev_ids, | 959 | .id_table = evdev_ids, |
724 | }; | 960 | }; |
725 | 961 | ||
726 | static int __init evdev_init(void) | 962 | static int __init evdev_init(void) |