Driver core: add device_rename function
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 3 Jul 2006 21:31:12 +0000 (14:31 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 26 Sep 2006 04:08:38 +0000 (21:08 -0700)
The network layer needs this to convert to using struct device instead
of a struct class_device.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/base/core.c
include/linux/device.h

index f1228f25efe092e3746fb7dfdda21cc62338071d..0db47561331e0420254f77bc1290e9130cebae1f 100644 (file)
@@ -736,3 +736,58 @@ void device_destroy(struct class *class, dev_t devt)
                device_unregister(dev);
 }
 EXPORT_SYMBOL_GPL(device_destroy);
+
+/**
+ * device_rename - renames a device
+ * @dev: the pointer to the struct device to be renamed
+ * @new_name: the new name of the device
+ */
+int device_rename(struct device *dev, char *new_name)
+{
+       char *old_class_name = NULL;
+       char *new_class_name = NULL;
+       char *old_symlink_name = NULL;
+       int error;
+
+       dev = get_device(dev);
+       if (!dev)
+               return -EINVAL;
+
+       pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name);
+
+       if ((dev->class) && (dev->parent))
+               old_class_name = make_class_name(dev->class->name, &dev->kobj);
+
+       if (dev->class) {
+               old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+               if (!old_symlink_name)
+                       return -ENOMEM;
+               strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
+       }
+
+       strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
+
+       error = kobject_rename(&dev->kobj, new_name);
+
+       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);
+                       sysfs_remove_link(&dev->parent->kobj, old_class_name);
+               }
+       }
+       if (dev->class) {
+               sysfs_remove_link(&dev->class->subsys.kset.kobj,
+                                 old_symlink_name);
+               sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
+                                 dev->bus_id);
+       }
+       put_device(dev);
+
+       kfree(old_class_name);
+       kfree(new_class_name);
+       kfree(old_symlink_name);
+
+       return error;
+}
index 3122bd25ce42b19361ee7ec3a10bda2fbbbe4cdb..3400e09bf4588ede20bc9e4b4a281c8643386e68 100644 (file)
@@ -380,6 +380,7 @@ extern int device_add(struct device * dev);
 extern void device_del(struct device * dev);
 extern int device_for_each_child(struct device *, void *,
                     int (*fn)(struct device *, void *));
+extern int device_rename(struct device *dev, char *new_name);
 
 /*
  * Manual binding of a device to driver. See drivers/base/bus.c