aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joydev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joydev.c')
-rw-r--r--drivers/input/joydev.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9f3529ad3fda..cf24a5bde539 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -465,21 +465,24 @@ static const struct file_operations joydev_fops = {
465 .fasync = joydev_fasync, 465 .fasync = joydev_fasync,
466}; 466};
467 467
468static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, 468static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
469 const struct input_device_id *id) 469 const struct input_device_id *id)
470{ 470{
471 struct joydev *joydev; 471 struct joydev *joydev;
472 struct class_device *cdev; 472 struct class_device *cdev;
473 dev_t devt;
473 int i, j, t, minor; 474 int i, j, t, minor;
475 int error;
474 476
475 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); 477 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
476 if (minor == JOYDEV_MINORS) { 478 if (minor == JOYDEV_MINORS) {
477 printk(KERN_ERR "joydev: no more free joydev devices\n"); 479 printk(KERN_ERR "joydev: no more free joydev devices\n");
478 return NULL; 480 return -ENFILE;
479 } 481 }
480 482
481 if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) 483 joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
482 return NULL; 484 if (!joydev)
485 return -ENOMEM;
483 486
484 INIT_LIST_HEAD(&joydev->list); 487 INIT_LIST_HEAD(&joydev->list);
485 init_waitqueue_head(&joydev->wait); 488 init_waitqueue_head(&joydev->wait);
@@ -534,22 +537,45 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
534 537
535 joydev_table[minor] = joydev; 538 joydev_table[minor] = joydev;
536 539
537 cdev = class_device_create(&input_class, &dev->cdev, 540 devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
538 MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), 541
539 dev->cdev.dev, joydev->name); 542 cdev = class_device_create(&input_class, &dev->cdev, devt,
543 dev->cdev.dev, joydev->name);
544 if (IS_ERR(cdev)) {
545 error = PTR_ERR(cdev);
546 goto err_free_joydev;
547 }
540 548
541 /* temporary symlink to keep userspace happy */ 549 /* temporary symlink to keep userspace happy */
542 sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, 550 error = sysfs_create_link(&input_class.subsys.kset.kobj,
543 joydev->name); 551 &cdev->kobj, joydev->name);
552 if (error)
553 goto err_cdev_destroy;
554
555 error = input_register_handle(&joydev->handle);
556 if (error)
557 goto err_remove_link;
558
559 return 0;
544 560
545 return &joydev->handle; 561 err_remove_link:
562 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
563 err_cdev_destroy:
564 class_device_destroy(&input_class, devt);
565 err_free_joydev:
566 joydev_table[minor] = NULL;
567 kfree(joydev);
568 return error;
546} 569}
547 570
571
548static void joydev_disconnect(struct input_handle *handle) 572static void joydev_disconnect(struct input_handle *handle)
549{ 573{
550 struct joydev *joydev = handle->private; 574 struct joydev *joydev = handle->private;
551 struct joydev_list *list; 575 struct joydev_list *list;
552 576
577 input_unregister_handle(handle);
578
553 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); 579 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
554 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); 580 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
555 joydev->exist = 0; 581 joydev->exist = 0;