aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-04-26 12:53:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-21 15:40:48 -0400
commitb7fe4a60f3a5a428832bf5dd9388e80f0d02fc2e (patch)
treee378263252c78af899e8db3f98a0e2cc6486a265 /drivers/base
parent3dda4e373c7474cfe280f4270b70c1563f92a2a7 (diff)
[PATCH] Driver core: class_device_add needs error checks
class_device_add needs to check the return value of all the setup it does. It doesn't handle out of memory well. This is not complete, probably more needs to be done. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/class.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index b1ea4df85c7d..48ad5df72812 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -535,18 +535,22 @@ int class_device_add(struct class_device *class_dev)
535 return -EINVAL; 535 return -EINVAL;
536 536
537 if (!strlen(class_dev->class_id)) 537 if (!strlen(class_dev->class_id))
538 goto register_done; 538 goto out1;
539 539
540 parent_class = class_get(class_dev->class); 540 parent_class = class_get(class_dev->class);
541 if (!parent_class) 541 if (!parent_class)
542 goto register_done; 542 goto out1;
543
543 parent_class_dev = class_device_get(class_dev->parent); 544 parent_class_dev = class_device_get(class_dev->parent);
544 545
545 pr_debug("CLASS: registering class device: ID = '%s'\n", 546 pr_debug("CLASS: registering class device: ID = '%s'\n",
546 class_dev->class_id); 547 class_dev->class_id);
547 548
548 /* first, register with generic layer. */ 549 /* first, register with generic layer. */
549 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 550 error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
551 if (error)
552 goto out2;
553
550 if (parent_class_dev) 554 if (parent_class_dev)
551 class_dev->kobj.parent = &parent_class_dev->kobj; 555 class_dev->kobj.parent = &parent_class_dev->kobj;
552 else 556 else
@@ -554,41 +558,56 @@ int class_device_add(struct class_device *class_dev)
554 558
555 error = kobject_add(&class_dev->kobj); 559 error = kobject_add(&class_dev->kobj);
556 if (error) 560 if (error)
557 goto register_done; 561 goto out2;
558 562
559 /* add the needed attributes to this device */ 563 /* add the needed attributes to this device */
560 class_dev->uevent_attr.attr.name = "uevent"; 564 class_dev->uevent_attr.attr.name = "uevent";
561 class_dev->uevent_attr.attr.mode = S_IWUSR; 565 class_dev->uevent_attr.attr.mode = S_IWUSR;
562 class_dev->uevent_attr.attr.owner = parent_class->owner; 566 class_dev->uevent_attr.attr.owner = parent_class->owner;
563 class_dev->uevent_attr.store = store_uevent; 567 class_dev->uevent_attr.store = store_uevent;
564 class_device_create_file(class_dev, &class_dev->uevent_attr); 568 error = class_device_create_file(class_dev, &class_dev->uevent_attr);
569 if (error)
570 goto out3;
565 571
566 if (MAJOR(class_dev->devt)) { 572 if (MAJOR(class_dev->devt)) {
567 struct class_device_attribute *attr; 573 struct class_device_attribute *attr;
568 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 574 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
569 if (!attr) { 575 if (!attr) {
570 error = -ENOMEM; 576 error = -ENOMEM;
571 kobject_del(&class_dev->kobj); 577 goto out4;
572 goto register_done;
573 } 578 }
574 attr->attr.name = "dev"; 579 attr->attr.name = "dev";
575 attr->attr.mode = S_IRUGO; 580 attr->attr.mode = S_IRUGO;
576 attr->attr.owner = parent_class->owner; 581 attr->attr.owner = parent_class->owner;
577 attr->show = show_dev; 582 attr->show = show_dev;
578 class_device_create_file(class_dev, attr); 583 error = class_device_create_file(class_dev, attr);
584 if (error) {
585 kfree(attr);
586 goto out4;
587 }
588
579 class_dev->devt_attr = attr; 589 class_dev->devt_attr = attr;
580 } 590 }
581 591
582 class_device_add_attrs(class_dev); 592 error = class_device_add_attrs(class_dev);
593 if (error)
594 goto out5;
595
583 if (class_dev->dev) { 596 if (class_dev->dev) {
584 class_name = make_class_name(class_dev); 597 class_name = make_class_name(class_dev);
585 sysfs_create_link(&class_dev->kobj, 598 error = sysfs_create_link(&class_dev->kobj,
586 &class_dev->dev->kobj, "device"); 599 &class_dev->dev->kobj, "device");
587 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 600 if (error)
588 class_name); 601 goto out6;
602 error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
603 class_name);
604 if (error)
605 goto out7;
589 } 606 }
590 607
591 class_device_add_groups(class_dev); 608 error = class_device_add_groups(class_dev);
609 if (error)
610 goto out8;
592 611
593 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 612 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
594 613
@@ -601,11 +620,28 @@ int class_device_add(struct class_device *class_dev)
601 } 620 }
602 up(&parent_class->sem); 621 up(&parent_class->sem);
603 622
604 register_done: 623 goto out1;
605 if (error) { 624
606 class_put(parent_class); 625 out8:
626 if (class_dev->dev)
627 sysfs_remove_link(&class_dev->kobj, class_name);
628 out7:
629 if (class_dev->dev)
630 sysfs_remove_link(&class_dev->kobj, "device");
631 out6:
632 class_device_remove_attrs(class_dev);
633 out5:
634 if (class_dev->devt_attr)
635 class_device_remove_file(class_dev, class_dev->devt_attr);
636 out4:
637 class_device_remove_file(class_dev, &class_dev->uevent_attr);
638 out3:
639 kobject_del(&class_dev->kobj);
640 out2:
641 if(parent_class_dev)
607 class_device_put(parent_class_dev); 642 class_device_put(parent_class_dev);
608 } 643 class_put(parent_class);
644 out1:
609 class_device_put(class_dev); 645 class_device_put(class_dev);
610 kfree(class_name); 646 kfree(class_name);
611 return error; 647 return error;