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 | } |