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)), 58 struct childless, subsys) : NULL; 59 } 60 61 static 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 72 static ssize_t childless_storeme_show(struct config_item *item, char *page) 73 { 74 return sprintf(page, "%d\n", to_childless(item)->storeme); 75 } 76 77 static 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 96 static 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 107 CONFIGFS_ATTR_RO(childless_, showme); 108 CONFIGFS_ATTR(childless_, storeme); 109 CONFIGFS_ATTR_RO(childless_, description); 110 111 static struct configfs_attribute *childless_attrs[] = { 112 &childless_attr_showme, 113 &childless_attr_storeme, 114 &childless_attr_description, 115 NULL, 116 }; 117 118 static struct config_item_type childless_type = { 119 .ct_attrs = childless_attrs, 120 .ct_owner = THIS_MODULE, 121 }; 122 123 static 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 146 struct simple_child { 147 struct config_item item; 148 int storeme; 149 }; 150 151 static 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 156 static 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 161 static 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 180 CONFIGFS_ATTR(simple_child_, storeme); 181 182 static struct configfs_attribute *simple_child_attrs[] = { 183 &simple_child_attr_storeme, 184 NULL, 185 }; 186 187 static void simple_child_release(struct config_item *item) 188 { 189 kfree(to_simple_child(item)); 190 } 191 192 static struct configfs_item_operations simple_child_item_ops = { 193 .release = simple_child_release, 194 }; 195 196 static 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 203 struct simple_children { 204 struct config_group group; 205 }; 206 207 static 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 213 static 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 230 static 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 240 CONFIGFS_ATTR_RO(simple_children_, description); 241 242 static struct configfs_attribute *simple_children_attrs[] = { 243 &simple_children_attr_description, 244 NULL, 245 }; 246 247 static void simple_children_release(struct config_item *item) 248 { 249 kfree(to_simple_children(item)); 250 } 251 252 static 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 */ 260 static struct configfs_group_operations simple_children_group_ops = { 261 .make_item = simple_children_make_item, 262 }; 263 264 static 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 271 static 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 293 static 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 309 static 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 319 CONFIGFS_ATTR_RO(group_children_, description); 320 321 static 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 */ 330 static struct configfs_group_operations group_children_group_ops = { 331 .make_group = group_children_make_group, 332 }; 333 334 static 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 340 static 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 */ 358 static struct configfs_subsystem *example_subsys[] = { 359 &childless_subsys.subsys, 360 &simple_children_subsys, 361 &group_children_subsys, 362 NULL, 363 }; 364 365 static 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 387 out_unregister: 388 for (i--; i >= 0; i--) 389 configfs_unregister_subsystem(example_subsys[i]); 390 391 return ret; 392 } 393 394 static 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 402 module_init(configfs_example_init); 403 module_exit(configfs_example_exit); 404 MODULE_LICENSE("GPL"); 405