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