aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@infradead.org>2007-02-21 12:44:51 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-23 17:52:09 -0500
commit82f0cf9b7c42684c29189ddb6d0bc86eb1137fc4 (patch)
tree3052eb95a5e6070cbee8a1262952abc48f2eedbe /drivers/base/core.c
parent4541ac94d0ea0b00776edd5904ac91dd6d6330f7 (diff)
Driver core: fix error by cleanup up symlinks properly
When a device fails to register the class symlinks where not cleaned up. This left a symlink in the /sys/class/"device"/ directory that pointed to no where. This caused the sysfs_follow_link Oops I reported earlier. This patch cleanups up the symlink. Please apply. Thank you. Signed-Off: James Simmons <jsimmons@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d04fd33dcd91..cf2a398aaaa1 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -637,12 +637,41 @@ int device_add(struct device *dev)
637 BUS_NOTIFY_DEL_DEVICE, dev); 637 BUS_NOTIFY_DEL_DEVICE, dev);
638 device_remove_groups(dev); 638 device_remove_groups(dev);
639 GroupError: 639 GroupError:
640 device_remove_attrs(dev); 640 device_remove_attrs(dev);
641 AttrsError: 641 AttrsError:
642 if (dev->devt_attr) { 642 if (dev->devt_attr) {
643 device_remove_file(dev, dev->devt_attr); 643 device_remove_file(dev, dev->devt_attr);
644 kfree(dev->devt_attr); 644 kfree(dev->devt_attr);
645 } 645 }
646
647 if (dev->class) {
648 sysfs_remove_link(&dev->kobj, "subsystem");
649 /* If this is not a "fake" compatible device, remove the
650 * symlink from the class to the device. */
651 if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
652 sysfs_remove_link(&dev->class->subsys.kset.kobj,
653 dev->bus_id);
654#ifdef CONFIG_SYSFS_DEPRECATED
655 if (parent) {
656 char *class_name = make_class_name(dev->class->name,
657 &dev->kobj);
658 if (class_name)
659 sysfs_remove_link(&dev->parent->kobj,
660 class_name);
661 kfree(class_name);
662 sysfs_remove_link(&dev->kobj, "device");
663 }
664#endif
665
666 down(&dev->class->sem);
667 /* notify any interfaces that the device is now gone */
668 list_for_each_entry(class_intf, &dev->class->interfaces, node)
669 if (class_intf->remove_dev)
670 class_intf->remove_dev(dev, class_intf);
671 /* remove the device from the class list */
672 list_del_init(&dev->node);
673 up(&dev->class->sem);
674 }
646 ueventattrError: 675 ueventattrError:
647 device_remove_file(dev, &dev->uevent_attr); 676 device_remove_file(dev, &dev->uevent_attr);
648 attrError: 677 attrError: