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