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)), struct childless, subsys) : NULL; 58} 59 60CONFIGFS_ATTR_STRUCT(childless); 61#define CHILDLESS_ATTR(_name, _mode, _show, _store) \ 62struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store) 63#define CHILDLESS_ATTR_RO(_name, _show) \ 64struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show); 65 66static ssize_t childless_showme_read(struct childless *childless, 67 char *page) 68{ 69 ssize_t pos; 70 71 pos = sprintf(page, "%d\n", childless->showme); 72 childless->showme++; 73 74 return pos; 75} 76 77static ssize_t childless_storeme_read(struct childless *childless, 78 char *page) 79{ 80 return sprintf(page, "%d\n", childless->storeme); 81} 82 83static ssize_t childless_storeme_write(struct childless *childless, 84 const char *page, 85 size_t count) 86{ 87 unsigned long tmp; 88 char *p = (char *) page; 89 90 tmp = simple_strtoul(p, &p, 10); 91 if (!p || (*p && (*p != '\n'))) 92 return -EINVAL; 93 94 if (tmp > INT_MAX) 95 return -ERANGE; 96 97 childless->storeme = tmp; 98 99 return count; 100} 101 102static ssize_t childless_description_read(struct childless *childless, 103 char *page) 104{ 105 return sprintf(page, 106"[01-childless]\n" 107"\n" 108"The childless subsystem is the simplest possible subsystem in\n" 109"configfs. It does not support the creation of child config_items.\n" 110"It only has a few attributes. In fact, it isn't much different\n" 111"than a directory in /proc.\n"); 112} 113 114CHILDLESS_ATTR_RO(showme, childless_showme_read); 115CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read, 116 childless_storeme_write); 117CHILDLESS_ATTR_RO(description, childless_description_read); 118 119static struct configfs_attribute *childless_attrs[] = { 120 &childless_attr_showme.attr, 121 &childless_attr_storeme.attr, 122 &childless_attr_description.attr, 123 NULL, 124}; 125 126CONFIGFS_ATTR_OPS(childless); 127static struct configfs_item_operations childless_item_ops = { 128 .show_attribute = childless_attr_show, 129 .store_attribute = childless_attr_store, 130}; 131 132static struct config_item_type childless_type = { 133 .ct_item_ops = &childless_item_ops, 134 .ct_attrs = childless_attrs, 135 .ct_owner = THIS_MODULE, 136}; 137 138static struct childless childless_subsys = { 139 .subsys = { 140 .su_group = { 141 .cg_item = { 142 .ci_namebuf = "01-childless", 143 .ci_type = &childless_type, 144 }, 145 }, 146 }, 147}; 148 149 150/* ----------------------------------------------------------------- */ 151 152/* 153 * 02-simple-children 154 * 155 * This example merely has a simple one-attribute child. Note that 156 * there is no extra attribute structure, as the child's attribute is 157 * known from the get-go. Also, there is no container for the 158 * subsystem, as it has no attributes of its own. 159 */ 160 161struct simple_child { 162 struct config_item item; 163 int storeme; 164}; 165 166static inline struct simple_child *to_simple_child(struct config_item *item) 167{ 168 return item ? container_of(item, struct simple_child, item) : NULL; 169} 170 171static struct configfs_attribute simple_child_attr_storeme = { 172 .ca_owner = THIS_MODULE, 173 .ca_name = "storeme", 174 .ca_mode = S_IRUGO | S_IWUSR, 175}; 176 177static struct configfs_attribute *simple_child_attrs[] = { 178 &simple_child_attr_storeme, 179 NULL, 180}; 181 182static ssize_t simple_child_attr_show(struct config_item *item, 183 struct configfs_attribute *attr, 184 char *page) 185{ 186 ssize_t count; 187 struct simple_child *simple_child = to_simple_child(item); 188 189 count = sprintf(page, "%d\n", simple_child->storeme); 190 191 return count; 192} 193 194static ssize_t simple_child_attr_store(struct config_item *item, 195 struct configfs_attribute *attr, 196 const char *page, size_t count) 197{ 198 struct simple_child *simple_child = to_simple_child(item); 199 unsigned long tmp; 200 char *p = (char *) page; 201 202 tmp = simple_strtoul(p, &p, 10); 203 if (!p || (*p && (*p != '\n'))) 204 return -EINVAL; 205 206 if (tmp > INT_MAX) 207 return -ERANGE; 208 209 simple_child->storeme = tmp; 210 211 return count; 212} 213 214static void simple_child_release(struct config_item *item) 215{ 216 kfree(to_simple_child(item)); 217} 218 219static struct configfs_item_operations simple_child_item_ops = { 220 .release = simple_child_release, 221 .show_attribute = simple_child_attr_show, 222 .store_attribute = simple_child_attr_store, 223}; 224 225static struct config_item_type simple_child_type = { 226 .ct_item_ops = &simple_child_item_ops, 227 .ct_attrs = simple_child_attrs, 228 .ct_owner = THIS_MODULE, 229}; 230 231 232struct simple_children { 233 struct config_group group; 234}; 235 236static inline struct simple_children *to_simple_children(struct config_item *item) 237{ 238 return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; 239} 240 241static struct config_item *simple_children_make_item(struct config_group *group, const char *name) 242{ 243 struct simple_child *simple_child; 244 245 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); 246 if (!simple_child) 247 return ERR_PTR(-ENOMEM); 248 249 config_item_init_type_name(&simple_child->item, name, 250 &simple_child_type); 251 252 simple_child->storeme = 0; 253 254 return &simple_child->item; 255} 256 257static struct configfs_attribute simple_children_attr_description = { 258 .ca_owner = THIS_MODULE, 259 .ca_name = "description", 260 .ca_mode = S_IRUGO, 261}; 262 263static struct configfs_attribute *simple_children_attrs[] = { 264 &simple_children_attr_description, 265 NULL, 266}; 267 268static ssize_t simple_children_attr_show(struct config_item *item, 269 struct configfs_attribute *attr, 270 char *page) 271{ 272 return sprintf(page, 273"[02-simple-children]\n" 274"\n" 275"This subsystem allows the creation of child config_items. These\n" 276"items have only one attribute that is readable and writeable.\n"); 277} 278 279static void simple_children_release(struct config_item *item) 280{ 281 kfree(to_simple_children(item)); 282} 283 284static struct configfs_item_operations simple_children_item_ops = { 285 .release = simple_children_release, 286 .show_attribute = simple_children_attr_show, 287}; 288 289/* 290 * Note that, since no extra work is required on ->drop_item(), 291 * no ->drop_item() is provided. 292 */ 293static struct configfs_group_operations simple_children_group_ops = { 294 .make_item = simple_children_make_item, 295}; 296 297static struct config_item_type simple_children_type = { 298 .ct_item_ops = &simple_children_item_ops, 299 .ct_group_ops = &simple_children_group_ops, 300 .ct_attrs = simple_children_attrs, 301 .ct_owner = THIS_MODULE, 302}; 303 304static struct configfs_subsystem simple_children_subsys = { 305 .su_group = { 306 .cg_item = { 307 .ci_namebuf = "02-simple-children", 308 .ci_type = &simple_children_type, 309 }, 310 }, 311}; 312 313 314/* ----------------------------------------------------------------- */ 315 316/* 317 * 03-group-children 318 * 319 * This example reuses the simple_children group from above. However, 320 * the simple_children group is not the subsystem itself, it is a 321 * child of the subsystem. Creation of a group in the subsystem creates 322 * a new simple_children group. That group can then have simple_child 323 * children of its own. 324 */ 325 326static struct config_group *group_children_make_group(struct config_group *group, const char *name) 327{ 328 struct simple_children *simple_children; 329 330 simple_children = kzalloc(sizeof(struct simple_children), 331 GFP_KERNEL); 332 if (!simple_children) 333 return ERR_PTR(-ENOMEM); 334 335 config_group_init_type_name(&simple_children->group, name, 336 &simple_children_type); 337 338 return &simple_children->group; 339} 340 341static struct configfs_attribute group_children_attr_description = { 342 .ca_owner = THIS_MODULE, 343 .ca_name = "description", 344 .ca_mode = S_IRUGO, 345}; 346 347static struct configfs_attribute *group_children_attrs[] = { 348 &group_children_attr_description, 349 NULL, 350}; 351 352static ssize_t group_children_attr_show(struct config_item *item, 353 struct configfs_attribute *attr, 354 char *page) 355{ 356 return sprintf(page, 357"[03-group-children]\n" 358"\n" 359"This subsystem allows the creation of child config_groups. These\n" 360"groups are like the subsystem simple-children.\n"); 361} 362 363static struct configfs_item_operations group_children_item_ops = { 364 .show_attribute = group_children_attr_show, 365}; 366 367/* 368 * Note that, since no extra work is required on ->drop_item(), 369 * no ->drop_item() is provided. 370 */ 371static struct configfs_group_operations group_children_group_ops = { 372 .make_group = group_children_make_group, 373}; 374 375static struct config_item_type group_children_type = { 376 .ct_item_ops = &group_children_item_ops, 377 .ct_group_ops = &group_children_group_ops, 378 .ct_attrs = group_children_attrs, 379 .ct_owner = THIS_MODULE, 380}; 381 382static struct configfs_subsystem group_children_subsys = { 383 .su_group = { 384 .cg_item = { 385 .ci_namebuf = "03-group-children", 386 .ci_type = &group_children_type, 387 }, 388 }, 389}; 390 391/* ----------------------------------------------------------------- */ 392 393/* 394 * We're now done with our subsystem definitions. 395 * For convenience in this module, here's a list of them all. It 396 * allows the init function to easily register them. Most modules 397 * will only have one subsystem, and will only call register_subsystem 398 * on it directly. 399 */ 400static struct configfs_subsystem *example_subsys[] = { 401 &childless_subsys.subsys, 402 &simple_children_subsys, 403 &group_children_subsys, 404 NULL, 405}; 406 407static int __init configfs_example_init(void) 408{ 409 int ret; 410 int i; 411 struct configfs_subsystem *subsys; 412 413 for (i = 0; example_subsys[i]; i++) { 414 subsys = example_subsys[i]; 415 416 config_group_init(&subsys->su_group); 417 mutex_init(&subsys->su_mutex); 418 ret = configfs_register_subsystem(subsys); 419 if (ret) { 420 printk(KERN_ERR "Error %d while registering subsystem %s\n", 421 ret, 422 subsys->su_group.cg_item.ci_namebuf); 423 goto out_unregister; 424 } 425 } 426 427 return 0; 428 429out_unregister: 430 for (i--; i >= 0; i--) 431 configfs_unregister_subsystem(example_subsys[i]); 432 433 return ret; 434} 435 436static void __exit configfs_example_exit(void) 437{ 438 int i; 439 440 for (i = 0; example_subsys[i]; i++) 441 configfs_unregister_subsystem(example_subsys[i]); 442} 443 444module_init(configfs_example_init); 445module_exit(configfs_example_exit); 446MODULE_LICENSE("GPL"); 447