aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2003-01-05 11:31:14 -0600
committerPatrick Mochel <mochel@osdl.org>2003-01-05 11:31:14 -0600
commit3e815107666d4ee5089661a7125af302797b3e08 (patch)
tree14feb5b3f7d430ab82aec3fd98aeffff1d0aab15 /lib
parent2e1c40373d7e424a20b44858246ad3ef2ddc4a36 (diff)
downloadhistory-3e815107666d4ee5089661a7125af302797b3e08.tar.gz
Introduce struct kset.
struct kset is what struct subsystem should have originally been called. It is a set of kobjects, and nothing more, with a much less confusing name than 'subsystem.' struct kset contains an embedded kobject, making it possible to represent it in the object hierarchy, and sysfs. This also provides a means for objects to easily express a list of subordinate objects. struct subsystem still exists, and contains an rwsem, which its subordinate ksets use to protect their lists. An arbitrary number of ksets may belong to a subsystem. A ksets specifies the subsystem it belongs to via its ->subsys field. struct subsystem also contains a default kset, which may be used without having to define a separate kset. The objects that defined subordinate subsystems (bus and class drivers) have been converted to use subordinate ksets instead. Note that the usage of ksets is flexible. - ksets may contain a list of objects of any type, not just kobjects. - The objects registered with a kset do not have to be registered. - ksets themselves do not have to be registered. One can be used by simply calling kset_init(). - ksets do not need a name if they are not registered. - Note however that locking must be done manually in these cases.
Diffstat (limited to 'lib')
-rw-r--r--lib/kobject.c120
1 files changed, 93 insertions, 27 deletions
diff --git a/lib/kobject.c b/lib/kobject.c
index f2f38b092a6a41..3d414df3683e2c 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -62,7 +62,7 @@ void kobject_init(struct kobject * kobj)
{
atomic_set(&kobj->refcount,1);
INIT_LIST_HEAD(&kobj->entry);
- kobj->subsys = subsys_get(kobj->subsys);
+ kobj->kset = kset_get(kobj->kset);
}
/**
@@ -73,7 +73,6 @@ void kobject_init(struct kobject * kobj)
int kobject_add(struct kobject * kobj)
{
int error = 0;
- struct subsystem * s = kobj->subsys;
struct kobject * parent;
if (!(kobj = kobject_get(kobj)))
@@ -81,19 +80,24 @@ int kobject_add(struct kobject * kobj)
parent = kobject_get(kobj->parent);
- pr_debug("kobject %s: registering. parent: %s, subsys: %s\n",
+ pr_debug("kobject %s: registering. parent: %s, set: %s\n",
kobj->name, parent ? parent->name : "<NULL>",
- kobj->subsys ? kobj->subsys->kobj.name : "<NULL>" );
+ kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
- if (s) {
- down_write(&s->rwsem);
+ if (kobj->subsys) {
+ if (!kobj->kset)
+ kobj->kset = &kobj->subsys->kset;
+ }
+
+ if (kobj->kset) {
+ down_write(&kobj->kset->subsys->rwsem);
if (parent)
list_add_tail(&kobj->entry,&parent->entry);
else {
- list_add_tail(&kobj->entry,&s->list);
- kobj->parent = kobject_get(&s->kobj);
+ list_add_tail(&kobj->entry,&kobj->kset->list);
+ kobj->parent = kobject_get(&kobj->kset->kobj);
}
- up_write(&s->rwsem);
+ up_write(&kobj->kset->subsys->rwsem);
}
error = create_dir(kobj);
if (error && parent)
@@ -127,10 +131,10 @@ int kobject_register(struct kobject * kobj)
void kobject_del(struct kobject * kobj)
{
sysfs_remove_dir(kobj);
- if (kobj->subsys) {
- down_write(&kobj->subsys->rwsem);
+ if (kobj->kset) {
+ down_write(&kobj->kset->subsys->rwsem);
list_del_init(&kobj->entry);
- up_write(&kobj->subsys->rwsem);
+ up_write(&kobj->kset->subsys->rwsem);
}
if (kobj->parent)
kobject_put(kobj->parent);
@@ -174,17 +178,13 @@ struct kobject * kobject_get(struct kobject * kobj)
void kobject_cleanup(struct kobject * kobj)
{
struct kobj_type * t = kobj->ktype;
- struct subsystem * s = kobj->subsys;
+ struct kset * s = kobj->kset;
pr_debug("kobject %s: cleaning up\n",kobj->name);
- if (s) {
- down_write(&s->rwsem);
- list_del_init(&kobj->entry);
- up_write(&s->rwsem);
- subsys_put(s);
- }
if (t && t->release)
t->release(kobj);
+ if (s)
+ kset_put(s);
}
/**
@@ -203,32 +203,98 @@ void kobject_put(struct kobject * kobj)
}
+/**
+ * kset_init - initialize a kset for use
+ * @k: kset
+ */
+
+void kset_init(struct kset * k)
+{
+ kobject_init(&k->kobj);
+ INIT_LIST_HEAD(&k->list);
+}
+
+
+/**
+ * kset_add - add a kset object to the hierarchy.
+ * @k: kset.
+ *
+ * Simply, this adds the kset's embedded kobject to the
+ * hierarchy.
+ * We also try to make sure that the kset's embedded kobject
+ * has a parent before it is added. We only care if the embedded
+ * kobject is not part of a kset itself, since kobject_add()
+ * assigns a parent in that case.
+ * If that is the case, and the kset has a controlling subsystem,
+ * then we set the kset's parent to be said subsystem.
+ */
+
+int kset_add(struct kset * k)
+{
+ if (!k->kobj.parent && !k->kobj.kset && k->subsys)
+ k->kobj.parent = &k->subsys->kset.kobj;
+
+ return kobject_add(&k->kobj);
+}
+
+
+/**
+ * kset_register - initialize and add a kset.
+ * @k: kset.
+ */
+
+int kset_register(struct kset * k)
+{
+ kset_init(k);
+ return kset_add(k);
+}
+
+
+/**
+ * kset_unregister - remove a kset.
+ * @k: kset.
+ */
+
+void kset_unregister(struct kset * k)
+{
+ kobject_unregister(&k->kobj);
+}
+
+
void subsystem_init(struct subsystem * s)
{
- kobject_init(&s->kobj);
+ memcpy(&s->kset.kobj,&s->kobj,sizeof(struct kobject));
init_rwsem(&s->rwsem);
- INIT_LIST_HEAD(&s->list);
+ kset_init(&s->kset);
}
/**
* subsystem_register - register a subsystem.
* @s: the subsystem we're registering.
+ *
+ * Once we register the subsystem, we want to make sure that
+ * the kset points back to this subsystem for correct usage of
+ * the rwsem.
*/
int subsystem_register(struct subsystem * s)
{
+ int error;
+
subsystem_init(s);
- if (s->parent)
- s->kobj.parent = &s->parent->kobj;
- pr_debug("subsystem %s: registering, parent: %s\n",
- s->kobj.name,s->parent ? s->parent->kobj.name : "<none>");
- return kobject_add(&s->kobj);
+ pr_debug("subsystem %s: registering\n",s->kobj.name);
+
+ if (!(error = kset_add(&s->kset))) {
+ if (!s->kset.subsys)
+ s->kset.subsys = s;
+ }
+ return error;
}
void subsystem_unregister(struct subsystem * s)
{
pr_debug("subsystem %s: unregistering\n",s->kobj.name);
- kobject_unregister(&s->kobj);
+ kset_unregister(&s->kset);
}