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