Add socket character device
[qemu/aliguori.git] / devices / plug.c
blobdfd25aa8ca9bcc5b8bee236e864f4a511b4d6a8f
1 #include "qemu/plug.h"
2 #include "qerror.h"
3 #include "string-visitor.h"
5 #define MAX_NAME (32 + 1)
6 #define MAX_TYPENAME (32 + 1)
8 struct PlugProperty
10 char name[MAX_NAME];
11 char typename[MAX_TYPENAME];
14 PlugPropertyAccessor *getter;
15 void *getter_opaque;
17 PlugPropertyAccessor *setter;
18 void *setter_opaque;
20 int flags;
22 PlugProperty *next;
25 void plug_add_property_full(Plug *plug, const char *name,
26 PlugPropertyAccessor *getter, void *getter_opaque,
27 PlugPropertyAccessor *setter, void *setter_opaque,
28 const char *typename, int flags)
30 PlugProperty *prop = qemu_mallocz(sizeof(*prop));
32 snprintf(prop->name, sizeof(prop->name), "%s", name);
33 snprintf(prop->typename, sizeof(prop->typename), "%s", typename);
35 prop->getter = getter;
36 prop->getter_opaque = getter_opaque;
38 prop->setter = setter;
39 prop->setter_opaque = setter_opaque;
41 prop->flags = flags;
43 prop->next = plug->first_prop;
44 plug->first_prop = prop;
47 static PlugProperty *plug_find_property(Plug *plug, const char *name)
49 PlugProperty *prop;
51 for (prop = plug->first_prop; prop; prop = prop->next) {
52 if (strcmp(prop->name, name) == 0) {
53 return prop;
57 return NULL;
60 void plug_set_property(Plug *plug, const char *name, Visitor *v, Error **errp)
62 PlugProperty *prop = plug_find_property(plug, name);
64 if (!prop) {
65 error_set(errp, QERR_PROPERTY_NOT_FOUND, type_get_id(TYPE_INSTANCE(plug)), name);
66 return;
69 if (!(prop->flags & PROP_F_WRITE) || (prop->flags & PROP_F_LOCKED)) {
70 error_set(errp, QERR_PROPERTY_READ_ONLY, type_get_id(TYPE_INSTANCE(plug)), name);
71 return;
74 prop->setter(plug, name, v, prop->setter_opaque, errp);
77 void plug_get_property(Plug *plug, const char *name, Visitor *v, Error **errp)
79 PlugProperty *prop = plug_find_property(plug, name);
81 if (!prop) {
82 error_set(errp, QERR_PROPERTY_NOT_FOUND, type_get_id(TYPE_INSTANCE(plug)), name);
83 printf("property not found\n");
84 return;
87 if (!(prop->flags & PROP_F_READ)) {
88 error_set(errp, QERR_PROPERTY_READ_ONLY, type_get_id(TYPE_INSTANCE(plug)), name);
89 printf("property read only\n");
90 return;
94 prop->getter(plug, name, v, prop->getter_opaque, errp);
97 void plug_lock_property(Plug *plug, const char *name)
99 PlugProperty *prop = plug_find_property(plug, name);
101 assert(prop != NULL);
103 prop->flags |= PROP_F_LOCKED;
106 void plug_unlock_property(Plug *plug, const char *name)
108 PlugProperty *prop = plug_find_property(plug, name);
110 assert(prop != NULL);
112 prop->flags &= ~PROP_F_LOCKED;
115 void plug_lock_all_properties(Plug *plug)
117 PlugProperty *prop;
119 for (prop = plug->first_prop; prop; prop = prop->next) {
120 prop->flags |= PROP_F_LOCKED;
124 void plug_unlock_all_properties(Plug *plug)
126 PlugProperty *prop;
128 for (prop = plug->first_prop; prop; prop = prop->next) {
129 prop->flags &= ~PROP_F_LOCKED;
133 void plug_foreach_property(Plug *plug, PropertyEnumerator *enumfn, void *opaque)
135 PlugProperty *prop;
137 for (prop = plug->first_prop; prop; prop = prop->next) {
138 enumfn(plug, prop->name, prop->typename, prop->flags, opaque);
142 void plug_set_realized(Plug *plug, bool realized)
144 PlugClass *class = PLUG_GET_CLASS(plug);
145 bool old_value = plug->realized;
147 plug->realized = realized;
149 if (plug->realized && !old_value) {
150 if (class->realize) {
151 class->realize(plug);
153 } else if (!plug->realized && old_value) {
154 if (class->unrealize) {
155 class->unrealize(plug);
160 bool plug_get_realized(Plug *plug)
162 return plug->realized;
165 char *plug_get_property_str(Plug *plug, const char *name, Error **errp)
167 StringOutputVisitor sov;
169 string_output_visitor_init(&sov);
170 plug_get_property(plug, name, &sov.parent, errp);
172 return qemu_strdup(sov.value);
175 static void plug_propagate_realized(Plug *plug, const char *name,
176 const char *typename, int flags,
177 void *opaque)
179 if (strstart(typename, "plug<", NULL)) {
180 char *child_name;
181 Plug *child_plug;
183 child_name = plug_get_property_str(plug, name, NULL);
184 child_plug = PLUG(type_find_by_id(child_name));
186 plug_set_realized(child_plug, plug_get_realized(plug));
188 qemu_free(child_name);
192 void plug_realize_all(Plug *plug)
194 /* This doesn't loop infinitely because the callbacks are only called when
195 * the state changes. */
196 plug_set_realized(plug, true);
197 plug_lock_all_properties(plug);
198 plug_foreach_property(plug, plug_propagate_realized, NULL);
201 void plug_unrealize_all(Plug *plug)
203 /* This doesn't loop infinitely because the callbacks are only called when
204 * the state changes. */
205 plug_set_realized(plug, false);
206 plug_unlock_all_properties(plug);
207 plug_foreach_property(plug, plug_propagate_realized, NULL);
210 static void plug_class_initfn(TypeClass *base_class)
212 PlugClass *class = PLUG_CLASS(base_class);
214 class->realize = plug_realize_all;
215 class->unrealize = plug_unrealize_all;
218 void plug_initialize(Plug *plug, const char *id)
220 type_initialize(plug, TYPE_PLUG, id);
223 void plug_finalize(Plug *plug)
225 type_finalize(plug);
228 static void plug_initfn(TypeInstance *inst)
230 Plug *obj = PLUG(inst);
232 plug_add_property_bool(obj, "realized",
233 plug_get_realized,
234 plug_set_realized,
235 PROP_F_READWRITE);
238 static const TypeInfo plug_type_info = {
239 .name = TYPE_PLUG,
240 .instance_size = sizeof(Plug),
241 .class_size = sizeof(PlugClass),
242 .instance_init = plug_initfn,
243 .class_init = plug_class_initfn,
246 static void register_devices(void)
248 type_register_static(&plug_type_info);
251 device_init(register_devices);