Statistics
| Branch: | Revision:

root / hw / qdev-properties.c @ 4e4fa398

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