1328970deSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
251798222SChristoph Hellwig /*
351798222SChristoph Hellwig  * vim: noexpandtab ts=8 sts=0 sw=8:
451798222SChristoph Hellwig  *
551798222SChristoph Hellwig  * configfs_example_macros.c - This file is a demonstration module
651798222SChristoph Hellwig  *      containing a number of configfs subsystems.  It uses the helper
751798222SChristoph Hellwig  *      macros defined by configfs.h
851798222SChristoph Hellwig  *
951798222SChristoph Hellwig  * Based on sysfs:
1051798222SChristoph Hellwig  * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
1151798222SChristoph Hellwig  *
1251798222SChristoph Hellwig  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
1351798222SChristoph Hellwig  */
1451798222SChristoph Hellwig 
1551798222SChristoph Hellwig #include <linux/init.h>
16b86ff67dSBartosz Golaszewski #include <linux/kernel.h>
1751798222SChristoph Hellwig #include <linux/module.h>
1851798222SChristoph Hellwig #include <linux/slab.h>
1951798222SChristoph Hellwig #include <linux/configfs.h>
2051798222SChristoph Hellwig 
2151798222SChristoph Hellwig /*
2251798222SChristoph Hellwig  * 01-childless
2351798222SChristoph Hellwig  *
2451798222SChristoph Hellwig  * This first example is a childless subsystem.  It cannot create
2551798222SChristoph Hellwig  * any config_items.  It just has attributes.
2651798222SChristoph Hellwig  *
2751798222SChristoph Hellwig  * Note that we are enclosing the configfs_subsystem inside a container.
2851798222SChristoph Hellwig  * This is not necessary if a subsystem has no attributes directly
2951798222SChristoph Hellwig  * on the subsystem.  See the next example, 02-simple-children, for
3051798222SChristoph Hellwig  * such a subsystem.
3151798222SChristoph Hellwig  */
3251798222SChristoph Hellwig 
3351798222SChristoph Hellwig struct childless {
3451798222SChristoph Hellwig 	struct configfs_subsystem subsys;
3551798222SChristoph Hellwig 	int showme;
3651798222SChristoph Hellwig 	int storeme;
3751798222SChristoph Hellwig };
3851798222SChristoph Hellwig 
3951798222SChristoph Hellwig static inline struct childless *to_childless(struct config_item *item)
4051798222SChristoph Hellwig {
41e0ee1fdbSBartosz Golaszewski 	return container_of(to_configfs_subsystem(to_config_group(item)),
42e0ee1fdbSBartosz Golaszewski 			    struct childless, subsys);
4351798222SChristoph Hellwig }
4451798222SChristoph Hellwig 
4551798222SChristoph Hellwig static ssize_t childless_showme_show(struct config_item *item, char *page)
4651798222SChristoph Hellwig {
4751798222SChristoph Hellwig 	struct childless *childless = to_childless(item);
4851798222SChristoph Hellwig 	ssize_t pos;
4951798222SChristoph Hellwig 
5051798222SChristoph Hellwig 	pos = sprintf(page, "%d\n", childless->showme);
5151798222SChristoph Hellwig 	childless->showme++;
5251798222SChristoph Hellwig 
5351798222SChristoph Hellwig 	return pos;
5451798222SChristoph Hellwig }
5551798222SChristoph Hellwig 
5651798222SChristoph Hellwig static ssize_t childless_storeme_show(struct config_item *item, char *page)
5751798222SChristoph Hellwig {
5851798222SChristoph Hellwig 	return sprintf(page, "%d\n", to_childless(item)->storeme);
5951798222SChristoph Hellwig }
6051798222SChristoph Hellwig 
6151798222SChristoph Hellwig static ssize_t childless_storeme_store(struct config_item *item,
6251798222SChristoph Hellwig 		const char *page, size_t count)
6351798222SChristoph Hellwig {
6451798222SChristoph Hellwig 	struct childless *childless = to_childless(item);
65b86ff67dSBartosz Golaszewski 	int ret;
6651798222SChristoph Hellwig 
67b86ff67dSBartosz Golaszewski 	ret = kstrtoint(page, 10, &childless->storeme);
68b86ff67dSBartosz Golaszewski 	if (ret)
69b86ff67dSBartosz Golaszewski 		return ret;
7051798222SChristoph Hellwig 
7151798222SChristoph Hellwig 	return count;
7251798222SChristoph Hellwig }
7351798222SChristoph Hellwig 
7451798222SChristoph Hellwig static ssize_t childless_description_show(struct config_item *item, char *page)
7551798222SChristoph Hellwig {
7651798222SChristoph Hellwig 	return sprintf(page,
7751798222SChristoph Hellwig "[01-childless]\n"
7851798222SChristoph Hellwig "\n"
7951798222SChristoph Hellwig "The childless subsystem is the simplest possible subsystem in\n"
8051798222SChristoph Hellwig "configfs.  It does not support the creation of child config_items.\n"
8151798222SChristoph Hellwig "It only has a few attributes.  In fact, it isn't much different\n"
8251798222SChristoph Hellwig "than a directory in /proc.\n");
8351798222SChristoph Hellwig }
8451798222SChristoph Hellwig 
8551798222SChristoph Hellwig CONFIGFS_ATTR_RO(childless_, showme);
8651798222SChristoph Hellwig CONFIGFS_ATTR(childless_, storeme);
8751798222SChristoph Hellwig CONFIGFS_ATTR_RO(childless_, description);
8851798222SChristoph Hellwig 
8951798222SChristoph Hellwig static struct configfs_attribute *childless_attrs[] = {
9051798222SChristoph Hellwig 	&childless_attr_showme,
9151798222SChristoph Hellwig 	&childless_attr_storeme,
9251798222SChristoph Hellwig 	&childless_attr_description,
9351798222SChristoph Hellwig 	NULL,
9451798222SChristoph Hellwig };
9551798222SChristoph Hellwig 
9684c43674SBhumika Goyal static const struct config_item_type childless_type = {
9751798222SChristoph Hellwig 	.ct_attrs	= childless_attrs,
9851798222SChristoph Hellwig 	.ct_owner	= THIS_MODULE,
9951798222SChristoph Hellwig };
10051798222SChristoph Hellwig 
10151798222SChristoph Hellwig static struct childless childless_subsys = {
10251798222SChristoph Hellwig 	.subsys = {
10351798222SChristoph Hellwig 		.su_group = {
10451798222SChristoph Hellwig 			.cg_item = {
10551798222SChristoph Hellwig 				.ci_namebuf = "01-childless",
10651798222SChristoph Hellwig 				.ci_type = &childless_type,
10751798222SChristoph Hellwig 			},
10851798222SChristoph Hellwig 		},
10951798222SChristoph Hellwig 	},
11051798222SChristoph Hellwig };
11151798222SChristoph Hellwig 
11251798222SChristoph Hellwig /* ----------------------------------------------------------------- */
11351798222SChristoph Hellwig 
11451798222SChristoph Hellwig /*
11551798222SChristoph Hellwig  * 02-simple-children
11651798222SChristoph Hellwig  *
11751798222SChristoph Hellwig  * This example merely has a simple one-attribute child.  Note that
11851798222SChristoph Hellwig  * there is no extra attribute structure, as the child's attribute is
11951798222SChristoph Hellwig  * known from the get-go.  Also, there is no container for the
12051798222SChristoph Hellwig  * subsystem, as it has no attributes of its own.
12151798222SChristoph Hellwig  */
12251798222SChristoph Hellwig 
12351798222SChristoph Hellwig struct simple_child {
12451798222SChristoph Hellwig 	struct config_item item;
12551798222SChristoph Hellwig 	int storeme;
12651798222SChristoph Hellwig };
12751798222SChristoph Hellwig 
12851798222SChristoph Hellwig static inline struct simple_child *to_simple_child(struct config_item *item)
12951798222SChristoph Hellwig {
130e0ee1fdbSBartosz Golaszewski 	return container_of(item, struct simple_child, item);
13151798222SChristoph Hellwig }
13251798222SChristoph Hellwig 
13351798222SChristoph Hellwig static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
13451798222SChristoph Hellwig {
13551798222SChristoph Hellwig 	return sprintf(page, "%d\n", to_simple_child(item)->storeme);
13651798222SChristoph Hellwig }
13751798222SChristoph Hellwig 
13851798222SChristoph Hellwig static ssize_t simple_child_storeme_store(struct config_item *item,
13951798222SChristoph Hellwig 		const char *page, size_t count)
14051798222SChristoph Hellwig {
14151798222SChristoph Hellwig 	struct simple_child *simple_child = to_simple_child(item);
142b86ff67dSBartosz Golaszewski 	int ret;
14351798222SChristoph Hellwig 
144b86ff67dSBartosz Golaszewski 	ret = kstrtoint(page, 10, &simple_child->storeme);
145b86ff67dSBartosz Golaszewski 	if (ret)
146b86ff67dSBartosz Golaszewski 		return ret;
14751798222SChristoph Hellwig 
14851798222SChristoph Hellwig 	return count;
14951798222SChristoph Hellwig }
15051798222SChristoph Hellwig 
15151798222SChristoph Hellwig CONFIGFS_ATTR(simple_child_, storeme);
15251798222SChristoph Hellwig 
15351798222SChristoph Hellwig static struct configfs_attribute *simple_child_attrs[] = {
15451798222SChristoph Hellwig 	&simple_child_attr_storeme,
15551798222SChristoph Hellwig 	NULL,
15651798222SChristoph Hellwig };
15751798222SChristoph Hellwig 
15851798222SChristoph Hellwig static void simple_child_release(struct config_item *item)
15951798222SChristoph Hellwig {
16051798222SChristoph Hellwig 	kfree(to_simple_child(item));
16151798222SChristoph Hellwig }
16251798222SChristoph Hellwig 
16351798222SChristoph Hellwig static struct configfs_item_operations simple_child_item_ops = {
16451798222SChristoph Hellwig 	.release	= simple_child_release,
16551798222SChristoph Hellwig };
16651798222SChristoph Hellwig 
16784c43674SBhumika Goyal static const struct config_item_type simple_child_type = {
16851798222SChristoph Hellwig 	.ct_item_ops	= &simple_child_item_ops,
16951798222SChristoph Hellwig 	.ct_attrs	= simple_child_attrs,
17051798222SChristoph Hellwig 	.ct_owner	= THIS_MODULE,
17151798222SChristoph Hellwig };
17251798222SChristoph Hellwig 
17351798222SChristoph Hellwig struct simple_children {
17451798222SChristoph Hellwig 	struct config_group group;
17551798222SChristoph Hellwig };
17651798222SChristoph Hellwig 
17751798222SChristoph Hellwig static inline struct simple_children *to_simple_children(struct config_item *item)
17851798222SChristoph Hellwig {
179e0ee1fdbSBartosz Golaszewski 	return container_of(to_config_group(item),
180e0ee1fdbSBartosz Golaszewski 			    struct simple_children, group);
18151798222SChristoph Hellwig }
18251798222SChristoph Hellwig 
18351798222SChristoph Hellwig static struct config_item *simple_children_make_item(struct config_group *group,
18451798222SChristoph Hellwig 		const char *name)
18551798222SChristoph Hellwig {
18651798222SChristoph Hellwig 	struct simple_child *simple_child;
18751798222SChristoph Hellwig 
18851798222SChristoph Hellwig 	simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
18951798222SChristoph Hellwig 	if (!simple_child)
19051798222SChristoph Hellwig 		return ERR_PTR(-ENOMEM);
19151798222SChristoph Hellwig 
19251798222SChristoph Hellwig 	config_item_init_type_name(&simple_child->item, name,
19351798222SChristoph Hellwig 				   &simple_child_type);
19451798222SChristoph Hellwig 
19551798222SChristoph Hellwig 	return &simple_child->item;
19651798222SChristoph Hellwig }
19751798222SChristoph Hellwig 
19851798222SChristoph Hellwig static ssize_t simple_children_description_show(struct config_item *item,
19951798222SChristoph Hellwig 		char *page)
20051798222SChristoph Hellwig {
20151798222SChristoph Hellwig 	return sprintf(page,
20251798222SChristoph Hellwig "[02-simple-children]\n"
20351798222SChristoph Hellwig "\n"
20451798222SChristoph Hellwig "This subsystem allows the creation of child config_items.  These\n"
20551798222SChristoph Hellwig "items have only one attribute that is readable and writeable.\n");
20651798222SChristoph Hellwig }
20751798222SChristoph Hellwig 
20851798222SChristoph Hellwig CONFIGFS_ATTR_RO(simple_children_, description);
20951798222SChristoph Hellwig 
21051798222SChristoph Hellwig static struct configfs_attribute *simple_children_attrs[] = {
21151798222SChristoph Hellwig 	&simple_children_attr_description,
21251798222SChristoph Hellwig 	NULL,
21351798222SChristoph Hellwig };
21451798222SChristoph Hellwig 
21551798222SChristoph Hellwig static void simple_children_release(struct config_item *item)
21651798222SChristoph Hellwig {
21751798222SChristoph Hellwig 	kfree(to_simple_children(item));
21851798222SChristoph Hellwig }
21951798222SChristoph Hellwig 
22051798222SChristoph Hellwig static struct configfs_item_operations simple_children_item_ops = {
22151798222SChristoph Hellwig 	.release	= simple_children_release,
22251798222SChristoph Hellwig };
22351798222SChristoph Hellwig 
22451798222SChristoph Hellwig /*
22551798222SChristoph Hellwig  * Note that, since no extra work is required on ->drop_item(),
22651798222SChristoph Hellwig  * no ->drop_item() is provided.
22751798222SChristoph Hellwig  */
22851798222SChristoph Hellwig static struct configfs_group_operations simple_children_group_ops = {
22951798222SChristoph Hellwig 	.make_item	= simple_children_make_item,
23051798222SChristoph Hellwig };
23151798222SChristoph Hellwig 
23284c43674SBhumika Goyal static const struct config_item_type simple_children_type = {
23351798222SChristoph Hellwig 	.ct_item_ops	= &simple_children_item_ops,
23451798222SChristoph Hellwig 	.ct_group_ops	= &simple_children_group_ops,
23551798222SChristoph Hellwig 	.ct_attrs	= simple_children_attrs,
23651798222SChristoph Hellwig 	.ct_owner	= THIS_MODULE,
23751798222SChristoph Hellwig };
23851798222SChristoph Hellwig 
23951798222SChristoph Hellwig static struct configfs_subsystem simple_children_subsys = {
24051798222SChristoph Hellwig 	.su_group = {
24151798222SChristoph Hellwig 		.cg_item = {
24251798222SChristoph Hellwig 			.ci_namebuf = "02-simple-children",
24351798222SChristoph Hellwig 			.ci_type = &simple_children_type,
24451798222SChristoph Hellwig 		},
24551798222SChristoph Hellwig 	},
24651798222SChristoph Hellwig };
24751798222SChristoph Hellwig 
24851798222SChristoph Hellwig /* ----------------------------------------------------------------- */
24951798222SChristoph Hellwig 
25051798222SChristoph Hellwig /*
25151798222SChristoph Hellwig  * 03-group-children
25251798222SChristoph Hellwig  *
25351798222SChristoph Hellwig  * This example reuses the simple_children group from above.  However,
25451798222SChristoph Hellwig  * the simple_children group is not the subsystem itself, it is a
25551798222SChristoph Hellwig  * child of the subsystem.  Creation of a group in the subsystem creates
25651798222SChristoph Hellwig  * a new simple_children group.  That group can then have simple_child
25751798222SChristoph Hellwig  * children of its own.
25851798222SChristoph Hellwig  */
25951798222SChristoph Hellwig 
26051798222SChristoph Hellwig static struct config_group *group_children_make_group(
26151798222SChristoph Hellwig 		struct config_group *group, const char *name)
26251798222SChristoph Hellwig {
26351798222SChristoph Hellwig 	struct simple_children *simple_children;
26451798222SChristoph Hellwig 
26551798222SChristoph Hellwig 	simple_children = kzalloc(sizeof(struct simple_children),
26651798222SChristoph Hellwig 				  GFP_KERNEL);
26751798222SChristoph Hellwig 	if (!simple_children)
26851798222SChristoph Hellwig 		return ERR_PTR(-ENOMEM);
26951798222SChristoph Hellwig 
27051798222SChristoph Hellwig 	config_group_init_type_name(&simple_children->group, name,
27151798222SChristoph Hellwig 				    &simple_children_type);
27251798222SChristoph Hellwig 
27351798222SChristoph Hellwig 	return &simple_children->group;
27451798222SChristoph Hellwig }
27551798222SChristoph Hellwig 
27651798222SChristoph Hellwig static ssize_t group_children_description_show(struct config_item *item,
27751798222SChristoph Hellwig 		char *page)
27851798222SChristoph Hellwig {
27951798222SChristoph Hellwig 	return sprintf(page,
28051798222SChristoph Hellwig "[03-group-children]\n"
28151798222SChristoph Hellwig "\n"
28251798222SChristoph Hellwig "This subsystem allows the creation of child config_groups.  These\n"
28351798222SChristoph Hellwig "groups are like the subsystem simple-children.\n");
28451798222SChristoph Hellwig }
28551798222SChristoph Hellwig 
28651798222SChristoph Hellwig CONFIGFS_ATTR_RO(group_children_, description);
28751798222SChristoph Hellwig 
28851798222SChristoph Hellwig static struct configfs_attribute *group_children_attrs[] = {
28951798222SChristoph Hellwig 	&group_children_attr_description,
29051798222SChristoph Hellwig 	NULL,
29151798222SChristoph Hellwig };
29251798222SChristoph Hellwig 
29351798222SChristoph Hellwig /*
29451798222SChristoph Hellwig  * Note that, since no extra work is required on ->drop_item(),
29551798222SChristoph Hellwig  * no ->drop_item() is provided.
29651798222SChristoph Hellwig  */
29751798222SChristoph Hellwig static struct configfs_group_operations group_children_group_ops = {
29851798222SChristoph Hellwig 	.make_group	= group_children_make_group,
29951798222SChristoph Hellwig };
30051798222SChristoph Hellwig 
30184c43674SBhumika Goyal static const struct config_item_type group_children_type = {
30251798222SChristoph Hellwig 	.ct_group_ops	= &group_children_group_ops,
30351798222SChristoph Hellwig 	.ct_attrs	= group_children_attrs,
30451798222SChristoph Hellwig 	.ct_owner	= THIS_MODULE,
30551798222SChristoph Hellwig };
30651798222SChristoph Hellwig 
30751798222SChristoph Hellwig static struct configfs_subsystem group_children_subsys = {
30851798222SChristoph Hellwig 	.su_group = {
30951798222SChristoph Hellwig 		.cg_item = {
31051798222SChristoph Hellwig 			.ci_namebuf = "03-group-children",
31151798222SChristoph Hellwig 			.ci_type = &group_children_type,
31251798222SChristoph Hellwig 		},
31351798222SChristoph Hellwig 	},
31451798222SChristoph Hellwig };
31551798222SChristoph Hellwig 
31651798222SChristoph Hellwig /* ----------------------------------------------------------------- */
31751798222SChristoph Hellwig 
31851798222SChristoph Hellwig /*
31951798222SChristoph Hellwig  * We're now done with our subsystem definitions.
32051798222SChristoph Hellwig  * For convenience in this module, here's a list of them all.  It
32151798222SChristoph Hellwig  * allows the init function to easily register them.  Most modules
32251798222SChristoph Hellwig  * will only have one subsystem, and will only call register_subsystem
32351798222SChristoph Hellwig  * on it directly.
32451798222SChristoph Hellwig  */
32551798222SChristoph Hellwig static struct configfs_subsystem *example_subsys[] = {
32651798222SChristoph Hellwig 	&childless_subsys.subsys,
32751798222SChristoph Hellwig 	&simple_children_subsys,
32851798222SChristoph Hellwig 	&group_children_subsys,
32951798222SChristoph Hellwig 	NULL,
33051798222SChristoph Hellwig };
33151798222SChristoph Hellwig 
33251798222SChristoph Hellwig static int __init configfs_example_init(void)
33351798222SChristoph Hellwig {
33451798222SChristoph Hellwig 	struct configfs_subsystem *subsys;
3354e415a84SBartosz Golaszewski 	int ret, i;
33651798222SChristoph Hellwig 
33751798222SChristoph Hellwig 	for (i = 0; example_subsys[i]; i++) {
33851798222SChristoph Hellwig 		subsys = example_subsys[i];
33951798222SChristoph Hellwig 
34051798222SChristoph Hellwig 		config_group_init(&subsys->su_group);
34151798222SChristoph Hellwig 		mutex_init(&subsys->su_mutex);
34251798222SChristoph Hellwig 		ret = configfs_register_subsystem(subsys);
34351798222SChristoph Hellwig 		if (ret) {
34451798222SChristoph Hellwig 			printk(KERN_ERR "Error %d while registering subsystem %s\n",
34551798222SChristoph Hellwig 			       ret,
34651798222SChristoph Hellwig 			       subsys->su_group.cg_item.ci_namebuf);
34751798222SChristoph Hellwig 			goto out_unregister;
34851798222SChristoph Hellwig 		}
34951798222SChristoph Hellwig 	}
35051798222SChristoph Hellwig 
35151798222SChristoph Hellwig 	return 0;
35251798222SChristoph Hellwig 
35351798222SChristoph Hellwig out_unregister:
35451798222SChristoph Hellwig 	for (i--; i >= 0; i--)
35551798222SChristoph Hellwig 		configfs_unregister_subsystem(example_subsys[i]);
35651798222SChristoph Hellwig 
35751798222SChristoph Hellwig 	return ret;
35851798222SChristoph Hellwig }
35951798222SChristoph Hellwig 
36051798222SChristoph Hellwig static void __exit configfs_example_exit(void)
36151798222SChristoph Hellwig {
36251798222SChristoph Hellwig 	int i;
36351798222SChristoph Hellwig 
36451798222SChristoph Hellwig 	for (i = 0; example_subsys[i]; i++)
36551798222SChristoph Hellwig 		configfs_unregister_subsystem(example_subsys[i]);
36651798222SChristoph Hellwig }
36751798222SChristoph Hellwig 
36851798222SChristoph Hellwig module_init(configfs_example_init);
36951798222SChristoph Hellwig module_exit(configfs_example_exit);
37051798222SChristoph Hellwig MODULE_LICENSE("GPL");
371