Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 61470
b: refs/heads/master
c: 2ee97ca
h: refs/heads/master
v: v3
  • Loading branch information
Cornelia Huck authored and Greg Kroah-Hartman committed Jul 18, 2007
1 parent 2333ba2 commit 226b75d
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 41 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: be3884943674f8ee7656b1d8b71c087ec900c836
refs/heads/master: 2ee97caf0a6602f749ddbfdb1449e383e1212707
145 changes: 105 additions & 40 deletions trunk/drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,82 @@ static int setup_parent(struct device *dev, struct device *parent)
return 0;
}

static int device_add_class_symlinks(struct device *dev)
{
int error;

if (!dev->class)
return 0;
error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
"subsystem");
if (error)
goto out;
/*
* 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.kobj) {
error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
dev->bus_id);
if (error)
goto out_subsys;
}
/* only bus-device parents get a "device"-link */
if (dev->parent && dev->parent->bus) {
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
"device");
if (error)
goto out_busid;
#ifdef CONFIG_SYSFS_DEPRECATED
{
char * class_name = make_class_name(dev->class->name,
&dev->kobj);
if (class_name)
error = sysfs_create_link(&dev->parent->kobj,
&dev->kobj, class_name);
kfree(class_name);
if (error)
goto out_device;
}
#endif
}
return 0;

#ifdef CONFIG_SYSFS_DEPRECATED
out_device:
if (dev->parent)
sysfs_remove_link(&dev->kobj, "device");
#endif
out_busid:
if (dev->kobj.parent != &dev->class->subsys.kobj)
sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
out_subsys:
sysfs_remove_link(&dev->kobj, "subsystem");
out:
return error;
}

static void device_remove_class_symlinks(struct device *dev)
{
if (!dev->class)
return;
if (dev->parent) {
#ifdef CONFIG_SYSFS_DEPRECATED
char *class_name;

class_name = make_class_name(dev->class->name, &dev->kobj);
if (class_name) {
sysfs_remove_link(&dev->parent->kobj, class_name);
kfree(class_name);
}
#endif
sysfs_remove_link(&dev->kobj, "device");
}
if (dev->kobj.parent != &dev->class->subsys.kobj)
sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
sysfs_remove_link(&dev->kobj, "subsystem");
}

/**
* device_add - add device to device hierarchy.
* @dev: device.
Expand All @@ -674,7 +750,6 @@ static int setup_parent(struct device *dev, struct device *parent)
int device_add(struct device *dev)
{
struct device *parent = NULL;
char *class_name = NULL;
struct class_interface *class_intf;
int error = -EINVAL;

Expand Down Expand Up @@ -714,27 +789,9 @@ int device_add(struct device *dev)
goto ueventattrError;
}

if (dev->class) {
sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
"subsystem");
/* 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.kobj)
sysfs_create_link(&dev->class->subsys.kobj,
&dev->kobj, dev->bus_id);
if (parent) {
sysfs_create_link(&dev->kobj, &dev->parent->kobj,
"device");
#ifdef CONFIG_SYSFS_DEPRECATED
class_name = make_class_name(dev->class->name,
&dev->kobj);
if (class_name)
sysfs_create_link(&dev->parent->kobj,
&dev->kobj, class_name);
#endif
}
}

error = device_add_class_symlinks(dev);
if (error)
goto SymlinkError;
error = device_add_attrs(dev);
if (error)
goto AttrsError;
Expand All @@ -761,7 +818,6 @@ int device_add(struct device *dev)
up(&dev->class->sem);
}
Done:
kfree(class_name);
put_device(dev);
return error;
BusError:
Expand All @@ -772,6 +828,8 @@ int device_add(struct device *dev)
BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_attrs(dev);
AttrsError:
device_remove_class_symlinks(dev);
SymlinkError:
if (MAJOR(dev->devt))
device_remove_file(dev, &devt_attr);

Expand Down Expand Up @@ -1156,7 +1214,7 @@ int device_rename(struct device *dev, char *new_name)
{
char *old_class_name = NULL;
char *new_class_name = NULL;
char *old_symlink_name = NULL;
char *old_device_name = NULL;
int error;

dev = get_device(dev);
Expand All @@ -1170,42 +1228,49 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif

if (dev->class) {
old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
if (!old_symlink_name) {
error = -ENOMEM;
goto out_free_old_class;
}
strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}

strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);

error = kobject_rename(&dev->kobj, new_name);
if (error) {
strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
goto out;
}

#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
new_class_name = make_class_name(dev->class->name, &dev->kobj);
if (new_class_name) {
sysfs_create_link(&dev->parent->kobj, &dev->kobj,
new_class_name);
error = sysfs_create_link(&dev->parent->kobj,
&dev->kobj, new_class_name);
if (error)
goto out;
sysfs_remove_link(&dev->parent->kobj, old_class_name);
}
}
#endif

if (dev->class) {
sysfs_remove_link(&dev->class->subsys.kobj,
old_symlink_name);
sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
dev->bus_id);
sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
dev->bus_id);
if (error) {
/* Uh... how to unravel this if restoring can fail? */
dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
__FUNCTION__, error);
}
}
out:
put_device(dev);

kfree(new_class_name);
kfree(old_symlink_name);
out_free_old_class:
kfree(old_class_name);
kfree(old_device_name);

return error;
}
Expand Down

0 comments on commit 226b75d

Please sign in to comment.