Commit 40fa5422 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 88a22c98
...@@ -384,6 +384,19 @@ void device_initialize(struct device *dev) ...@@ -384,6 +384,19 @@ void device_initialize(struct device *dev)
device_init_wakeup(dev, 0); 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) static int virtual_device_parent(struct device *dev)
{ {
if (!dev->class) if (!dev->class)
...@@ -401,6 +414,22 @@ static int virtual_device_parent(struct device *dev) ...@@ -401,6 +414,22 @@ static int virtual_device_parent(struct device *dev)
return 0; 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. * device_add - add device to device hierarchy.
* @dev: device. * @dev: device.
...@@ -423,23 +452,18 @@ int device_add(struct device *dev) ...@@ -423,23 +452,18 @@ int device_add(struct device *dev)
if (!dev || !strlen(dev->bus_id)) if (!dev || !strlen(dev->bus_id))
goto Error; goto Error;
/* if this is a class device, and has no parent, create one */ pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
if ((dev->class) && (dev->parent == NULL)) {
error = virtual_device_parent(dev);
if (error)
goto Error;
}
parent = get_device(dev->parent); 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. */ /* first, register with generic layer. */
kobject_set_name(&dev->kobj, "%s", dev->bus_id); kobject_set_name(&dev->kobj, "%s", dev->bus_id);
if (parent) error = kobject_add(&dev->kobj);
dev->kobj.parent = &parent->kobj; if (error)
if ((error = kobject_add(&dev->kobj)))
goto Error; goto Error;
/* notify platform of device entry */ /* notify platform of device entry */
...@@ -484,8 +508,11 @@ int device_add(struct device *dev) ...@@ -484,8 +508,11 @@ int device_add(struct device *dev)
if (dev->class) { if (dev->class) {
sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj,
"subsystem"); "subsystem");
sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, /* If this is not a "fake" compatible device, then create the
dev->bus_id); * 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) { if (parent) {
sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
class_name = make_class_name(dev->class->name, &dev->kobj); class_name = make_class_name(dev->class->name, &dev->kobj);
...@@ -623,7 +650,11 @@ void device_del(struct device * dev) ...@@ -623,7 +650,11 @@ void device_del(struct device * dev)
} }
if (dev->class) { if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem"); 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); class_name = make_class_name(dev->class->name, &dev->kobj);
if (parent) { if (parent) {
sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "device");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment