Statistics
| Branch: | Revision:

root / hw / qdev-properties.c @ c13a9e61

History | View | Annotate | Download (30.9 kB)

1 1503fff3 Gerd Hoffmann
#include "net.h"
2 ee6847d1 Gerd Hoffmann
#include "qdev.h"
3 9f59b566 Markus Armbruster
#include "qerror.h"
4 2446333c Blue Swirl
#include "blockdev.h"
5 2b584959 Markus Armbruster
#include "hw/block-common.h"
6 606c10e2 Zhi Yong Wu
#include "net/hub.h"
7 ee6847d1 Gerd Hoffmann
8 ee6847d1 Gerd Hoffmann
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
9 ee6847d1 Gerd Hoffmann
{
10 ee6847d1 Gerd Hoffmann
    void *ptr = dev;
11 ee6847d1 Gerd Hoffmann
    ptr += prop->offset;
12 ee6847d1 Gerd Hoffmann
    return ptr;
13 ee6847d1 Gerd Hoffmann
}
14 ee6847d1 Gerd Hoffmann
15 d4d34b0d Markus Armbruster
static void get_pointer(Object *obj, Visitor *v, Property *prop,
16 d4d34b0d Markus Armbruster
                        const char *(*print)(void *ptr),
17 d4d34b0d Markus Armbruster
                        const char *name, Error **errp)
18 d4d34b0d Markus Armbruster
{
19 d4d34b0d Markus Armbruster
    DeviceState *dev = DEVICE(obj);
20 d4d34b0d Markus Armbruster
    void **ptr = qdev_get_prop_ptr(dev, prop);
21 d4d34b0d Markus Armbruster
    char *p;
22 d4d34b0d Markus Armbruster
23 d4d34b0d Markus Armbruster
    p = (char *) (*ptr ? print(*ptr) : "");
24 d4d34b0d Markus Armbruster
    visit_type_str(v, &p, name, errp);
25 d4d34b0d Markus Armbruster
}
26 d4d34b0d Markus Armbruster
27 d4d34b0d Markus Armbruster
static void set_pointer(Object *obj, Visitor *v, Property *prop,
28 d4d34b0d Markus Armbruster
                        int (*parse)(DeviceState *dev, const char *str,
29 d4d34b0d Markus Armbruster
                                     void **ptr),
30 d4d34b0d Markus Armbruster
                        const char *name, Error **errp)
31 d4d34b0d Markus Armbruster
{
32 d4d34b0d Markus Armbruster
    DeviceState *dev = DEVICE(obj);
33 d4d34b0d Markus Armbruster
    Error *local_err = NULL;
34 d4d34b0d Markus Armbruster
    void **ptr = qdev_get_prop_ptr(dev, prop);
35 d4d34b0d Markus Armbruster
    char *str;
36 d4d34b0d Markus Armbruster
    int ret;
37 d4d34b0d Markus Armbruster
38 d4d34b0d Markus Armbruster
    if (dev->state != DEV_STATE_CREATED) {
39 d4d34b0d Markus Armbruster
        error_set(errp, QERR_PERMISSION_DENIED);
40 d4d34b0d Markus Armbruster
        return;
41 d4d34b0d Markus Armbruster
    }
42 d4d34b0d Markus Armbruster
43 d4d34b0d Markus Armbruster
    visit_type_str(v, &str, name, &local_err);
44 d4d34b0d Markus Armbruster
    if (local_err) {
45 d4d34b0d Markus Armbruster
        error_propagate(errp, local_err);
46 d4d34b0d Markus Armbruster
        return;
47 d4d34b0d Markus Armbruster
    }
48 d4d34b0d Markus Armbruster
    if (!*str) {
49 d4d34b0d Markus Armbruster
        g_free(str);
50 d4d34b0d Markus Armbruster
        *ptr = NULL;
51 d4d34b0d Markus Armbruster
        return;
52 d4d34b0d Markus Armbruster
    }
53 d4d34b0d Markus Armbruster
    ret = parse(dev, str, ptr);
54 d4d34b0d Markus Armbruster
    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
55 d4d34b0d Markus Armbruster
    g_free(str);
56 d4d34b0d Markus Armbruster
}
57 d4d34b0d Markus Armbruster
58 d4d34b0d Markus Armbruster
static void get_enum(Object *obj, Visitor *v, void *opaque,
59 d4d34b0d Markus Armbruster
                     const char *name, Error **errp)
60 d4d34b0d Markus Armbruster
{
61 d4d34b0d Markus Armbruster
    DeviceState *dev = DEVICE(obj);
62 d4d34b0d Markus Armbruster
    Property *prop = opaque;
63 d4d34b0d Markus Armbruster
    int *ptr = qdev_get_prop_ptr(dev, prop);
64 d4d34b0d Markus Armbruster
65 d4d34b0d Markus Armbruster
    visit_type_enum(v, ptr, prop->info->enum_table,
66 d4d34b0d Markus Armbruster
                    prop->info->name, prop->name, errp);
67 d4d34b0d Markus Armbruster
}
68 d4d34b0d Markus Armbruster
69 d4d34b0d Markus Armbruster
static void set_enum(Object *obj, Visitor *v, void *opaque,
70 d4d34b0d Markus Armbruster
                     const char *name, Error **errp)
71 d4d34b0d Markus Armbruster
{
72 d4d34b0d Markus Armbruster
    DeviceState *dev = DEVICE(obj);
73 d4d34b0d Markus Armbruster
    Property *prop = opaque;
74 d4d34b0d Markus Armbruster
    int *ptr = qdev_get_prop_ptr(dev, prop);
75 d4d34b0d Markus Armbruster
76 d4d34b0d Markus Armbruster
    if (dev->state != DEV_STATE_CREATED) {
77 d4d34b0d Markus Armbruster
        error_set(errp, QERR_PERMISSION_DENIED);
78 d4d34b0d Markus Armbruster
        return;
79 d4d34b0d Markus Armbruster
    }
80 d4d34b0d Markus Armbruster
81 d4d34b0d Markus Armbruster
    visit_type_enum(v, ptr, prop->info->enum_table,
82 d4d34b0d Markus Armbruster
                    prop->info->name, prop->name, errp);
83 d4d34b0d Markus Armbruster
}
84 d4d34b0d Markus Armbruster
85 d4d34b0d Markus Armbruster
/* Bit */
86 d4d34b0d Markus Armbruster
87 d2364ee4 Michael S. Tsirkin
static uint32_t qdev_get_prop_mask(Property *prop)
88 d2364ee4 Michael S. Tsirkin
{
89 a3d4a1b0 Paolo Bonzini
    assert(prop->info == &qdev_prop_bit);
90 d2364ee4 Michael S. Tsirkin
    return 0x1 << prop->bitnr;
91 d2364ee4 Michael S. Tsirkin
}
92 d2364ee4 Michael S. Tsirkin
93 d2364ee4 Michael S. Tsirkin
static void bit_prop_set(DeviceState *dev, Property *props, bool val)
94 d2364ee4 Michael S. Tsirkin
{
95 d2364ee4 Michael S. Tsirkin
    uint32_t *p = qdev_get_prop_ptr(dev, props);
96 d2364ee4 Michael S. Tsirkin
    uint32_t mask = qdev_get_prop_mask(props);
97 d2364ee4 Michael S. Tsirkin
    if (val)
98 dbd48324 Michael S. Tsirkin
        *p |= mask;
99 d2364ee4 Michael S. Tsirkin
    else
100 d2364ee4 Michael S. Tsirkin
        *p &= ~mask;
101 d2364ee4 Michael S. Tsirkin
}
102 d2364ee4 Michael S. Tsirkin
103 d2364ee4 Michael S. Tsirkin
static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
104 d2364ee4 Michael S. Tsirkin
{
105 5a5e3d55 David 'Digit' Turner
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
106 d2364ee4 Michael S. Tsirkin
    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
107 d2364ee4 Michael S. Tsirkin
}
108 d2364ee4 Michael S. Tsirkin
109 57c9fafe Anthony Liguori
static void get_bit(Object *obj, Visitor *v, void *opaque,
110 80e555c2 Paolo Bonzini
                    const char *name, Error **errp)
111 80e555c2 Paolo Bonzini
{
112 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
113 80e555c2 Paolo Bonzini
    Property *prop = opaque;
114 80e555c2 Paolo Bonzini
    uint32_t *p = qdev_get_prop_ptr(dev, prop);
115 80e555c2 Paolo Bonzini
    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
116 80e555c2 Paolo Bonzini
117 80e555c2 Paolo Bonzini
    visit_type_bool(v, &value, name, errp);
118 80e555c2 Paolo Bonzini
}
119 80e555c2 Paolo Bonzini
120 57c9fafe Anthony Liguori
static void set_bit(Object *obj, Visitor *v, void *opaque,
121 80e555c2 Paolo Bonzini
                    const char *name, Error **errp)
122 80e555c2 Paolo Bonzini
{
123 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
124 80e555c2 Paolo Bonzini
    Property *prop = opaque;
125 80e555c2 Paolo Bonzini
    Error *local_err = NULL;
126 80e555c2 Paolo Bonzini
    bool value;
127 80e555c2 Paolo Bonzini
128 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
129 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
130 80e555c2 Paolo Bonzini
        return;
131 80e555c2 Paolo Bonzini
    }
132 80e555c2 Paolo Bonzini
133 80e555c2 Paolo Bonzini
    visit_type_bool(v, &value, name, &local_err);
134 80e555c2 Paolo Bonzini
    if (local_err) {
135 80e555c2 Paolo Bonzini
        error_propagate(errp, local_err);
136 80e555c2 Paolo Bonzini
        return;
137 80e555c2 Paolo Bonzini
    }
138 80e555c2 Paolo Bonzini
    bit_prop_set(dev, prop, value);
139 80e555c2 Paolo Bonzini
}
140 80e555c2 Paolo Bonzini
141 d2364ee4 Michael S. Tsirkin
PropertyInfo qdev_prop_bit = {
142 cafe5bdb Paolo Bonzini
    .name  = "boolean",
143 cafe5bdb Paolo Bonzini
    .legacy_name  = "on/off",
144 d2364ee4 Michael S. Tsirkin
    .print = print_bit,
145 80e555c2 Paolo Bonzini
    .get   = get_bit,
146 80e555c2 Paolo Bonzini
    .set   = set_bit,
147 d2364ee4 Michael S. Tsirkin
};
148 d2364ee4 Michael S. Tsirkin
149 c7cc172d Juan Quintela
/* --- 8bit integer --- */
150 c7cc172d Juan Quintela
151 c08fb2ac Michael Roth
static void get_uint8(Object *obj, Visitor *v, void *opaque,
152 c08fb2ac Michael Roth
                      const char *name, Error **errp)
153 80e555c2 Paolo Bonzini
{
154 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
155 80e555c2 Paolo Bonzini
    Property *prop = opaque;
156 c08fb2ac Michael Roth
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
157 80e555c2 Paolo Bonzini
158 c08fb2ac Michael Roth
    visit_type_uint8(v, ptr, name, errp);
159 80e555c2 Paolo Bonzini
}
160 80e555c2 Paolo Bonzini
161 c08fb2ac Michael Roth
static void set_uint8(Object *obj, Visitor *v, void *opaque,
162 c08fb2ac Michael Roth
                      const char *name, Error **errp)
163 80e555c2 Paolo Bonzini
{
164 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
165 80e555c2 Paolo Bonzini
    Property *prop = opaque;
166 27712df9 Paolo Bonzini
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
167 80e555c2 Paolo Bonzini
168 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
169 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
170 80e555c2 Paolo Bonzini
        return;
171 80e555c2 Paolo Bonzini
    }
172 80e555c2 Paolo Bonzini
173 27712df9 Paolo Bonzini
    visit_type_uint8(v, ptr, name, errp);
174 80e555c2 Paolo Bonzini
}
175 80e555c2 Paolo Bonzini
176 c7cc172d Juan Quintela
PropertyInfo qdev_prop_uint8 = {
177 c7cc172d Juan Quintela
    .name  = "uint8",
178 c08fb2ac Michael Roth
    .get   = get_uint8,
179 c08fb2ac Michael Roth
    .set   = set_uint8,
180 c7cc172d Juan Quintela
};
181 c7cc172d Juan Quintela
182 6835678c Jan Kiszka
/* --- 8bit hex value --- */
183 6835678c Jan Kiszka
184 6835678c Jan Kiszka
static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
185 6835678c Jan Kiszka
{
186 6835678c Jan Kiszka
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
187 6835678c Jan Kiszka
    char *end;
188 6835678c Jan Kiszka
189 97aa6e9b Paolo Bonzini
    if (str[0] != '0' || str[1] != 'x') {
190 97aa6e9b Paolo Bonzini
        return -EINVAL;
191 97aa6e9b Paolo Bonzini
    }
192 97aa6e9b Paolo Bonzini
193 6835678c Jan Kiszka
    *ptr = strtoul(str, &end, 16);
194 6835678c Jan Kiszka
    if ((*end != '\0') || (end == str)) {
195 6835678c Jan Kiszka
        return -EINVAL;
196 6835678c Jan Kiszka
    }
197 6835678c Jan Kiszka
198 6835678c Jan Kiszka
    return 0;
199 6835678c Jan Kiszka
}
200 6835678c Jan Kiszka
201 6835678c Jan Kiszka
static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
202 6835678c Jan Kiszka
{
203 6835678c Jan Kiszka
    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
204 6835678c Jan Kiszka
    return snprintf(dest, len, "0x%" PRIx8, *ptr);
205 6835678c Jan Kiszka
}
206 6835678c Jan Kiszka
207 6835678c Jan Kiszka
PropertyInfo qdev_prop_hex8 = {
208 cafe5bdb Paolo Bonzini
    .name  = "uint8",
209 cafe5bdb Paolo Bonzini
    .legacy_name  = "hex8",
210 6835678c Jan Kiszka
    .parse = parse_hex8,
211 6835678c Jan Kiszka
    .print = print_hex8,
212 c08fb2ac Michael Roth
    .get   = get_uint8,
213 c08fb2ac Michael Roth
    .set   = set_uint8,
214 6835678c Jan Kiszka
};
215 6835678c Jan Kiszka
216 ee6847d1 Gerd Hoffmann
/* --- 16bit integer --- */
217 ee6847d1 Gerd Hoffmann
218 c08fb2ac Michael Roth
static void get_uint16(Object *obj, Visitor *v, void *opaque,
219 c08fb2ac Michael Roth
                       const char *name, Error **errp)
220 80e555c2 Paolo Bonzini
{
221 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
222 80e555c2 Paolo Bonzini
    Property *prop = opaque;
223 c08fb2ac Michael Roth
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
224 80e555c2 Paolo Bonzini
225 c08fb2ac Michael Roth
    visit_type_uint16(v, ptr, name, errp);
226 80e555c2 Paolo Bonzini
}
227 80e555c2 Paolo Bonzini
228 c08fb2ac Michael Roth
static void set_uint16(Object *obj, Visitor *v, void *opaque,
229 c08fb2ac Michael Roth
                       const char *name, Error **errp)
230 80e555c2 Paolo Bonzini
{
231 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
232 80e555c2 Paolo Bonzini
    Property *prop = opaque;
233 27712df9 Paolo Bonzini
    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
234 80e555c2 Paolo Bonzini
235 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
236 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
237 80e555c2 Paolo Bonzini
        return;
238 80e555c2 Paolo Bonzini
    }
239 80e555c2 Paolo Bonzini
240 27712df9 Paolo Bonzini
    visit_type_uint16(v, ptr, name, errp);
241 80e555c2 Paolo Bonzini
}
242 80e555c2 Paolo Bonzini
243 ee6847d1 Gerd Hoffmann
PropertyInfo qdev_prop_uint16 = {
244 ee6847d1 Gerd Hoffmann
    .name  = "uint16",
245 c08fb2ac Michael Roth
    .get   = get_uint16,
246 c08fb2ac Michael Roth
    .set   = set_uint16,
247 ee6847d1 Gerd Hoffmann
};
248 ee6847d1 Gerd Hoffmann
249 ee6847d1 Gerd Hoffmann
/* --- 32bit integer --- */
250 ee6847d1 Gerd Hoffmann
251 c08fb2ac Michael Roth
static void get_uint32(Object *obj, Visitor *v, void *opaque,
252 c08fb2ac Michael Roth
                       const char *name, Error **errp)
253 c08fb2ac Michael Roth
{
254 c08fb2ac Michael Roth
    DeviceState *dev = DEVICE(obj);
255 c08fb2ac Michael Roth
    Property *prop = opaque;
256 27712df9 Paolo Bonzini
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
257 c08fb2ac Michael Roth
258 27712df9 Paolo Bonzini
    visit_type_uint32(v, ptr, name, errp);
259 c08fb2ac Michael Roth
}
260 c08fb2ac Michael Roth
261 c08fb2ac Michael Roth
static void set_uint32(Object *obj, Visitor *v, void *opaque,
262 c08fb2ac Michael Roth
                       const char *name, Error **errp)
263 c08fb2ac Michael Roth
{
264 c08fb2ac Michael Roth
    DeviceState *dev = DEVICE(obj);
265 c08fb2ac Michael Roth
    Property *prop = opaque;
266 27712df9 Paolo Bonzini
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
267 c08fb2ac Michael Roth
268 c08fb2ac Michael Roth
    if (dev->state != DEV_STATE_CREATED) {
269 c08fb2ac Michael Roth
        error_set(errp, QERR_PERMISSION_DENIED);
270 c08fb2ac Michael Roth
        return;
271 c08fb2ac Michael Roth
    }
272 c08fb2ac Michael Roth
273 27712df9 Paolo Bonzini
    visit_type_uint32(v, ptr, name, errp);
274 c08fb2ac Michael Roth
}
275 c08fb2ac Michael Roth
276 57c9fafe Anthony Liguori
static void get_int32(Object *obj, Visitor *v, void *opaque,
277 80e555c2 Paolo Bonzini
                      const char *name, Error **errp)
278 80e555c2 Paolo Bonzini
{
279 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
280 80e555c2 Paolo Bonzini
    Property *prop = opaque;
281 80e555c2 Paolo Bonzini
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
282 80e555c2 Paolo Bonzini
283 c08fb2ac Michael Roth
    visit_type_int32(v, ptr, name, errp);
284 80e555c2 Paolo Bonzini
}
285 80e555c2 Paolo Bonzini
286 57c9fafe Anthony Liguori
static void set_int32(Object *obj, Visitor *v, void *opaque,
287 80e555c2 Paolo Bonzini
                      const char *name, Error **errp)
288 80e555c2 Paolo Bonzini
{
289 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
290 80e555c2 Paolo Bonzini
    Property *prop = opaque;
291 27712df9 Paolo Bonzini
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
292 80e555c2 Paolo Bonzini
293 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
294 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
295 80e555c2 Paolo Bonzini
        return;
296 80e555c2 Paolo Bonzini
    }
297 80e555c2 Paolo Bonzini
298 27712df9 Paolo Bonzini
    visit_type_int32(v, ptr, name, errp);
299 80e555c2 Paolo Bonzini
}
300 80e555c2 Paolo Bonzini
301 ee6847d1 Gerd Hoffmann
PropertyInfo qdev_prop_uint32 = {
302 ee6847d1 Gerd Hoffmann
    .name  = "uint32",
303 c08fb2ac Michael Roth
    .get   = get_uint32,
304 c08fb2ac Michael Roth
    .set   = set_uint32,
305 ee6847d1 Gerd Hoffmann
};
306 ee6847d1 Gerd Hoffmann
307 316940b0 Gerd Hoffmann
PropertyInfo qdev_prop_int32 = {
308 316940b0 Gerd Hoffmann
    .name  = "int32",
309 80e555c2 Paolo Bonzini
    .get   = get_int32,
310 80e555c2 Paolo Bonzini
    .set   = set_int32,
311 316940b0 Gerd Hoffmann
};
312 316940b0 Gerd Hoffmann
313 ee6847d1 Gerd Hoffmann
/* --- 32bit hex value --- */
314 ee6847d1 Gerd Hoffmann
315 ee6847d1 Gerd Hoffmann
static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
316 ee6847d1 Gerd Hoffmann
{
317 ee6847d1 Gerd Hoffmann
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
318 449041d4 Kevin Wolf
    char *end;
319 ee6847d1 Gerd Hoffmann
320 97aa6e9b Paolo Bonzini
    if (str[0] != '0' || str[1] != 'x') {
321 97aa6e9b Paolo Bonzini
        return -EINVAL;
322 97aa6e9b Paolo Bonzini
    }
323 97aa6e9b Paolo Bonzini
324 449041d4 Kevin Wolf
    *ptr = strtoul(str, &end, 16);
325 449041d4 Kevin Wolf
    if ((*end != '\0') || (end == str)) {
326 6bf38816 Markus Armbruster
        return -EINVAL;
327 449041d4 Kevin Wolf
    }
328 449041d4 Kevin Wolf
329 ee6847d1 Gerd Hoffmann
    return 0;
330 ee6847d1 Gerd Hoffmann
}
331 ee6847d1 Gerd Hoffmann
332 ee6847d1 Gerd Hoffmann
static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
333 ee6847d1 Gerd Hoffmann
{
334 ee6847d1 Gerd Hoffmann
    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
335 ee6847d1 Gerd Hoffmann
    return snprintf(dest, len, "0x%" PRIx32, *ptr);
336 ee6847d1 Gerd Hoffmann
}
337 ee6847d1 Gerd Hoffmann
338 ee6847d1 Gerd Hoffmann
PropertyInfo qdev_prop_hex32 = {
339 cafe5bdb Paolo Bonzini
    .name  = "uint32",
340 cafe5bdb Paolo Bonzini
    .legacy_name  = "hex32",
341 ee6847d1 Gerd Hoffmann
    .parse = parse_hex32,
342 ee6847d1 Gerd Hoffmann
    .print = print_hex32,
343 c08fb2ac Michael Roth
    .get   = get_uint32,
344 c08fb2ac Michael Roth
    .set   = set_uint32,
345 ee6847d1 Gerd Hoffmann
};
346 ee6847d1 Gerd Hoffmann
347 5a053d1f Blue Swirl
/* --- 64bit integer --- */
348 5a053d1f Blue Swirl
349 c08fb2ac Michael Roth
static void get_uint64(Object *obj, Visitor *v, void *opaque,
350 c08fb2ac Michael Roth
                       const char *name, Error **errp)
351 80e555c2 Paolo Bonzini
{
352 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
353 80e555c2 Paolo Bonzini
    Property *prop = opaque;
354 c08fb2ac Michael Roth
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
355 80e555c2 Paolo Bonzini
356 c08fb2ac Michael Roth
    visit_type_uint64(v, ptr, name, errp);
357 80e555c2 Paolo Bonzini
}
358 80e555c2 Paolo Bonzini
359 c08fb2ac Michael Roth
static void set_uint64(Object *obj, Visitor *v, void *opaque,
360 c08fb2ac Michael Roth
                       const char *name, Error **errp)
361 80e555c2 Paolo Bonzini
{
362 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
363 80e555c2 Paolo Bonzini
    Property *prop = opaque;
364 c08fb2ac Michael Roth
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
365 80e555c2 Paolo Bonzini
366 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
367 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
368 80e555c2 Paolo Bonzini
        return;
369 80e555c2 Paolo Bonzini
    }
370 80e555c2 Paolo Bonzini
371 c08fb2ac Michael Roth
    visit_type_uint64(v, ptr, name, errp);
372 80e555c2 Paolo Bonzini
}
373 80e555c2 Paolo Bonzini
374 5a053d1f Blue Swirl
PropertyInfo qdev_prop_uint64 = {
375 5a053d1f Blue Swirl
    .name  = "uint64",
376 c08fb2ac Michael Roth
    .get   = get_uint64,
377 c08fb2ac Michael Roth
    .set   = set_uint64,
378 5a053d1f Blue Swirl
};
379 5a053d1f Blue Swirl
380 5a053d1f Blue Swirl
/* --- 64bit hex value --- */
381 5a053d1f Blue Swirl
382 5a053d1f Blue Swirl
static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
383 5a053d1f Blue Swirl
{
384 5a053d1f Blue Swirl
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
385 449041d4 Kevin Wolf
    char *end;
386 5a053d1f Blue Swirl
387 97aa6e9b Paolo Bonzini
    if (str[0] != '0' || str[1] != 'x') {
388 97aa6e9b Paolo Bonzini
        return -EINVAL;
389 97aa6e9b Paolo Bonzini
    }
390 97aa6e9b Paolo Bonzini
391 449041d4 Kevin Wolf
    *ptr = strtoull(str, &end, 16);
392 449041d4 Kevin Wolf
    if ((*end != '\0') || (end == str)) {
393 6bf38816 Markus Armbruster
        return -EINVAL;
394 449041d4 Kevin Wolf
    }
395 449041d4 Kevin Wolf
396 5a053d1f Blue Swirl
    return 0;
397 5a053d1f Blue Swirl
}
398 5a053d1f Blue Swirl
399 5a053d1f Blue Swirl
static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
400 5a053d1f Blue Swirl
{
401 5a053d1f Blue Swirl
    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
402 5a053d1f Blue Swirl
    return snprintf(dest, len, "0x%" PRIx64, *ptr);
403 5a053d1f Blue Swirl
}
404 5a053d1f Blue Swirl
405 5a053d1f Blue Swirl
PropertyInfo qdev_prop_hex64 = {
406 cafe5bdb Paolo Bonzini
    .name  = "uint64",
407 cafe5bdb Paolo Bonzini
    .legacy_name  = "hex64",
408 5a053d1f Blue Swirl
    .parse = parse_hex64,
409 5a053d1f Blue Swirl
    .print = print_hex64,
410 c08fb2ac Michael Roth
    .get   = get_uint64,
411 c08fb2ac Michael Roth
    .set   = set_uint64,
412 5a053d1f Blue Swirl
};
413 5a053d1f Blue Swirl
414 59419663 Gerd Hoffmann
/* --- string --- */
415 59419663 Gerd Hoffmann
416 dd0ba250 Paolo Bonzini
static void release_string(Object *obj, const char *name, void *opaque)
417 d21357df Markus Armbruster
{
418 dd0ba250 Paolo Bonzini
    Property *prop = opaque;
419 dd0ba250 Paolo Bonzini
    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
420 d21357df Markus Armbruster
}
421 d21357df Markus Armbruster
422 59419663 Gerd Hoffmann
static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
423 59419663 Gerd Hoffmann
{
424 59419663 Gerd Hoffmann
    char **ptr = qdev_get_prop_ptr(dev, prop);
425 59419663 Gerd Hoffmann
    if (!*ptr)
426 59419663 Gerd Hoffmann
        return snprintf(dest, len, "<null>");
427 59419663 Gerd Hoffmann
    return snprintf(dest, len, "\"%s\"", *ptr);
428 59419663 Gerd Hoffmann
}
429 59419663 Gerd Hoffmann
430 57c9fafe Anthony Liguori
static void get_string(Object *obj, Visitor *v, void *opaque,
431 80e555c2 Paolo Bonzini
                       const char *name, Error **errp)
432 80e555c2 Paolo Bonzini
{
433 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
434 80e555c2 Paolo Bonzini
    Property *prop = opaque;
435 80e555c2 Paolo Bonzini
    char **ptr = qdev_get_prop_ptr(dev, prop);
436 80e555c2 Paolo Bonzini
437 80e555c2 Paolo Bonzini
    if (!*ptr) {
438 80e555c2 Paolo Bonzini
        char *str = (char *)"";
439 80e555c2 Paolo Bonzini
        visit_type_str(v, &str, name, errp);
440 80e555c2 Paolo Bonzini
    } else {
441 80e555c2 Paolo Bonzini
        visit_type_str(v, ptr, name, errp);
442 80e555c2 Paolo Bonzini
    }
443 80e555c2 Paolo Bonzini
}
444 80e555c2 Paolo Bonzini
445 57c9fafe Anthony Liguori
static void set_string(Object *obj, Visitor *v, void *opaque,
446 80e555c2 Paolo Bonzini
                       const char *name, Error **errp)
447 80e555c2 Paolo Bonzini
{
448 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
449 80e555c2 Paolo Bonzini
    Property *prop = opaque;
450 80e555c2 Paolo Bonzini
    char **ptr = qdev_get_prop_ptr(dev, prop);
451 80e555c2 Paolo Bonzini
    Error *local_err = NULL;
452 80e555c2 Paolo Bonzini
    char *str;
453 80e555c2 Paolo Bonzini
454 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
455 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
456 80e555c2 Paolo Bonzini
        return;
457 80e555c2 Paolo Bonzini
    }
458 80e555c2 Paolo Bonzini
459 80e555c2 Paolo Bonzini
    visit_type_str(v, &str, name, &local_err);
460 80e555c2 Paolo Bonzini
    if (local_err) {
461 80e555c2 Paolo Bonzini
        error_propagate(errp, local_err);
462 80e555c2 Paolo Bonzini
        return;
463 80e555c2 Paolo Bonzini
    }
464 80e555c2 Paolo Bonzini
    if (*ptr) {
465 80e555c2 Paolo Bonzini
        g_free(*ptr);
466 80e555c2 Paolo Bonzini
    }
467 80e555c2 Paolo Bonzini
    *ptr = str;
468 80e555c2 Paolo Bonzini
}
469 80e555c2 Paolo Bonzini
470 59419663 Gerd Hoffmann
PropertyInfo qdev_prop_string = {
471 59419663 Gerd Hoffmann
    .name  = "string",
472 59419663 Gerd Hoffmann
    .print = print_string,
473 dd0ba250 Paolo Bonzini
    .release = release_string,
474 80e555c2 Paolo Bonzini
    .get   = get_string,
475 80e555c2 Paolo Bonzini
    .set   = set_string,
476 59419663 Gerd Hoffmann
};
477 59419663 Gerd Hoffmann
478 14b41872 Gerd Hoffmann
/* --- drive --- */
479 14b41872 Gerd Hoffmann
480 7b009e5d Paolo Bonzini
static int parse_drive(DeviceState *dev, const char *str, void **ptr)
481 14b41872 Gerd Hoffmann
{
482 f8b6cc00 Markus Armbruster
    BlockDriverState *bs;
483 14b41872 Gerd Hoffmann
484 f8b6cc00 Markus Armbruster
    bs = bdrv_find(str);
485 f8b6cc00 Markus Armbruster
    if (bs == NULL)
486 6bf38816 Markus Armbruster
        return -ENOENT;
487 fa879d62 Markus Armbruster
    if (bdrv_attach_dev(bs, dev) < 0)
488 18846dee Markus Armbruster
        return -EEXIST;
489 f8b6cc00 Markus Armbruster
    *ptr = bs;
490 14b41872 Gerd Hoffmann
    return 0;
491 14b41872 Gerd Hoffmann
}
492 14b41872 Gerd Hoffmann
493 dd0ba250 Paolo Bonzini
static void release_drive(Object *obj, const char *name, void *opaque)
494 14bafc54 Markus Armbruster
{
495 dd0ba250 Paolo Bonzini
    DeviceState *dev = DEVICE(obj);
496 dd0ba250 Paolo Bonzini
    Property *prop = opaque;
497 f8b6cc00 Markus Armbruster
    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
498 14bafc54 Markus Armbruster
499 14bafc54 Markus Armbruster
    if (*ptr) {
500 fa879d62 Markus Armbruster
        bdrv_detach_dev(*ptr, dev);
501 f8b6cc00 Markus Armbruster
        blockdev_auto_del(*ptr);
502 14bafc54 Markus Armbruster
    }
503 14bafc54 Markus Armbruster
}
504 14bafc54 Markus Armbruster
505 7b009e5d Paolo Bonzini
static const char *print_drive(void *ptr)
506 14b41872 Gerd Hoffmann
{
507 7b009e5d Paolo Bonzini
    return bdrv_get_device_name(ptr);
508 14b41872 Gerd Hoffmann
}
509 14b41872 Gerd Hoffmann
510 7b009e5d Paolo Bonzini
static void get_drive(Object *obj, Visitor *v, void *opaque,
511 7b009e5d Paolo Bonzini
                      const char *name, Error **errp)
512 7b009e5d Paolo Bonzini
{
513 7b009e5d Paolo Bonzini
    get_pointer(obj, v, opaque, print_drive, name, errp);
514 7b009e5d Paolo Bonzini
}
515 7b009e5d Paolo Bonzini
516 7b009e5d Paolo Bonzini
static void set_drive(Object *obj, Visitor *v, void *opaque,
517 7b009e5d Paolo Bonzini
                      const char *name, Error **errp)
518 7b009e5d Paolo Bonzini
{
519 7b009e5d Paolo Bonzini
    set_pointer(obj, v, opaque, parse_drive, name, errp);
520 7b009e5d Paolo Bonzini
}
521 7b009e5d Paolo Bonzini
522 14b41872 Gerd Hoffmann
PropertyInfo qdev_prop_drive = {
523 14b41872 Gerd Hoffmann
    .name  = "drive",
524 7b009e5d Paolo Bonzini
    .get   = get_drive,
525 7b009e5d Paolo Bonzini
    .set   = set_drive,
526 dd0ba250 Paolo Bonzini
    .release = release_drive,
527 14b41872 Gerd Hoffmann
};
528 14b41872 Gerd Hoffmann
529 313feaab Gerd Hoffmann
/* --- character device --- */
530 313feaab Gerd Hoffmann
531 7b009e5d Paolo Bonzini
static int parse_chr(DeviceState *dev, const char *str, void **ptr)
532 06113719 Gerd Hoffmann
{
533 7b009e5d Paolo Bonzini
    CharDriverState *chr = qemu_chr_find(str);
534 7b009e5d Paolo Bonzini
    if (chr == NULL) {
535 6bf38816 Markus Armbruster
        return -ENOENT;
536 2d6c1ef4 Amit Shah
    }
537 7b009e5d Paolo Bonzini
    if (chr->avail_connections < 1) {
538 2d6c1ef4 Amit Shah
        return -EEXIST;
539 2d6c1ef4 Amit Shah
    }
540 7b009e5d Paolo Bonzini
    *ptr = chr;
541 7b009e5d Paolo Bonzini
    --chr->avail_connections;
542 06113719 Gerd Hoffmann
    return 0;
543 06113719 Gerd Hoffmann
}
544 06113719 Gerd Hoffmann
545 dd0ba250 Paolo Bonzini
static void release_chr(Object *obj, const char *name, void *opaque)
546 a87f3e8b Amit Shah
{
547 dd0ba250 Paolo Bonzini
    DeviceState *dev = DEVICE(obj);
548 dd0ba250 Paolo Bonzini
    Property *prop = opaque;
549 a87f3e8b Amit Shah
    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
550 a87f3e8b Amit Shah
551 a87f3e8b Amit Shah
    if (*ptr) {
552 a87f3e8b Amit Shah
        qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
553 a87f3e8b Amit Shah
    }
554 a87f3e8b Amit Shah
}
555 a87f3e8b Amit Shah
556 a87f3e8b Amit Shah
557 7b009e5d Paolo Bonzini
static const char *print_chr(void *ptr)
558 313feaab Gerd Hoffmann
{
559 7b009e5d Paolo Bonzini
    CharDriverState *chr = ptr;
560 bc19fcaa Blue Swirl
561 7b009e5d Paolo Bonzini
    return chr->label ? chr->label : "";
562 7b009e5d Paolo Bonzini
}
563 7b009e5d Paolo Bonzini
564 7b009e5d Paolo Bonzini
static void get_chr(Object *obj, Visitor *v, void *opaque,
565 7b009e5d Paolo Bonzini
                    const char *name, Error **errp)
566 7b009e5d Paolo Bonzini
{
567 7b009e5d Paolo Bonzini
    get_pointer(obj, v, opaque, print_chr, name, errp);
568 7b009e5d Paolo Bonzini
}
569 7b009e5d Paolo Bonzini
570 7b009e5d Paolo Bonzini
static void set_chr(Object *obj, Visitor *v, void *opaque,
571 7b009e5d Paolo Bonzini
                    const char *name, Error **errp)
572 7b009e5d Paolo Bonzini
{
573 7b009e5d Paolo Bonzini
    set_pointer(obj, v, opaque, parse_chr, name, errp);
574 313feaab Gerd Hoffmann
}
575 313feaab Gerd Hoffmann
576 313feaab Gerd Hoffmann
PropertyInfo qdev_prop_chr = {
577 313feaab Gerd Hoffmann
    .name  = "chr",
578 7b009e5d Paolo Bonzini
    .get   = get_chr,
579 7b009e5d Paolo Bonzini
    .set   = set_chr,
580 dd0ba250 Paolo Bonzini
    .release = release_chr,
581 313feaab Gerd Hoffmann
};
582 313feaab Gerd Hoffmann
583 2ef924b4 Gerd Hoffmann
/* --- netdev device --- */
584 2ef924b4 Gerd Hoffmann
585 7b009e5d Paolo Bonzini
static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
586 2ef924b4 Gerd Hoffmann
{
587 4e68f7a0 Stefan Hajnoczi
    NetClientState *netdev = qemu_find_netdev(str);
588 2ef924b4 Gerd Hoffmann
589 7b009e5d Paolo Bonzini
    if (netdev == NULL) {
590 6bf38816 Markus Armbruster
        return -ENOENT;
591 7b009e5d Paolo Bonzini
    }
592 7b009e5d Paolo Bonzini
    if (netdev->peer) {
593 27f3f8a3 Markus Armbruster
        return -EEXIST;
594 27f3f8a3 Markus Armbruster
    }
595 7b009e5d Paolo Bonzini
    *ptr = netdev;
596 2ef924b4 Gerd Hoffmann
    return 0;
597 2ef924b4 Gerd Hoffmann
}
598 2ef924b4 Gerd Hoffmann
599 7b009e5d Paolo Bonzini
static const char *print_netdev(void *ptr)
600 2ef924b4 Gerd Hoffmann
{
601 4e68f7a0 Stefan Hajnoczi
    NetClientState *netdev = ptr;
602 2ef924b4 Gerd Hoffmann
603 7b009e5d Paolo Bonzini
    return netdev->name ? netdev->name : "";
604 7b009e5d Paolo Bonzini
}
605 7b009e5d Paolo Bonzini
606 7b009e5d Paolo Bonzini
static void get_netdev(Object *obj, Visitor *v, void *opaque,
607 7b009e5d Paolo Bonzini
                       const char *name, Error **errp)
608 7b009e5d Paolo Bonzini
{
609 7b009e5d Paolo Bonzini
    get_pointer(obj, v, opaque, print_netdev, name, errp);
610 7b009e5d Paolo Bonzini
}
611 7b009e5d Paolo Bonzini
612 7b009e5d Paolo Bonzini
static void set_netdev(Object *obj, Visitor *v, void *opaque,
613 7b009e5d Paolo Bonzini
                       const char *name, Error **errp)
614 7b009e5d Paolo Bonzini
{
615 7b009e5d Paolo Bonzini
    set_pointer(obj, v, opaque, parse_netdev, name, errp);
616 2ef924b4 Gerd Hoffmann
}
617 2ef924b4 Gerd Hoffmann
618 2ef924b4 Gerd Hoffmann
PropertyInfo qdev_prop_netdev = {
619 2ef924b4 Gerd Hoffmann
    .name  = "netdev",
620 7b009e5d Paolo Bonzini
    .get   = get_netdev,
621 7b009e5d Paolo Bonzini
    .set   = set_netdev,
622 2ef924b4 Gerd Hoffmann
};
623 2ef924b4 Gerd Hoffmann
624 851bec09 Gerd Hoffmann
/* --- vlan --- */
625 851bec09 Gerd Hoffmann
626 851bec09 Gerd Hoffmann
static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
627 851bec09 Gerd Hoffmann
{
628 4e68f7a0 Stefan Hajnoczi
    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
629 851bec09 Gerd Hoffmann
630 851bec09 Gerd Hoffmann
    if (*ptr) {
631 606c10e2 Zhi Yong Wu
        int id;
632 606c10e2 Zhi Yong Wu
        if (!net_hub_id_for_client(*ptr, &id)) {
633 606c10e2 Zhi Yong Wu
            return snprintf(dest, len, "%d", id);
634 606c10e2 Zhi Yong Wu
        }
635 851bec09 Gerd Hoffmann
    }
636 606c10e2 Zhi Yong Wu
637 606c10e2 Zhi Yong Wu
    return snprintf(dest, len, "<null>");
638 851bec09 Gerd Hoffmann
}
639 851bec09 Gerd Hoffmann
640 57c9fafe Anthony Liguori
static void get_vlan(Object *obj, Visitor *v, void *opaque,
641 80e555c2 Paolo Bonzini
                     const char *name, Error **errp)
642 80e555c2 Paolo Bonzini
{
643 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
644 80e555c2 Paolo Bonzini
    Property *prop = opaque;
645 4e68f7a0 Stefan Hajnoczi
    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
646 606c10e2 Zhi Yong Wu
    int32_t id = -1;
647 80e555c2 Paolo Bonzini
648 606c10e2 Zhi Yong Wu
    if (*ptr) {
649 606c10e2 Zhi Yong Wu
        int hub_id;
650 606c10e2 Zhi Yong Wu
        if (!net_hub_id_for_client(*ptr, &hub_id)) {
651 606c10e2 Zhi Yong Wu
            id = hub_id;
652 606c10e2 Zhi Yong Wu
        }
653 606c10e2 Zhi Yong Wu
    }
654 606c10e2 Zhi Yong Wu
655 606c10e2 Zhi Yong Wu
    visit_type_int32(v, &id, name, errp);
656 80e555c2 Paolo Bonzini
}
657 80e555c2 Paolo Bonzini
658 57c9fafe Anthony Liguori
static void set_vlan(Object *obj, Visitor *v, void *opaque,
659 80e555c2 Paolo Bonzini
                     const char *name, Error **errp)
660 80e555c2 Paolo Bonzini
{
661 57c9fafe Anthony Liguori
    DeviceState *dev = DEVICE(obj);
662 80e555c2 Paolo Bonzini
    Property *prop = opaque;
663 4e68f7a0 Stefan Hajnoczi
    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
664 80e555c2 Paolo Bonzini
    Error *local_err = NULL;
665 606c10e2 Zhi Yong Wu
    int32_t id;
666 4e68f7a0 Stefan Hajnoczi
    NetClientState *hubport;
667 80e555c2 Paolo Bonzini
668 80e555c2 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
669 80e555c2 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
670 80e555c2 Paolo Bonzini
        return;
671 80e555c2 Paolo Bonzini
    }
672 80e555c2 Paolo Bonzini
673 606c10e2 Zhi Yong Wu
    visit_type_int32(v, &id, name, &local_err);
674 80e555c2 Paolo Bonzini
    if (local_err) {
675 80e555c2 Paolo Bonzini
        error_propagate(errp, local_err);
676 80e555c2 Paolo Bonzini
        return;
677 80e555c2 Paolo Bonzini
    }
678 80e555c2 Paolo Bonzini
    if (id == -1) {
679 80e555c2 Paolo Bonzini
        *ptr = NULL;
680 80e555c2 Paolo Bonzini
        return;
681 80e555c2 Paolo Bonzini
    }
682 606c10e2 Zhi Yong Wu
683 606c10e2 Zhi Yong Wu
    hubport = net_hub_port_find(id);
684 606c10e2 Zhi Yong Wu
    if (!hubport) {
685 80e555c2 Paolo Bonzini
        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
686 80e555c2 Paolo Bonzini
                  name, prop->info->name);
687 80e555c2 Paolo Bonzini
        return;
688 80e555c2 Paolo Bonzini
    }
689 606c10e2 Zhi Yong Wu
    *ptr = hubport;
690 80e555c2 Paolo Bonzini
}
691 80e555c2 Paolo Bonzini
692 851bec09 Gerd Hoffmann
PropertyInfo qdev_prop_vlan = {
693 851bec09 Gerd Hoffmann
    .name  = "vlan",
694 851bec09 Gerd Hoffmann
    .print = print_vlan,
695 80e555c2 Paolo Bonzini
    .get   = get_vlan,
696 80e555c2 Paolo Bonzini
    .set   = set_vlan,
697 851bec09 Gerd Hoffmann
};
698 851bec09 Gerd Hoffmann
699 ee6847d1 Gerd Hoffmann
/* --- pointer --- */
700 ee6847d1 Gerd Hoffmann
701 036f7166 Markus Armbruster
/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
702 ee6847d1 Gerd Hoffmann
PropertyInfo qdev_prop_ptr = {
703 ee6847d1 Gerd Hoffmann
    .name  = "ptr",
704 ee6847d1 Gerd Hoffmann
};
705 ee6847d1 Gerd Hoffmann
706 ee6847d1 Gerd Hoffmann
/* --- mac address --- */
707 ee6847d1 Gerd Hoffmann
708 ee6847d1 Gerd Hoffmann
/*
709 ee6847d1 Gerd Hoffmann
 * accepted syntax versions:
710 ee6847d1 Gerd Hoffmann
 *   01:02:03:04:05:06
711 ee6847d1 Gerd Hoffmann
 *   01-02-03-04-05-06
712 ee6847d1 Gerd Hoffmann
 */
713 e39e5d60 Paolo Bonzini
static void get_mac(Object *obj, Visitor *v, void *opaque,
714 e39e5d60 Paolo Bonzini
                    const char *name, Error **errp)
715 ee6847d1 Gerd Hoffmann
{
716 e39e5d60 Paolo Bonzini
    DeviceState *dev = DEVICE(obj);
717 e39e5d60 Paolo Bonzini
    Property *prop = opaque;
718 1503fff3 Gerd Hoffmann
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
719 e39e5d60 Paolo Bonzini
    char buffer[2 * 6 + 5 + 1];
720 e39e5d60 Paolo Bonzini
    char *p = buffer;
721 e39e5d60 Paolo Bonzini
722 e39e5d60 Paolo Bonzini
    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
723 e39e5d60 Paolo Bonzini
             mac->a[0], mac->a[1], mac->a[2],
724 e39e5d60 Paolo Bonzini
             mac->a[3], mac->a[4], mac->a[5]);
725 e39e5d60 Paolo Bonzini
726 e39e5d60 Paolo Bonzini
    visit_type_str(v, &p, name, errp);
727 e39e5d60 Paolo Bonzini
}
728 e39e5d60 Paolo Bonzini
729 e39e5d60 Paolo Bonzini
static void set_mac(Object *obj, Visitor *v, void *opaque,
730 e39e5d60 Paolo Bonzini
                    const char *name, Error **errp)
731 e39e5d60 Paolo Bonzini
{
732 e39e5d60 Paolo Bonzini
    DeviceState *dev = DEVICE(obj);
733 e39e5d60 Paolo Bonzini
    Property *prop = opaque;
734 e39e5d60 Paolo Bonzini
    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
735 e39e5d60 Paolo Bonzini
    Error *local_err = NULL;
736 ee6847d1 Gerd Hoffmann
    int i, pos;
737 e39e5d60 Paolo Bonzini
    char *str, *p;
738 e39e5d60 Paolo Bonzini
739 e39e5d60 Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
740 e39e5d60 Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
741 e39e5d60 Paolo Bonzini
        return;
742 e39e5d60 Paolo Bonzini
    }
743 e39e5d60 Paolo Bonzini
744 e39e5d60 Paolo Bonzini
    visit_type_str(v, &str, name, &local_err);
745 e39e5d60 Paolo Bonzini
    if (local_err) {
746 e39e5d60 Paolo Bonzini
        error_propagate(errp, local_err);
747 e39e5d60 Paolo Bonzini
        return;
748 e39e5d60 Paolo Bonzini
    }
749 ee6847d1 Gerd Hoffmann
750 ee6847d1 Gerd Hoffmann
    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
751 88e150a5 Christoph Egger
        if (!qemu_isxdigit(str[pos]))
752 e39e5d60 Paolo Bonzini
            goto inval;
753 88e150a5 Christoph Egger
        if (!qemu_isxdigit(str[pos+1]))
754 e39e5d60 Paolo Bonzini
            goto inval;
755 1503fff3 Gerd Hoffmann
        if (i == 5) {
756 1503fff3 Gerd Hoffmann
            if (str[pos+2] != '\0')
757 e39e5d60 Paolo Bonzini
                goto inval;
758 1503fff3 Gerd Hoffmann
        } else {
759 1503fff3 Gerd Hoffmann
            if (str[pos+2] != ':' && str[pos+2] != '-')
760 e39e5d60 Paolo Bonzini
                goto inval;
761 1503fff3 Gerd Hoffmann
        }
762 1503fff3 Gerd Hoffmann
        mac->a[i] = strtol(str+pos, &p, 16);
763 ee6847d1 Gerd Hoffmann
    }
764 a3400466 dunrong huang
    g_free(str);
765 e39e5d60 Paolo Bonzini
    return;
766 1503fff3 Gerd Hoffmann
767 e39e5d60 Paolo Bonzini
inval:
768 e39e5d60 Paolo Bonzini
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
769 a3400466 dunrong huang
    g_free(str);
770 ee6847d1 Gerd Hoffmann
}
771 ee6847d1 Gerd Hoffmann
772 ee6847d1 Gerd Hoffmann
PropertyInfo qdev_prop_macaddr = {
773 1503fff3 Gerd Hoffmann
    .name  = "macaddr",
774 e39e5d60 Paolo Bonzini
    .get   = get_mac,
775 e39e5d60 Paolo Bonzini
    .set   = set_mac,
776 ee6847d1 Gerd Hoffmann
};
777 ee6847d1 Gerd Hoffmann
778 4e4fa398 Jan Kiszka
/* --- lost tick policy --- */
779 4e4fa398 Jan Kiszka
780 1ce05125 Paolo Bonzini
static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
781 1ce05125 Paolo Bonzini
    [LOST_TICK_DISCARD] = "discard",
782 1ce05125 Paolo Bonzini
    [LOST_TICK_DELAY] = "delay",
783 1ce05125 Paolo Bonzini
    [LOST_TICK_MERGE] = "merge",
784 1ce05125 Paolo Bonzini
    [LOST_TICK_SLEW] = "slew",
785 1ce05125 Paolo Bonzini
    [LOST_TICK_MAX] = NULL,
786 4e4fa398 Jan Kiszka
};
787 4e4fa398 Jan Kiszka
788 1ce05125 Paolo Bonzini
QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
789 1ce05125 Paolo Bonzini
790 4e4fa398 Jan Kiszka
PropertyInfo qdev_prop_losttickpolicy = {
791 1ce05125 Paolo Bonzini
    .name  = "LostTickPolicy",
792 1ce05125 Paolo Bonzini
    .enum_table  = lost_tick_policy_table,
793 1ce05125 Paolo Bonzini
    .get   = get_enum,
794 1ce05125 Paolo Bonzini
    .set   = set_enum,
795 4e4fa398 Jan Kiszka
};
796 4e4fa398 Jan Kiszka
797 8cd41745 Markus Armbruster
/* --- BIOS CHS translation */
798 8cd41745 Markus Armbruster
799 8cd41745 Markus Armbruster
static const char *bios_chs_trans_table[] = {
800 8cd41745 Markus Armbruster
    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
801 8cd41745 Markus Armbruster
    [BIOS_ATA_TRANSLATION_NONE] = "none",
802 8cd41745 Markus Armbruster
    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
803 8cd41745 Markus Armbruster
};
804 8cd41745 Markus Armbruster
805 8cd41745 Markus Armbruster
PropertyInfo qdev_prop_bios_chs_trans = {
806 8cd41745 Markus Armbruster
    .name = "bios-chs-trans",
807 8cd41745 Markus Armbruster
    .enum_table = bios_chs_trans_table,
808 8cd41745 Markus Armbruster
    .get = get_enum,
809 8cd41745 Markus Armbruster
    .set = set_enum,
810 8cd41745 Markus Armbruster
};
811 8cd41745 Markus Armbruster
812 05cb5fe4 Gerd Hoffmann
/* --- pci address --- */
813 05cb5fe4 Gerd Hoffmann
814 05cb5fe4 Gerd Hoffmann
/*
815 05cb5fe4 Gerd Hoffmann
 * bus-local address, i.e. "$slot" or "$slot.$fn"
816 05cb5fe4 Gerd Hoffmann
 */
817 768a9ebe Paolo Bonzini
static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
818 768a9ebe Paolo Bonzini
                          const char *name, Error **errp)
819 05cb5fe4 Gerd Hoffmann
{
820 768a9ebe Paolo Bonzini
    DeviceState *dev = DEVICE(obj);
821 768a9ebe Paolo Bonzini
    Property *prop = opaque;
822 27712df9 Paolo Bonzini
    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
823 05cb5fe4 Gerd Hoffmann
    unsigned int slot, fn, n;
824 768a9ebe Paolo Bonzini
    Error *local_err = NULL;
825 a3400466 dunrong huang
    char *str;
826 768a9ebe Paolo Bonzini
827 768a9ebe Paolo Bonzini
    if (dev->state != DEV_STATE_CREATED) {
828 768a9ebe Paolo Bonzini
        error_set(errp, QERR_PERMISSION_DENIED);
829 768a9ebe Paolo Bonzini
        return;
830 768a9ebe Paolo Bonzini
    }
831 768a9ebe Paolo Bonzini
832 768a9ebe Paolo Bonzini
    visit_type_str(v, &str, name, &local_err);
833 768a9ebe Paolo Bonzini
    if (local_err) {
834 5c878008 Stefan Weil
        error_free(local_err);
835 27712df9 Paolo Bonzini
        local_err = NULL;
836 27712df9 Paolo Bonzini
        visit_type_int32(v, &value, name, &local_err);
837 27712df9 Paolo Bonzini
        if (local_err) {
838 27712df9 Paolo Bonzini
            error_propagate(errp, local_err);
839 27712df9 Paolo Bonzini
        } else if (value < -1 || value > 255) {
840 27712df9 Paolo Bonzini
            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
841 27712df9 Paolo Bonzini
                      "pci_devfn");
842 27712df9 Paolo Bonzini
        } else {
843 27712df9 Paolo Bonzini
            *ptr = value;
844 27712df9 Paolo Bonzini
        }
845 27712df9 Paolo Bonzini
        return;
846 768a9ebe Paolo Bonzini
    }
847 05cb5fe4 Gerd Hoffmann
848 05cb5fe4 Gerd Hoffmann
    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
849 05cb5fe4 Gerd Hoffmann
        fn = 0;
850 05cb5fe4 Gerd Hoffmann
        if (sscanf(str, "%x%n", &slot, &n) != 1) {
851 768a9ebe Paolo Bonzini
            goto invalid;
852 05cb5fe4 Gerd Hoffmann
        }
853 05cb5fe4 Gerd Hoffmann
    }
854 768a9ebe Paolo Bonzini
    if (str[n] != '\0' || fn > 7 || slot > 31) {
855 768a9ebe Paolo Bonzini
        goto invalid;
856 768a9ebe Paolo Bonzini
    }
857 05cb5fe4 Gerd Hoffmann
    *ptr = slot << 3 | fn;
858 a3400466 dunrong huang
    g_free(str);
859 768a9ebe Paolo Bonzini
    return;
860 768a9ebe Paolo Bonzini
861 768a9ebe Paolo Bonzini
invalid:
862 768a9ebe Paolo Bonzini
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
863 a3400466 dunrong huang
    g_free(str);
864 05cb5fe4 Gerd Hoffmann
}
865 05cb5fe4 Gerd Hoffmann
866 05cb5fe4 Gerd Hoffmann
static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
867 05cb5fe4 Gerd Hoffmann
{
868 09f1bbcd Michael Roth
    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
869 05cb5fe4 Gerd Hoffmann
870 73538c31 Blue Swirl
    if (*ptr == -1) {
871 05cb5fe4 Gerd Hoffmann
        return snprintf(dest, len, "<unset>");
872 05cb5fe4 Gerd Hoffmann
    } else {
873 05cb5fe4 Gerd Hoffmann
        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
874 05cb5fe4 Gerd Hoffmann
    }
875 05cb5fe4 Gerd Hoffmann
}
876 05cb5fe4 Gerd Hoffmann
877 05cb5fe4 Gerd Hoffmann
PropertyInfo qdev_prop_pci_devfn = {
878 b403298a Paolo Bonzini
    .name  = "int32",
879 b403298a Paolo Bonzini
    .legacy_name  = "pci-devfn",
880 05cb5fe4 Gerd Hoffmann
    .print = print_pci_devfn,
881 b403298a Paolo Bonzini
    .get   = get_int32,
882 768a9ebe Paolo Bonzini
    .set   = set_pci_devfn,
883 05cb5fe4 Gerd Hoffmann
};
884 05cb5fe4 Gerd Hoffmann
885 02fda01c Stefan Hajnoczi
/* --- blocksize --- */
886 02fda01c Stefan Hajnoczi
887 02fda01c Stefan Hajnoczi
static void set_blocksize(Object *obj, Visitor *v, void *opaque,
888 02fda01c Stefan Hajnoczi
                          const char *name, Error **errp)
889 02fda01c Stefan Hajnoczi
{
890 02fda01c Stefan Hajnoczi
    DeviceState *dev = DEVICE(obj);
891 02fda01c Stefan Hajnoczi
    Property *prop = opaque;
892 c08fb2ac Michael Roth
    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
893 02fda01c Stefan Hajnoczi
    Error *local_err = NULL;
894 27712df9 Paolo Bonzini
    const int64_t min = 512;
895 27712df9 Paolo Bonzini
    const int64_t max = 32768;
896 02fda01c Stefan Hajnoczi
897 02fda01c Stefan Hajnoczi
    if (dev->state != DEV_STATE_CREATED) {
898 02fda01c Stefan Hajnoczi
        error_set(errp, QERR_PERMISSION_DENIED);
899 02fda01c Stefan Hajnoczi
        return;
900 02fda01c Stefan Hajnoczi
    }
901 02fda01c Stefan Hajnoczi
902 c08fb2ac Michael Roth
    visit_type_uint16(v, &value, name, &local_err);
903 02fda01c Stefan Hajnoczi
    if (local_err) {
904 02fda01c Stefan Hajnoczi
        error_propagate(errp, local_err);
905 02fda01c Stefan Hajnoczi
        return;
906 02fda01c Stefan Hajnoczi
    }
907 27712df9 Paolo Bonzini
    if (value < min || value > max) {
908 02fda01c Stefan Hajnoczi
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
909 27712df9 Paolo Bonzini
                  dev->id?:"", name, (int64_t)value, min, max);
910 02fda01c Stefan Hajnoczi
        return;
911 02fda01c Stefan Hajnoczi
    }
912 02fda01c Stefan Hajnoczi
913 02fda01c Stefan Hajnoczi
    /* We rely on power-of-2 blocksizes for bitmasks */
914 02fda01c Stefan Hajnoczi
    if ((value & (value - 1)) != 0) {
915 02fda01c Stefan Hajnoczi
        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
916 c08fb2ac Michael Roth
                  dev->id?:"", name, (int64_t)value);
917 02fda01c Stefan Hajnoczi
        return;
918 02fda01c Stefan Hajnoczi
    }
919 02fda01c Stefan Hajnoczi
920 02fda01c Stefan Hajnoczi
    *ptr = value;
921 02fda01c Stefan Hajnoczi
}
922 02fda01c Stefan Hajnoczi
923 02fda01c Stefan Hajnoczi
PropertyInfo qdev_prop_blocksize = {
924 02fda01c Stefan Hajnoczi
    .name  = "blocksize",
925 c08fb2ac Michael Roth
    .get   = get_uint16,
926 02fda01c Stefan Hajnoczi
    .set   = set_blocksize,
927 02fda01c Stefan Hajnoczi
};
928 02fda01c Stefan Hajnoczi
929 679042f0 Anthony PERARD
/* --- pci host address --- */
930 679042f0 Anthony PERARD
931 679042f0 Anthony PERARD
static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
932 679042f0 Anthony PERARD
                                 const char *name, Error **errp)
933 679042f0 Anthony PERARD
{
934 679042f0 Anthony PERARD
    DeviceState *dev = DEVICE(obj);
935 679042f0 Anthony PERARD
    Property *prop = opaque;
936 679042f0 Anthony PERARD
    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
937 679042f0 Anthony PERARD
    char buffer[] = "xxxx:xx:xx.x";
938 679042f0 Anthony PERARD
    char *p = buffer;
939 679042f0 Anthony PERARD
    int rc = 0;
940 679042f0 Anthony PERARD
941 679042f0 Anthony PERARD
    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
942 679042f0 Anthony PERARD
                  addr->domain, addr->bus, addr->slot, addr->function);
943 679042f0 Anthony PERARD
    assert(rc == sizeof(buffer) - 1);
944 679042f0 Anthony PERARD
945 679042f0 Anthony PERARD
    visit_type_str(v, &p, name, errp);
946 679042f0 Anthony PERARD
}
947 679042f0 Anthony PERARD
948 679042f0 Anthony PERARD
/*
949 679042f0 Anthony PERARD
 * Parse [<domain>:]<bus>:<slot>.<func>
950 679042f0 Anthony PERARD
 *   if <domain> is not supplied, it's assumed to be 0.
951 679042f0 Anthony PERARD
 */
952 679042f0 Anthony PERARD
static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
953 679042f0 Anthony PERARD
                                 const char *name, Error **errp)
954 679042f0 Anthony PERARD
{
955 679042f0 Anthony PERARD
    DeviceState *dev = DEVICE(obj);
956 679042f0 Anthony PERARD
    Property *prop = opaque;
957 679042f0 Anthony PERARD
    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
958 679042f0 Anthony PERARD
    Error *local_err = NULL;
959 679042f0 Anthony PERARD
    char *str, *p;
960 679042f0 Anthony PERARD
    char *e;
961 679042f0 Anthony PERARD
    unsigned long val;
962 679042f0 Anthony PERARD
    unsigned long dom = 0, bus = 0;
963 679042f0 Anthony PERARD
    unsigned int slot = 0, func = 0;
964 679042f0 Anthony PERARD
965 679042f0 Anthony PERARD
    if (dev->state != DEV_STATE_CREATED) {
966 679042f0 Anthony PERARD
        error_set(errp, QERR_PERMISSION_DENIED);
967 679042f0 Anthony PERARD
        return;
968 679042f0 Anthony PERARD
    }
969 679042f0 Anthony PERARD
970 679042f0 Anthony PERARD
    visit_type_str(v, &str, name, &local_err);
971 679042f0 Anthony PERARD
    if (local_err) {
972 679042f0 Anthony PERARD
        error_propagate(errp, local_err);
973 679042f0 Anthony PERARD
        return;
974 679042f0 Anthony PERARD
    }
975 679042f0 Anthony PERARD
976 679042f0 Anthony PERARD
    p = str;
977 679042f0 Anthony PERARD
    val = strtoul(p, &e, 16);
978 679042f0 Anthony PERARD
    if (e == p || *e != ':') {
979 679042f0 Anthony PERARD
        goto inval;
980 679042f0 Anthony PERARD
    }
981 679042f0 Anthony PERARD
    bus = val;
982 679042f0 Anthony PERARD
983 679042f0 Anthony PERARD
    p = e + 1;
984 679042f0 Anthony PERARD
    val = strtoul(p, &e, 16);
985 679042f0 Anthony PERARD
    if (e == p) {
986 679042f0 Anthony PERARD
        goto inval;
987 679042f0 Anthony PERARD
    }
988 679042f0 Anthony PERARD
    if (*e == ':') {
989 679042f0 Anthony PERARD
        dom = bus;
990 679042f0 Anthony PERARD
        bus = val;
991 679042f0 Anthony PERARD
        p = e + 1;
992 679042f0 Anthony PERARD
        val = strtoul(p, &e, 16);
993 679042f0 Anthony PERARD
        if (e == p) {
994 679042f0 Anthony PERARD
            goto inval;
995 679042f0 Anthony PERARD
        }
996 679042f0 Anthony PERARD
    }
997 679042f0 Anthony PERARD
    slot = val;
998 679042f0 Anthony PERARD
999 679042f0 Anthony PERARD
    if (*e != '.') {
1000 679042f0 Anthony PERARD
        goto inval;
1001 679042f0 Anthony PERARD
    }
1002 679042f0 Anthony PERARD
    p = e + 1;
1003 679042f0 Anthony PERARD
    val = strtoul(p, &e, 10);
1004 679042f0 Anthony PERARD
    if (e == p) {
1005 679042f0 Anthony PERARD
        goto inval;
1006 679042f0 Anthony PERARD
    }
1007 679042f0 Anthony PERARD
    func = val;
1008 679042f0 Anthony PERARD
1009 679042f0 Anthony PERARD
    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
1010 679042f0 Anthony PERARD
        goto inval;
1011 679042f0 Anthony PERARD
    }
1012 679042f0 Anthony PERARD
1013 679042f0 Anthony PERARD
    if (*e) {
1014 679042f0 Anthony PERARD
        goto inval;
1015 679042f0 Anthony PERARD
    }
1016 679042f0 Anthony PERARD
1017 679042f0 Anthony PERARD
    addr->domain = dom;
1018 679042f0 Anthony PERARD
    addr->bus = bus;
1019 679042f0 Anthony PERARD
    addr->slot = slot;
1020 679042f0 Anthony PERARD
    addr->function = func;
1021 679042f0 Anthony PERARD
1022 679042f0 Anthony PERARD
    g_free(str);
1023 679042f0 Anthony PERARD
    return;
1024 679042f0 Anthony PERARD
1025 679042f0 Anthony PERARD
inval:
1026 679042f0 Anthony PERARD
    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
1027 679042f0 Anthony PERARD
    g_free(str);
1028 679042f0 Anthony PERARD
}
1029 679042f0 Anthony PERARD
1030 679042f0 Anthony PERARD
PropertyInfo qdev_prop_pci_host_devaddr = {
1031 679042f0 Anthony PERARD
    .name = "pci-host-devaddr",
1032 679042f0 Anthony PERARD
    .get = get_pci_host_devaddr,
1033 679042f0 Anthony PERARD
    .set = set_pci_host_devaddr,
1034 679042f0 Anthony PERARD
};
1035 679042f0 Anthony PERARD
1036 ee6847d1 Gerd Hoffmann
/* --- public helpers --- */
1037 ee6847d1 Gerd Hoffmann
1038 ee6847d1 Gerd Hoffmann
static Property *qdev_prop_walk(Property *props, const char *name)
1039 ee6847d1 Gerd Hoffmann
{
1040 ee6847d1 Gerd Hoffmann
    if (!props)
1041 ee6847d1 Gerd Hoffmann
        return NULL;
1042 ee6847d1 Gerd Hoffmann
    while (props->name) {
1043 ee6847d1 Gerd Hoffmann
        if (strcmp(props->name, name) == 0)
1044 ee6847d1 Gerd Hoffmann
            return props;
1045 ee6847d1 Gerd Hoffmann
        props++;
1046 ee6847d1 Gerd Hoffmann
    }
1047 ee6847d1 Gerd Hoffmann
    return NULL;
1048 ee6847d1 Gerd Hoffmann
}
1049 ee6847d1 Gerd Hoffmann
1050 ee6847d1 Gerd Hoffmann
static Property *qdev_prop_find(DeviceState *dev, const char *name)
1051 ee6847d1 Gerd Hoffmann
{
1052 bce54474 Paolo Bonzini
    ObjectClass *class;
1053 ee6847d1 Gerd Hoffmann
    Property *prop;
1054 ee6847d1 Gerd Hoffmann
1055 ee6847d1 Gerd Hoffmann
    /* device properties */
1056 bce54474 Paolo Bonzini
    class = object_get_class(OBJECT(dev));
1057 bce54474 Paolo Bonzini
    do {
1058 bce54474 Paolo Bonzini
        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
1059 bce54474 Paolo Bonzini
        if (prop) {
1060 bce54474 Paolo Bonzini
            return prop;
1061 bce54474 Paolo Bonzini
        }
1062 bce54474 Paolo Bonzini
        class = object_class_get_parent(class);
1063 bce54474 Paolo Bonzini
    } while (class != object_class_by_name(TYPE_DEVICE));
1064 ee6847d1 Gerd Hoffmann
1065 ee6847d1 Gerd Hoffmann
    return NULL;
1066 ee6847d1 Gerd Hoffmann
}
1067 ee6847d1 Gerd Hoffmann
1068 7db4c4e8 Paolo Bonzini
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1069 7db4c4e8 Paolo Bonzini
                                    Property *prop, const char *value)
1070 7db4c4e8 Paolo Bonzini
{
1071 7db4c4e8 Paolo Bonzini
    switch (ret) {
1072 7db4c4e8 Paolo Bonzini
    case -EEXIST:
1073 7db4c4e8 Paolo Bonzini
        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
1074 f79f2bfc Anthony Liguori
                  object_get_typename(OBJECT(dev)), prop->name, value);
1075 7db4c4e8 Paolo Bonzini
        break;
1076 7db4c4e8 Paolo Bonzini
    default:
1077 7db4c4e8 Paolo Bonzini
    case -EINVAL:
1078 7db4c4e8 Paolo Bonzini
        error_set(errp, QERR_PROPERTY_VALUE_BAD,
1079 f79f2bfc Anthony Liguori
                  object_get_typename(OBJECT(dev)), prop->name, value);
1080 7db4c4e8 Paolo Bonzini
        break;
1081 7db4c4e8 Paolo Bonzini
    case -ENOENT:
1082 7db4c4e8 Paolo Bonzini
        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
1083 f79f2bfc Anthony Liguori
                  object_get_typename(OBJECT(dev)), prop->name, value);
1084 7db4c4e8 Paolo Bonzini
        break;
1085 7db4c4e8 Paolo Bonzini
    case 0:
1086 7db4c4e8 Paolo Bonzini
        break;
1087 7db4c4e8 Paolo Bonzini
    }
1088 7db4c4e8 Paolo Bonzini
}
1089 7db4c4e8 Paolo Bonzini
1090 ee6847d1 Gerd Hoffmann
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
1091 ee6847d1 Gerd Hoffmann
{
1092 d822979b Paolo Bonzini
    char *legacy_name;
1093 d822979b Paolo Bonzini
    Error *err = NULL;
1094 ee6847d1 Gerd Hoffmann
1095 d822979b Paolo Bonzini
    legacy_name = g_strdup_printf("legacy-%s", name);
1096 d822979b Paolo Bonzini
    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
1097 0c96e285 Paolo Bonzini
        object_property_parse(OBJECT(dev), value, legacy_name, &err);
1098 d822979b Paolo Bonzini
    } else {
1099 0c96e285 Paolo Bonzini
        object_property_parse(OBJECT(dev), value, name, &err);
1100 ee6847d1 Gerd Hoffmann
    }
1101 d822979b Paolo Bonzini
    g_free(legacy_name);
1102 d822979b Paolo Bonzini
1103 d822979b Paolo Bonzini
    if (err) {
1104 7db4c4e8 Paolo Bonzini
        qerror_report_err(err);
1105 7db4c4e8 Paolo Bonzini
        error_free(err);
1106 9ef5c4bf Gerd Hoffmann
        return -1;
1107 9ef5c4bf Gerd Hoffmann
    }
1108 9ef5c4bf Gerd Hoffmann
    return 0;
1109 ee6847d1 Gerd Hoffmann
}
1110 ee6847d1 Gerd Hoffmann
1111 f4594a3b Isaku Yamahata
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1112 f4594a3b Isaku Yamahata
{
1113 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1114 9b170e60 Paolo Bonzini
    object_property_set_bool(OBJECT(dev), value, name, &errp);
1115 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1116 f4594a3b Isaku Yamahata
}
1117 f4594a3b Isaku Yamahata
1118 c7cc172d Juan Quintela
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1119 c7cc172d Juan Quintela
{
1120 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1121 9b170e60 Paolo Bonzini
    object_property_set_int(OBJECT(dev), value, name, &errp);
1122 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1123 c7cc172d Juan Quintela
}
1124 c7cc172d Juan Quintela
1125 ee6847d1 Gerd Hoffmann
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1126 ee6847d1 Gerd Hoffmann
{
1127 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1128 9b170e60 Paolo Bonzini
    object_property_set_int(OBJECT(dev), value, name, &errp);
1129 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1130 ee6847d1 Gerd Hoffmann
}
1131 ee6847d1 Gerd Hoffmann
1132 ee6847d1 Gerd Hoffmann
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1133 ee6847d1 Gerd Hoffmann
{
1134 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1135 9b170e60 Paolo Bonzini
    object_property_set_int(OBJECT(dev), value, name, &errp);
1136 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1137 ee6847d1 Gerd Hoffmann
}
1138 ee6847d1 Gerd Hoffmann
1139 316940b0 Gerd Hoffmann
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1140 316940b0 Gerd Hoffmann
{
1141 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1142 9b170e60 Paolo Bonzini
    object_property_set_int(OBJECT(dev), value, name, &errp);
1143 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1144 316940b0 Gerd Hoffmann
}
1145 316940b0 Gerd Hoffmann
1146 5a053d1f Blue Swirl
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1147 5a053d1f Blue Swirl
{
1148 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1149 9b170e60 Paolo Bonzini
    object_property_set_int(OBJECT(dev), value, name, &errp);
1150 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1151 5a053d1f Blue Swirl
}
1152 5a053d1f Blue Swirl
1153 3b25597b Christian Borntraeger
void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1154 cc984673 Markus Armbruster
{
1155 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1156 9b170e60 Paolo Bonzini
    object_property_set_str(OBJECT(dev), value, name, &errp);
1157 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1158 cc984673 Markus Armbruster
}
1159 cc984673 Markus Armbruster
1160 18846dee Markus Armbruster
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
1161 14b41872 Gerd Hoffmann
{
1162 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1163 0a54a0ce Paolo Bonzini
    const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
1164 0a54a0ce Paolo Bonzini
    object_property_set_str(OBJECT(dev), bdrv_name,
1165 9b170e60 Paolo Bonzini
                            name, &errp);
1166 9b170e60 Paolo Bonzini
    if (errp) {
1167 9b170e60 Paolo Bonzini
        qerror_report_err(errp);
1168 9b170e60 Paolo Bonzini
        error_free(errp);
1169 18846dee Markus Armbruster
        return -1;
1170 18846dee Markus Armbruster
    }
1171 18846dee Markus Armbruster
    return 0;
1172 14b41872 Gerd Hoffmann
}
1173 14b41872 Gerd Hoffmann
1174 18846dee Markus Armbruster
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
1175 18846dee Markus Armbruster
{
1176 18846dee Markus Armbruster
    if (qdev_prop_set_drive(dev, name, value) < 0) {
1177 18846dee Markus Armbruster
        exit(1);
1178 18846dee Markus Armbruster
    }
1179 18846dee Markus Armbruster
}
1180 313feaab Gerd Hoffmann
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
1181 313feaab Gerd Hoffmann
{
1182 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1183 0a54a0ce Paolo Bonzini
    assert(!value || value->label);
1184 0a54a0ce Paolo Bonzini
    object_property_set_str(OBJECT(dev),
1185 0a54a0ce Paolo Bonzini
                            value ? value->label : "", name, &errp);
1186 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1187 313feaab Gerd Hoffmann
}
1188 313feaab Gerd Hoffmann
1189 4e68f7a0 Stefan Hajnoczi
void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value)
1190 2ef924b4 Gerd Hoffmann
{
1191 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1192 0a54a0ce Paolo Bonzini
    assert(!value || value->name);
1193 0a54a0ce Paolo Bonzini
    object_property_set_str(OBJECT(dev),
1194 0a54a0ce Paolo Bonzini
                            value ? value->name : "", name, &errp);
1195 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1196 2ef924b4 Gerd Hoffmann
}
1197 2ef924b4 Gerd Hoffmann
1198 1503fff3 Gerd Hoffmann
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
1199 1503fff3 Gerd Hoffmann
{
1200 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1201 9b170e60 Paolo Bonzini
    char str[2 * 6 + 5 + 1];
1202 9b170e60 Paolo Bonzini
    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1203 9b170e60 Paolo Bonzini
             value[0], value[1], value[2], value[3], value[4], value[5]);
1204 9b170e60 Paolo Bonzini
1205 9b170e60 Paolo Bonzini
    object_property_set_str(OBJECT(dev), str, name, &errp);
1206 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1207 1503fff3 Gerd Hoffmann
}
1208 1503fff3 Gerd Hoffmann
1209 9b170e60 Paolo Bonzini
void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1210 4e4fa398 Jan Kiszka
{
1211 9b170e60 Paolo Bonzini
    Property *prop;
1212 9b170e60 Paolo Bonzini
    Error *errp = NULL;
1213 9b170e60 Paolo Bonzini
1214 9b170e60 Paolo Bonzini
    prop = qdev_prop_find(dev, name);
1215 9b170e60 Paolo Bonzini
    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1216 9b170e60 Paolo Bonzini
                            name, &errp);
1217 59f971d4 Paolo Bonzini
    assert_no_error(errp);
1218 4e4fa398 Jan Kiszka
}
1219 4e4fa398 Jan Kiszka
1220 ee6847d1 Gerd Hoffmann
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1221 ee6847d1 Gerd Hoffmann
{
1222 7a7aae21 Paolo Bonzini
    Property *prop;
1223 7a7aae21 Paolo Bonzini
    void **ptr;
1224 7a7aae21 Paolo Bonzini
1225 7a7aae21 Paolo Bonzini
    prop = qdev_prop_find(dev, name);
1226 7a7aae21 Paolo Bonzini
    assert(prop && prop->info == &qdev_prop_ptr);
1227 7a7aae21 Paolo Bonzini
    ptr = qdev_get_prop_ptr(dev, prop);
1228 7a7aae21 Paolo Bonzini
    *ptr = value;
1229 ee6847d1 Gerd Hoffmann
}
1230 ee6847d1 Gerd Hoffmann
1231 458fb679 Gerd Hoffmann
static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
1232 b6b61144 Gerd Hoffmann
1233 25920d6a Kevin Wolf
static void qdev_prop_register_global(GlobalProperty *prop)
1234 b6b61144 Gerd Hoffmann
{
1235 458fb679 Gerd Hoffmann
    QTAILQ_INSERT_TAIL(&global_props, prop, next);
1236 b6b61144 Gerd Hoffmann
}
1237 b6b61144 Gerd Hoffmann
1238 458fb679 Gerd Hoffmann
void qdev_prop_register_global_list(GlobalProperty *props)
1239 b6b61144 Gerd Hoffmann
{
1240 458fb679 Gerd Hoffmann
    int i;
1241 b6b61144 Gerd Hoffmann
1242 458fb679 Gerd Hoffmann
    for (i = 0; props[i].driver != NULL; i++) {
1243 458fb679 Gerd Hoffmann
        qdev_prop_register_global(props+i);
1244 b6b61144 Gerd Hoffmann
    }
1245 458fb679 Gerd Hoffmann
}
1246 458fb679 Gerd Hoffmann
1247 458fb679 Gerd Hoffmann
void qdev_prop_set_globals(DeviceState *dev)
1248 458fb679 Gerd Hoffmann
{
1249 bce54474 Paolo Bonzini
    ObjectClass *class = object_get_class(OBJECT(dev));
1250 bce54474 Paolo Bonzini
1251 bce54474 Paolo Bonzini
    do {
1252 bce54474 Paolo Bonzini
        GlobalProperty *prop;
1253 bce54474 Paolo Bonzini
        QTAILQ_FOREACH(prop, &global_props, next) {
1254 bce54474 Paolo Bonzini
            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
1255 bce54474 Paolo Bonzini
                continue;
1256 bce54474 Paolo Bonzini
            }
1257 bce54474 Paolo Bonzini
            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
1258 bce54474 Paolo Bonzini
                exit(1);
1259 bce54474 Paolo Bonzini
            }
1260 b6b61144 Gerd Hoffmann
        }
1261 bce54474 Paolo Bonzini
        class = object_class_get_parent(class);
1262 bce54474 Paolo Bonzini
    } while (class);
1263 b6b61144 Gerd Hoffmann
}
1264 25920d6a Kevin Wolf
1265 25920d6a Kevin Wolf
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
1266 25920d6a Kevin Wolf
{
1267 25920d6a Kevin Wolf
    GlobalProperty *g;
1268 25920d6a Kevin Wolf
1269 7267c094 Anthony Liguori
    g = g_malloc0(sizeof(*g));
1270 25920d6a Kevin Wolf
    g->driver   = qemu_opt_get(opts, "driver");
1271 25920d6a Kevin Wolf
    g->property = qemu_opt_get(opts, "property");
1272 25920d6a Kevin Wolf
    g->value    = qemu_opt_get(opts, "value");
1273 25920d6a Kevin Wolf
    qdev_prop_register_global(g);
1274 25920d6a Kevin Wolf
    return 0;
1275 25920d6a Kevin Wolf
}
1276 25920d6a Kevin Wolf
1277 25920d6a Kevin Wolf
void qemu_add_globals(void)
1278 25920d6a Kevin Wolf
{
1279 3329f07b Gerd Hoffmann
    qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
1280 25920d6a Kevin Wolf
}