summaryrefslogtreecommitdiff
path: root/c_src/include/linux/kobject.h
blob: c33b21267e21f75ad763706ce9782c76c7ae90f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * kobject.h - generic kernel object infrastructure.
 *
 * Copyright (c) 2002-2003 Patrick Mochel
 * Copyright (c) 2002-2003 Open Source Development Labs
 * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com>
 * Copyright (c) 2006-2008 Novell Inc.
 *
 * This file is released under the GPLv2.
 *
 * Please read Documentation/kobject.txt before using the kobject
 * interface, ESPECIALLY the parts about reference counts and object
 * destructors.
 */

#ifndef _KOBJECT_H_
#define _KOBJECT_H_

#include <linux/atomic.h>
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/workqueue.h>

struct kset;

struct kobj_type {
	void (*release)(struct kobject *kobj);
	const struct sysfs_ops *sysfs_ops;
	const struct attribute_group **default_groups;
	const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
	const void *(*namespace)(struct kobject *kobj);
};

struct kobj_uevent_env {
};

struct kobj_attribute {
	struct attribute attr;
	ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
			char *buf);
	ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
			 const char *buf, size_t count);
};

struct kobject {
	struct kobject		*parent;
	struct kset		*kset;
	const struct kobj_type	*ktype;
	struct kernfs_node	*sd; /* sysfs directory entry */
	atomic_t		ref;
	unsigned int state_initialized:1;
	unsigned int state_in_sysfs:1;
	unsigned int state_add_uevent_sent:1;
	unsigned int state_remove_uevent_sent:1;
	unsigned int uevent_suppress:1;
};

struct kset {
	struct kobject		kobj;
};

#define kobject_add(...)	0

static inline void kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
{
	memset(kobj, 0, sizeof(*kobj));

	atomic_set(&kobj->ref, 1);
	kobj->ktype = ktype;
	kobj->state_initialized = 1;
}

static inline void kobject_del(struct kobject *kobj);

static inline void kobject_cleanup(struct kobject *kobj)
{
	const struct kobj_type *t = kobj->ktype;

	/* remove from sysfs if the caller did not do it */
	if (kobj->state_in_sysfs)
		kobject_del(kobj);

	if (t && t->release)
		t->release(kobj);
}

static inline void kobject_put(struct kobject *kobj)
{
	BUG_ON(!kobj);
	BUG_ON(!kobj->state_initialized);

	if (atomic_dec_and_test(&kobj->ref))
		kobject_cleanup(kobj);
}

static inline void kobject_del(struct kobject *kobj)
{
	if (!kobj)
		return;

	kobj->state_in_sysfs = 0;
#if 0
	kobj_kset_leave(kobj);
#endif
	kobject_put(kobj->parent);
	kobj->parent = NULL;
}

static inline struct kobject *kobject_get(struct kobject *kobj)
{
	BUG_ON(!kobj);
	BUG_ON(!kobj->state_initialized);

	atomic_inc(&kobj->ref);
	return kobj;
}

static inline void kset_unregister(struct kset *kset)
{
	kfree(kset);
}

#define kset_create_and_add(_name, _u, _parent)				\
	((struct kset *) kzalloc(sizeof(struct kset), GFP_KERNEL))

#endif /* _KOBJECT_H_ */