Based on kernel version 4.3. Page generated on 2015-11-02 12:49 EST.
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 49 struct childless { 50 struct configfs_subsystem subsys; 51 int showme; 52 int storeme; 53 }; 54 55 static 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 60 CONFIGFS_ATTR_STRUCT(childless); 61 #define CHILDLESS_ATTR(_name, _mode, _show, _store) \ 62 struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store) 63 #define CHILDLESS_ATTR_RO(_name, _show) \ 64 struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show); 65 66 static 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 77 static ssize_t childless_storeme_read(struct childless *childless, 78 char *page) 79 { 80 return sprintf(page, "%d\n", childless->storeme); 81 } 82 83 static 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 102 static 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 114 CHILDLESS_ATTR_RO(showme, childless_showme_read); 115 CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read, 116 childless_storeme_write); 117 CHILDLESS_ATTR_RO(description, childless_description_read); 118 119 static struct configfs_attribute *childless_attrs[] = { 120 &childless_attr_showme.attr, 121 &childless_attr_storeme.attr, 122 &childless_attr_description.attr, 123 NULL, 124 }; 125 126 CONFIGFS_ATTR_OPS(childless); 127 static struct configfs_item_operations childless_item_ops = { 128 .show_attribute = childless_attr_show, 129 .store_attribute = childless_attr_store, 130 }; 131 132 static 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 138 static 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 161 struct simple_child { 162 struct config_item item; 163 int storeme; 164 }; 165 166 static 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 171 static 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 177 static struct configfs_attribute *simple_child_attrs[] = { 178 &simple_child_attr_storeme, 179 NULL, 180 }; 181 182 static 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 194 static 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 214 static void simple_child_release(struct config_item *item) 215 { 216 kfree(to_simple_child(item)); 217 } 218 219 static 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 225 static 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 232 struct simple_children { 233 struct config_group group; 234 }; 235 236 static 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 241 static 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 257 static struct configfs_attribute simple_children_attr_description = { 258 .ca_owner = THIS_MODULE, 259 .ca_name = "description", 260 .ca_mode = S_IRUGO, 261 }; 262 263 static struct configfs_attribute *simple_children_attrs[] = { 264 &simple_children_attr_description, 265 NULL, 266 }; 267 268 static 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 279 static void simple_children_release(struct config_item *item) 280 { 281 kfree(to_simple_children(item)); 282 } 283 284 static 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 */ 293 static struct configfs_group_operations simple_children_group_ops = { 294 .make_item = simple_children_make_item, 295 }; 296 297 static 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 304 static 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 326 static 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 341 static struct configfs_attribute group_children_attr_description = { 342 .ca_owner = THIS_MODULE, 343 .ca_name = "description", 344 .ca_mode = S_IRUGO, 345 }; 346 347 static struct configfs_attribute *group_children_attrs[] = { 348 &group_children_attr_description, 349 NULL, 350 }; 351 352 static 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 363 static 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 */ 371 static struct configfs_group_operations group_children_group_ops = { 372 .make_group = group_children_make_group, 373 }; 374 375 static 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 382 static 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 */ 400 static struct configfs_subsystem *example_subsys[] = { 401 &childless_subsys.subsys, 402 &simple_children_subsys, 403 &group_children_subsys, 404 NULL, 405 }; 406 407 static 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 429 out_unregister: 430 for (i--; i >= 0; i--) 431 configfs_unregister_subsystem(example_subsys[i]); 432 433 return ret; 434 } 435 436 static 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 444 module_init(configfs_example_init); 445 module_exit(configfs_example_exit); 446 MODULE_LICENSE("GPL");