xref: /freebsd/sys/compat/linuxkpi/common/src/linux_kobject.c (revision fe84281803d62a6846ecab5f5a7c8b4e49b0f0e0)
180446fc7SJean-Sébastien Pédron /*-
280446fc7SJean-Sébastien Pédron  * Copyright (c) 2010 Isilon Systems, Inc.
380446fc7SJean-Sébastien Pédron  * Copyright (c) 2010 iX Systems, Inc.
480446fc7SJean-Sébastien Pédron  * Copyright (c) 2010 Panasas, Inc.
580446fc7SJean-Sébastien Pédron  * Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
680446fc7SJean-Sébastien Pédron  * All rights reserved.
780446fc7SJean-Sébastien Pédron  *
880446fc7SJean-Sébastien Pédron  * Redistribution and use in source and binary forms, with or without
980446fc7SJean-Sébastien Pédron  * modification, are permitted provided that the following conditions
1080446fc7SJean-Sébastien Pédron  * are met:
1180446fc7SJean-Sébastien Pédron  * 1. Redistributions of source code must retain the above copyright
1280446fc7SJean-Sébastien Pédron  *    notice unmodified, this list of conditions, and the following
1380446fc7SJean-Sébastien Pédron  *    disclaimer.
1480446fc7SJean-Sébastien Pédron  * 2. Redistributions in binary form must reproduce the above copyright
1580446fc7SJean-Sébastien Pédron  *    notice, this list of conditions and the following disclaimer in the
1680446fc7SJean-Sébastien Pédron  *    documentation and/or other materials provided with the distribution.
1780446fc7SJean-Sébastien Pédron  *
1880446fc7SJean-Sébastien Pédron  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1980446fc7SJean-Sébastien Pédron  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2080446fc7SJean-Sébastien Pédron  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2180446fc7SJean-Sébastien Pédron  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2280446fc7SJean-Sébastien Pédron  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2380446fc7SJean-Sébastien Pédron  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2480446fc7SJean-Sébastien Pédron  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2580446fc7SJean-Sébastien Pédron  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2680446fc7SJean-Sébastien Pédron  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2780446fc7SJean-Sébastien Pédron  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2880446fc7SJean-Sébastien Pédron  */
2980446fc7SJean-Sébastien Pédron 
3080446fc7SJean-Sébastien Pédron #include <linux/kobject.h>
3180446fc7SJean-Sébastien Pédron #include <linux/sysfs.h>
3280446fc7SJean-Sébastien Pédron 
33*fe842818SJean-Sébastien Pédron static void kset_join(struct kobject *kobj);
34*fe842818SJean-Sébastien Pédron static void kset_leave(struct kobject *kobj);
35*fe842818SJean-Sébastien Pédron static void kset_kfree(struct kobject *kobj);
36*fe842818SJean-Sébastien Pédron 
3780446fc7SJean-Sébastien Pédron struct kobject *
kobject_create(void)3880446fc7SJean-Sébastien Pédron kobject_create(void)
3980446fc7SJean-Sébastien Pédron {
4080446fc7SJean-Sébastien Pédron 	struct kobject *kobj;
4180446fc7SJean-Sébastien Pédron 
4280446fc7SJean-Sébastien Pédron 	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
4380446fc7SJean-Sébastien Pédron 	if (kobj == NULL)
4480446fc7SJean-Sébastien Pédron 		return (NULL);
4580446fc7SJean-Sébastien Pédron 	kobject_init(kobj, &linux_kfree_type);
4680446fc7SJean-Sébastien Pédron 
4780446fc7SJean-Sébastien Pédron 	return (kobj);
4880446fc7SJean-Sébastien Pédron }
4980446fc7SJean-Sébastien Pédron 
5080446fc7SJean-Sébastien Pédron 
5180446fc7SJean-Sébastien Pédron int
kobject_set_name_vargs(struct kobject * kobj,const char * fmt,va_list args)5280446fc7SJean-Sébastien Pédron kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args)
5380446fc7SJean-Sébastien Pédron {
5480446fc7SJean-Sébastien Pédron 	va_list tmp_va;
5580446fc7SJean-Sébastien Pédron 	int len;
5680446fc7SJean-Sébastien Pédron 	char *old;
5780446fc7SJean-Sébastien Pédron 	char *name;
5880446fc7SJean-Sébastien Pédron 	char dummy;
5980446fc7SJean-Sébastien Pédron 
6080446fc7SJean-Sébastien Pédron 	old = kobj->name;
6180446fc7SJean-Sébastien Pédron 
6280446fc7SJean-Sébastien Pédron 	if (old && fmt == NULL)
6380446fc7SJean-Sébastien Pédron 		return (0);
6480446fc7SJean-Sébastien Pédron 
6580446fc7SJean-Sébastien Pédron 	/* compute length of string */
6680446fc7SJean-Sébastien Pédron 	va_copy(tmp_va, args);
6780446fc7SJean-Sébastien Pédron 	len = vsnprintf(&dummy, 0, fmt, tmp_va);
6880446fc7SJean-Sébastien Pédron 	va_end(tmp_va);
6980446fc7SJean-Sébastien Pédron 
7080446fc7SJean-Sébastien Pédron 	/* account for zero termination */
7180446fc7SJean-Sébastien Pédron 	len++;
7280446fc7SJean-Sébastien Pédron 
7380446fc7SJean-Sébastien Pédron 	/* check for error */
7480446fc7SJean-Sébastien Pédron 	if (len < 1)
7580446fc7SJean-Sébastien Pédron 		return (-EINVAL);
7680446fc7SJean-Sébastien Pédron 
7780446fc7SJean-Sébastien Pédron 	/* allocate memory for string */
7880446fc7SJean-Sébastien Pédron 	name = kzalloc(len, GFP_KERNEL);
7980446fc7SJean-Sébastien Pédron 	if (name == NULL)
8080446fc7SJean-Sébastien Pédron 		return (-ENOMEM);
8180446fc7SJean-Sébastien Pédron 	vsnprintf(name, len, fmt, args);
8280446fc7SJean-Sébastien Pédron 	kobj->name = name;
8380446fc7SJean-Sébastien Pédron 
8480446fc7SJean-Sébastien Pédron 	/* free old string */
8580446fc7SJean-Sébastien Pédron 	kfree(old);
8680446fc7SJean-Sébastien Pédron 
8780446fc7SJean-Sébastien Pédron 	/* filter new string */
8880446fc7SJean-Sébastien Pédron 	for (; *name != '\0'; name++)
8980446fc7SJean-Sébastien Pédron 		if (*name == '/')
9080446fc7SJean-Sébastien Pédron 			*name = '!';
9180446fc7SJean-Sébastien Pédron 	return (0);
9280446fc7SJean-Sébastien Pédron }
9380446fc7SJean-Sébastien Pédron 
9480446fc7SJean-Sébastien Pédron int
kobject_set_name(struct kobject * kobj,const char * fmt,...)9580446fc7SJean-Sébastien Pédron kobject_set_name(struct kobject *kobj, const char *fmt, ...)
9680446fc7SJean-Sébastien Pédron {
9780446fc7SJean-Sébastien Pédron 	va_list args;
9880446fc7SJean-Sébastien Pédron 	int error;
9980446fc7SJean-Sébastien Pédron 
10080446fc7SJean-Sébastien Pédron 	va_start(args, fmt);
10180446fc7SJean-Sébastien Pédron 	error = kobject_set_name_vargs(kobj, fmt, args);
10280446fc7SJean-Sébastien Pédron 	va_end(args);
10380446fc7SJean-Sébastien Pédron 
10480446fc7SJean-Sébastien Pédron 	return (error);
10580446fc7SJean-Sébastien Pédron }
10680446fc7SJean-Sébastien Pédron 
10780446fc7SJean-Sébastien Pédron static int
kobject_add_complete(struct kobject * kobj)108*fe842818SJean-Sébastien Pédron kobject_add_complete(struct kobject *kobj)
10980446fc7SJean-Sébastien Pédron {
11080446fc7SJean-Sébastien Pédron 	const struct kobj_type *t;
11180446fc7SJean-Sébastien Pédron 	int error;
11280446fc7SJean-Sébastien Pédron 
113*fe842818SJean-Sébastien Pédron 	if (kobj->kset != NULL) {
114*fe842818SJean-Sébastien Pédron 		kset_join(kobj);
115*fe842818SJean-Sébastien Pédron 		kobj->parent = &kobj->kset->kobj;
116*fe842818SJean-Sébastien Pédron 	}
117*fe842818SJean-Sébastien Pédron 
11880446fc7SJean-Sébastien Pédron 	error = sysfs_create_dir(kobj);
11980446fc7SJean-Sébastien Pédron 	if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
12080446fc7SJean-Sébastien Pédron 		struct attribute **attr;
12180446fc7SJean-Sébastien Pédron 		t = kobj->ktype;
12280446fc7SJean-Sébastien Pédron 
12380446fc7SJean-Sébastien Pédron 		for (attr = t->default_attrs; *attr != NULL; attr++) {
12480446fc7SJean-Sébastien Pédron 			error = sysfs_create_file(kobj, *attr);
12580446fc7SJean-Sébastien Pédron 			if (error)
12680446fc7SJean-Sébastien Pédron 				break;
12780446fc7SJean-Sébastien Pédron 		}
12880446fc7SJean-Sébastien Pédron 		if (error)
12980446fc7SJean-Sébastien Pédron 			sysfs_remove_dir(kobj);
13080446fc7SJean-Sébastien Pédron 	}
131*fe842818SJean-Sébastien Pédron 
132*fe842818SJean-Sébastien Pédron 	if (error != 0)
133*fe842818SJean-Sébastien Pédron 		kset_leave(kobj);
134*fe842818SJean-Sébastien Pédron 
13580446fc7SJean-Sébastien Pédron 	return (error);
13680446fc7SJean-Sébastien Pédron }
13780446fc7SJean-Sébastien Pédron 
13880446fc7SJean-Sébastien Pédron int
kobject_add(struct kobject * kobj,struct kobject * parent,const char * fmt,...)13980446fc7SJean-Sébastien Pédron kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
14080446fc7SJean-Sébastien Pédron {
14180446fc7SJean-Sébastien Pédron 	va_list args;
14280446fc7SJean-Sébastien Pédron 	int error;
14380446fc7SJean-Sébastien Pédron 
144*fe842818SJean-Sébastien Pédron 	kobj->parent = parent;
145*fe842818SJean-Sébastien Pédron 
14680446fc7SJean-Sébastien Pédron 	va_start(args, fmt);
14780446fc7SJean-Sébastien Pédron 	error = kobject_set_name_vargs(kobj, fmt, args);
14880446fc7SJean-Sébastien Pédron 	va_end(args);
14980446fc7SJean-Sébastien Pédron 	if (error)
15080446fc7SJean-Sébastien Pédron 		return (error);
15180446fc7SJean-Sébastien Pédron 
152*fe842818SJean-Sébastien Pédron 	return kobject_add_complete(kobj);
15380446fc7SJean-Sébastien Pédron }
15480446fc7SJean-Sébastien Pédron 
15580446fc7SJean-Sébastien Pédron int
kobject_init_and_add(struct kobject * kobj,const struct kobj_type * ktype,struct kobject * parent,const char * fmt,...)15680446fc7SJean-Sébastien Pédron kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
15780446fc7SJean-Sébastien Pédron     struct kobject *parent, const char *fmt, ...)
15880446fc7SJean-Sébastien Pédron {
15980446fc7SJean-Sébastien Pédron 	va_list args;
16080446fc7SJean-Sébastien Pédron 	int error;
16180446fc7SJean-Sébastien Pédron 
16280446fc7SJean-Sébastien Pédron 	kobject_init(kobj, ktype);
16380446fc7SJean-Sébastien Pédron 	kobj->ktype = ktype;
16480446fc7SJean-Sébastien Pédron 	kobj->parent = parent;
16580446fc7SJean-Sébastien Pédron 	kobj->name = NULL;
16680446fc7SJean-Sébastien Pédron 
16780446fc7SJean-Sébastien Pédron 	va_start(args, fmt);
16880446fc7SJean-Sébastien Pédron 	error = kobject_set_name_vargs(kobj, fmt, args);
16980446fc7SJean-Sébastien Pédron 	va_end(args);
17080446fc7SJean-Sébastien Pédron 	if (error)
17180446fc7SJean-Sébastien Pédron 		return (error);
172*fe842818SJean-Sébastien Pédron 	return kobject_add_complete(kobj);
17380446fc7SJean-Sébastien Pédron }
17480446fc7SJean-Sébastien Pédron 
17580446fc7SJean-Sébastien Pédron void
linux_kobject_release(struct kref * kref)17680446fc7SJean-Sébastien Pédron linux_kobject_release(struct kref *kref)
17780446fc7SJean-Sébastien Pédron {
17880446fc7SJean-Sébastien Pédron 	struct kobject *kobj;
17980446fc7SJean-Sébastien Pédron 	char *name;
18080446fc7SJean-Sébastien Pédron 
18180446fc7SJean-Sébastien Pédron 	kobj = container_of(kref, struct kobject, kref);
18280446fc7SJean-Sébastien Pédron 	sysfs_remove_dir(kobj);
183*fe842818SJean-Sébastien Pédron 	kset_leave(kobj);
18480446fc7SJean-Sébastien Pédron 	name = kobj->name;
18580446fc7SJean-Sébastien Pédron 	if (kobj->ktype && kobj->ktype->release)
18680446fc7SJean-Sébastien Pédron 		kobj->ktype->release(kobj);
18780446fc7SJean-Sébastien Pédron 	kfree(name);
18880446fc7SJean-Sébastien Pédron }
18980446fc7SJean-Sébastien Pédron 
19080446fc7SJean-Sébastien Pédron static void
linux_kobject_kfree(struct kobject * kobj)19180446fc7SJean-Sébastien Pédron linux_kobject_kfree(struct kobject *kobj)
19280446fc7SJean-Sébastien Pédron {
19380446fc7SJean-Sébastien Pédron 	kfree(kobj);
19480446fc7SJean-Sébastien Pédron }
19580446fc7SJean-Sébastien Pédron 
19680446fc7SJean-Sébastien Pédron const struct kobj_type linux_kfree_type = {
19780446fc7SJean-Sébastien Pédron 	.release = linux_kobject_kfree
19880446fc7SJean-Sébastien Pédron };
19980446fc7SJean-Sébastien Pédron 
20080446fc7SJean-Sébastien Pédron void
linux_kobject_kfree_name(struct kobject * kobj)20180446fc7SJean-Sébastien Pédron linux_kobject_kfree_name(struct kobject *kobj)
20280446fc7SJean-Sébastien Pédron {
20380446fc7SJean-Sébastien Pédron 	if (kobj) {
20480446fc7SJean-Sébastien Pédron 		kfree(kobj->name);
20580446fc7SJean-Sébastien Pédron 	}
20680446fc7SJean-Sébastien Pédron }
20780446fc7SJean-Sébastien Pédron 
20880446fc7SJean-Sébastien Pédron static ssize_t
lkpi_kobj_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)20980446fc7SJean-Sébastien Pédron lkpi_kobj_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
21080446fc7SJean-Sébastien Pédron {
21180446fc7SJean-Sébastien Pédron 	struct kobj_attribute *ka =
21280446fc7SJean-Sébastien Pédron 	    container_of(attr, struct kobj_attribute, attr);
21380446fc7SJean-Sébastien Pédron 
21480446fc7SJean-Sébastien Pédron 	if (ka->show == NULL)
21580446fc7SJean-Sébastien Pédron 		return (-EIO);
21680446fc7SJean-Sébastien Pédron 
21780446fc7SJean-Sébastien Pédron 	return (ka->show(kobj, ka, buf));
21880446fc7SJean-Sébastien Pédron }
21980446fc7SJean-Sébastien Pédron 
22080446fc7SJean-Sébastien Pédron static ssize_t
lkpi_kobj_attr_store(struct kobject * kobj,struct attribute * attr,const char * buf,size_t count)22180446fc7SJean-Sébastien Pédron lkpi_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
22280446fc7SJean-Sébastien Pédron     const char *buf, size_t count)
22380446fc7SJean-Sébastien Pédron {
22480446fc7SJean-Sébastien Pédron 	struct kobj_attribute *ka =
22580446fc7SJean-Sébastien Pédron 	    container_of(attr, struct kobj_attribute, attr);
22680446fc7SJean-Sébastien Pédron 
22780446fc7SJean-Sébastien Pédron 	if (ka->store == NULL)
22880446fc7SJean-Sébastien Pédron 		return (-EIO);
22980446fc7SJean-Sébastien Pédron 
23080446fc7SJean-Sébastien Pédron 	return (ka->store(kobj, ka, buf, count));
23180446fc7SJean-Sébastien Pédron }
23280446fc7SJean-Sébastien Pédron 
23380446fc7SJean-Sébastien Pédron const struct sysfs_ops kobj_sysfs_ops = {
23480446fc7SJean-Sébastien Pédron 	.show	= lkpi_kobj_attr_show,
23580446fc7SJean-Sébastien Pédron 	.store	= lkpi_kobj_attr_store,
23680446fc7SJean-Sébastien Pédron };
237*fe842818SJean-Sébastien Pédron 
238*fe842818SJean-Sébastien Pédron const struct kobj_type linux_kset_kfree_type = {
239*fe842818SJean-Sébastien Pédron 	.release = kset_kfree
240*fe842818SJean-Sébastien Pédron };
241*fe842818SJean-Sébastien Pédron 
242*fe842818SJean-Sébastien Pédron static struct kset *
kset_create(const char * name,const struct kset_uevent_ops * uevent_ops,struct kobject * parent_kobj)243*fe842818SJean-Sébastien Pédron kset_create(const char *name,
244*fe842818SJean-Sébastien Pédron     const struct kset_uevent_ops *uevent_ops,
245*fe842818SJean-Sébastien Pédron     struct kobject *parent_kobj)
246*fe842818SJean-Sébastien Pédron {
247*fe842818SJean-Sébastien Pédron 	struct kset *kset;
248*fe842818SJean-Sébastien Pédron 
249*fe842818SJean-Sébastien Pédron 	kset = kzalloc(sizeof(*kset), GFP_KERNEL);
250*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
251*fe842818SJean-Sébastien Pédron 		return (NULL);
252*fe842818SJean-Sébastien Pédron 
253*fe842818SJean-Sébastien Pédron 	kset->uevent_ops = uevent_ops;
254*fe842818SJean-Sébastien Pédron 
255*fe842818SJean-Sébastien Pédron 	kobject_set_name(&kset->kobj, "%s", name);
256*fe842818SJean-Sébastien Pédron 	kset->kobj.parent = parent_kobj;
257*fe842818SJean-Sébastien Pédron 	kset->kobj.kset = NULL;
258*fe842818SJean-Sébastien Pédron 
259*fe842818SJean-Sébastien Pédron 	return (kset);
260*fe842818SJean-Sébastien Pédron }
261*fe842818SJean-Sébastien Pédron 
262*fe842818SJean-Sébastien Pédron void
kset_init(struct kset * kset)263*fe842818SJean-Sébastien Pédron kset_init(struct kset *kset)
264*fe842818SJean-Sébastien Pédron {
265*fe842818SJean-Sébastien Pédron 	kobject_init(&kset->kobj, &linux_kset_kfree_type);
266*fe842818SJean-Sébastien Pédron 	INIT_LIST_HEAD(&kset->list);
267*fe842818SJean-Sébastien Pédron 	spin_lock_init(&kset->list_lock);
268*fe842818SJean-Sébastien Pédron }
269*fe842818SJean-Sébastien Pédron 
270*fe842818SJean-Sébastien Pédron static void
kset_join(struct kobject * kobj)271*fe842818SJean-Sébastien Pédron kset_join(struct kobject *kobj)
272*fe842818SJean-Sébastien Pédron {
273*fe842818SJean-Sébastien Pédron 	struct kset *kset;
274*fe842818SJean-Sébastien Pédron 
275*fe842818SJean-Sébastien Pédron 	kset = kobj->kset;
276*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
277*fe842818SJean-Sébastien Pédron 		return;
278*fe842818SJean-Sébastien Pédron 
279*fe842818SJean-Sébastien Pédron 	kset_get(kobj->kset);
280*fe842818SJean-Sébastien Pédron 
281*fe842818SJean-Sébastien Pédron 	spin_lock(&kset->list_lock);
282*fe842818SJean-Sébastien Pédron 	list_add_tail(&kobj->entry, &kset->list);
283*fe842818SJean-Sébastien Pédron 	spin_unlock(&kset->list_lock);
284*fe842818SJean-Sébastien Pédron }
285*fe842818SJean-Sébastien Pédron 
286*fe842818SJean-Sébastien Pédron static void
kset_leave(struct kobject * kobj)287*fe842818SJean-Sébastien Pédron kset_leave(struct kobject *kobj)
288*fe842818SJean-Sébastien Pédron {
289*fe842818SJean-Sébastien Pédron 	struct kset *kset;
290*fe842818SJean-Sébastien Pédron 
291*fe842818SJean-Sébastien Pédron 	kset = kobj->kset;
292*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
293*fe842818SJean-Sébastien Pédron 		return;
294*fe842818SJean-Sébastien Pédron 
295*fe842818SJean-Sébastien Pédron 	spin_lock(&kset->list_lock);
296*fe842818SJean-Sébastien Pédron 	list_del_init(&kobj->entry);
297*fe842818SJean-Sébastien Pédron 	spin_unlock(&kset->list_lock);
298*fe842818SJean-Sébastien Pédron 
299*fe842818SJean-Sébastien Pédron 	kset_put(kobj->kset);
300*fe842818SJean-Sébastien Pédron }
301*fe842818SJean-Sébastien Pédron 
302*fe842818SJean-Sébastien Pédron struct kset *
kset_create_and_add(const char * name,const struct kset_uevent_ops * u,struct kobject * parent_kobj)303*fe842818SJean-Sébastien Pédron kset_create_and_add(const char *name, const struct kset_uevent_ops *u,
304*fe842818SJean-Sébastien Pédron     struct kobject *parent_kobj)
305*fe842818SJean-Sébastien Pédron {
306*fe842818SJean-Sébastien Pédron 	int ret;
307*fe842818SJean-Sébastien Pédron 	struct kset *kset;
308*fe842818SJean-Sébastien Pédron 
309*fe842818SJean-Sébastien Pédron 	kset = kset_create(name, u, parent_kobj);
310*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
311*fe842818SJean-Sébastien Pédron 		return (NULL);
312*fe842818SJean-Sébastien Pédron 
313*fe842818SJean-Sébastien Pédron 	ret = kset_register(kset);
314*fe842818SJean-Sébastien Pédron 	if (ret != 0) {
315*fe842818SJean-Sébastien Pédron 		linux_kobject_kfree_name(&kset->kobj);
316*fe842818SJean-Sébastien Pédron 		kfree(kset);
317*fe842818SJean-Sébastien Pédron 		return (NULL);
318*fe842818SJean-Sébastien Pédron 	}
319*fe842818SJean-Sébastien Pédron 
320*fe842818SJean-Sébastien Pédron 	return (kset);
321*fe842818SJean-Sébastien Pédron }
322*fe842818SJean-Sébastien Pédron 
323*fe842818SJean-Sébastien Pédron int
kset_register(struct kset * kset)324*fe842818SJean-Sébastien Pédron kset_register(struct kset *kset)
325*fe842818SJean-Sébastien Pédron {
326*fe842818SJean-Sébastien Pédron 	int ret;
327*fe842818SJean-Sébastien Pédron 
328*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
329*fe842818SJean-Sébastien Pédron 		return -EINVAL;
330*fe842818SJean-Sébastien Pédron 
331*fe842818SJean-Sébastien Pédron 	kset_init(kset);
332*fe842818SJean-Sébastien Pédron 	ret = kobject_add_complete(&kset->kobj);
333*fe842818SJean-Sébastien Pédron 
334*fe842818SJean-Sébastien Pédron 	return ret;
335*fe842818SJean-Sébastien Pédron }
336*fe842818SJean-Sébastien Pédron 
337*fe842818SJean-Sébastien Pédron void
kset_unregister(struct kset * kset)338*fe842818SJean-Sébastien Pédron kset_unregister(struct kset *kset)
339*fe842818SJean-Sébastien Pédron {
340*fe842818SJean-Sébastien Pédron 	if (kset == NULL)
341*fe842818SJean-Sébastien Pédron 		return;
342*fe842818SJean-Sébastien Pédron 
343*fe842818SJean-Sébastien Pédron 	kobject_del(&kset->kobj);
344*fe842818SJean-Sébastien Pédron 	kobject_put(&kset->kobj);
345*fe842818SJean-Sébastien Pédron }
346*fe842818SJean-Sébastien Pédron 
347*fe842818SJean-Sébastien Pédron static void
kset_kfree(struct kobject * kobj)348*fe842818SJean-Sébastien Pédron kset_kfree(struct kobject *kobj)
349*fe842818SJean-Sébastien Pédron {
350*fe842818SJean-Sébastien Pédron 	struct kset *kset;
351*fe842818SJean-Sébastien Pédron 
352*fe842818SJean-Sébastien Pédron 	kset = to_kset(kobj);
353*fe842818SJean-Sébastien Pédron 	kfree(kset);
354*fe842818SJean-Sébastien Pédron }
355