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