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