diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-04-12 01:30:15 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-04-12 01:30:15 -0400 |
commit | d542ed82fdc72cf63549deec19e86ee4addf2499 (patch) | |
tree | 201c713b24a429d34272998ae3ecca87c937709a /drivers/input/mousedev.c | |
parent | d0ffb9be866519775da19c0a6790f5431c1a8dc6 (diff) |
Input: handlers - handle errors from input_open_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mousedev.c')
-rw-r--r-- | drivers/input/mousedev.c | 114 |
1 files changed, 80 insertions, 34 deletions
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index f6a62687d9e4..764970f5da2e 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -66,6 +66,9 @@ struct mousedev { | |||
66 | struct list_head client_list; | 66 | struct list_head client_list; |
67 | struct input_handle handle; | 67 | struct input_handle handle; |
68 | 68 | ||
69 | struct list_head mixdev_node; | ||
70 | int mixdev_open; | ||
71 | |||
69 | struct mousedev_hw_data packet; | 72 | struct mousedev_hw_data packet; |
70 | unsigned int pkt_count; | 73 | unsigned int pkt_count; |
71 | int old_x[4], old_y[4]; | 74 | int old_x[4], old_y[4]; |
@@ -111,6 +114,7 @@ static struct input_handler mousedev_handler; | |||
111 | 114 | ||
112 | static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; | 115 | static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; |
113 | static struct mousedev mousedev_mix; | 116 | static struct mousedev mousedev_mix; |
117 | static LIST_HEAD(mousedev_mix_list); | ||
114 | 118 | ||
115 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) | 119 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) |
116 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) | 120 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) |
@@ -364,18 +368,63 @@ static void mousedev_free(struct mousedev *mousedev) | |||
364 | kfree(mousedev); | 368 | kfree(mousedev); |
365 | } | 369 | } |
366 | 370 | ||
367 | static void mixdev_release(void) | 371 | static int mixdev_add_device(struct mousedev *mousedev) |
368 | { | 372 | { |
369 | struct input_handle *handle; | 373 | int error; |
370 | 374 | ||
371 | list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { | 375 | if (mousedev_mix.open) { |
372 | struct mousedev *mousedev = handle->private; | 376 | error = input_open_device(&mousedev->handle); |
377 | if (error) | ||
378 | return error; | ||
373 | 379 | ||
374 | if (!mousedev->open) { | 380 | mousedev->open++; |
375 | if (mousedev->exist) | 381 | mousedev->mixdev_open++; |
376 | input_close_device(&mousedev->handle); | 382 | } |
377 | else | 383 | |
378 | mousedev_free(mousedev); | 384 | list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); |
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static void mixdev_remove_device(struct mousedev *mousedev) | ||
390 | { | ||
391 | if (mousedev->mixdev_open) { | ||
392 | mousedev->mixdev_open = 0; | ||
393 | if (!--mousedev->open && mousedev->exist) | ||
394 | input_close_device(&mousedev->handle); | ||
395 | } | ||
396 | |||
397 | list_del_init(&mousedev->mixdev_node); | ||
398 | } | ||
399 | |||
400 | static void mixdev_open_devices(void) | ||
401 | { | ||
402 | struct mousedev *mousedev; | ||
403 | |||
404 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | ||
405 | if (mousedev->exist && !mousedev->open) { | ||
406 | if (input_open_device(&mousedev->handle)) | ||
407 | continue; | ||
408 | |||
409 | mousedev->open++; | ||
410 | mousedev->mixdev_open++; | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | |||
415 | static void mixdev_close_devices(void) | ||
416 | { | ||
417 | struct mousedev *mousedev, *next; | ||
418 | |||
419 | list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { | ||
420 | if (mousedev->mixdev_open) { | ||
421 | mousedev->mixdev_open = 0; | ||
422 | if (!--mousedev->open) { | ||
423 | if (mousedev->exist) | ||
424 | input_close_device(&mousedev->handle); | ||
425 | else | ||
426 | mousedev_free(mousedev); | ||
427 | } | ||
379 | } | 428 | } |
380 | } | 429 | } |
381 | } | 430 | } |
@@ -392,23 +441,22 @@ static int mousedev_release(struct inode *inode, struct file *file) | |||
392 | 441 | ||
393 | if (!--mousedev->open) { | 442 | if (!--mousedev->open) { |
394 | if (mousedev->minor == MOUSEDEV_MIX) | 443 | if (mousedev->minor == MOUSEDEV_MIX) |
395 | mixdev_release(); | 444 | mixdev_close_devices(); |
396 | else if (!mousedev_mix.open) { | 445 | else if (mousedev->exist) |
397 | if (mousedev->exist) | 446 | input_close_device(&mousedev->handle); |
398 | input_close_device(&mousedev->handle); | 447 | else |
399 | else | 448 | mousedev_free(mousedev); |
400 | mousedev_free(mousedev); | ||
401 | } | ||
402 | } | 449 | } |
403 | 450 | ||
404 | return 0; | 451 | return 0; |
405 | } | 452 | } |
406 | 453 | ||
454 | |||
407 | static int mousedev_open(struct inode *inode, struct file *file) | 455 | static int mousedev_open(struct inode *inode, struct file *file) |
408 | { | 456 | { |
409 | struct mousedev_client *client; | 457 | struct mousedev_client *client; |
410 | struct input_handle *handle; | ||
411 | struct mousedev *mousedev; | 458 | struct mousedev *mousedev; |
459 | int error; | ||
412 | int i; | 460 | int i; |
413 | 461 | ||
414 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 462 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
@@ -436,15 +484,16 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
436 | list_add_tail(&client->node, &mousedev->client_list); | 484 | list_add_tail(&client->node, &mousedev->client_list); |
437 | 485 | ||
438 | if (!mousedev->open++) { | 486 | if (!mousedev->open++) { |
439 | if (mousedev->minor == MOUSEDEV_MIX) { | 487 | if (mousedev->minor == MOUSEDEV_MIX) |
440 | list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { | 488 | mixdev_open_devices(); |
441 | struct mousedev *md = handle->private; | 489 | else if (mousedev->exist) { |
442 | if (!md->open && md->exist) | 490 | error = input_open_device(&mousedev->handle); |
443 | input_open_device(handle); | 491 | if (error) { |
492 | list_del(&client->node); | ||
493 | kfree(client); | ||
494 | return error; | ||
444 | } | 495 | } |
445 | } else | 496 | } |
446 | if (!mousedev_mix.open && mousedev->exist) | ||
447 | input_open_device(&mousedev->handle); | ||
448 | } | 497 | } |
449 | 498 | ||
450 | file->private_data = client; | 499 | file->private_data = client; |
@@ -683,11 +732,9 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev | |||
683 | if (error) | 732 | if (error) |
684 | goto err_remove_link; | 733 | goto err_remove_link; |
685 | 734 | ||
686 | if (mousedev_mix.open) { | 735 | error = mixdev_add_device(mousedev); |
687 | error = input_open_device(&mousedev->handle); | 736 | if (error) |
688 | if (error) | 737 | goto err_unregister_handle; |
689 | goto err_unregister_handle; | ||
690 | } | ||
691 | 738 | ||
692 | return 0; | 739 | return 0; |
693 | 740 | ||
@@ -715,16 +762,15 @@ static void mousedev_disconnect(struct input_handle *handle) | |||
715 | MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); | 762 | MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); |
716 | mousedev->exist = 0; | 763 | mousedev->exist = 0; |
717 | 764 | ||
765 | mixdev_remove_device(mousedev); | ||
766 | |||
718 | if (mousedev->open) { | 767 | if (mousedev->open) { |
719 | input_close_device(handle); | 768 | input_close_device(handle); |
720 | wake_up_interruptible(&mousedev->wait); | 769 | wake_up_interruptible(&mousedev->wait); |
721 | list_for_each_entry(client, &mousedev->client_list, node) | 770 | list_for_each_entry(client, &mousedev->client_list, node) |
722 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); | 771 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
723 | } else { | 772 | } else |
724 | if (mousedev_mix.open) | ||
725 | input_close_device(handle); | ||
726 | mousedev_free(mousedev); | 773 | mousedev_free(mousedev); |
727 | } | ||
728 | } | 774 | } |
729 | 775 | ||
730 | static const struct input_device_id mousedev_ids[] = { | 776 | static const struct input_device_id mousedev_ids[] = { |