Like the SUBSYTEM= key we find in the environment of the uevent, this
creates a generic "subsystem" link in sysfs for every device. Userspace
usually doesn't care at all if its a "class" or a "bus" device. This
provides an unified way to determine the subsytem of a device, regardless
of the way the driver core has created it.
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#include <linux/buffer_head.h>
#include <linux/mutex.h>
#include <linux/buffer_head.h>
#include <linux/mutex.h>
-static struct subsystem block_subsys;
-
+struct subsystem block_subsys;
static DEFINE_MUTEX(block_subsys_lock);
/*
static DEFINE_MUTEX(block_subsys_lock);
/*
.uevent = block_uevent,
};
.uevent = block_uevent,
};
-/* declare block_subsys. */
-static decl_subsys(block, &ktype_block, &block_uevent_ops);
-
+decl_subsys(block, &ktype_block, &block_uevent_ops);
/*
* aggregate disk stat collector. Uses the same stats that the sysfs
/*
* aggregate disk stat collector. Uses the same stats that the sysfs
error = device_add_attrs(bus, dev);
if (!error) {
sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
error = device_add_attrs(bus, dev);
if (!error) {
sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
+ sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem");
sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
}
}
sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
}
}
void bus_remove_device(struct device * dev)
{
if (dev->bus) {
void bus_remove_device(struct device * dev)
{
if (dev->bus) {
+ sysfs_remove_link(&dev->kobj, "subsystem");
sysfs_remove_link(&dev->kobj, "bus");
sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
device_remove_attrs(dev->bus, dev);
sysfs_remove_link(&dev->kobj, "bus");
sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
device_remove_attrs(dev->bus, dev);
goto out2;
/* add the needed attributes to this device */
goto out2;
/* add the needed attributes to this device */
+ sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem");
class_dev->uevent_attr.attr.name = "uevent";
class_dev->uevent_attr.attr.mode = S_IWUSR;
class_dev->uevent_attr.attr.owner = parent_class->owner;
class_dev->uevent_attr.attr.name = "uevent";
class_dev->uevent_attr.attr.mode = S_IWUSR;
class_dev->uevent_attr.attr.owner = parent_class->owner;
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
}
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
}
+ sysfs_remove_link(&class_dev->kobj, "subsystem");
class_device_remove_file(class_dev, &class_dev->uevent_attr);
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_file(class_dev, &class_dev->uevent_attr);
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
+ 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);
sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
dev->bus_id);
if ((error = device_pm_add(dev)))
goto PMError;
if ((error = device_pm_add(dev)))
goto PMError;
klist_del(&dev->knode_parent);
if (dev->devt_attr)
device_remove_file(dev, dev->devt_attr);
klist_del(&dev->knode_parent);
if (dev->devt_attr)
device_remove_file(dev, dev->devt_attr);
+ if (dev->class) {
+ sysfs_remove_link(&dev->kobj, "subsystem");
sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
device_remove_file(dev, &dev->uevent_attr);
/* Notify the platform of the removal, in case they
device_remove_file(dev, &dev->uevent_attr);
/* Notify the platform of the removal, in case they
p->ios[0] = p->ios[1] = 0;
p->sectors[0] = p->sectors[1] = 0;
devfs_remove("%s/part%d", disk->devfs_name, part);
p->ios[0] = p->ios[1] = 0;
p->sectors[0] = p->sectors[1] = 0;
devfs_remove("%s/part%d", disk->devfs_name, part);
+ sysfs_remove_link(&p->kobj, "subsystem");
if (p->holder_dir)
kobject_unregister(p->holder_dir);
kobject_uevent(&p->kobj, KOBJ_REMOVE);
if (p->holder_dir)
kobject_unregister(p->holder_dir);
kobject_uevent(&p->kobj, KOBJ_REMOVE);
kobject_add(&p->kobj);
if (!disk->part_uevent_suppress)
kobject_uevent(&p->kobj, KOBJ_ADD);
kobject_add(&p->kobj);
if (!disk->part_uevent_suppress)
kobject_uevent(&p->kobj, KOBJ_ADD);
+ sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
partition_sysfs_add_subdir(p);
disk->part[part-1] = p;
}
partition_sysfs_add_subdir(p);
disk->part[part-1] = p;
}
+ sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem");
}
/* Not exported, helper to add_disk(). */
}
/* Not exported, helper to add_disk(). */
put_device(disk->driverfs_dev);
disk->driverfs_dev = NULL;
}
put_device(disk->driverfs_dev);
disk->driverfs_dev = NULL;
}
+ sysfs_remove_link(&disk->kobj, "subsystem");
kobject_del(&disk->kobj);
}
kobject_del(&disk->kobj);
}