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