Subversion Repositories shark

Rev

Rev 437 | Rev 456 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
437 giacomo 1
/*
2
 * kobject.c - library routines for handling generic kernel objects
3
 *
4
 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
5
 *
6
 * This file is released under the GPLv2.
7
 *
8
 *
9
 * Please see the file Documentation/kobject.txt for critical information
10
 * about using the kobject interface.
11
 */
12
 
13
#undef DEBUG
14
 
15
#include <ll/stdarg.h>
16
 
17
#include <linuxcomp.h>
18
 
19
#include <linux/kobject.h>
20
#include <linux/string.h>
21
#include <linux/module.h>
22
#include <linux/stat.h>
23
 
24
/**
25
 *      populate_dir - populate directory with attributes.
26
 *      @kobj:  object we're working on.
27
 *
28
 *      Most subsystems have a set of default attributes that
29
 *      are associated with an object that registers with them.
30
 *      This is a helper called during object registration that
31
 *      loops through the default attributes of the subsystem
32
 *      and creates attributes files for them in sysfs.
33
 *
34
 */
35
 
36
static int create_dir(struct kobject * kobj)
37
{
38
        int error = 0;
39
        if (kobject_name(kobj)) {
40
        }
41
        return error;
42
}
43
 
44
 
45
static inline struct kobject * to_kobj(struct list_head * entry)
46
{
47
        return container_of(entry,struct kobject,entry);
48
}
49
 
50
 
51
#ifdef CONFIG_HOTPLUG
52
static int get_kobj_path_length(struct kset *kset, struct kobject *kobj)
53
{
54
        int length = 1;
55
        struct kobject * parent = kobj;
56
 
57
        /* walk up the ancestors until we hit the one pointing to the
58
         * root.
59
         * Add 1 to strlen for leading '/' of each level.
60
         */
61
        do {
62
                length += strlen(kobject_name(parent)) + 1;
63
                parent = parent->parent;
64
        } while (parent);
65
        return length;
66
}
67
 
68
static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path, int length)
69
{
70
        struct kobject * parent;
71
 
72
        --length;
73
        for (parent = kobj; parent; parent = parent->parent) {
74
                int cur = strlen(kobject_name(parent));
75
                /* back up enough to print this name with '/' */
76
                length -= cur;
77
                strncpy (path + length, kobject_name(parent), cur);
78
                *(path + --length) = '/';
79
        }
80
 
81
        pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
82
}
83
 
84
#define BUFFER_SIZE     1024    /* should be enough memory for the env */
85
#define NUM_ENVP        32      /* number of env pointers */
86
static unsigned long sequence_num;
87
static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
88
 
89
static void kset_hotplug(const char *action, struct kset *kset,
90
                         struct kobject *kobj)
91
{
92
        char *argv [3];
93
        char **envp = NULL;
94
        char *buffer = NULL;
95
        char *scratch;
96
        int i = 0;
97
        int retval;
98
        int kobj_path_length;
99
        char *kobj_path = NULL;
100
        char *name = NULL;
101
        unsigned long seq;
102
 
103
        /* If the kset has a filter operation, call it. If it returns
104
           failure, no hotplug event is required. */
105
        if (kset->hotplug_ops->filter) {
106
                if (!kset->hotplug_ops->filter(kset, kobj))
107
                        return;
108
        }
109
 
110
        pr_debug ("%s\n", __FUNCTION__);
111
 
112
        if (!hotplug_path[0])
113
                return;
114
 
115
        envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
116
        if (!envp)
117
                return;
118
        memset (envp, 0x00, NUM_ENVP * sizeof (char *));
119
 
120
        buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
121
        if (!buffer)
122
                goto exit;
123
 
124
        if (kset->hotplug_ops->name)
125
                name = kset->hotplug_ops->name(kset, kobj);
126
        if (name == NULL)
127
                name = kset->kobj.name;
128
 
129
        argv [0] = hotplug_path;
130
        argv [1] = name;
131
        argv [2] = 0;
132
 
133
        /* minimal command environment */
134
        envp [i++] = "HOME=/";
135
        envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
136
 
137
        scratch = buffer;
138
 
139
        envp [i++] = scratch;
140
        scratch += sprintf(scratch, "ACTION=%s", action) + 1;
141
 
142
        spin_lock(&sequence_lock);
143
        seq = sequence_num++;
144
        spin_unlock(&sequence_lock);
145
 
146
        envp [i++] = scratch;
147
        scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1;
148
 
149
        kobj_path_length = get_kobj_path_length (kset, kobj);
150
        kobj_path = kmalloc (kobj_path_length, GFP_KERNEL);
151
        if (!kobj_path)
152
                goto exit;
153
        memset (kobj_path, 0x00, kobj_path_length);
154
        fill_kobj_path (kset, kobj, kobj_path, kobj_path_length);
155
 
156
        envp [i++] = scratch;
157
        scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
158
 
159
        if (kset->hotplug_ops->hotplug) {
160
                /* have the kset specific function add its stuff */
161
                retval = kset->hotplug_ops->hotplug (kset, kobj,
162
                                  &envp[i], NUM_ENVP - i, scratch,
163
                                  BUFFER_SIZE - (scratch - buffer));
164
                if (retval) {
165
                        pr_debug ("%s - hotplug() returned %d\n",
166
                                  __FUNCTION__, retval);
167
                        goto exit;
168
                }
169
        }
170
 
171
        pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],
172
                  envp[0], envp[1], envp[2], envp[3]);
173
        retval = call_usermodehelper (argv[0], argv, envp, 0);
174
        if (retval)
175
                pr_debug ("%s - call_usermodehelper returned %d\n",
176
                          __FUNCTION__, retval);
177
 
178
exit:
179
        kfree(kobj_path);
180
        kfree(buffer);
181
        kfree(envp);
182
        return;
183
}
184
#else
185
static void kset_hotplug(const char *action, struct kset *kset,
186
                         struct kobject *kobj)
187
{
188
        return;
189
}
190
#endif  /* CONFIG_HOTPLUG */
191
 
192
/**
193
 *      kobject_init - initialize object.
194
 *      @kobj:  object in question.
195
 */
196
 
197
void kobject_init(struct kobject * kobj)
198
{
199
        atomic_set(&kobj->refcount,1);
200
        INIT_LIST_HEAD(&kobj->entry);
201
        kobj->kset = kset_get(kobj->kset);
202
}
203
 
204
 
205
/**
206
 *      unlink - remove kobject from kset list.
207
 *      @kobj:  kobject.
208
 *
209
 *      Remove the kobject from the kset list and decrement
210
 *      its parent's refcount.
211
 *      This is separated out, so we can use it in both
212
 *      kobject_del() and kobject_add() on error.
213
 */
214
 
215
static void unlink(struct kobject * kobj)
216
{
217
        if (kobj->kset) {
218
                list_del_init(&kobj->entry);
219
        }
220
        kobject_put(kobj);
221
}
222
 
223
/**
224
 *      kobject_add - add an object to the hierarchy.
225
 *      @kobj:  object.
226
 */
227
 
228
int kobject_add(struct kobject * kobj)
229
{
230
        int error = 0;
231
        struct kobject * parent;
232
        struct kobject * top_kobj;
233
 
234
        if (!(kobj = kobject_get(kobj)))
235
                return -ENOENT;
236
        if (!kobj->k_name)
237
                kobj->k_name = kobj->name;
238
        parent = kobject_get(kobj->parent);
239
 
240
        pr_debug("kobject %s: registering. parent: %s, set: %s\n",
241
                 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
242
                 kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
243
 
244
        if (kobj->kset) {
245
 
246
                if (!parent)
247
                        parent = kobject_get(&kobj->kset->kobj);
248
 
249
                list_add_tail(&kobj->entry,&kobj->kset->list);
250
        }
251
        kobj->parent = parent;
252
 
253
        error = create_dir(kobj);
254
        if (error) {
255
                unlink(kobj);
256
                if (parent)
257
                        kobject_put(parent);
258
        } else {
259
                /* If this kobj does not belong to a kset,
260
                   try to find a parent that does. */
261
                top_kobj = kobj;
262
                if (!top_kobj->kset && top_kobj->parent) {
263
                        do {
264
                                top_kobj = top_kobj->parent;
265
                        } while (!top_kobj->kset && top_kobj->parent);
266
                }
267
 
268
                if (top_kobj->kset && top_kobj->kset->hotplug_ops)
269
                        kset_hotplug("add", top_kobj->kset, kobj);
270
        }
271
        return error;
272
}
273
 
274
 
275
/**
276
 *      kobject_register - initialize and add an object.
277
 *      @kobj:  object in question.
278
 */
279
 
280
int kobject_register(struct kobject * kobj)
281
{
282
        int error = 0;
283
        if (kobj) {
284
                kobject_init(kobj);
285
                error = kobject_add(kobj);
286
                if (error) {
287
                        printk("kobject_register failed for %s (%d)\n",
288
                               kobject_name(kobj),error);
289
                        dump_stack();
290
                }
291
        } else
292
                error = -EINVAL;
293
        return error;
294
}
295
 
296
 
297
/**
298
 *      kobject_set_name - Set the name of an object
299
 *      @kobj:  object.
300
 *      @name:  name.
301
 *
302
 *      If strlen(name) < KOBJ_NAME_LEN, then use a dynamically allocated
303
 *      string that @kobj->k_name points to. Otherwise, use the static
304
 *      @kobj->name array.
305
 */
306
 
307
int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
308
{
309
        int error = 0;
310
        int limit = KOBJ_NAME_LEN;
311
        int need;
312
        va_list args;
313
        char * name;
314
 
315
        va_start(args,fmt);
316
        /*
317
         * First, try the static array
318
         */
455 giacomo 319
        need = vsnprintf26(kobj->name,limit,fmt,args);
320
        if (need < limit)
437 giacomo 321
                name = kobj->name;
322
        else {
323
                /*
324
                 * Need more space? Allocate it and try again
325
                 */
326
                name = kmalloc(need,GFP_KERNEL);
327
                if (!name) {
328
                        error = -ENOMEM;
329
                        goto Done;
330
                }
331
                limit = need;
455 giacomo 332
                need = vsnprintf26(name,limit,fmt,args);
437 giacomo 333
 
334
                /* Still? Give up. */
335
                if (need > limit) {
336
                        kfree(name);
337
                        error = -EFAULT;
338
                        goto Done;
339
                }
340
        }
341
 
342
        /* Free the old name, if necessary. */
343
        if (kobj->k_name && kobj->k_name != kobj->name)
344
                kfree(kobj->k_name);
345
 
346
        /* Now, set the new name */
347
        kobj->k_name = name;
348
 Done:
349
        va_end(args);
350
        return error;
351
}
352
 
353
EXPORT_SYMBOL(kobject_set_name);
354
 
355
 
356
/**
357
 *      kobject_rename - change the name of an object
358
 *      @kobj:  object in question.
359
 *      @new_name: object's new name
360
 */
361
 
362
void kobject_rename(struct kobject * kobj, char *new_name)
363
{
364
        kobj = kobject_get(kobj);
365
        if (!kobj)
366
                return;
367
        kobject_put(kobj);
368
}
369
 
370
/**
371
 *      kobject_del - unlink kobject from hierarchy.
372
 *      @kobj:  object.
373
 */
374
 
375
void kobject_del(struct kobject * kobj)
376
{
377
        struct kobject * top_kobj;
378
 
379
        /* If this kobj does not belong to a kset,
380
           try to find a parent that does. */
381
        top_kobj = kobj;
382
        if (!top_kobj->kset && top_kobj->parent) {
383
                do {
384
                        top_kobj = top_kobj->parent;
385
                } while (!top_kobj->kset && top_kobj->parent);
386
        }
387
 
388
        if (top_kobj->kset && top_kobj->kset->hotplug_ops)
389
                kset_hotplug("remove", top_kobj->kset, kobj);
390
 
391
        unlink(kobj);
392
}
393
 
394
/**
395
 *      kobject_unregister - remove object from hierarchy and decrement refcount.
396
 *      @kobj:  object going away.
397
 */
398
 
399
void kobject_unregister(struct kobject * kobj)
400
{
401
        pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
402
        kobject_del(kobj);
403
        kobject_put(kobj);
404
}
405
 
406
/**
407
 *      kobject_get - increment refcount for object.
408
 *      @kobj:  object.
409
 */
410
 
411
struct kobject * kobject_get(struct kobject * kobj)
412
{
413
        struct kobject * ret = kobj;
414
 
415
        if (kobj) {
416
                WARN_ON(!atomic_read(&kobj->refcount));
417
                atomic_inc(&kobj->refcount);
418
        } else
419
                ret = NULL;
420
        return ret;
421
}
422
 
423
/**
424
 *      kobject_cleanup - free kobject resources.
425
 *      @kobj:  object.
426
 */
427
 
428
void kobject_cleanup(struct kobject * kobj)
429
{
430
        struct kobj_type * t = get_ktype(kobj);
431
        struct kset * s = kobj->kset;
432
        struct kobject * parent = kobj->parent;
433
 
434
        pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
435
        if (kobj->k_name != kobj->name)
436
                kfree(kobj->k_name);
437
        kobj->k_name = NULL;
438
        if (t && t->release)
439
                t->release(kobj);
440
        if (s)
441
                kset_put(s);
442
        if (parent)
443
                kobject_put(parent);
444
}
445
 
446
/**
447
 *      kobject_put - decrement refcount for object.
448
 *      @kobj:  object.
449
 *
450
 *      Decrement the refcount, and if 0, call kobject_cleanup().
451
 */
452
 
453
void kobject_put(struct kobject * kobj)
454
{
455
        if (atomic_dec_and_test(&kobj->refcount))
456
                kobject_cleanup(kobj);
457
}
458
 
459
 
460
/**
461
 *      kset_init - initialize a kset for use
462
 *      @k:     kset
463
 */
464
 
465
void kset_init(struct kset * k)
466
{
467
        kobject_init(&k->kobj);
468
        INIT_LIST_HEAD(&k->list);
469
}
470
 
471
 
472
/**
473
 *      kset_add - add a kset object to the hierarchy.
474
 *      @k:     kset.
475
 *
476
 *      Simply, this adds the kset's embedded kobject to the
477
 *      hierarchy.
478
 *      We also try to make sure that the kset's embedded kobject
479
 *      has a parent before it is added. We only care if the embedded
480
 *      kobject is not part of a kset itself, since kobject_add()
481
 *      assigns a parent in that case.
482
 *      If that is the case, and the kset has a controlling subsystem,
483
 *      then we set the kset's parent to be said subsystem.
484
 */
485
 
486
int kset_add(struct kset * k)
487
{
488
        if (!k->kobj.parent && !k->kobj.kset && k->subsys)
489
                k->kobj.parent = &k->subsys->kset.kobj;
490
 
491
        return kobject_add(&k->kobj);
492
}
493
 
494
 
495
/**
496
 *      kset_register - initialize and add a kset.
497
 *      @k:     kset.
498
 */
499
 
500
int kset_register(struct kset * k)
501
{
502
        kset_init(k);
503
        return kset_add(k);
504
}
505
 
506
 
507
/**
508
 *      kset_unregister - remove a kset.
509
 *      @k:     kset.
510
 */
511
 
512
void kset_unregister(struct kset * k)
513
{
514
        kobject_unregister(&k->kobj);
515
}
516
 
517
 
518
/**
519
 *      kset_find_obj - search for object in kset.
520
 *      @kset:  kset we're looking in.
521
 *      @name:  object's name.
522
 *
523
 *      Lock kset via @kset->subsys, and iterate over @kset->list,
524
 *      looking for a matching kobject. Return object if found.
525
 */
526
 
527
struct kobject * kset_find_obj(struct kset * kset, const char * name)
528
{
529
        struct list_head * entry;
530
        struct kobject * ret = NULL;
531
 
532
        list_for_each(entry,&kset->list) {
533
                struct kobject * k = to_kobj(entry);
534
                if (!strcmp(kobject_name(k),name)) {
535
                        ret = k;
536
                        break;
537
                }
538
        }
539
        return ret;
540
}
541
 
542
 
543
void subsystem_init(struct subsystem * s)
544
{
545
        kset_init(&s->kset);
546
}
547
 
548
/**
549
 *      subsystem_register - register a subsystem.
550
 *      @s:     the subsystem we're registering.
551
 *
552
 *      Once we register the subsystem, we want to make sure that
553
 *      the kset points back to this subsystem for correct usage of
554
 *      the rwsem.
555
 */
556
 
557
int subsystem_register(struct subsystem * s)
558
{
559
        int error;
560
 
561
        subsystem_init(s);
562
        pr_debug("subsystem %s: registering\n",s->kset.kobj.name);
563
 
564
        if (!(error = kset_add(&s->kset))) {
565
                if (!s->kset.subsys)
566
                        s->kset.subsys = s;
567
        }
568
        return error;
569
}
570
 
571
void subsystem_unregister(struct subsystem * s)
572
{
573
        pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
574
        kset_unregister(&s->kset);
575
}
576
 
577
 
578
/**
579
 *      subsystem_create_file - export sysfs attribute file.
580
 *      @s:     subsystem.
581
 *      @a:     subsystem attribute descriptor.
582
 */
583
 
584
int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
585
{
586
        int error = 0;
587
        if (subsys_get(s)) {
588
                subsys_put(s);
589
        }
590
        return error;
591
}
592
 
593
 
594
/**
595
 *      subsystem_remove_file - remove sysfs attribute file.
596
 *      @s:     subsystem.
597
 *      @a:     attribute desciptor.
598
 */
599
 
600
void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
601
{
602
        if (subsys_get(s)) {
603
                subsys_put(s);
604
        }
605
}
606
 
607
 
608
EXPORT_SYMBOL(kobject_init);
609
EXPORT_SYMBOL(kobject_register);
610
EXPORT_SYMBOL(kobject_unregister);
611
EXPORT_SYMBOL(kobject_get);
612
EXPORT_SYMBOL(kobject_put);
613
 
614
EXPORT_SYMBOL(kset_register);
615
EXPORT_SYMBOL(kset_unregister);
616
EXPORT_SYMBOL(kset_find_obj);
617
 
618
EXPORT_SYMBOL(subsystem_init);
619
EXPORT_SYMBOL(subsystem_register);
620
EXPORT_SYMBOL(subsystem_unregister);
621
EXPORT_SYMBOL(subsys_create_file);
622
EXPORT_SYMBOL(subsys_remove_file);