summaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-10-24 00:37:58 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-01 14:51:58 -0800
commit40fa54226f518a9bc97ed1d711c0016e416e3782 (patch)
treefd1a432e23b847e831564e13bb93956b07329b23 /drivers/base/core.c
parent88a22c985e3545c55c9779971007f0f29f912519 (diff)
downloadlinux-40fa54226f518a9bc97ed1d711c0016e416e3782.tar.gz
linux-40fa54226f518a9bc97ed1d711c0016e416e3782.tar.bz2
linux-40fa54226f518a9bc97ed1d711c0016e416e3782.zip
Driver core: make old versions of udev work properly
If CONFIG_SYSFS_DEPRECATED is enabled, old versions of udev will work properly with devices that are associated with a class. Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c59
1 files changed, 45 insertions, 14 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index dbcd40b987d2..8f8347b9197f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -384,6 +384,19 @@ void device_initialize(struct device *dev)
device_init_wakeup(dev, 0);
}
+#ifdef CONFIG_SYSFS_DEPRECATED
+int setup_parent(struct device *dev, struct device *parent)
+{
+ /* Set the parent to the class, not the parent device */
+ /* this keeps sysfs from having a symlink to make old udevs happy */
+ if (dev->class)
+ dev->kobj.parent = &dev->class->subsys.kset.kobj;
+ else if (parent)
+ dev->kobj.parent = &parent->kobj;
+
+ return 0;
+}
+#else
static int virtual_device_parent(struct device *dev)
{
if (!dev->class)
@@ -401,6 +414,22 @@ static int virtual_device_parent(struct device *dev)
return 0;
}
+int setup_parent(struct device *dev, struct device *parent)
+{
+ int error;
+
+ /* if this is a class device, and has no parent, create one */
+ if ((dev->class) && (parent == NULL)) {
+ error = virtual_device_parent(dev);
+ if (error)
+ return error;
+ } else if (parent)
+ dev->kobj.parent = &parent->kobj;
+
+ return 0;
+}
+#endif
+
/**
* device_add - add device to device hierarchy.
* @dev: device.
@@ -423,23 +452,18 @@ int device_add(struct device *dev)
if (!dev || !strlen(dev->bus_id))
goto Error;
- /* if this is a class device, and has no parent, create one */
- if ((dev->class) && (dev->parent == NULL)) {
- error = virtual_device_parent(dev);
- if (error)
- goto Error;
- }
+ pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
parent = get_device(dev->parent);
- pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
+ error = setup_parent(dev, parent);
+ if (error)
+ goto Error;
/* first, register with generic layer. */
kobject_set_name(&dev->kobj, "%s", dev->bus_id);
- if (parent)
- dev->kobj.parent = &parent->kobj;
-
- if ((error = kobject_add(&dev->kobj)))
+ error = kobject_add(&dev->kobj);
+ if (error)
goto Error;
/* notify platform of device entry */
@@ -484,8 +508,11 @@ int device_add(struct device *dev)
if (dev->class) {
sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj,
"subsystem");
- sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
- dev->bus_id);
+ /* If this is not a "fake" compatible device, then create the
+ * symlink from the class to the device. */
+ if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
+ sysfs_create_link(&dev->class->subsys.kset.kobj,
+ &dev->kobj, dev->bus_id);
if (parent) {
sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -623,7 +650,11 @@ void device_del(struct device * dev)
}
if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem");
- sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
+ /* If this is not a "fake" compatible device, remove the
+ * symlink from the class to the device. */
+ if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
+ sysfs_remove_link(&dev->class->subsys.kset.kobj,
+ dev->bus_id);
class_name = make_class_name(dev->class->name, &dev->kobj);
if (parent) {
sysfs_remove_link(&dev->kobj, "device");