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 | |
| parent | d0ffb9be866519775da19c0a6790f5431c1a8dc6 (diff) | |
Input: handlers - handle errors from input_open_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/evdev.c | 11 | ||||
| -rw-r--r-- | drivers/input/joydev.c | 11 | ||||
| -rw-r--r-- | drivers/input/mousedev.c | 114 | ||||
| -rw-r--r-- | drivers/input/tsdev.c | 11 |
4 files changed, 107 insertions, 40 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 8a4cce5c7806..6cff8096d56a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -130,6 +130,7 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
| 130 | struct evdev_client *client; | 130 | struct evdev_client *client; |
| 131 | struct evdev *evdev; | 131 | struct evdev *evdev; |
| 132 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 132 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
| 133 | int error; | ||
| 133 | 134 | ||
| 134 | if (i >= EVDEV_MINORS) | 135 | if (i >= EVDEV_MINORS) |
| 135 | return -ENODEV; | 136 | return -ENODEV; |
| @@ -146,8 +147,14 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
| 146 | client->evdev = evdev; | 147 | client->evdev = evdev; |
| 147 | list_add_tail(&client->node, &evdev->client_list); | 148 | list_add_tail(&client->node, &evdev->client_list); |
| 148 | 149 | ||
| 149 | if (!evdev->open++ && evdev->exist) | 150 | if (!evdev->open++ && evdev->exist) { |
| 150 | input_open_device(&evdev->handle); | 151 | error = input_open_device(&evdev->handle); |
| 152 | if (error) { | ||
| 153 | list_del(&client->node); | ||
| 154 | kfree(client); | ||
| 155 | return error; | ||
| 156 | } | ||
| 157 | } | ||
| 151 | 158 | ||
| 152 | file->private_data = client; | 159 | file->private_data = client; |
| 153 | return 0; | 160 | return 0; |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 09b8223de5ec..4f37224d2268 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -170,6 +170,7 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
| 170 | struct joydev_client *client; | 170 | struct joydev_client *client; |
| 171 | struct joydev *joydev; | 171 | struct joydev *joydev; |
| 172 | int i = iminor(inode) - JOYDEV_MINOR_BASE; | 172 | int i = iminor(inode) - JOYDEV_MINOR_BASE; |
| 173 | int error; | ||
| 173 | 174 | ||
| 174 | if (i >= JOYDEV_MINORS) | 175 | if (i >= JOYDEV_MINORS) |
| 175 | return -ENODEV; | 176 | return -ENODEV; |
| @@ -185,8 +186,14 @@ static int joydev_open(struct inode *inode, struct file *file) | |||
| 185 | client->joydev = joydev; | 186 | client->joydev = joydev; |
| 186 | list_add_tail(&client->node, &joydev->client_list); | 187 | list_add_tail(&client->node, &joydev->client_list); |
| 187 | 188 | ||
| 188 | if (!joydev->open++ && joydev->exist) | 189 | if (!joydev->open++ && joydev->exist) { |
| 189 | input_open_device(&joydev->handle); | 190 | error = input_open_device(&joydev->handle); |
| 191 | if (error) { | ||
| 192 | list_del(&client->node); | ||
| 193 | kfree(client); | ||
| 194 | return error; | ||
| 195 | } | ||
| 196 | } | ||
| 190 | 197 | ||
| 191 | file->private_data = client; | 198 | file->private_data = client; |
| 192 | return 0; | 199 | return 0; |
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[] = { |
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index fbef35d2d76c..8e2d2c924adf 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c | |||
| @@ -151,6 +151,7 @@ static int tsdev_open(struct inode *inode, struct file *file) | |||
| 151 | int i = iminor(inode) - TSDEV_MINOR_BASE; | 151 | int i = iminor(inode) - TSDEV_MINOR_BASE; |
| 152 | struct tsdev_client *client; | 152 | struct tsdev_client *client; |
| 153 | struct tsdev *tsdev; | 153 | struct tsdev *tsdev; |
| 154 | int error; | ||
| 154 | 155 | ||
| 155 | printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " | 156 | printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " |
| 156 | "for removal.\nSee Documentation/feature-removal-schedule.txt " | 157 | "for removal.\nSee Documentation/feature-removal-schedule.txt " |
| @@ -171,8 +172,14 @@ static int tsdev_open(struct inode *inode, struct file *file) | |||
| 171 | client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; | 172 | client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; |
| 172 | list_add_tail(&client->node, &tsdev->client_list); | 173 | list_add_tail(&client->node, &tsdev->client_list); |
| 173 | 174 | ||
| 174 | if (!tsdev->open++ && tsdev->exist) | 175 | if (!tsdev->open++ && tsdev->exist) { |
| 175 | input_open_device(&tsdev->handle); | 176 | error = input_open_device(&tsdev->handle); |
| 177 | if (error) { | ||
| 178 | list_del(&client->node); | ||
| 179 | kfree(client); | ||
| 180 | return error; | ||
| 181 | } | ||
| 182 | } | ||
| 176 | 183 | ||
| 177 | file->private_data = client; | 184 | file->private_data = client; |
| 178 | return 0; | 185 | return 0; |
