1/* 2 * vim: noexpandtab ts=8 sts=0 sw=8: 3 * 4 * configfs_example_macros.c - This file is a demonstration module 5 * containing a number of configfs subsystems. It uses the helper 6 * macros defined by configfs.h 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public 19 * License along with this program; if not, write to the 20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 * Boston, MA 021110-1307, USA. 22 * 23 * Based on sysfs: 24 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 25 * 26 * configfs Copyright (C) 2005 Oracle. All rights reserved. 27 */ 28 29#include <linux/init.h> 30#include <linux/module.h> 31#include <linux/slab.h> 32 33#include <linux/configfs.h> 34 35 36 37/* 38 * 01-childless 39 * 40 * This first example is a childless subsystem. It cannot create 41 * any config_items. It just has attributes. 42 * 43 * Note that we are enclosing the configfs_subsystem inside a container. 44 * This is not necessary if a subsystem has no attributes directly 45 * on the subsystem. See the next example, 02-simple-children, for 46 * such a subsystem. 47 */ 48 49struct childless { 50 struct configfs_subsystem subsys; 51 int showme; 52 int storeme; 53}; 54 55static inline struct childless *to_childless(struct config_item *item) 56{ 57 return item ? container_of(to_configfs_subsystem(to_config_group(item)), 58 struct childless, subsys) : NULL; 59} 60 61static ssize_t childless_showme_show(struct config_item *item, char *page) 62{ 63 struct childless *childless = to_childless(item); 64 ssize_t pos; 65 66 pos = sprintf(page, "%d\n", childless->showme); 67 childless->showme++; 68 69 return pos; 70} 71 72static ssize_t childless_storeme_show(struct config_item *item, char *page) 73{ 74 return sprintf(page, "%d\n", to_childless(item)->storeme); 75} 76 77static ssize_t childless_storeme_store(struct config_item *item, 78 const char *page, size_t count) 79{ 80 struct childless *childless = to_childless(item); 81 unsigned long tmp; 82 char *p = (char *) page; 83 84 tmp = simple_strtoul(p, &p, 10); 85 if (!p || (*p && (*p != '\n'))) 86 return -EINVAL; 87 88 if (tmp > INT_MAX) 89 return -ERANGE; 90 91 childless->storeme = tmp; 92 93 return count; 94} 95 96static ssize_t childless_description_show(struct config_item *item, char *page) 97{ 98 return sprintf(page, 99"[01-childless]\n" 100"\n" 101"The childless subsystem is the simplest possible subsystem in\n" 102"configfs. It does not support the creation of child config_items.\n" 103"It only has a few attributes. In fact, it isn't much different\n" 104"than a directory in /proc.\n"); 105} 106 107CONFIGFS_ATTR_RO(childless_, showme); 108CONFIGFS_ATTR(childless_, storeme); 109CONFIGFS_ATTR_RO(childless_, description); 110 111static struct configfs_attribute *childless_attrs[] = { 112 &childless_attr_showme, 113 &childless_attr_storeme, 114 &childless_attr_description, 115 NULL, 116}; 117 118static struct config_item_type childless_type = { 119 .ct_attrs = childless_attrs, 120 .ct_owner = THIS_MODULE, 121}; 122 123static struct childless childless_subsys = { 124 .subsys = { 125 .su_group = { 126 .cg_item = { 127 .ci_namebuf = "01-childless", 128 .ci_type = &childless_type, 129 }, 130 }, 131 }, 132}; 133 134 135/* ----------------------------------------------------------------- */ 136 137/* 138 * 02-simple-children 139 * 140 * This example merely has a simple one-attribute child. Note that 141 * there is no extra attribute structure, as the child's attribute is 142 * known from the get-go. Also, there is no container for the 143 * subsystem, as it has no attributes of its own. 144 */ 145 146struct simple_child { 147 struct config_item item; 148 int storeme; 149}; 150 151static inline struct simple_child *to_simple_child(struct config_item *item) 152{ 153 return item ? container_of(item, struct simple_child, item) : NULL; 154} 155 156static ssize_t simple_child_storeme_show(struct config_item *item, char *page) 157{ 158 return sprintf(page, "%d\n", to_simple_child(item)->storeme); 159} 160 161static ssize_t simple_child_storeme_store(struct config_item *item, 162 const char *page, size_t count) 163{ 164 struct simple_child *simple_child = to_simple_child(item); 165 unsigned long tmp; 166 char *p = (char *) page; 167 168 tmp = simple_strtoul(p, &p, 10); 169 if (!p || (*p && (*p != '\n'))) 170 return -EINVAL; 171 172 if (tmp > INT_MAX) 173 return -ERANGE; 174 175 simple_child->storeme = tmp; 176 177 return count; 178} 179 180CONFIGFS_ATTR(simple_child_, storeme); 181 182static struct configfs_attribute *simple_child_attrs[] = { 183 &simple_child_attr_storeme, 184 NULL, 185}; 186 187static void simple_child_release(struct config_item *item) 188{ 189 kfree(to_simple_child(item)); 190} 191 192static struct configfs_item_operations simple_child_item_ops = { 193 .release = simple_child_release, 194}; 195 196static struct config_item_type simple_child_type = { 197 .ct_item_ops = &simple_child_item_ops, 198 .ct_attrs = simple_child_attrs, 199 .ct_owner = THIS_MODULE, 200}; 201 202 203struct simple_children { 204 struct config_group group; 205}; 206 207static inline struct simple_children *to_simple_children(struct config_item *item) 208{ 209 return item ? container_of(to_config_group(item), 210 struct simple_children, group) : NULL; 211} 212 213static struct config_item *simple_children_make_item(struct config_group *group, 214 const char *name) 215{ 216 struct simple_child *simple_child; 217 218 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); 219 if (!simple_child) 220 return ERR_PTR(-ENOMEM); 221 222 config_item_init_type_name(&simple_child->item, name, 223 &simple_child_type); 224 225 simple_child->storeme = 0; 226 227 return &simple_child->item; 228} 229 230static ssize_t simple_children_description_show(struct config_item *item, 231 char *page) 232{ 233 return sprintf(page, 234"[02-simple-children]\n" 235"\n" 236"This subsystem allows the creation of child config_items. These\n" 237"items have only one attribute that is readable and writeable.\n"); 238} 239 240CONFIGFS_ATTR_RO(simple_children_, description); 241 242static struct configfs_attribute *simple_children_attrs[] = { 243 &simple_children_attr_description, 244 NULL, 245}; 246 247static void simple_children_release(struct config_item *item) 248{ 249 kfree(to_simple_children(item)); 250} 251 252static struct configfs_item_operations simple_children_item_ops = { 253 .release = simple_children_release, 254}; 255 256/* 257 * Note that, since no extra work is required on ->drop_item(), 258 * no ->drop_item() is provided. 259 */ 260static struct configfs_group_operations simple_children_group_ops = { 261 .make_item = simple_children_make_item, 262}; 263 264static struct config_item_type simple_children_type = { 265 .ct_item_ops = &simple_children_item_ops, 266 .ct_group_ops = &simple_children_group_ops, 267 .ct_attrs = simple_children_attrs, 268 .ct_owner = THIS_MODULE, 269}; 270 271static struct configfs_subsystem simple_children_subsys = { 272 .su_group = { 273 .cg_item = { 274 .ci_namebuf = "02-simple-children", 275 .ci_type = &simple_children_type, 276 }, 277 }, 278}; 279 280 281/* ----------------------------------------------------------------- */ 282 283/* 284 * 03-group-children 285 * 286 * This example reuses the simple_children group from above. However, 287 * the simple_children group is not the subsystem itself, it is a 288 * child of the subsystem. Creation of a group in the subsystem creates 289 * a new simple_children group. That group can then have simple_child 290 * children of its own. 291 */ 292 293static struct config_group *group_children_make_group( 294 struct config_group *group, const char *name) 295{ 296 struct simple_children *simple_children; 297 298 simple_children = kzalloc(sizeof(struct simple_children), 299 GFP_KERNEL); 300 if (!simple_children) 301 return ERR_PTR(-ENOMEM); 302 303 config_group_init_type_name(&simple_children->group, name, 304 &simple_children_type); 305 306 return &simple_children->group; 307} 308 309static ssize_t group_children_description_show(struct config_item *item, 310 char *page) 311{ 312 return sprintf(page, 313"[03-group-children]\n" 314"\n" 315"This subsystem allows the creation of child config_groups. These\n" 316"groups are like the subsystem simple-children.\n"); 317} 318 319CONFIGFS_ATTR_RO(group_children_, description); 320 321static struct configfs_attribute *group_children_attrs[] = { 322 &group_children_attr_description, 323 NULL, 324}; 325 326/* 327 * Note that, since no extra work is required on ->drop_item(), 328 * no ->drop_item() is provided. 329 */ 330static struct configfs_group_operations group_children_group_ops = { 331 .make_group = group_children_make_group, 332}; 333 334static struct config_item_type group_children_type = { 335 .ct_group_ops = &group_children_group_ops, 336 .ct_attrs = group_children_attrs, 337 .ct_owner = THIS_MODULE, 338}; 339 340static struct configfs_subsystem group_children_subsys = { 341 .su_group = { 342 .cg_item = { 343 .ci_namebuf = "03-group-children", 344 .ci_type = &group_children_type, 345 }, 346 }, 347}; 348 349/* ----------------------------------------------------------------- */ 350 351/* 352 * We're now done with our subsystem definitions. 353 * For convenience in this module, here's a list of them all. It 354 * allows the init function to easily register them. Most modules 355 * will only have one subsystem, and will only call register_subsystem 356 * on it directly. 357 */ 358static struct configfs_subsystem *example_subsys[] = { 359 &childless_subsys.subsys, 360 &simple_children_subsys, 361 &group_children_subsys, 362 NULL, 363}; 364 365static int __init configfs_example_init(void) 366{ 367 int ret; 368 int i; 369 struct configfs_subsystem *subsys; 370 371 for (i = 0; example_subsys[i]; i++) { 372 subsys = example_subsys[i]; 373 374 config_group_init(&subsys->su_group); 375 mutex_init(&subsys->su_mutex); 376 ret = configfs_register_subsystem(subsys); 377 if (ret) { 378 printk(KERN_ERR "Error %d while registering subsystem %s\n", 379 ret, 380 subsys->su_group.cg_item.ci_namebuf); 381 goto out_unregister; 382 } 383 } 384 385 return 0; 386 387out_unregister: 388 for (i--; i >= 0; i--) 389 configfs_unregister_subsystem(example_subsys[i]); 390 391 return ret; 392} 393 394static void __exit configfs_example_exit(void) 395{ 396 int i; 397 398 for (i = 0; example_subsys[i]; i++) 399 configfs_unregister_subsystem(example_subsys[i]); 400} 401 402module_init(configfs_example_init); 403module_exit(configfs_example_exit); 404MODULE_LICENSE("GPL"); 405