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 0 : static void internal_container_klist_get(struct klist_node *n)
32 : {
33 0 : struct internal_container *ic =
34 0 : container_of(n, struct internal_container, node);
35 0 : get_device(&ic->classdev);
36 0 : }
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 0 : attribute_container_classdev_to_container(struct device *classdev)
55 : {
56 0 : struct internal_container *ic =
57 0 : container_of(classdev, struct internal_container, classdev);
58 0 : 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 0 : attribute_container_register(struct attribute_container *cont)
74 : {
75 0 : INIT_LIST_HEAD(&cont->node);
76 0 : klist_init(&cont->containers, internal_container_klist_get,
77 : internal_container_klist_put);
78 :
79 0 : mutex_lock(&attribute_container_mutex);
80 0 : list_add_tail(&cont->node, &attribute_container_list);
81 0 : mutex_unlock(&attribute_container_mutex);
82 :
83 0 : 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 0 : attribute_container_add_device(struct device *dev,
142 : int (*fn)(struct attribute_container *,
143 : struct device *,
144 : struct device *))
145 : {
146 0 : struct attribute_container *cont;
147 :
148 0 : mutex_lock(&attribute_container_mutex);
149 0 : list_for_each_entry(cont, &attribute_container_list, node) {
150 0 : struct internal_container *ic;
151 :
152 0 : if (attribute_container_no_classdevs(cont))
153 0 : continue;
154 :
155 0 : if (!cont->match(cont, dev))
156 0 : continue;
157 :
158 0 : ic = kzalloc(sizeof(*ic), GFP_KERNEL);
159 0 : if (!ic) {
160 0 : dev_err(dev, "failed to allocate class container\n");
161 0 : continue;
162 : }
163 :
164 0 : ic->cont = cont;
165 0 : device_initialize(&ic->classdev);
166 0 : ic->classdev.parent = get_device(dev);
167 0 : ic->classdev.class = cont->class;
168 0 : cont->class->dev_release = attribute_container_release;
169 0 : dev_set_name(&ic->classdev, "%s", dev_name(dev));
170 0 : if (fn)
171 0 : fn(cont, dev, &ic->classdev);
172 : else
173 0 : attribute_container_add_class_device(&ic->classdev);
174 0 : klist_add_tail(&ic->node, &cont->containers);
175 : }
176 0 : mutex_unlock(&attribute_container_mutex);
177 0 : }
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 0 : 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 0 : int ret;
248 0 : struct internal_container *ic, *failed;
249 0 : struct klist_iter iter;
250 :
251 0 : if (attribute_container_no_classdevs(cont))
252 0 : return fn(cont, dev, NULL);
253 :
254 0 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
255 0 : if (dev == ic->classdev.parent) {
256 0 : ret = fn(cont, dev, &ic->classdev);
257 0 : if (ret) {
258 0 : failed = ic;
259 0 : klist_iter_exit(&iter);
260 0 : goto fail;
261 : }
262 : }
263 : }
264 : return 0;
265 :
266 0 : 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 0 : 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 0 : struct attribute_container *cont, *failed = NULL;
306 0 : int ret = 0;
307 :
308 0 : mutex_lock(&attribute_container_mutex);
309 :
310 0 : list_for_each_entry(cont, &attribute_container_list, node) {
311 :
312 0 : if (!cont->match(cont, dev))
313 0 : continue;
314 :
315 0 : ret = do_attribute_container_device_trigger_safe(dev, cont,
316 : fn, undo);
317 0 : if (ret) {
318 : failed = cont;
319 : break;
320 : }
321 : }
322 :
323 0 : 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 0 : mutex_unlock(&attribute_container_mutex);
338 0 : 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 0 : attribute_container_device_trigger(struct device *dev,
354 : int (*fn)(struct attribute_container *,
355 : struct device *,
356 : struct device *))
357 : {
358 0 : struct attribute_container *cont;
359 :
360 0 : mutex_lock(&attribute_container_mutex);
361 0 : list_for_each_entry(cont, &attribute_container_list, node) {
362 0 : struct internal_container *ic;
363 0 : struct klist_iter iter;
364 :
365 0 : if (!cont->match(cont, dev))
366 0 : continue;
367 :
368 0 : if (attribute_container_no_classdevs(cont)) {
369 0 : fn(cont, dev, NULL);
370 0 : continue;
371 : }
372 :
373 0 : klist_for_each_entry(ic, &cont->containers, node, &iter) {
374 0 : if (dev == ic->classdev.parent)
375 0 : fn(cont, dev, &ic->classdev);
376 : }
377 : }
378 0 : mutex_unlock(&attribute_container_mutex);
379 0 : }
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 0 : attribute_container_add_attrs(struct device *classdev)
418 : {
419 0 : struct attribute_container *cont =
420 0 : attribute_container_classdev_to_container(classdev);
421 0 : struct device_attribute **attrs = cont->attrs;
422 0 : int i, error;
423 :
424 0 : BUG_ON(attrs && cont->grp);
425 :
426 0 : if (!attrs && !cont->grp)
427 : return 0;
428 :
429 0 : if (cont->grp)
430 0 : return sysfs_create_group(&classdev->kobj, cont->grp);
431 :
432 0 : for (i = 0; attrs[i]; i++) {
433 0 : sysfs_attr_init(&attrs[i]->attr);
434 0 : error = device_create_file(classdev, attrs[i]);
435 0 : 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 0 : attribute_container_add_class_device(struct device *classdev)
453 : {
454 0 : int error = device_add(classdev);
455 :
456 0 : if (error)
457 : return error;
458 0 : 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 0 : 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);
|