aboutsummaryrefslogtreecommitdiffstats
path: root/samples/configfs/configfs_sample.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 23:04:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 23:04:17 -0500
commit9aa3d651a9199103eb6451aeb0ac1b66a6d770a6 (patch)
tree42cc631c54e1fcbdeedee8e955c4797634a91af7 /samples/configfs/configfs_sample.c
parent5d2eb548b309be34ecf3b91f0b7300a2b9d09b8c (diff)
parent517982229f78b2aebf00a8a337e84e8eeea70b8e (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "This series contains HCH's changes to absorb configfs attribute ->show() + ->store() function pointer usage from it's original tree-wide consumers, into common configfs code. It includes usb-gadget, target w/ drivers, netconsole and ocfs2 changes to realize the improved simplicity, that now renders the original include/target/configfs_macros.h CPP magic for fabric drivers and others, unnecessary and obsolete. And with common code in place, new configfs attributes can be added easier than ever before. Note, there are further improvements in-flight from other folks for v4.5 code in configfs land, plus number of target fixes for post -rc1 code" In the meantime, a new user of the now-removed old configfs API came in through the char/misc tree in commit 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices"). This merge resolution comes from Alexander Shishkin, who updated his stm class tracing abstraction to account for the removal of the old show_attribute and store_attribute methods in commit 517982229f78 ("configfs: remove old API") from this pull. As Alexander says about that patch: "There's no need to keep an extra wrapper structure per item and the awkward show_attribute/store_attribute item ops are no longer needed. This patch converts policy code to the new api, all the while making the code quite a bit smaller and easier on the eyes. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>" That patch was folded into the merge so that the tree should be fully bisectable. * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (23 commits) configfs: remove old API ocfs2/cluster: use per-attribute show and store methods ocfs2/cluster: move locking into attribute store methods netconsole: use per-attribute show and store methods target: use per-attribute show and store methods spear13xx_pcie_gadget: use per-attribute show and store methods dlm: use per-attribute show and store methods usb-gadget/f_serial: use per-attribute show and store methods usb-gadget/f_phonet: use per-attribute show and store methods usb-gadget/f_obex: use per-attribute show and store methods usb-gadget/f_uac2: use per-attribute show and store methods usb-gadget/f_uac1: use per-attribute show and store methods usb-gadget/f_mass_storage: use per-attribute show and store methods usb-gadget/f_sourcesink: use per-attribute show and store methods usb-gadget/f_printer: use per-attribute show and store methods usb-gadget/f_midi: use per-attribute show and store methods usb-gadget/f_loopback: use per-attribute show and store methods usb-gadget/ether: use per-attribute show and store methods usb-gadget/f_acm: use per-attribute show and store methods usb-gadget/f_hid: use per-attribute show and store methods ...
Diffstat (limited to 'samples/configfs/configfs_sample.c')
-rw-r--r--samples/configfs/configfs_sample.c404
1 files changed, 404 insertions, 0 deletions
diff --git a/samples/configfs/configfs_sample.c b/samples/configfs/configfs_sample.c
new file mode 100644
index 000000000000..1ea33119e532
--- /dev/null
+++ b/samples/configfs/configfs_sample.c
@@ -0,0 +1,404 @@
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)),
58 struct childless, subsys) : NULL;
59}
60
61static 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
72static ssize_t childless_storeme_show(struct config_item *item, char *page)
73{
74 return sprintf(page, "%d\n", to_childless(item)->storeme);
75}
76
77static 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
96static 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
107CONFIGFS_ATTR_RO(childless_, showme);
108CONFIGFS_ATTR(childless_, storeme);
109CONFIGFS_ATTR_RO(childless_, description);
110
111static struct configfs_attribute *childless_attrs[] = {
112 &childless_attr_showme,
113 &childless_attr_storeme,
114 &childless_attr_description,
115 NULL,
116};
117
118static struct config_item_type childless_type = {
119 .ct_attrs = childless_attrs,
120 .ct_owner = THIS_MODULE,
121};
122
123static 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
146struct simple_child {
147 struct config_item item;
148 int storeme;
149};
150
151static 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
156static 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
161static 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
180CONFIGFS_ATTR(simple_child_, storeme);
181
182static struct configfs_attribute *simple_child_attrs[] = {
183 &simple_child_attr_storeme,
184 NULL,
185};
186
187static void simple_child_release(struct config_item *item)
188{
189 kfree(to_simple_child(item));
190}
191
192static struct configfs_item_operations simple_child_item_ops = {
193 .release = simple_child_release,
194};
195
196static 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
203struct simple_children {
204 struct config_group group;
205};
206
207static 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
213static 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
230static 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
240CONFIGFS_ATTR_RO(simple_children_, description);
241
242static struct configfs_attribute *simple_children_attrs[] = {
243 &simple_children_attr_description,
244 NULL,
245};
246
247static void simple_children_release(struct config_item *item)
248{
249 kfree(to_simple_children(item));
250}
251
252static 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 */
260static struct configfs_group_operations simple_children_group_ops = {
261 .make_item = simple_children_make_item,
262};
263
264static 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
271static 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
293static 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
309static 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
319CONFIGFS_ATTR_RO(group_children_, description);
320
321static 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 */
330static struct configfs_group_operations group_children_group_ops = {
331 .make_group = group_children_make_group,
332};
333
334static 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
340static 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 */
358static struct configfs_subsystem *example_subsys[] = {
359 &childless_subsys.subsys,
360 &simple_children_subsys,
361 &group_children_subsys,
362 NULL,
363};
364
365static 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
387out_unregister:
388 for (i--; i >= 0; i--)
389 configfs_unregister_subsystem(example_subsys[i]);
390
391 return ret;
392}
393
394static 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
402module_init(configfs_example_init);
403module_exit(configfs_example_exit);
404MODULE_LICENSE("GPL");