Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:
"Some more updates for the input subsystem.

You will get a fix for race in mousedev that has been causing quite a
few oopses lately and a small fixup for force feedback support in
evdev"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: mousedev - fix race when creating mixed device
Input: don't modify the id of ioctl-provided ff effect on upload failure

+45 -32
+3 -1
drivers/input/evdev.c
··· 954 954 return -EFAULT; 955 955 956 956 error = input_ff_upload(dev, &effect, file); 957 + if (error) 958 + return error; 957 959 958 960 if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) 959 961 return -EFAULT; 960 962 961 - return error; 963 + return 0; 962 964 } 963 965 964 966 /* Multi-number variable-length handlers */
+42 -31
drivers/input/mousedev.c
··· 67 67 struct device dev; 68 68 struct cdev cdev; 69 69 bool exist; 70 - bool is_mixdev; 71 70 72 71 struct list_head mixdev_node; 73 72 bool opened_by_mixdev; ··· 76 77 int old_x[4], old_y[4]; 77 78 int frac_dx, frac_dy; 78 79 unsigned long touch; 80 + 81 + int (*open_device)(struct mousedev *mousedev); 82 + void (*close_device)(struct mousedev *mousedev); 79 83 }; 80 84 81 85 enum mousedev_emul { ··· 117 115 118 116 static struct mousedev *mousedev_mix; 119 117 static LIST_HEAD(mousedev_mix_list); 120 - 121 - static void mixdev_open_devices(void); 122 - static void mixdev_close_devices(void); 123 118 124 119 #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) 125 120 #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) ··· 427 428 if (retval) 428 429 return retval; 429 430 430 - if (mousedev->is_mixdev) 431 - mixdev_open_devices(); 432 - else if (!mousedev->exist) 431 + if (!mousedev->exist) 433 432 retval = -ENODEV; 434 433 else if (!mousedev->open++) { 435 434 retval = input_open_device(&mousedev->handle); ··· 443 446 { 444 447 mutex_lock(&mousedev->mutex); 445 448 446 - if (mousedev->is_mixdev) 447 - mixdev_close_devices(); 448 - else if (mousedev->exist && !--mousedev->open) 449 + if (mousedev->exist && !--mousedev->open) 449 450 input_close_device(&mousedev->handle); 450 451 451 452 mutex_unlock(&mousedev->mutex); ··· 454 459 * stream. Note that this function is called with mousedev_mix->mutex 455 460 * held. 456 461 */ 457 - static void mixdev_open_devices(void) 462 + static int mixdev_open_devices(struct mousedev *mixdev) 458 463 { 459 - struct mousedev *mousedev; 464 + int error; 460 465 461 - if (mousedev_mix->open++) 462 - return; 466 + error = mutex_lock_interruptible(&mixdev->mutex); 467 + if (error) 468 + return error; 463 469 464 - list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 465 - if (!mousedev->opened_by_mixdev) { 466 - if (mousedev_open_device(mousedev)) 467 - continue; 470 + if (!mixdev->open++) { 471 + struct mousedev *mousedev; 468 472 469 - mousedev->opened_by_mixdev = true; 473 + list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 474 + if (!mousedev->opened_by_mixdev) { 475 + if (mousedev_open_device(mousedev)) 476 + continue; 477 + 478 + mousedev->opened_by_mixdev = true; 479 + } 470 480 } 471 481 } 482 + 483 + mutex_unlock(&mixdev->mutex); 484 + return 0; 472 485 } 473 486 474 487 /* ··· 484 481 * device. Note that this function is called with mousedev_mix->mutex 485 482 * held. 486 483 */ 487 - static void mixdev_close_devices(void) 484 + static void mixdev_close_devices(struct mousedev *mixdev) 488 485 { 489 - struct mousedev *mousedev; 486 + mutex_lock(&mixdev->mutex); 490 487 491 - if (--mousedev_mix->open) 492 - return; 488 + if (!--mixdev->open) { 489 + struct mousedev *mousedev; 493 490 494 - list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 495 - if (mousedev->opened_by_mixdev) { 496 - mousedev->opened_by_mixdev = false; 497 - mousedev_close_device(mousedev); 491 + list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 492 + if (mousedev->opened_by_mixdev) { 493 + mousedev->opened_by_mixdev = false; 494 + mousedev_close_device(mousedev); 495 + } 498 496 } 499 497 } 498 + 499 + mutex_unlock(&mixdev->mutex); 500 500 } 501 501 502 502 ··· 528 522 mousedev_detach_client(mousedev, client); 529 523 kfree(client); 530 524 531 - mousedev_close_device(mousedev); 525 + mousedev->close_device(mousedev); 532 526 533 527 return 0; 534 528 } ··· 556 550 client->mousedev = mousedev; 557 551 mousedev_attach_client(mousedev, client); 558 552 559 - error = mousedev_open_device(mousedev); 553 + error = mousedev->open_device(mousedev); 560 554 if (error) 561 555 goto err_free_client; 562 556 ··· 867 861 868 862 if (mixdev) { 869 863 dev_set_name(&mousedev->dev, "mice"); 864 + 865 + mousedev->open_device = mixdev_open_devices; 866 + mousedev->close_device = mixdev_close_devices; 870 867 } else { 871 868 int dev_no = minor; 872 869 /* Normalize device number if it falls into legacy range */ 873 870 if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS) 874 871 dev_no -= MOUSEDEV_MINOR_BASE; 875 872 dev_set_name(&mousedev->dev, "mouse%d", dev_no); 873 + 874 + mousedev->open_device = mousedev_open_device; 875 + mousedev->close_device = mousedev_close_device; 876 876 } 877 877 878 878 mousedev->exist = true; 879 - mousedev->is_mixdev = mixdev; 880 879 mousedev->handle.dev = input_get_device(dev); 881 880 mousedev->handle.name = dev_name(&mousedev->dev); 882 881 mousedev->handle.handler = handler; ··· 930 919 device_del(&mousedev->dev); 931 920 mousedev_cleanup(mousedev); 932 921 input_free_minor(MINOR(mousedev->dev.devt)); 933 - if (!mousedev->is_mixdev) 922 + if (mousedev != mousedev_mix) 934 923 input_unregister_handle(&mousedev->handle); 935 924 put_device(&mousedev->dev); 936 925 }