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