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