diff options
author | Patrick Mochel <mochel@osdl.org> | 2003-01-06 01:56:02 -0600 |
---|---|---|
committer | Patrick Mochel <mochel@osdl.org> | 2003-01-06 01:56:02 -0600 |
commit | 6fec616121f529857e6c68c584b7938dd568fbba (patch) | |
tree | 4f4bc88fa130b3440535b5fcbee51f5ebe4aba0d /lib | |
parent | 5c29ea4442e5139fb1fe5d3ead774e9206ef0324 (diff) | |
parent | 6ed6b9bf5b5d80581ebfcc3fa2738ee386b78cd1 (diff) | |
download | history-6fec616121f529857e6c68c584b7938dd568fbba.tar.gz |
Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kobject.c | 137 |
1 files changed, 103 insertions, 34 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index 24807bc72f81b8..59872973992a17 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -11,6 +11,14 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED; +static inline struct kobj_type * get_ktype(struct kobject * k) +{ + if (k->kset && k->kset->ktype) + return k->kset->ktype; + else + return k->ktype; +} + /** * populate_dir - populate directory with attributes. * @kobj: object we're working on. @@ -25,13 +33,13 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED; static int populate_dir(struct kobject * kobj) { - struct subsystem * s = kobj->subsys; + struct kobj_type * t = get_ktype(kobj); struct attribute * attr; int error = 0; int i; - if (s && s->default_attrs) { - for (i = 0; (attr = s->default_attrs[i]); i++) { + if (t && t->default_attrs) { + for (i = 0; (attr = t->default_attrs[i]); i++) { if ((error = sysfs_create_file(kobj,attr))) break; } @@ -62,7 +70,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 +81,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 +88,19 @@ 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->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 +134,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); @@ -173,17 +180,14 @@ struct kobject * kobject_get(struct kobject * kobj) void kobject_cleanup(struct kobject * kobj) { - struct subsystem * s = kobj->subsys; + struct kobj_type * t = get_ktype(kobj); + 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); - if (s->release) - s->release(kobj); - up_write(&s->rwsem); - subsys_put(s); - } + if (t && t->release) + t->release(kobj); + if (s) + kset_put(s); } /** @@ -202,32 +206,97 @@ 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); 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); } @@ -241,7 +310,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) { int error = 0; if (subsys_get(s)) { - error = sysfs_create_file(&s->kobj,&a->attr); + error = sysfs_create_file(&s->kset.kobj,&a->attr); subsys_put(s); } return error; @@ -257,7 +326,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) { if (subsys_get(s)) { - sysfs_remove_file(&s->kobj,&a->attr); + sysfs_remove_file(&s->kset.kobj,&a->attr); subsys_put(s); } } |