Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * attribute_container.c - implementation of a simple container for classes
4 : : *
5 : : * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
6 : : *
7 : : * The basic idea here is to enable a device to be attached to an
8 : : * aritrary numer of classes without having to allocate storage for them.
9 : : * Instead, the contained classes select the devices they need to attach
10 : : * to via a matching function.
11 : : */
12 : :
13 : : #include <linux/attribute_container.h>
14 : : #include <linux/device.h>
15 : : #include <linux/kernel.h>
16 : : #include <linux/slab.h>
17 : : #include <linux/list.h>
18 : : #include <linux/module.h>
19 : : #include <linux/mutex.h>
20 : :
21 : : #include "base.h"
22 : :
23 : : /* This is a private structure used to tie the classdev and the
24 : : * container .. it should never be visible outside this file */
25 : : struct internal_container {
26 : : struct klist_node node;
27 : : struct attribute_container *cont;
28 : : struct device classdev;
29 : : };
30 : :
31 : 88 : static void internal_container_klist_get(struct klist_node *n)
32 : : {
33 : 88 : struct internal_container *ic =
34 : 88 : container_of(n, struct internal_container, node);
35 : 88 : get_device(&ic->classdev);
36 : 88 : }
37 : :
38 : 0 : static void internal_container_klist_put(struct klist_node *n)
39 : : {
40 : 0 : struct internal_container *ic =
41 : 0 : container_of(n, struct internal_container, node);
42 : 0 : put_device(&ic->classdev);
43 : 0 : }
44 : :
45 : :
46 : : /**
47 : : * attribute_container_classdev_to_container - given a classdev, return the container
48 : : *
49 : : * @classdev: the class device created by attribute_container_add_device.
50 : : *
51 : : * Returns the container associated with this classdev.
52 : : */
53 : : struct attribute_container *
54 : 88 : attribute_container_classdev_to_container(struct device *classdev)
55 : : {
56 : 88 : struct internal_container *ic =
57 : 88 : container_of(classdev, struct internal_container, classdev);
58 : 88 : return ic->cont;
59 : : }
60 : : EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container);
61 : :
62 : : static LIST_HEAD(attribute_container_list);
63 : :
64 : : static DEFINE_MUTEX(attribute_container_mutex);
65 : :
66 : : /**
67 : : * attribute_container_register - register an attribute container
68 : : *
69 : : * @cont: The container to register. This must be allocated by the
70 : : * callee and should also be zeroed by it.
71 : : */
72 : : int
73 : 44 : attribute_container_register(struct attribute_container *cont)
74 : : {
75 : 44 : INIT_LIST_HEAD(&cont->node);
76 : 44 : klist_init(&cont->containers, internal_container_klist_get,
77 : : internal_container_klist_put);
78 : :
79 : 44 : mutex_lock(&attribute_container_mutex);
80 : 44 : list_add_tail(&cont->node, &attribute_container_list);
81 : 44 : mutex_unlock(&attribute_container_mutex);
82 : :
83 : 44 : return 0;
84 : : }
85 : : EXPORT_SYMBOL_GPL(attribute_container_register);
86 : :
87 : : /**
88 : : * attribute_container_unregister - remove a container registration
89 : : *
90 : : * @cont: previously registered container to remove
91 : : */
92 : : int
93 : 0 : attribute_container_unregister(struct attribute_container *cont)
94 : : {
95 : 0 : int retval = -EBUSY;
96 : :
97 : 0 : mutex_lock(&attribute_container_mutex);
98 : 0 : spin_lock(&cont->containers.k_lock);
99 [ # # ]: 0 : if (!list_empty(&cont->containers.k_list))
100 : 0 : goto out;
101 : 0 : retval = 0;
102 : 0 : list_del(&cont->node);
103 : 0 : out:
104 : 0 : spin_unlock(&cont->containers.k_lock);
105 : 0 : mutex_unlock(&attribute_container_mutex);
106 : 0 : return retval;
107 : :
108 : : }
109 : : EXPORT_SYMBOL_GPL(attribute_container_unregister);
110 : :
111 : : /* private function used as class release */
112 : 0 : static void attribute_container_release(struct device *classdev)
113 : : {
114 : 0 : struct internal_container *ic
115 : 0 : = container_of(classdev, struct internal_container, classdev);
116 : 0 : struct device *dev = classdev->parent;
117 : :
118 : 0 : kfree(ic);
119 : 0 : put_device(dev);
120 : 0 : }
121 : :
122 : : /**
123 : : * attribute_container_add_device - see if any container is interested in dev
124 : : *
125 : : * @dev: device to add attributes to
126 : : * @fn: function to trigger addition of class device.
127 : : *
128 : : * This function allocates storage for the class device(s) to be
129 : : * attached to dev (one for each matching attribute_container). If no
130 : : * fn is provided, the code will simply register the class device via
131 : : * device_add. If a function is provided, it is expected to add
132 : : * the class device at the appropriate time. One of the things that
133 : : * might be necessary is to allocate and initialise the classdev and
134 : : * then add it a later time. To do this, call this routine for
135 : : * allocation and initialisation and then use
136 : : * attribute_container_device_trigger() to call device_add() on
137 : : * it. Note: after this, the class device contains a reference to dev
138 : : * which is not relinquished until the release of the classdev.
139 : : */
140 : : void
141 : 176 : attribute_container_add_device(struct device *dev,
142 : : int (*fn)(struct attribute_container *,
143 : : struct device *,
144 : : struct device *))
145 : : {
146 : 176 : struct attribute_container *cont;
147 : :
148 : 176 : mutex_lock(&attribute_container_mutex);
149 [ + + ]: 880 : list_for_each_entry(cont, &attribute_container_list, node) {
150 : 704 : struct internal_container *ic;
151 : :
152 [ + + ]: 704 : if (attribute_container_no_classdevs(cont))
153 : 176 : continue;
154 : :
155 [ + + ]: 528 : if (!cont->match(cont, dev))
156 : 440 : continue;
157 : :
158 : 88 : ic = kzalloc(sizeof(*ic), GFP_KERNEL);
159 [ - + ]: 88 : if (!ic) {
160 : 0 : dev_err(dev, "failed to allocate class container\n");
161 : 0 : continue;
162 : : }
163 : :
164 : 88 : ic->cont = cont;
165 : 88 : device_initialize(&ic->classdev);
166 : 88 : ic->classdev.parent = get_device(dev);
167 : 88 : ic->classdev.class = cont->class;
168 : 88 : cont->class->dev_release = attribute_container_release;
169 [ + - ]: 176 : dev_set_name(&ic->classdev, "%s", dev_name(dev));
170 [ + - ]: 88 : if (fn)
171 : 88 : fn(cont, dev, &ic->classdev);
172 : : else
173 : 0 : attribute_container_add_class_device(&ic->classdev);
174 : 88 : klist_add_tail(&ic->node, &cont->containers);
175 : : }
176 : 176 : mutex_unlock(&attribute_container_mutex);
177 : 176 : }
178 : :
179 : : /* FIXME: can't break out of this unless klist_iter_exit is also
180 : : * called before doing the break
181 : : */
182 : : #define klist_for_each_entry(pos, head, member, iter) \
183 : : for (klist_iter_init(head, iter); (pos = ({ \
184 : : struct klist_node *n = klist_next(iter); \
185 : : n ? container_of(n, typeof(*pos), member) : \
186 : : ({ klist_iter_exit(iter) ; NULL; }); \
187 : : })) != NULL;)
188 : :
189 : :
190 : : /**
191 : : * attribute_container_remove_device - make device eligible for removal.
192 : : *
193 : : * @dev: The generic device
194 : : * @fn: A function to call to remove the device
195 : : *
196 : : * This routine triggers device removal. If fn is NULL, then it is
197 : : * simply done via device_unregister (note that if something
198 : : * still has a reference to the classdev, then the memory occupied
199 : : * will not be freed until the classdev is released). If you want a
200 : : * two phase release: remove from visibility and then delete the
201 : : * device, then you should use this routine with a fn that calls
202 : : * device_del() and then use attribute_container_device_trigger()
203 : : * to do the final put on the classdev.
204 : : */
205 : : void
206 : 0 : attribute_container_remove_device(struct device *dev,
207 : : void (*fn)(struct attribute_container *,
208 : : struct device *,
209 : : struct device *))
210 : : {
211 : 0 : struct attribute_container *cont;
212 : :
213 : 0 : mutex_lock(&attribute_container_mutex);
214 [ # # ]: 0 : list_for_each_entry(cont, &attribute_container_list, node) {
215 : 0 : struct internal_container *ic;
216 : 0 : struct klist_iter iter;
217 : :
218 [ # # ]: 0 : if (attribute_container_no_classdevs(cont))
219 : 0 : continue;
220 : :
221 [ # # ]: 0 : if (!cont->match(cont, dev))
222 : 0 : continue;
223 : :
224 [ # # ]: 0 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
225 [ # # ]: 0 : if (dev != ic->classdev.parent)
226 : 0 : continue;
227 : 0 : klist_del(&ic->node);
228 [ # # ]: 0 : if (fn)
229 : 0 : fn(cont, dev, &ic->classdev);
230 : : else {
231 : 0 : attribute_container_remove_attrs(&ic->classdev);
232 : 0 : device_unregister(&ic->classdev);
233 : : }
234 : : }
235 : : }
236 : 0 : mutex_unlock(&attribute_container_mutex);
237 : 0 : }
238 : :
239 : : static int
240 : 88 : do_attribute_container_device_trigger_safe(struct device *dev,
241 : : struct attribute_container *cont,
242 : : int (*fn)(struct attribute_container *,
243 : : struct device *, struct device *),
244 : : int (*undo)(struct attribute_container *,
245 : : struct device *, struct device *))
246 : : {
247 : 88 : int ret;
248 : 88 : struct internal_container *ic, *failed;
249 : 88 : struct klist_iter iter;
250 : :
251 [ - + ]: 88 : if (attribute_container_no_classdevs(cont))
252 : 0 : return fn(cont, dev, NULL);
253 : :
254 [ + + ]: 352 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
255 [ + + ]: 176 : if (dev == ic->classdev.parent) {
256 : 88 : ret = fn(cont, dev, &ic->classdev);
257 [ - + ]: 88 : if (ret) {
258 : 0 : failed = ic;
259 : 0 : klist_iter_exit(&iter);
260 : 0 : goto fail;
261 : : }
262 : : }
263 : : }
264 : : return 0;
265 : :
266 : : fail:
267 [ # # ]: 0 : if (!undo)
268 : : return ret;
269 : :
270 : : /* Attempt to undo the work partially done. */
271 [ # # ]: 0 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
272 [ # # ]: 0 : if (ic == failed) {
273 : 0 : klist_iter_exit(&iter);
274 : 0 : break;
275 : : }
276 [ # # ]: 0 : if (dev == ic->classdev.parent)
277 : 0 : undo(cont, dev, &ic->classdev);
278 : : }
279 : : return ret;
280 : : }
281 : :
282 : : /**
283 : : * attribute_container_device_trigger_safe - execute a trigger for each
284 : : * matching classdev or fail all of them.
285 : : *
286 : : * @dev: The generic device to run the trigger for
287 : : * @fn the function to execute for each classdev.
288 : : * @undo A function to undo the work previously done in case of error
289 : : *
290 : : * This function is a safe version of
291 : : * attribute_container_device_trigger. It stops on the first error and
292 : : * undo the partial work that has been done, on previous classdev. It
293 : : * is guaranteed that either they all succeeded, or none of them
294 : : * succeeded.
295 : : */
296 : : int
297 : 176 : attribute_container_device_trigger_safe(struct device *dev,
298 : : int (*fn)(struct attribute_container *,
299 : : struct device *,
300 : : struct device *),
301 : : int (*undo)(struct attribute_container *,
302 : : struct device *,
303 : : struct device *))
304 : : {
305 : 176 : struct attribute_container *cont, *failed = NULL;
306 : 176 : int ret = 0;
307 : :
308 : 176 : mutex_lock(&attribute_container_mutex);
309 : :
310 [ + + ]: 880 : list_for_each_entry(cont, &attribute_container_list, node) {
311 : :
312 [ + + ]: 704 : if (!cont->match(cont, dev))
313 : 616 : continue;
314 : :
315 : 88 : ret = do_attribute_container_device_trigger_safe(dev, cont,
316 : : fn, undo);
317 [ + - ]: 88 : if (ret) {
318 : : failed = cont;
319 : : break;
320 : : }
321 : : }
322 : :
323 [ - + - - : 176 : if (ret && !WARN_ON(!undo)) {
- - ]
324 [ # # ]: 0 : list_for_each_entry(cont, &attribute_container_list, node) {
325 : :
326 [ # # ]: 0 : if (failed == cont)
327 : : break;
328 : :
329 [ # # ]: 0 : if (!cont->match(cont, dev))
330 : 0 : continue;
331 : :
332 : 0 : do_attribute_container_device_trigger_safe(dev, cont,
333 : : undo, NULL);
334 : : }
335 : : }
336 : :
337 : 176 : mutex_unlock(&attribute_container_mutex);
338 : 176 : return ret;
339 : :
340 : : }
341 : :
342 : : /**
343 : : * attribute_container_device_trigger - execute a trigger for each matching classdev
344 : : *
345 : : * @dev: The generic device to run the trigger for
346 : : * @fn the function to execute for each classdev.
347 : : *
348 : : * This function is for executing a trigger when you need to know both
349 : : * the container and the classdev. If you only care about the
350 : : * container, then use attribute_container_trigger() instead.
351 : : */
352 : : void
353 : 176 : attribute_container_device_trigger(struct device *dev,
354 : : int (*fn)(struct attribute_container *,
355 : : struct device *,
356 : : struct device *))
357 : : {
358 : 176 : struct attribute_container *cont;
359 : :
360 : 176 : mutex_lock(&attribute_container_mutex);
361 [ + + ]: 880 : list_for_each_entry(cont, &attribute_container_list, node) {
362 : 704 : struct internal_container *ic;
363 : 704 : struct klist_iter iter;
364 : :
365 [ + + ]: 704 : if (!cont->match(cont, dev))
366 : 616 : continue;
367 : :
368 [ - + ]: 88 : if (attribute_container_no_classdevs(cont)) {
369 : 0 : fn(cont, dev, NULL);
370 : 0 : continue;
371 : : }
372 : :
373 [ + + ]: 352 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
374 [ + + ]: 176 : if (dev == ic->classdev.parent)
375 : 88 : fn(cont, dev, &ic->classdev);
376 : : }
377 : : }
378 : 176 : mutex_unlock(&attribute_container_mutex);
379 : 176 : }
380 : :
381 : : /**
382 : : * attribute_container_trigger - trigger a function for each matching container
383 : : *
384 : : * @dev: The generic device to activate the trigger for
385 : : * @fn: the function to trigger
386 : : *
387 : : * This routine triggers a function that only needs to know the
388 : : * matching containers (not the classdev) associated with a device.
389 : : * It is more lightweight than attribute_container_device_trigger, so
390 : : * should be used in preference unless the triggering function
391 : : * actually needs to know the classdev.
392 : : */
393 : : void
394 : 0 : attribute_container_trigger(struct device *dev,
395 : : int (*fn)(struct attribute_container *,
396 : : struct device *))
397 : : {
398 : 0 : struct attribute_container *cont;
399 : :
400 : 0 : mutex_lock(&attribute_container_mutex);
401 [ # # ]: 0 : list_for_each_entry(cont, &attribute_container_list, node) {
402 [ # # ]: 0 : if (cont->match(cont, dev))
403 : 0 : fn(cont, dev);
404 : : }
405 : 0 : mutex_unlock(&attribute_container_mutex);
406 : 0 : }
407 : :
408 : : /**
409 : : * attribute_container_add_attrs - add attributes
410 : : *
411 : : * @classdev: The class device
412 : : *
413 : : * This simply creates all the class device sysfs files from the
414 : : * attributes listed in the container
415 : : */
416 : : int
417 : 88 : attribute_container_add_attrs(struct device *classdev)
418 : : {
419 : 88 : struct attribute_container *cont =
420 : : attribute_container_classdev_to_container(classdev);
421 : 88 : struct device_attribute **attrs = cont->attrs;
422 : 88 : int i, error;
423 : :
424 [ + - - + ]: 88 : BUG_ON(attrs && cont->grp);
425 : :
426 [ - + - - ]: 88 : if (!attrs && !cont->grp)
427 : : return 0;
428 : :
429 [ - + ]: 88 : if (cont->grp)
430 : 0 : return sysfs_create_group(&classdev->kobj, cont->grp);
431 : :
432 [ + + ]: 616 : for (i = 0; attrs[i]; i++) {
433 : 528 : sysfs_attr_init(&attrs[i]->attr);
434 : 528 : error = device_create_file(classdev, attrs[i]);
435 [ - + ]: 528 : if (error)
436 : 0 : return error;
437 : : }
438 : :
439 : : return 0;
440 : : }
441 : :
442 : : /**
443 : : * attribute_container_add_class_device - same function as device_add
444 : : *
445 : : * @classdev: the class device to add
446 : : *
447 : : * This performs essentially the same function as device_add except for
448 : : * attribute containers, namely add the classdev to the system and then
449 : : * create the attribute files
450 : : */
451 : : int
452 : 88 : attribute_container_add_class_device(struct device *classdev)
453 : : {
454 : 88 : int error = device_add(classdev);
455 : :
456 [ + - ]: 88 : if (error)
457 : : return error;
458 : 88 : return attribute_container_add_attrs(classdev);
459 : : }
460 : :
461 : : /**
462 : : * attribute_container_add_class_device_adapter - simple adapter for triggers
463 : : *
464 : : * This function is identical to attribute_container_add_class_device except
465 : : * that it is designed to be called from the triggers
466 : : */
467 : : int
468 : 0 : attribute_container_add_class_device_adapter(struct attribute_container *cont,
469 : : struct device *dev,
470 : : struct device *classdev)
471 : : {
472 : 0 : return attribute_container_add_class_device(classdev);
473 : : }
474 : :
475 : : /**
476 : : * attribute_container_remove_attrs - remove any attribute files
477 : : *
478 : : * @classdev: The class device to remove the files from
479 : : *
480 : : */
481 : : void
482 : 0 : attribute_container_remove_attrs(struct device *classdev)
483 : : {
484 : 0 : struct attribute_container *cont =
485 : : attribute_container_classdev_to_container(classdev);
486 : 0 : struct device_attribute **attrs = cont->attrs;
487 : 0 : int i;
488 : :
489 [ # # # # ]: 0 : if (!attrs && !cont->grp)
490 : : return;
491 : :
492 [ # # ]: 0 : if (cont->grp) {
493 : 0 : sysfs_remove_group(&classdev->kobj, cont->grp);
494 : 0 : return ;
495 : : }
496 : :
497 [ # # ]: 0 : for (i = 0; attrs[i]; i++)
498 : 0 : device_remove_file(classdev, attrs[i]);
499 : : }
500 : :
501 : : /**
502 : : * attribute_container_class_device_del - equivalent of class_device_del
503 : : *
504 : : * @classdev: the class device
505 : : *
506 : : * This function simply removes all the attribute files and then calls
507 : : * device_del.
508 : : */
509 : : void
510 : 0 : attribute_container_class_device_del(struct device *classdev)
511 : : {
512 : 0 : attribute_container_remove_attrs(classdev);
513 : 0 : device_del(classdev);
514 : 0 : }
515 : :
516 : : /**
517 : : * attribute_container_find_class_device - find the corresponding class_device
518 : : *
519 : : * @cont: the container
520 : : * @dev: the generic device
521 : : *
522 : : * Looks up the device in the container's list of class devices and returns
523 : : * the corresponding class_device.
524 : : */
525 : : struct device *
526 : 0 : attribute_container_find_class_device(struct attribute_container *cont,
527 : : struct device *dev)
528 : : {
529 : 0 : struct device *cdev = NULL;
530 : 0 : struct internal_container *ic;
531 : 0 : struct klist_iter iter;
532 : :
533 [ # # ]: 0 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
534 [ # # ]: 0 : if (ic->classdev.parent == dev) {
535 : 0 : cdev = &ic->classdev;
536 : : /* FIXME: must exit iterator then break */
537 : 0 : klist_iter_exit(&iter);
538 : 0 : break;
539 : : }
540 : : }
541 : :
542 : 0 : return cdev;
543 : : }
544 : : EXPORT_SYMBOL_GPL(attribute_container_find_class_device);
|