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