aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-04-12 01:30:15 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-04-12 01:30:15 -0400
commitd542ed82fdc72cf63549deec19e86ee4addf2499 (patch)
tree201c713b24a429d34272998ae3ecca87c937709a
parentd0ffb9be866519775da19c0a6790f5431c1a8dc6 (diff)
Input: handlers - handle errors from input_open_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/evdev.c11
-rw-r--r--drivers/input/joydev.c11
-rw-r--r--drivers/input/mousedev.c114
-rw-r--r--drivers/input/tsdev.c11
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
112static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; 115static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
113static struct mousedev mousedev_mix; 116static struct mousedev mousedev_mix;
117static 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
367static void mixdev_release(void) 371static 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
389static 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
400static 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
415static 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
407static int mousedev_open(struct inode *inode, struct file *file) 455static 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
730static const struct input_device_id mousedev_ids[] = { 776static 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;