Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * configfs_example_macros.c - This file is a demonstration module
0004  *      containing a number of configfs subsystems.  It uses the helper
0005  *      macros defined by configfs.h
0006  *
0007  * Based on sysfs:
0008  *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
0009  *
0010  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
0011  */
0012 
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/slab.h>
0017 #include <linux/configfs.h>
0018 
0019 /*
0020  * 01-childless
0021  *
0022  * This first example is a childless subsystem.  It cannot create
0023  * any config_items.  It just has attributes.
0024  *
0025  * Note that we are enclosing the configfs_subsystem inside a container.
0026  * This is not necessary if a subsystem has no attributes directly
0027  * on the subsystem.  See the next example, 02-simple-children, for
0028  * such a subsystem.
0029  */
0030 
0031 struct childless {
0032     struct configfs_subsystem subsys;
0033     int showme;
0034     int storeme;
0035 };
0036 
0037 static inline struct childless *to_childless(struct config_item *item)
0038 {
0039     return container_of(to_configfs_subsystem(to_config_group(item)),
0040                 struct childless, subsys);
0041 }
0042 
0043 static ssize_t childless_showme_show(struct config_item *item, char *page)
0044 {
0045     struct childless *childless = to_childless(item);
0046     ssize_t pos;
0047 
0048     pos = sprintf(page, "%d\n", childless->showme);
0049     childless->showme++;
0050 
0051     return pos;
0052 }
0053 
0054 static ssize_t childless_storeme_show(struct config_item *item, char *page)
0055 {
0056     return sprintf(page, "%d\n", to_childless(item)->storeme);
0057 }
0058 
0059 static ssize_t childless_storeme_store(struct config_item *item,
0060         const char *page, size_t count)
0061 {
0062     struct childless *childless = to_childless(item);
0063     int ret;
0064 
0065     ret = kstrtoint(page, 10, &childless->storeme);
0066     if (ret)
0067         return ret;
0068 
0069     return count;
0070 }
0071 
0072 static ssize_t childless_description_show(struct config_item *item, char *page)
0073 {
0074     return sprintf(page,
0075 "[01-childless]\n"
0076 "\n"
0077 "The childless subsystem is the simplest possible subsystem in\n"
0078 "configfs.  It does not support the creation of child config_items.\n"
0079 "It only has a few attributes.  In fact, it isn't much different\n"
0080 "than a directory in /proc.\n");
0081 }
0082 
0083 CONFIGFS_ATTR_RO(childless_, showme);
0084 CONFIGFS_ATTR(childless_, storeme);
0085 CONFIGFS_ATTR_RO(childless_, description);
0086 
0087 static struct configfs_attribute *childless_attrs[] = {
0088     &childless_attr_showme,
0089     &childless_attr_storeme,
0090     &childless_attr_description,
0091     NULL,
0092 };
0093 
0094 static const struct config_item_type childless_type = {
0095     .ct_attrs   = childless_attrs,
0096     .ct_owner   = THIS_MODULE,
0097 };
0098 
0099 static struct childless childless_subsys = {
0100     .subsys = {
0101         .su_group = {
0102             .cg_item = {
0103                 .ci_namebuf = "01-childless",
0104                 .ci_type = &childless_type,
0105             },
0106         },
0107     },
0108 };
0109 
0110 /* ----------------------------------------------------------------- */
0111 
0112 /*
0113  * 02-simple-children
0114  *
0115  * This example merely has a simple one-attribute child.  Note that
0116  * there is no extra attribute structure, as the child's attribute is
0117  * known from the get-go.  Also, there is no container for the
0118  * subsystem, as it has no attributes of its own.
0119  */
0120 
0121 struct simple_child {
0122     struct config_item item;
0123     int storeme;
0124 };
0125 
0126 static inline struct simple_child *to_simple_child(struct config_item *item)
0127 {
0128     return container_of(item, struct simple_child, item);
0129 }
0130 
0131 static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
0132 {
0133     return sprintf(page, "%d\n", to_simple_child(item)->storeme);
0134 }
0135 
0136 static ssize_t simple_child_storeme_store(struct config_item *item,
0137         const char *page, size_t count)
0138 {
0139     struct simple_child *simple_child = to_simple_child(item);
0140     int ret;
0141 
0142     ret = kstrtoint(page, 10, &simple_child->storeme);
0143     if (ret)
0144         return ret;
0145 
0146     return count;
0147 }
0148 
0149 CONFIGFS_ATTR(simple_child_, storeme);
0150 
0151 static struct configfs_attribute *simple_child_attrs[] = {
0152     &simple_child_attr_storeme,
0153     NULL,
0154 };
0155 
0156 static void simple_child_release(struct config_item *item)
0157 {
0158     kfree(to_simple_child(item));
0159 }
0160 
0161 static struct configfs_item_operations simple_child_item_ops = {
0162     .release    = simple_child_release,
0163 };
0164 
0165 static const struct config_item_type simple_child_type = {
0166     .ct_item_ops    = &simple_child_item_ops,
0167     .ct_attrs   = simple_child_attrs,
0168     .ct_owner   = THIS_MODULE,
0169 };
0170 
0171 struct simple_children {
0172     struct config_group group;
0173 };
0174 
0175 static inline struct simple_children *to_simple_children(struct config_item *item)
0176 {
0177     return container_of(to_config_group(item),
0178                 struct simple_children, group);
0179 }
0180 
0181 static struct config_item *simple_children_make_item(struct config_group *group,
0182         const char *name)
0183 {
0184     struct simple_child *simple_child;
0185 
0186     simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
0187     if (!simple_child)
0188         return ERR_PTR(-ENOMEM);
0189 
0190     config_item_init_type_name(&simple_child->item, name,
0191                    &simple_child_type);
0192 
0193     return &simple_child->item;
0194 }
0195 
0196 static ssize_t simple_children_description_show(struct config_item *item,
0197         char *page)
0198 {
0199     return sprintf(page,
0200 "[02-simple-children]\n"
0201 "\n"
0202 "This subsystem allows the creation of child config_items.  These\n"
0203 "items have only one attribute that is readable and writeable.\n");
0204 }
0205 
0206 CONFIGFS_ATTR_RO(simple_children_, description);
0207 
0208 static struct configfs_attribute *simple_children_attrs[] = {
0209     &simple_children_attr_description,
0210     NULL,
0211 };
0212 
0213 static void simple_children_release(struct config_item *item)
0214 {
0215     kfree(to_simple_children(item));
0216 }
0217 
0218 static struct configfs_item_operations simple_children_item_ops = {
0219     .release    = simple_children_release,
0220 };
0221 
0222 /*
0223  * Note that, since no extra work is required on ->drop_item(),
0224  * no ->drop_item() is provided.
0225  */
0226 static struct configfs_group_operations simple_children_group_ops = {
0227     .make_item  = simple_children_make_item,
0228 };
0229 
0230 static const struct config_item_type simple_children_type = {
0231     .ct_item_ops    = &simple_children_item_ops,
0232     .ct_group_ops   = &simple_children_group_ops,
0233     .ct_attrs   = simple_children_attrs,
0234     .ct_owner   = THIS_MODULE,
0235 };
0236 
0237 static struct configfs_subsystem simple_children_subsys = {
0238     .su_group = {
0239         .cg_item = {
0240             .ci_namebuf = "02-simple-children",
0241             .ci_type = &simple_children_type,
0242         },
0243     },
0244 };
0245 
0246 /* ----------------------------------------------------------------- */
0247 
0248 /*
0249  * 03-group-children
0250  *
0251  * This example reuses the simple_children group from above.  However,
0252  * the simple_children group is not the subsystem itself, it is a
0253  * child of the subsystem.  Creation of a group in the subsystem creates
0254  * a new simple_children group.  That group can then have simple_child
0255  * children of its own.
0256  */
0257 
0258 static struct config_group *group_children_make_group(
0259         struct config_group *group, const char *name)
0260 {
0261     struct simple_children *simple_children;
0262 
0263     simple_children = kzalloc(sizeof(struct simple_children),
0264                   GFP_KERNEL);
0265     if (!simple_children)
0266         return ERR_PTR(-ENOMEM);
0267 
0268     config_group_init_type_name(&simple_children->group, name,
0269                     &simple_children_type);
0270 
0271     return &simple_children->group;
0272 }
0273 
0274 static ssize_t group_children_description_show(struct config_item *item,
0275         char *page)
0276 {
0277     return sprintf(page,
0278 "[03-group-children]\n"
0279 "\n"
0280 "This subsystem allows the creation of child config_groups.  These\n"
0281 "groups are like the subsystem simple-children.\n");
0282 }
0283 
0284 CONFIGFS_ATTR_RO(group_children_, description);
0285 
0286 static struct configfs_attribute *group_children_attrs[] = {
0287     &group_children_attr_description,
0288     NULL,
0289 };
0290 
0291 /*
0292  * Note that, since no extra work is required on ->drop_item(),
0293  * no ->drop_item() is provided.
0294  */
0295 static struct configfs_group_operations group_children_group_ops = {
0296     .make_group = group_children_make_group,
0297 };
0298 
0299 static const struct config_item_type group_children_type = {
0300     .ct_group_ops   = &group_children_group_ops,
0301     .ct_attrs   = group_children_attrs,
0302     .ct_owner   = THIS_MODULE,
0303 };
0304 
0305 static struct configfs_subsystem group_children_subsys = {
0306     .su_group = {
0307         .cg_item = {
0308             .ci_namebuf = "03-group-children",
0309             .ci_type = &group_children_type,
0310         },
0311     },
0312 };
0313 
0314 /* ----------------------------------------------------------------- */
0315 
0316 /*
0317  * We're now done with our subsystem definitions.
0318  * For convenience in this module, here's a list of them all.  It
0319  * allows the init function to easily register them.  Most modules
0320  * will only have one subsystem, and will only call register_subsystem
0321  * on it directly.
0322  */
0323 static struct configfs_subsystem *example_subsys[] = {
0324     &childless_subsys.subsys,
0325     &simple_children_subsys,
0326     &group_children_subsys,
0327     NULL,
0328 };
0329 
0330 static int __init configfs_example_init(void)
0331 {
0332     struct configfs_subsystem *subsys;
0333     int ret, i;
0334 
0335     for (i = 0; example_subsys[i]; i++) {
0336         subsys = example_subsys[i];
0337 
0338         config_group_init(&subsys->su_group);
0339         mutex_init(&subsys->su_mutex);
0340         ret = configfs_register_subsystem(subsys);
0341         if (ret) {
0342             pr_err("Error %d while registering subsystem %s\n",
0343                    ret, subsys->su_group.cg_item.ci_namebuf);
0344             goto out_unregister;
0345         }
0346     }
0347 
0348     return 0;
0349 
0350 out_unregister:
0351     for (i--; i >= 0; i--)
0352         configfs_unregister_subsystem(example_subsys[i]);
0353 
0354     return ret;
0355 }
0356 
0357 static void __exit configfs_example_exit(void)
0358 {
0359     int i;
0360 
0361     for (i = 0; example_subsys[i]; i++)
0362         configfs_unregister_subsystem(example_subsys[i]);
0363 }
0364 
0365 module_init(configfs_example_init);
0366 module_exit(configfs_example_exit);
0367 MODULE_LICENSE("GPL");