1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/kobject.h>
16#include <linux/string.h>
17#include <linux/module.h>
18#include <linux/stat.h>
19#include <linux/slab.h>
20
21
22
23
24
25
26
27
28
29
30
31
32
33static int populate_dir(struct kobject * kobj)
34{
35 struct kobj_type * t = get_ktype(kobj);
36 struct attribute * attr;
37 int error = 0;
38 int i;
39
40 if (t && t->default_attrs) {
41 for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
42 if ((error = sysfs_create_file(kobj,attr)))
43 break;
44 }
45 }
46 return error;
47}
48
49static int create_dir(struct kobject * kobj)
50{
51 int error = 0;
52 if (kobject_name(kobj)) {
53 error = sysfs_create_dir(kobj);
54 if (!error) {
55 if ((error = populate_dir(kobj)))
56 sysfs_remove_dir(kobj);
57 }
58 }
59 return error;
60}
61
62static inline struct kobject * to_kobj(struct list_head * entry)
63{
64 return container_of(entry,struct kobject,entry);
65}
66
67static int get_kobj_path_length(struct kobject *kobj)
68{
69 int length = 1;
70 struct kobject * parent = kobj;
71
72
73
74
75
76 do {
77 if (kobject_name(parent) == NULL)
78 return 0;
79 length += strlen(kobject_name(parent)) + 1;
80 parent = parent->parent;
81 } while (parent);
82 return length;
83}
84
85static void fill_kobj_path(struct kobject *kobj, char *path, int length)
86{
87 struct kobject * parent;
88
89 --length;
90 for (parent = kobj; parent; parent = parent->parent) {
91 int cur = strlen(kobject_name(parent));
92
93 length -= cur;
94 strncpy (path + length, kobject_name(parent), cur);
95 *(path + --length) = '/';
96 }
97
98 pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
99}
100
101
102
103
104
105
106
107
108
109char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
110{
111 char *path;
112 int len;
113
114 len = get_kobj_path_length(kobj);
115 if (len == 0)
116 return NULL;
117 path = kzalloc(len, gfp_mask);
118 if (!path)
119 return NULL;
120 fill_kobj_path(kobj, path, len);
121
122 return path;
123}
124EXPORT_SYMBOL_GPL(kobject_get_path);
125
126
127
128
129
130void kobject_init(struct kobject * kobj)
131{
132 if (!kobj)
133 return;
134 kref_init(&kobj->kref);
135 INIT_LIST_HEAD(&kobj->entry);
136 kobj->kset = kset_get(kobj->kset);
137}
138
139
140
141
142
143
144
145
146
147
148
149
150static void unlink(struct kobject * kobj)
151{
152 if (kobj->kset) {
153 spin_lock(&kobj->kset->list_lock);
154 list_del_init(&kobj->entry);
155 spin_unlock(&kobj->kset->list_lock);
156 }
157 kobject_put(kobj);
158}
159
160
161
162
163
164
165int kobject_add(struct kobject * kobj)
166{
167 int error = 0;
168 struct kobject * parent;
169
170 if (!(kobj = kobject_get(kobj)))
171 return -ENOENT;
172 if (!kobj->k_name)
173 kobject_set_name(kobj, "NO_NAME");
174 if (!*kobj->k_name) {
175 pr_debug("kobject attempted to be registered with no name!\n");
176 WARN_ON(1);
177 kobject_put(kobj);
178 return -EINVAL;
179 }
180 parent = kobject_get(kobj->parent);
181
182 pr_debug("kobject %s: registering. parent: %s, set: %s\n",
183 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
184 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
185
186 if (kobj->kset) {
187 spin_lock(&kobj->kset->list_lock);
188
189 if (!parent)
190 parent = kobject_get(&kobj->kset->kobj);
191
192 list_add_tail(&kobj->entry,&kobj->kset->list);
193 spin_unlock(&kobj->kset->list_lock);
194 kobj->parent = parent;
195 }
196
197 error = create_dir(kobj);
198 if (error) {
199
200 unlink(kobj);
201 kobject_put(parent);
202
203
204 if (error == -EEXIST)
205 printk(KERN_ERR "kobject_add failed for %s with "
206 "-EEXIST, don't try to register things with "
207 "the same name in the same directory.\n",
208 kobject_name(kobj));
209 else
210 printk(KERN_ERR "kobject_add failed for %s (%d)\n",
211 kobject_name(kobj), error);
212 dump_stack();
213 }
214
215 return error;
216}
217
218
219
220
221
222
223int kobject_register(struct kobject * kobj)
224{
225 int error = -EINVAL;
226 if (kobj) {
227 kobject_init(kobj);
228 error = kobject_add(kobj);
229 if (!error)
230 kobject_uevent(kobj, KOBJ_ADD);
231 }
232 return error;
233}
234
235
236
237
238
239
240
241
242
243
244
245int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
246{
247 int error = 0;
248 int limit;
249 int need;
250 va_list args;
251 char *name;
252
253
254 name = kmalloc(1024, GFP_KERNEL);
255 if (!name) {
256 error = -ENOMEM;
257 goto done;
258 }
259 va_start(args, fmt);
260 need = vsnprintf(name, 1024, fmt, args);
261 va_end(args);
262 kfree(name);
263
264
265 limit = need + 1;
266 name = kmalloc(limit, GFP_KERNEL);
267 if (!name) {
268 error = -ENOMEM;
269 goto done;
270 }
271 va_start(args, fmt);
272 need = vsnprintf(name, limit, fmt, args);
273 va_end(args);
274
275
276 if (need >= limit) {
277 kfree(name);
278 error = -EFAULT;
279 goto done;
280 }
281
282
283 kfree(kobj->k_name);
284
285
286 kobj->k_name = name;
287done:
288 return error;
289}
290EXPORT_SYMBOL(kobject_set_name);
291
292
293
294
295
296
297
298int kobject_rename(struct kobject * kobj, const char *new_name)
299{
300 int error = 0;
301 const char *devpath = NULL;
302 char *devpath_string = NULL;
303 char *envp[2];
304
305 kobj = kobject_get(kobj);
306 if (!kobj)
307 return -EINVAL;
308 if (!kobj->parent)
309 return -EINVAL;
310
311
312 if (kobj->kset) {
313 struct kobject *temp_kobj;
314 temp_kobj = kset_find_obj(kobj->kset, new_name);
315 if (temp_kobj) {
316 printk(KERN_WARNING "kobject '%s' cannot be renamed "
317 "to '%s' as '%s' is already in existence.\n",
318 kobject_name(kobj), new_name, new_name);
319 kobject_put(temp_kobj);
320 return -EINVAL;
321 }
322 }
323
324 devpath = kobject_get_path(kobj, GFP_KERNEL);
325 if (!devpath) {
326 error = -ENOMEM;
327 goto out;
328 }
329 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
330 if (!devpath_string) {
331 error = -ENOMEM;
332 goto out;
333 }
334 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
335 envp[0] = devpath_string;
336 envp[1] = NULL;
337
338
339
340 error = sysfs_rename_dir(kobj, new_name);
341
342
343
344
345 if (!error)
346 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
347
348out:
349 kfree(devpath_string);
350 kfree(devpath);
351 kobject_put(kobj);
352
353 return error;
354}
355
356
357
358
359
360
361
362int kobject_move(struct kobject *kobj, struct kobject *new_parent)
363{
364 int error;
365 struct kobject *old_parent;
366 const char *devpath = NULL;
367 char *devpath_string = NULL;
368 char *envp[2];
369
370 kobj = kobject_get(kobj);
371 if (!kobj)
372 return -EINVAL;
373 new_parent = kobject_get(new_parent);
374 if (!new_parent) {
375 if (kobj->kset)
376 new_parent = kobject_get(&kobj->kset->kobj);
377 }
378
379 devpath = kobject_get_path(kobj, GFP_KERNEL);
380 if (!devpath) {
381 error = -ENOMEM;
382 goto out;
383 }
384 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
385 if (!devpath_string) {
386 error = -ENOMEM;
387 goto out;
388 }
389 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
390 envp[0] = devpath_string;
391 envp[1] = NULL;
392 error = sysfs_move_dir(kobj, new_parent);
393 if (error)
394 goto out;
395 old_parent = kobj->parent;
396 kobj->parent = new_parent;
397 new_parent = NULL;
398 kobject_put(old_parent);
399 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
400out:
401 kobject_put(new_parent);
402 kobject_put(kobj);
403 kfree(devpath_string);
404 kfree(devpath);
405 return error;
406}
407
408
409
410
411
412
413void kobject_del(struct kobject * kobj)
414{
415 if (!kobj)
416 return;
417 sysfs_remove_dir(kobj);
418 unlink(kobj);
419}
420
421
422
423
424
425
426void kobject_unregister(struct kobject * kobj)
427{
428 if (!kobj)
429 return;
430 pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
431 kobject_uevent(kobj, KOBJ_REMOVE);
432 kobject_del(kobj);
433 kobject_put(kobj);
434}
435
436
437
438
439
440
441struct kobject * kobject_get(struct kobject * kobj)
442{
443 if (kobj)
444 kref_get(&kobj->kref);
445 return kobj;
446}
447
448
449
450
451
452
453void kobject_cleanup(struct kobject * kobj)
454{
455 struct kobj_type * t = get_ktype(kobj);
456 struct kset * s = kobj->kset;
457 struct kobject * parent = kobj->parent;
458 const char *name = kobj->k_name;
459
460 pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
461 if (t && t->release) {
462 t->release(kobj);
463
464
465
466 kfree(name);
467 }
468 if (s)
469 kset_put(s);
470 kobject_put(parent);
471}
472
473static void kobject_release(struct kref *kref)
474{
475 kobject_cleanup(container_of(kref, struct kobject, kref));
476}
477
478
479
480
481
482
483
484void kobject_put(struct kobject * kobj)
485{
486 if (kobj)
487 kref_put(&kobj->kref, kobject_release);
488}
489
490
491static void dir_release(struct kobject *kobj)
492{
493 kfree(kobj);
494}
495
496static struct kobj_type dir_ktype = {
497 .release = dir_release,
498 .sysfs_ops = NULL,
499 .default_attrs = NULL,
500};
501
502
503
504
505
506
507
508
509
510struct kobject *kobject_kset_add_dir(struct kset *kset,
511 struct kobject *parent, const char *name)
512{
513 struct kobject *k;
514 int ret;
515
516 if (!parent)
517 return NULL;
518
519 k = kzalloc(sizeof(*k), GFP_KERNEL);
520 if (!k)
521 return NULL;
522
523 k->kset = kset;
524 k->parent = parent;
525 k->ktype = &dir_ktype;
526 kobject_set_name(k, name);
527 ret = kobject_register(k);
528 if (ret < 0) {
529 printk(KERN_WARNING "%s: kobject_register error: %d\n",
530 __func__, ret);
531 kobject_del(k);
532 return NULL;
533 }
534
535 return k;
536}
537
538
539
540
541
542
543
544
545struct kobject *kobject_add_dir(struct kobject *parent, const char *name)
546{
547 return kobject_kset_add_dir(NULL, parent, name);
548}
549
550
551
552
553
554
555void kset_init(struct kset * k)
556{
557 kobject_init(&k->kobj);
558 INIT_LIST_HEAD(&k->list);
559 spin_lock_init(&k->list_lock);
560}
561
562
563
564
565
566
567
568int kset_add(struct kset * k)
569{
570 return kobject_add(&k->kobj);
571}
572
573
574
575
576
577
578
579int kset_register(struct kset * k)
580{
581 int err;
582
583 if (!k)
584 return -EINVAL;
585
586 kset_init(k);
587 err = kset_add(k);
588 if (err)
589 return err;
590 kobject_uevent(&k->kobj, KOBJ_ADD);
591 return 0;
592}
593
594
595
596
597
598
599
600void kset_unregister(struct kset * k)
601{
602 if (!k)
603 return;
604 kobject_unregister(&k->kobj);
605}
606
607
608
609
610
611
612
613
614
615
616
617
618struct kobject * kset_find_obj(struct kset * kset, const char * name)
619{
620 struct list_head * entry;
621 struct kobject * ret = NULL;
622
623 spin_lock(&kset->list_lock);
624 list_for_each(entry,&kset->list) {
625 struct kobject * k = to_kobj(entry);
626 if (kobject_name(k) && !strcmp(kobject_name(k),name)) {
627 ret = kobject_get(k);
628 break;
629 }
630 }
631 spin_unlock(&kset->list_lock);
632 return ret;
633}
634
635int subsystem_register(struct kset *s)
636{
637 return kset_register(s);
638}
639
640void subsystem_unregister(struct kset *s)
641{
642 kset_unregister(s);
643}
644
645
646
647
648
649
650
651int subsys_create_file(struct kset *s, struct subsys_attribute *a)
652{
653 int error = 0;
654
655 if (!s || !a)
656 return -EINVAL;
657
658 if (kset_get(s)) {
659 error = sysfs_create_file(&s->kobj, &a->attr);
660 kset_put(s);
661 }
662 return error;
663}
664
665EXPORT_SYMBOL(kobject_init);
666EXPORT_SYMBOL(kobject_register);
667EXPORT_SYMBOL(kobject_unregister);
668EXPORT_SYMBOL(kobject_get);
669EXPORT_SYMBOL(kobject_put);
670EXPORT_SYMBOL(kobject_add);
671EXPORT_SYMBOL(kobject_del);
672
673EXPORT_SYMBOL(kset_register);
674EXPORT_SYMBOL(kset_unregister);
675
676EXPORT_SYMBOL(subsystem_register);
677EXPORT_SYMBOL(subsystem_unregister);
678EXPORT_SYMBOL(subsys_create_file);
679