root / hw / qdev-properties.c @ ae710b99
History | View | Annotate | Download (29.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 | 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 (*ptr) {
|
425 | 80e555c2 | Paolo Bonzini | g_free(*ptr); |
426 | 80e555c2 | Paolo Bonzini | } |
427 | 80e555c2 | Paolo Bonzini | *ptr = str; |
428 | 80e555c2 | Paolo Bonzini | } |
429 | 80e555c2 | Paolo Bonzini | |
430 | 59419663 | Gerd Hoffmann | PropertyInfo qdev_prop_string = { |
431 | 59419663 | Gerd Hoffmann | .name = "string",
|
432 | 59419663 | Gerd Hoffmann | .print = print_string, |
433 | dd0ba250 | Paolo Bonzini | .release = release_string, |
434 | 80e555c2 | Paolo Bonzini | .get = get_string, |
435 | 80e555c2 | Paolo Bonzini | .set = set_string, |
436 | 59419663 | Gerd Hoffmann | }; |
437 | 59419663 | Gerd Hoffmann | |
438 | 14b41872 | Gerd Hoffmann | /* --- drive --- */
|
439 | 14b41872 | Gerd Hoffmann | |
440 | 7b009e5d | Paolo Bonzini | static int parse_drive(DeviceState *dev, const char *str, void **ptr) |
441 | 14b41872 | Gerd Hoffmann | { |
442 | f8b6cc00 | Markus Armbruster | BlockDriverState *bs; |
443 | 14b41872 | Gerd Hoffmann | |
444 | f8b6cc00 | Markus Armbruster | bs = bdrv_find(str); |
445 | f8b6cc00 | Markus Armbruster | if (bs == NULL) |
446 | 6bf38816 | Markus Armbruster | return -ENOENT;
|
447 | fa879d62 | Markus Armbruster | if (bdrv_attach_dev(bs, dev) < 0) |
448 | 18846dee | Markus Armbruster | return -EEXIST;
|
449 | f8b6cc00 | Markus Armbruster | *ptr = bs; |
450 | 14b41872 | Gerd Hoffmann | return 0; |
451 | 14b41872 | Gerd Hoffmann | } |
452 | 14b41872 | Gerd Hoffmann | |
453 | dd0ba250 | Paolo Bonzini | static void release_drive(Object *obj, const char *name, void *opaque) |
454 | 14bafc54 | Markus Armbruster | { |
455 | dd0ba250 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
456 | dd0ba250 | Paolo Bonzini | Property *prop = opaque; |
457 | f8b6cc00 | Markus Armbruster | BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); |
458 | 14bafc54 | Markus Armbruster | |
459 | 14bafc54 | Markus Armbruster | if (*ptr) {
|
460 | fa879d62 | Markus Armbruster | bdrv_detach_dev(*ptr, dev); |
461 | f8b6cc00 | Markus Armbruster | blockdev_auto_del(*ptr); |
462 | 14bafc54 | Markus Armbruster | } |
463 | 14bafc54 | Markus Armbruster | } |
464 | 14bafc54 | Markus Armbruster | |
465 | 7b009e5d | Paolo Bonzini | static const char *print_drive(void *ptr) |
466 | 14b41872 | Gerd Hoffmann | { |
467 | 7b009e5d | Paolo Bonzini | return bdrv_get_device_name(ptr);
|
468 | 14b41872 | Gerd Hoffmann | } |
469 | 14b41872 | Gerd Hoffmann | |
470 | 7b009e5d | Paolo Bonzini | static void get_pointer(Object *obj, Visitor *v, Property *prop, |
471 | 7b009e5d | Paolo Bonzini | const char *(*print)(void *ptr), |
472 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
473 | 80e555c2 | Paolo Bonzini | { |
474 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
475 | 80e555c2 | Paolo Bonzini | void **ptr = qdev_get_prop_ptr(dev, prop);
|
476 | 7b009e5d | Paolo Bonzini | char *p;
|
477 | 80e555c2 | Paolo Bonzini | |
478 | 7b009e5d | Paolo Bonzini | p = (char *) (*ptr ? print(*ptr) : ""); |
479 | 80e555c2 | Paolo Bonzini | visit_type_str(v, &p, name, errp); |
480 | 80e555c2 | Paolo Bonzini | } |
481 | 80e555c2 | Paolo Bonzini | |
482 | 7b009e5d | Paolo Bonzini | static void set_pointer(Object *obj, Visitor *v, Property *prop, |
483 | 7b009e5d | Paolo Bonzini | int (*parse)(DeviceState *dev, const char *str, void **ptr), |
484 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
485 | 80e555c2 | Paolo Bonzini | { |
486 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
487 | 80e555c2 | Paolo Bonzini | Error *local_err = NULL;
|
488 | 7b009e5d | Paolo Bonzini | void **ptr = qdev_get_prop_ptr(dev, prop);
|
489 | 80e555c2 | Paolo Bonzini | char *str;
|
490 | 80e555c2 | Paolo Bonzini | int ret;
|
491 | 80e555c2 | Paolo Bonzini | |
492 | 80e555c2 | Paolo Bonzini | if (dev->state != DEV_STATE_CREATED) {
|
493 | 80e555c2 | Paolo Bonzini | error_set(errp, QERR_PERMISSION_DENIED); |
494 | 80e555c2 | Paolo Bonzini | return;
|
495 | 80e555c2 | Paolo Bonzini | } |
496 | 80e555c2 | Paolo Bonzini | |
497 | 80e555c2 | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
498 | 80e555c2 | Paolo Bonzini | if (local_err) {
|
499 | 80e555c2 | Paolo Bonzini | error_propagate(errp, local_err); |
500 | 80e555c2 | Paolo Bonzini | return;
|
501 | 80e555c2 | Paolo Bonzini | } |
502 | 80e555c2 | Paolo Bonzini | if (!*str) {
|
503 | 80e555c2 | Paolo Bonzini | g_free(str); |
504 | 0a54a0ce | Paolo Bonzini | *ptr = NULL;
|
505 | 80e555c2 | Paolo Bonzini | return;
|
506 | 80e555c2 | Paolo Bonzini | } |
507 | 7b009e5d | Paolo Bonzini | ret = parse(dev, str, ptr); |
508 | 80e555c2 | Paolo Bonzini | error_set_from_qdev_prop_error(errp, ret, dev, prop, str); |
509 | 80e555c2 | Paolo Bonzini | g_free(str); |
510 | 80e555c2 | Paolo Bonzini | } |
511 | 80e555c2 | Paolo Bonzini | |
512 | 7b009e5d | Paolo Bonzini | static void get_drive(Object *obj, Visitor *v, void *opaque, |
513 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
514 | 7b009e5d | Paolo Bonzini | { |
515 | 7b009e5d | Paolo Bonzini | get_pointer(obj, v, opaque, print_drive, name, errp); |
516 | 7b009e5d | Paolo Bonzini | } |
517 | 7b009e5d | Paolo Bonzini | |
518 | 7b009e5d | Paolo Bonzini | static void set_drive(Object *obj, Visitor *v, void *opaque, |
519 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
520 | 7b009e5d | Paolo Bonzini | { |
521 | 7b009e5d | Paolo Bonzini | set_pointer(obj, v, opaque, parse_drive, name, errp); |
522 | 7b009e5d | Paolo Bonzini | } |
523 | 7b009e5d | Paolo Bonzini | |
524 | 14b41872 | Gerd Hoffmann | PropertyInfo qdev_prop_drive = { |
525 | 14b41872 | Gerd Hoffmann | .name = "drive",
|
526 | 7b009e5d | Paolo Bonzini | .get = get_drive, |
527 | 7b009e5d | Paolo Bonzini | .set = set_drive, |
528 | dd0ba250 | Paolo Bonzini | .release = release_drive, |
529 | 14b41872 | Gerd Hoffmann | }; |
530 | 14b41872 | Gerd Hoffmann | |
531 | 313feaab | Gerd Hoffmann | /* --- character device --- */
|
532 | 313feaab | Gerd Hoffmann | |
533 | 7b009e5d | Paolo Bonzini | static int parse_chr(DeviceState *dev, const char *str, void **ptr) |
534 | 06113719 | Gerd Hoffmann | { |
535 | 7b009e5d | Paolo Bonzini | CharDriverState *chr = qemu_chr_find(str); |
536 | 7b009e5d | Paolo Bonzini | if (chr == NULL) { |
537 | 6bf38816 | Markus Armbruster | return -ENOENT;
|
538 | 2d6c1ef4 | Amit Shah | } |
539 | 7b009e5d | Paolo Bonzini | if (chr->avail_connections < 1) { |
540 | 2d6c1ef4 | Amit Shah | return -EEXIST;
|
541 | 2d6c1ef4 | Amit Shah | } |
542 | 7b009e5d | Paolo Bonzini | *ptr = chr; |
543 | 7b009e5d | Paolo Bonzini | --chr->avail_connections; |
544 | 06113719 | Gerd Hoffmann | return 0; |
545 | 06113719 | Gerd Hoffmann | } |
546 | 06113719 | Gerd Hoffmann | |
547 | dd0ba250 | Paolo Bonzini | static void release_chr(Object *obj, const char *name, void *opaque) |
548 | a87f3e8b | Amit Shah | { |
549 | dd0ba250 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
550 | dd0ba250 | Paolo Bonzini | Property *prop = opaque; |
551 | a87f3e8b | Amit Shah | CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); |
552 | a87f3e8b | Amit Shah | |
553 | a87f3e8b | Amit Shah | if (*ptr) {
|
554 | a87f3e8b | Amit Shah | qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); |
555 | a87f3e8b | Amit Shah | } |
556 | a87f3e8b | Amit Shah | } |
557 | a87f3e8b | Amit Shah | |
558 | a87f3e8b | Amit Shah | |
559 | 7b009e5d | Paolo Bonzini | static const char *print_chr(void *ptr) |
560 | 313feaab | Gerd Hoffmann | { |
561 | 7b009e5d | Paolo Bonzini | CharDriverState *chr = ptr; |
562 | bc19fcaa | Blue Swirl | |
563 | 7b009e5d | Paolo Bonzini | return chr->label ? chr->label : ""; |
564 | 7b009e5d | Paolo Bonzini | } |
565 | 7b009e5d | Paolo Bonzini | |
566 | 7b009e5d | Paolo Bonzini | static void get_chr(Object *obj, Visitor *v, void *opaque, |
567 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
568 | 7b009e5d | Paolo Bonzini | { |
569 | 7b009e5d | Paolo Bonzini | get_pointer(obj, v, opaque, print_chr, name, errp); |
570 | 7b009e5d | Paolo Bonzini | } |
571 | 7b009e5d | Paolo Bonzini | |
572 | 7b009e5d | Paolo Bonzini | static void set_chr(Object *obj, Visitor *v, void *opaque, |
573 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
574 | 7b009e5d | Paolo Bonzini | { |
575 | 7b009e5d | Paolo Bonzini | set_pointer(obj, v, opaque, parse_chr, name, errp); |
576 | 313feaab | Gerd Hoffmann | } |
577 | 313feaab | Gerd Hoffmann | |
578 | 313feaab | Gerd Hoffmann | PropertyInfo qdev_prop_chr = { |
579 | 313feaab | Gerd Hoffmann | .name = "chr",
|
580 | 7b009e5d | Paolo Bonzini | .get = get_chr, |
581 | 7b009e5d | Paolo Bonzini | .set = set_chr, |
582 | dd0ba250 | Paolo Bonzini | .release = release_chr, |
583 | 313feaab | Gerd Hoffmann | }; |
584 | 313feaab | Gerd Hoffmann | |
585 | 2ef924b4 | Gerd Hoffmann | /* --- netdev device --- */
|
586 | 2ef924b4 | Gerd Hoffmann | |
587 | 7b009e5d | Paolo Bonzini | static int parse_netdev(DeviceState *dev, const char *str, void **ptr) |
588 | 2ef924b4 | Gerd Hoffmann | { |
589 | 7b009e5d | Paolo Bonzini | VLANClientState *netdev = qemu_find_netdev(str); |
590 | 2ef924b4 | Gerd Hoffmann | |
591 | 7b009e5d | Paolo Bonzini | if (netdev == NULL) { |
592 | 6bf38816 | Markus Armbruster | return -ENOENT;
|
593 | 7b009e5d | Paolo Bonzini | } |
594 | 7b009e5d | Paolo Bonzini | if (netdev->peer) {
|
595 | 27f3f8a3 | Markus Armbruster | return -EEXIST;
|
596 | 27f3f8a3 | Markus Armbruster | } |
597 | 7b009e5d | Paolo Bonzini | *ptr = netdev; |
598 | 2ef924b4 | Gerd Hoffmann | return 0; |
599 | 2ef924b4 | Gerd Hoffmann | } |
600 | 2ef924b4 | Gerd Hoffmann | |
601 | 7b009e5d | Paolo Bonzini | static const char *print_netdev(void *ptr) |
602 | 2ef924b4 | Gerd Hoffmann | { |
603 | 7b009e5d | Paolo Bonzini | VLANClientState *netdev = ptr; |
604 | 2ef924b4 | Gerd Hoffmann | |
605 | 7b009e5d | Paolo Bonzini | return netdev->name ? netdev->name : ""; |
606 | 7b009e5d | Paolo Bonzini | } |
607 | 7b009e5d | Paolo Bonzini | |
608 | 7b009e5d | Paolo Bonzini | static void get_netdev(Object *obj, Visitor *v, void *opaque, |
609 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
610 | 7b009e5d | Paolo Bonzini | { |
611 | 7b009e5d | Paolo Bonzini | get_pointer(obj, v, opaque, print_netdev, name, errp); |
612 | 7b009e5d | Paolo Bonzini | } |
613 | 7b009e5d | Paolo Bonzini | |
614 | 7b009e5d | Paolo Bonzini | static void set_netdev(Object *obj, Visitor *v, void *opaque, |
615 | 7b009e5d | Paolo Bonzini | const char *name, Error **errp) |
616 | 7b009e5d | Paolo Bonzini | { |
617 | 7b009e5d | Paolo Bonzini | set_pointer(obj, v, opaque, parse_netdev, name, errp); |
618 | 2ef924b4 | Gerd Hoffmann | } |
619 | 2ef924b4 | Gerd Hoffmann | |
620 | 2ef924b4 | Gerd Hoffmann | PropertyInfo qdev_prop_netdev = { |
621 | 2ef924b4 | Gerd Hoffmann | .name = "netdev",
|
622 | 7b009e5d | Paolo Bonzini | .get = get_netdev, |
623 | 7b009e5d | Paolo Bonzini | .set = set_netdev, |
624 | 2ef924b4 | Gerd Hoffmann | }; |
625 | 2ef924b4 | Gerd Hoffmann | |
626 | 851bec09 | Gerd Hoffmann | /* --- vlan --- */
|
627 | 851bec09 | Gerd Hoffmann | |
628 | 851bec09 | Gerd Hoffmann | static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) |
629 | 851bec09 | Gerd Hoffmann | { |
630 | 851bec09 | Gerd Hoffmann | VLANState **ptr = qdev_get_prop_ptr(dev, prop); |
631 | 851bec09 | Gerd Hoffmann | |
632 | 851bec09 | Gerd Hoffmann | if (*ptr) {
|
633 | 851bec09 | Gerd Hoffmann | return snprintf(dest, len, "%d", (*ptr)->id); |
634 | 851bec09 | Gerd Hoffmann | } else {
|
635 | 851bec09 | Gerd Hoffmann | return snprintf(dest, len, "<null>"); |
636 | 851bec09 | Gerd Hoffmann | } |
637 | 851bec09 | Gerd Hoffmann | } |
638 | 851bec09 | Gerd Hoffmann | |
639 | 57c9fafe | Anthony Liguori | static void get_vlan(Object *obj, Visitor *v, void *opaque, |
640 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
641 | 80e555c2 | Paolo Bonzini | { |
642 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
643 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
644 | 80e555c2 | Paolo Bonzini | VLANState **ptr = qdev_get_prop_ptr(dev, prop); |
645 | 80e555c2 | Paolo Bonzini | int64_t id; |
646 | 80e555c2 | Paolo Bonzini | |
647 | 80e555c2 | Paolo Bonzini | id = *ptr ? (*ptr)->id : -1;
|
648 | 80e555c2 | Paolo Bonzini | visit_type_int(v, &id, name, errp); |
649 | 80e555c2 | Paolo Bonzini | } |
650 | 80e555c2 | Paolo Bonzini | |
651 | 57c9fafe | Anthony Liguori | static void set_vlan(Object *obj, Visitor *v, void *opaque, |
652 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
653 | 80e555c2 | Paolo Bonzini | { |
654 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
655 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
656 | 80e555c2 | Paolo Bonzini | VLANState **ptr = qdev_get_prop_ptr(dev, prop); |
657 | 80e555c2 | Paolo Bonzini | Error *local_err = NULL;
|
658 | 80e555c2 | Paolo Bonzini | int64_t id; |
659 | 80e555c2 | Paolo Bonzini | VLANState *vlan; |
660 | 80e555c2 | Paolo Bonzini | |
661 | 80e555c2 | Paolo Bonzini | if (dev->state != DEV_STATE_CREATED) {
|
662 | 80e555c2 | Paolo Bonzini | error_set(errp, QERR_PERMISSION_DENIED); |
663 | 80e555c2 | Paolo Bonzini | return;
|
664 | 80e555c2 | Paolo Bonzini | } |
665 | 80e555c2 | Paolo Bonzini | |
666 | 80e555c2 | Paolo Bonzini | visit_type_int(v, &id, name, &local_err); |
667 | 80e555c2 | Paolo Bonzini | if (local_err) {
|
668 | 80e555c2 | Paolo Bonzini | error_propagate(errp, local_err); |
669 | 80e555c2 | Paolo Bonzini | return;
|
670 | 80e555c2 | Paolo Bonzini | } |
671 | 80e555c2 | Paolo Bonzini | if (id == -1) { |
672 | 80e555c2 | Paolo Bonzini | *ptr = NULL;
|
673 | 80e555c2 | Paolo Bonzini | return;
|
674 | 80e555c2 | Paolo Bonzini | } |
675 | 80e555c2 | Paolo Bonzini | vlan = qemu_find_vlan(id, 1);
|
676 | 80e555c2 | Paolo Bonzini | if (!vlan) {
|
677 | 80e555c2 | Paolo Bonzini | error_set(errp, QERR_INVALID_PARAMETER_VALUE, |
678 | 80e555c2 | Paolo Bonzini | name, prop->info->name); |
679 | 80e555c2 | Paolo Bonzini | return;
|
680 | 80e555c2 | Paolo Bonzini | } |
681 | 80e555c2 | Paolo Bonzini | *ptr = vlan; |
682 | 80e555c2 | Paolo Bonzini | } |
683 | 80e555c2 | Paolo Bonzini | |
684 | 851bec09 | Gerd Hoffmann | PropertyInfo qdev_prop_vlan = { |
685 | 851bec09 | Gerd Hoffmann | .name = "vlan",
|
686 | 851bec09 | Gerd Hoffmann | .print = print_vlan, |
687 | 80e555c2 | Paolo Bonzini | .get = get_vlan, |
688 | 80e555c2 | Paolo Bonzini | .set = set_vlan, |
689 | 851bec09 | Gerd Hoffmann | }; |
690 | 851bec09 | Gerd Hoffmann | |
691 | ee6847d1 | Gerd Hoffmann | /* --- pointer --- */
|
692 | ee6847d1 | Gerd Hoffmann | |
693 | 036f7166 | Markus Armbruster | /* Not a proper property, just for dirty hacks. TODO Remove it! */
|
694 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_ptr = { |
695 | ee6847d1 | Gerd Hoffmann | .name = "ptr",
|
696 | ee6847d1 | Gerd Hoffmann | }; |
697 | ee6847d1 | Gerd Hoffmann | |
698 | ee6847d1 | Gerd Hoffmann | /* --- mac address --- */
|
699 | ee6847d1 | Gerd Hoffmann | |
700 | ee6847d1 | Gerd Hoffmann | /*
|
701 | ee6847d1 | Gerd Hoffmann | * accepted syntax versions:
|
702 | ee6847d1 | Gerd Hoffmann | * 01:02:03:04:05:06
|
703 | ee6847d1 | Gerd Hoffmann | * 01-02-03-04-05-06
|
704 | ee6847d1 | Gerd Hoffmann | */
|
705 | e39e5d60 | Paolo Bonzini | static void get_mac(Object *obj, Visitor *v, void *opaque, |
706 | e39e5d60 | Paolo Bonzini | const char *name, Error **errp) |
707 | ee6847d1 | Gerd Hoffmann | { |
708 | e39e5d60 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
709 | e39e5d60 | Paolo Bonzini | Property *prop = opaque; |
710 | 1503fff3 | Gerd Hoffmann | MACAddr *mac = qdev_get_prop_ptr(dev, prop); |
711 | e39e5d60 | Paolo Bonzini | char buffer[2 * 6 + 5 + 1]; |
712 | e39e5d60 | Paolo Bonzini | char *p = buffer;
|
713 | e39e5d60 | Paolo Bonzini | |
714 | e39e5d60 | Paolo Bonzini | snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", |
715 | e39e5d60 | Paolo Bonzini | mac->a[0], mac->a[1], mac->a[2], |
716 | e39e5d60 | Paolo Bonzini | mac->a[3], mac->a[4], mac->a[5]); |
717 | e39e5d60 | Paolo Bonzini | |
718 | e39e5d60 | Paolo Bonzini | visit_type_str(v, &p, name, errp); |
719 | e39e5d60 | Paolo Bonzini | } |
720 | e39e5d60 | Paolo Bonzini | |
721 | e39e5d60 | Paolo Bonzini | static void set_mac(Object *obj, Visitor *v, void *opaque, |
722 | e39e5d60 | Paolo Bonzini | const char *name, Error **errp) |
723 | e39e5d60 | Paolo Bonzini | { |
724 | e39e5d60 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
725 | e39e5d60 | Paolo Bonzini | Property *prop = opaque; |
726 | e39e5d60 | Paolo Bonzini | MACAddr *mac = qdev_get_prop_ptr(dev, prop); |
727 | e39e5d60 | Paolo Bonzini | Error *local_err = NULL;
|
728 | ee6847d1 | Gerd Hoffmann | int i, pos;
|
729 | e39e5d60 | Paolo Bonzini | char *str, *p;
|
730 | e39e5d60 | Paolo Bonzini | |
731 | e39e5d60 | Paolo Bonzini | if (dev->state != DEV_STATE_CREATED) {
|
732 | e39e5d60 | Paolo Bonzini | error_set(errp, QERR_PERMISSION_DENIED); |
733 | e39e5d60 | Paolo Bonzini | return;
|
734 | e39e5d60 | Paolo Bonzini | } |
735 | e39e5d60 | Paolo Bonzini | |
736 | e39e5d60 | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
737 | e39e5d60 | Paolo Bonzini | if (local_err) {
|
738 | e39e5d60 | Paolo Bonzini | error_propagate(errp, local_err); |
739 | e39e5d60 | Paolo Bonzini | return;
|
740 | e39e5d60 | Paolo Bonzini | } |
741 | ee6847d1 | Gerd Hoffmann | |
742 | ee6847d1 | Gerd Hoffmann | for (i = 0, pos = 0; i < 6; i++, pos += 3) { |
743 | 88e150a5 | Christoph Egger | if (!qemu_isxdigit(str[pos]))
|
744 | e39e5d60 | Paolo Bonzini | goto inval;
|
745 | 88e150a5 | Christoph Egger | if (!qemu_isxdigit(str[pos+1])) |
746 | e39e5d60 | Paolo Bonzini | goto inval;
|
747 | 1503fff3 | Gerd Hoffmann | if (i == 5) { |
748 | 1503fff3 | Gerd Hoffmann | if (str[pos+2] != '\0') |
749 | e39e5d60 | Paolo Bonzini | goto inval;
|
750 | 1503fff3 | Gerd Hoffmann | } else {
|
751 | 1503fff3 | Gerd Hoffmann | if (str[pos+2] != ':' && str[pos+2] != '-') |
752 | e39e5d60 | Paolo Bonzini | goto inval;
|
753 | 1503fff3 | Gerd Hoffmann | } |
754 | 1503fff3 | Gerd Hoffmann | mac->a[i] = strtol(str+pos, &p, 16);
|
755 | ee6847d1 | Gerd Hoffmann | } |
756 | a3400466 | dunrong huang | g_free(str); |
757 | e39e5d60 | Paolo Bonzini | return;
|
758 | 1503fff3 | Gerd Hoffmann | |
759 | e39e5d60 | Paolo Bonzini | inval:
|
760 | e39e5d60 | Paolo Bonzini | error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); |
761 | a3400466 | dunrong huang | g_free(str); |
762 | ee6847d1 | Gerd Hoffmann | } |
763 | ee6847d1 | Gerd Hoffmann | |
764 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_macaddr = { |
765 | 1503fff3 | Gerd Hoffmann | .name = "macaddr",
|
766 | e39e5d60 | Paolo Bonzini | .get = get_mac, |
767 | e39e5d60 | Paolo Bonzini | .set = set_mac, |
768 | ee6847d1 | Gerd Hoffmann | }; |
769 | ee6847d1 | Gerd Hoffmann | |
770 | 4e4fa398 | Jan Kiszka | |
771 | 4e4fa398 | Jan Kiszka | /* --- lost tick policy --- */
|
772 | 4e4fa398 | Jan Kiszka | |
773 | 1ce05125 | Paolo Bonzini | static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = { |
774 | 1ce05125 | Paolo Bonzini | [LOST_TICK_DISCARD] = "discard",
|
775 | 1ce05125 | Paolo Bonzini | [LOST_TICK_DELAY] = "delay",
|
776 | 1ce05125 | Paolo Bonzini | [LOST_TICK_MERGE] = "merge",
|
777 | 1ce05125 | Paolo Bonzini | [LOST_TICK_SLEW] = "slew",
|
778 | 1ce05125 | Paolo Bonzini | [LOST_TICK_MAX] = NULL,
|
779 | 4e4fa398 | Jan Kiszka | }; |
780 | 4e4fa398 | Jan Kiszka | |
781 | 1ce05125 | Paolo Bonzini | QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); |
782 | 1ce05125 | Paolo Bonzini | |
783 | 1ce05125 | Paolo Bonzini | static void get_enum(Object *obj, Visitor *v, void *opaque, |
784 | 1ce05125 | Paolo Bonzini | const char *name, Error **errp) |
785 | 4e4fa398 | Jan Kiszka | { |
786 | 1ce05125 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
787 | 1ce05125 | Paolo Bonzini | Property *prop = opaque; |
788 | 1ce05125 | Paolo Bonzini | int *ptr = qdev_get_prop_ptr(dev, prop);
|
789 | 4e4fa398 | Jan Kiszka | |
790 | 1ce05125 | Paolo Bonzini | visit_type_enum(v, ptr, prop->info->enum_table, |
791 | 1ce05125 | Paolo Bonzini | prop->info->name, prop->name, errp); |
792 | 4e4fa398 | Jan Kiszka | } |
793 | 4e4fa398 | Jan Kiszka | |
794 | 1ce05125 | Paolo Bonzini | static void set_enum(Object *obj, Visitor *v, void *opaque, |
795 | 1ce05125 | Paolo Bonzini | const char *name, Error **errp) |
796 | 4e4fa398 | Jan Kiszka | { |
797 | 1ce05125 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
798 | 1ce05125 | Paolo Bonzini | Property *prop = opaque; |
799 | 1ce05125 | Paolo Bonzini | int *ptr = qdev_get_prop_ptr(dev, prop);
|
800 | 4e4fa398 | Jan Kiszka | |
801 | 1ce05125 | Paolo Bonzini | if (dev->state != DEV_STATE_CREATED) {
|
802 | 1ce05125 | Paolo Bonzini | error_set(errp, QERR_PERMISSION_DENIED); |
803 | 1ce05125 | Paolo Bonzini | return;
|
804 | 1ce05125 | Paolo Bonzini | } |
805 | 1ce05125 | Paolo Bonzini | |
806 | 1ce05125 | Paolo Bonzini | visit_type_enum(v, ptr, prop->info->enum_table, |
807 | 1ce05125 | Paolo Bonzini | prop->info->name, prop->name, errp); |
808 | 4e4fa398 | Jan Kiszka | } |
809 | 4e4fa398 | Jan Kiszka | |
810 | 4e4fa398 | Jan Kiszka | PropertyInfo qdev_prop_losttickpolicy = { |
811 | 1ce05125 | Paolo Bonzini | .name = "LostTickPolicy",
|
812 | 1ce05125 | Paolo Bonzini | .enum_table = lost_tick_policy_table, |
813 | 1ce05125 | Paolo Bonzini | .get = get_enum, |
814 | 1ce05125 | Paolo Bonzini | .set = set_enum, |
815 | 4e4fa398 | Jan Kiszka | }; |
816 | 4e4fa398 | Jan Kiszka | |
817 | 05cb5fe4 | Gerd Hoffmann | /* --- pci address --- */
|
818 | 05cb5fe4 | Gerd Hoffmann | |
819 | 05cb5fe4 | Gerd Hoffmann | /*
|
820 | 05cb5fe4 | Gerd Hoffmann | * bus-local address, i.e. "$slot" or "$slot.$fn"
|
821 | 05cb5fe4 | Gerd Hoffmann | */
|
822 | 768a9ebe | Paolo Bonzini | static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, |
823 | 768a9ebe | Paolo Bonzini | const char *name, Error **errp) |
824 | 05cb5fe4 | Gerd Hoffmann | { |
825 | 768a9ebe | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
826 | 768a9ebe | Paolo Bonzini | Property *prop = opaque; |
827 | 05cb5fe4 | Gerd Hoffmann | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
828 | 05cb5fe4 | Gerd Hoffmann | unsigned int slot, fn, n; |
829 | 768a9ebe | Paolo Bonzini | Error *local_err = NULL;
|
830 | a3400466 | dunrong huang | char *str;
|
831 | 768a9ebe | Paolo Bonzini | |
832 | 768a9ebe | Paolo Bonzini | if (dev->state != DEV_STATE_CREATED) {
|
833 | 768a9ebe | Paolo Bonzini | error_set(errp, QERR_PERMISSION_DENIED); |
834 | 768a9ebe | Paolo Bonzini | return;
|
835 | 768a9ebe | Paolo Bonzini | } |
836 | 768a9ebe | Paolo Bonzini | |
837 | 768a9ebe | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
838 | 768a9ebe | Paolo Bonzini | if (local_err) {
|
839 | 5c878008 | Stefan Weil | error_free(local_err); |
840 | 768a9ebe | Paolo Bonzini | return set_int32(obj, v, opaque, name, errp);
|
841 | 768a9ebe | Paolo Bonzini | } |
842 | 05cb5fe4 | Gerd Hoffmann | |
843 | 05cb5fe4 | Gerd Hoffmann | if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { |
844 | 05cb5fe4 | Gerd Hoffmann | fn = 0;
|
845 | 05cb5fe4 | Gerd Hoffmann | if (sscanf(str, "%x%n", &slot, &n) != 1) { |
846 | 768a9ebe | Paolo Bonzini | goto invalid;
|
847 | 05cb5fe4 | Gerd Hoffmann | } |
848 | 05cb5fe4 | Gerd Hoffmann | } |
849 | 768a9ebe | Paolo Bonzini | if (str[n] != '\0' || fn > 7 || slot > 31) { |
850 | 768a9ebe | Paolo Bonzini | goto invalid;
|
851 | 768a9ebe | Paolo Bonzini | } |
852 | 05cb5fe4 | Gerd Hoffmann | *ptr = slot << 3 | fn;
|
853 | a3400466 | dunrong huang | g_free(str); |
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 | a3400466 | dunrong huang | g_free(str); |
859 | 05cb5fe4 | Gerd Hoffmann | } |
860 | 05cb5fe4 | Gerd Hoffmann | |
861 | 05cb5fe4 | Gerd Hoffmann | static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len) |
862 | 05cb5fe4 | Gerd Hoffmann | { |
863 | 05cb5fe4 | Gerd Hoffmann | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
864 | 05cb5fe4 | Gerd Hoffmann | |
865 | 73538c31 | Blue Swirl | if (*ptr == -1) { |
866 | 05cb5fe4 | Gerd Hoffmann | return snprintf(dest, len, "<unset>"); |
867 | 05cb5fe4 | Gerd Hoffmann | } else {
|
868 | 05cb5fe4 | Gerd Hoffmann | return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); |
869 | 05cb5fe4 | Gerd Hoffmann | } |
870 | 05cb5fe4 | Gerd Hoffmann | } |
871 | 05cb5fe4 | Gerd Hoffmann | |
872 | 05cb5fe4 | Gerd Hoffmann | PropertyInfo qdev_prop_pci_devfn = { |
873 | b403298a | Paolo Bonzini | .name = "int32",
|
874 | b403298a | Paolo Bonzini | .legacy_name = "pci-devfn",
|
875 | 05cb5fe4 | Gerd Hoffmann | .print = print_pci_devfn, |
876 | b403298a | Paolo Bonzini | .get = get_int32, |
877 | 768a9ebe | Paolo Bonzini | .set = set_pci_devfn, |
878 | b403298a | Paolo Bonzini | /* FIXME: this should be -1...255, but the address is stored
|
879 | b403298a | Paolo Bonzini | * into an uint32_t rather than int32_t.
|
880 | b403298a | Paolo Bonzini | */
|
881 | b403298a | Paolo Bonzini | .min = 0,
|
882 | b403298a | Paolo Bonzini | .max = 0xFFFFFFFFULL,
|
883 | 05cb5fe4 | Gerd Hoffmann | }; |
884 | 05cb5fe4 | Gerd Hoffmann | |
885 | 02fda01c | Stefan Hajnoczi | /* --- blocksize --- */
|
886 | 02fda01c | Stefan Hajnoczi | |
887 | 02fda01c | Stefan Hajnoczi | static void set_blocksize(Object *obj, Visitor *v, void *opaque, |
888 | 02fda01c | Stefan Hajnoczi | const char *name, Error **errp) |
889 | 02fda01c | Stefan Hajnoczi | { |
890 | 02fda01c | Stefan Hajnoczi | DeviceState *dev = DEVICE(obj); |
891 | 02fda01c | Stefan Hajnoczi | Property *prop = opaque; |
892 | 02fda01c | Stefan Hajnoczi | int16_t *ptr = qdev_get_prop_ptr(dev, prop); |
893 | 02fda01c | Stefan Hajnoczi | Error *local_err = NULL;
|
894 | 02fda01c | Stefan Hajnoczi | int64_t value; |
895 | 02fda01c | Stefan Hajnoczi | |
896 | 02fda01c | Stefan Hajnoczi | if (dev->state != DEV_STATE_CREATED) {
|
897 | 02fda01c | Stefan Hajnoczi | error_set(errp, QERR_PERMISSION_DENIED); |
898 | 02fda01c | Stefan Hajnoczi | return;
|
899 | 02fda01c | Stefan Hajnoczi | } |
900 | 02fda01c | Stefan Hajnoczi | |
901 | 02fda01c | Stefan Hajnoczi | visit_type_int(v, &value, name, &local_err); |
902 | 02fda01c | Stefan Hajnoczi | if (local_err) {
|
903 | 02fda01c | Stefan Hajnoczi | error_propagate(errp, local_err); |
904 | 02fda01c | Stefan Hajnoczi | return;
|
905 | 02fda01c | Stefan Hajnoczi | } |
906 | 02fda01c | Stefan Hajnoczi | if (value < prop->info->min || value > prop->info->max) {
|
907 | 02fda01c | Stefan Hajnoczi | error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, |
908 | 02fda01c | Stefan Hajnoczi | dev->id?:"", name, value, prop->info->min,
|
909 | 02fda01c | Stefan Hajnoczi | prop->info->max); |
910 | 02fda01c | Stefan Hajnoczi | return;
|
911 | 02fda01c | Stefan Hajnoczi | } |
912 | 02fda01c | Stefan Hajnoczi | |
913 | 02fda01c | Stefan Hajnoczi | /* We rely on power-of-2 blocksizes for bitmasks */
|
914 | 02fda01c | Stefan Hajnoczi | if ((value & (value - 1)) != 0) { |
915 | 02fda01c | Stefan Hajnoczi | error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2, |
916 | 02fda01c | Stefan Hajnoczi | dev->id?:"", name, value);
|
917 | 02fda01c | Stefan Hajnoczi | return;
|
918 | 02fda01c | Stefan Hajnoczi | } |
919 | 02fda01c | Stefan Hajnoczi | |
920 | 02fda01c | Stefan Hajnoczi | *ptr = value; |
921 | 02fda01c | Stefan Hajnoczi | } |
922 | 02fda01c | Stefan Hajnoczi | |
923 | 02fda01c | Stefan Hajnoczi | PropertyInfo qdev_prop_blocksize = { |
924 | 02fda01c | Stefan Hajnoczi | .name = "blocksize",
|
925 | 02fda01c | Stefan Hajnoczi | .get = get_int16, |
926 | 02fda01c | Stefan Hajnoczi | .set = set_blocksize, |
927 | 02fda01c | Stefan Hajnoczi | .min = 512,
|
928 | 02fda01c | Stefan Hajnoczi | .max = 65024,
|
929 | 02fda01c | Stefan Hajnoczi | }; |
930 | 02fda01c | Stefan Hajnoczi | |
931 | ee6847d1 | Gerd Hoffmann | /* --- public helpers --- */
|
932 | ee6847d1 | Gerd Hoffmann | |
933 | ee6847d1 | Gerd Hoffmann | static Property *qdev_prop_walk(Property *props, const char *name) |
934 | ee6847d1 | Gerd Hoffmann | { |
935 | ee6847d1 | Gerd Hoffmann | if (!props)
|
936 | ee6847d1 | Gerd Hoffmann | return NULL; |
937 | ee6847d1 | Gerd Hoffmann | while (props->name) {
|
938 | ee6847d1 | Gerd Hoffmann | if (strcmp(props->name, name) == 0) |
939 | ee6847d1 | Gerd Hoffmann | return props;
|
940 | ee6847d1 | Gerd Hoffmann | props++; |
941 | ee6847d1 | Gerd Hoffmann | } |
942 | ee6847d1 | Gerd Hoffmann | return NULL; |
943 | ee6847d1 | Gerd Hoffmann | } |
944 | ee6847d1 | Gerd Hoffmann | |
945 | ee6847d1 | Gerd Hoffmann | static Property *qdev_prop_find(DeviceState *dev, const char *name) |
946 | ee6847d1 | Gerd Hoffmann | { |
947 | ee6847d1 | Gerd Hoffmann | Property *prop; |
948 | ee6847d1 | Gerd Hoffmann | |
949 | ee6847d1 | Gerd Hoffmann | /* device properties */
|
950 | 4be9f0d1 | Anthony Liguori | prop = qdev_prop_walk(qdev_get_props(dev), name); |
951 | ee6847d1 | Gerd Hoffmann | if (prop)
|
952 | ee6847d1 | Gerd Hoffmann | return prop;
|
953 | ee6847d1 | Gerd Hoffmann | |
954 | ee6847d1 | Gerd Hoffmann | /* bus properties */
|
955 | ee6847d1 | Gerd Hoffmann | prop = qdev_prop_walk(dev->parent_bus->info->props, name); |
956 | ee6847d1 | Gerd Hoffmann | if (prop)
|
957 | ee6847d1 | Gerd Hoffmann | return prop;
|
958 | ee6847d1 | Gerd Hoffmann | |
959 | ee6847d1 | Gerd Hoffmann | return NULL; |
960 | ee6847d1 | Gerd Hoffmann | } |
961 | ee6847d1 | Gerd Hoffmann | |
962 | d8ed79ae | Gerd Hoffmann | int qdev_prop_exists(DeviceState *dev, const char *name) |
963 | d8ed79ae | Gerd Hoffmann | { |
964 | d8ed79ae | Gerd Hoffmann | return qdev_prop_find(dev, name) ? true : false; |
965 | d8ed79ae | Gerd Hoffmann | } |
966 | d8ed79ae | Gerd Hoffmann | |
967 | 7db4c4e8 | Paolo Bonzini | void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, |
968 | 7db4c4e8 | Paolo Bonzini | Property *prop, const char *value) |
969 | 7db4c4e8 | Paolo Bonzini | { |
970 | 7db4c4e8 | Paolo Bonzini | switch (ret) {
|
971 | 7db4c4e8 | Paolo Bonzini | case -EEXIST:
|
972 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_IN_USE, |
973 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
974 | 7db4c4e8 | Paolo Bonzini | break;
|
975 | 7db4c4e8 | Paolo Bonzini | default:
|
976 | 7db4c4e8 | Paolo Bonzini | case -EINVAL:
|
977 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_BAD, |
978 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
979 | 7db4c4e8 | Paolo Bonzini | break;
|
980 | 7db4c4e8 | Paolo Bonzini | case -ENOENT:
|
981 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND, |
982 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
983 | 7db4c4e8 | Paolo Bonzini | break;
|
984 | 7db4c4e8 | Paolo Bonzini | case 0: |
985 | 7db4c4e8 | Paolo Bonzini | break;
|
986 | 7db4c4e8 | Paolo Bonzini | } |
987 | 7db4c4e8 | Paolo Bonzini | } |
988 | 7db4c4e8 | Paolo Bonzini | |
989 | ee6847d1 | Gerd Hoffmann | int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) |
990 | ee6847d1 | Gerd Hoffmann | { |
991 | d822979b | Paolo Bonzini | char *legacy_name;
|
992 | d822979b | Paolo Bonzini | Error *err = NULL;
|
993 | ee6847d1 | Gerd Hoffmann | |
994 | d822979b | Paolo Bonzini | legacy_name = g_strdup_printf("legacy-%s", name);
|
995 | d822979b | Paolo Bonzini | if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { |
996 | 0c96e285 | Paolo Bonzini | object_property_parse(OBJECT(dev), value, legacy_name, &err); |
997 | d822979b | Paolo Bonzini | } else {
|
998 | 0c96e285 | Paolo Bonzini | object_property_parse(OBJECT(dev), value, name, &err); |
999 | ee6847d1 | Gerd Hoffmann | } |
1000 | d822979b | Paolo Bonzini | g_free(legacy_name); |
1001 | d822979b | Paolo Bonzini | |
1002 | d822979b | Paolo Bonzini | if (err) {
|
1003 | 7db4c4e8 | Paolo Bonzini | qerror_report_err(err); |
1004 | 7db4c4e8 | Paolo Bonzini | error_free(err); |
1005 | 9ef5c4bf | Gerd Hoffmann | return -1; |
1006 | 9ef5c4bf | Gerd Hoffmann | } |
1007 | 9ef5c4bf | Gerd Hoffmann | return 0; |
1008 | ee6847d1 | Gerd Hoffmann | } |
1009 | ee6847d1 | Gerd Hoffmann | |
1010 | f4594a3b | Isaku Yamahata | void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) |
1011 | f4594a3b | Isaku Yamahata | { |
1012 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1013 | 9b170e60 | Paolo Bonzini | object_property_set_bool(OBJECT(dev), value, name, &errp); |
1014 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1015 | f4594a3b | Isaku Yamahata | } |
1016 | f4594a3b | Isaku Yamahata | |
1017 | c7cc172d | Juan Quintela | void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) |
1018 | c7cc172d | Juan Quintela | { |
1019 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1020 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1021 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1022 | c7cc172d | Juan Quintela | } |
1023 | c7cc172d | Juan Quintela | |
1024 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) |
1025 | ee6847d1 | Gerd Hoffmann | { |
1026 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1027 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1028 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1029 | ee6847d1 | Gerd Hoffmann | } |
1030 | ee6847d1 | Gerd Hoffmann | |
1031 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) |
1032 | ee6847d1 | Gerd Hoffmann | { |
1033 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1034 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1035 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1036 | ee6847d1 | Gerd Hoffmann | } |
1037 | ee6847d1 | Gerd Hoffmann | |
1038 | 316940b0 | Gerd Hoffmann | void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) |
1039 | 316940b0 | Gerd Hoffmann | { |
1040 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1041 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1042 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1043 | 316940b0 | Gerd Hoffmann | } |
1044 | 316940b0 | Gerd Hoffmann | |
1045 | 5a053d1f | Blue Swirl | void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) |
1046 | 5a053d1f | Blue Swirl | { |
1047 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1048 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1049 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1050 | 5a053d1f | Blue Swirl | } |
1051 | 5a053d1f | Blue Swirl | |
1052 | cc984673 | Markus Armbruster | void qdev_prop_set_string(DeviceState *dev, const char *name, char *value) |
1053 | cc984673 | Markus Armbruster | { |
1054 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1055 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), value, name, &errp); |
1056 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1057 | cc984673 | Markus Armbruster | } |
1058 | cc984673 | Markus Armbruster | |
1059 | 18846dee | Markus Armbruster | int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) |
1060 | 14b41872 | Gerd Hoffmann | { |
1061 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1062 | 0a54a0ce | Paolo Bonzini | const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; |
1063 | 0a54a0ce | Paolo Bonzini | object_property_set_str(OBJECT(dev), bdrv_name, |
1064 | 9b170e60 | Paolo Bonzini | name, &errp); |
1065 | 9b170e60 | Paolo Bonzini | if (errp) {
|
1066 | 9b170e60 | Paolo Bonzini | qerror_report_err(errp); |
1067 | 9b170e60 | Paolo Bonzini | error_free(errp); |
1068 | 18846dee | Markus Armbruster | return -1; |
1069 | 18846dee | Markus Armbruster | } |
1070 | 18846dee | Markus Armbruster | return 0; |
1071 | 14b41872 | Gerd Hoffmann | } |
1072 | 14b41872 | Gerd Hoffmann | |
1073 | 18846dee | Markus Armbruster | void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value) |
1074 | 18846dee | Markus Armbruster | { |
1075 | 18846dee | Markus Armbruster | if (qdev_prop_set_drive(dev, name, value) < 0) { |
1076 | 18846dee | Markus Armbruster | exit(1);
|
1077 | 18846dee | Markus Armbruster | } |
1078 | 18846dee | Markus Armbruster | } |
1079 | 313feaab | Gerd Hoffmann | void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) |
1080 | 313feaab | Gerd Hoffmann | { |
1081 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1082 | 0a54a0ce | Paolo Bonzini | assert(!value || value->label); |
1083 | 0a54a0ce | Paolo Bonzini | object_property_set_str(OBJECT(dev), |
1084 | 0a54a0ce | Paolo Bonzini | value ? value->label : "", name, &errp);
|
1085 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1086 | 313feaab | Gerd Hoffmann | } |
1087 | 313feaab | Gerd Hoffmann | |
1088 | 2ef924b4 | Gerd Hoffmann | void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value) |
1089 | 2ef924b4 | Gerd Hoffmann | { |
1090 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1091 | 0a54a0ce | Paolo Bonzini | assert(!value || value->name); |
1092 | 0a54a0ce | Paolo Bonzini | object_property_set_str(OBJECT(dev), |
1093 | 0a54a0ce | Paolo Bonzini | value ? value->name : "", name, &errp);
|
1094 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1095 | 2ef924b4 | Gerd Hoffmann | } |
1096 | 2ef924b4 | Gerd Hoffmann | |
1097 | 851bec09 | Gerd Hoffmann | void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value) |
1098 | 851bec09 | Gerd Hoffmann | { |
1099 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1100 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
|
1101 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1102 | 851bec09 | Gerd Hoffmann | } |
1103 | 851bec09 | Gerd Hoffmann | |
1104 | 1503fff3 | Gerd Hoffmann | void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) |
1105 | 1503fff3 | Gerd Hoffmann | { |
1106 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1107 | 9b170e60 | Paolo Bonzini | char str[2 * 6 + 5 + 1]; |
1108 | 9b170e60 | Paolo Bonzini | snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", |
1109 | 9b170e60 | Paolo Bonzini | value[0], value[1], value[2], value[3], value[4], value[5]); |
1110 | 9b170e60 | Paolo Bonzini | |
1111 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), str, name, &errp); |
1112 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1113 | 1503fff3 | Gerd Hoffmann | } |
1114 | 1503fff3 | Gerd Hoffmann | |
1115 | 9b170e60 | Paolo Bonzini | void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) |
1116 | 4e4fa398 | Jan Kiszka | { |
1117 | 9b170e60 | Paolo Bonzini | Property *prop; |
1118 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1119 | 9b170e60 | Paolo Bonzini | |
1120 | 9b170e60 | Paolo Bonzini | prop = qdev_prop_find(dev, name); |
1121 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), prop->info->enum_table[value], |
1122 | 9b170e60 | Paolo Bonzini | name, &errp); |
1123 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1124 | 4e4fa398 | Jan Kiszka | } |
1125 | 4e4fa398 | Jan Kiszka | |
1126 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) |
1127 | ee6847d1 | Gerd Hoffmann | { |
1128 | 7a7aae21 | Paolo Bonzini | Property *prop; |
1129 | 7a7aae21 | Paolo Bonzini | void **ptr;
|
1130 | 7a7aae21 | Paolo Bonzini | |
1131 | 7a7aae21 | Paolo Bonzini | prop = qdev_prop_find(dev, name); |
1132 | 7a7aae21 | Paolo Bonzini | assert(prop && prop->info == &qdev_prop_ptr); |
1133 | 7a7aae21 | Paolo Bonzini | ptr = qdev_get_prop_ptr(dev, prop); |
1134 | 7a7aae21 | Paolo Bonzini | *ptr = value; |
1135 | ee6847d1 | Gerd Hoffmann | } |
1136 | ee6847d1 | Gerd Hoffmann | |
1137 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_defaults(DeviceState *dev, Property *props)
|
1138 | ee6847d1 | Gerd Hoffmann | { |
1139 | 4f2d3d70 | Paolo Bonzini | Object *obj = OBJECT(dev); |
1140 | ee6847d1 | Gerd Hoffmann | if (!props)
|
1141 | ee6847d1 | Gerd Hoffmann | return;
|
1142 | 4f2d3d70 | Paolo Bonzini | for (; props->name; props++) {
|
1143 | 4f2d3d70 | Paolo Bonzini | Error *errp = NULL;
|
1144 | 4f2d3d70 | Paolo Bonzini | if (props->qtype == QTYPE_NONE) {
|
1145 | 4f2d3d70 | Paolo Bonzini | continue;
|
1146 | ee6847d1 | Gerd Hoffmann | } |
1147 | 4f2d3d70 | Paolo Bonzini | if (props->qtype == QTYPE_QBOOL) {
|
1148 | 4f2d3d70 | Paolo Bonzini | object_property_set_bool(obj, props->defval, props->name, &errp); |
1149 | 4f2d3d70 | Paolo Bonzini | } else if (props->info->enum_table) { |
1150 | 4f2d3d70 | Paolo Bonzini | object_property_set_str(obj, props->info->enum_table[props->defval], |
1151 | 4f2d3d70 | Paolo Bonzini | props->name, &errp); |
1152 | 4f2d3d70 | Paolo Bonzini | } else if (props->qtype == QTYPE_QINT) { |
1153 | 4f2d3d70 | Paolo Bonzini | object_property_set_int(obj, props->defval, props->name, &errp); |
1154 | 4f2d3d70 | Paolo Bonzini | } |
1155 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1156 | ee6847d1 | Gerd Hoffmann | } |
1157 | ee6847d1 | Gerd Hoffmann | } |
1158 | ee6847d1 | Gerd Hoffmann | |
1159 | 458fb679 | Gerd Hoffmann | static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
|
1160 | b6b61144 | Gerd Hoffmann | |
1161 | 25920d6a | Kevin Wolf | static void qdev_prop_register_global(GlobalProperty *prop) |
1162 | b6b61144 | Gerd Hoffmann | { |
1163 | 458fb679 | Gerd Hoffmann | QTAILQ_INSERT_TAIL(&global_props, prop, next); |
1164 | b6b61144 | Gerd Hoffmann | } |
1165 | b6b61144 | Gerd Hoffmann | |
1166 | 458fb679 | Gerd Hoffmann | void qdev_prop_register_global_list(GlobalProperty *props)
|
1167 | b6b61144 | Gerd Hoffmann | { |
1168 | 458fb679 | Gerd Hoffmann | int i;
|
1169 | b6b61144 | Gerd Hoffmann | |
1170 | 458fb679 | Gerd Hoffmann | for (i = 0; props[i].driver != NULL; i++) { |
1171 | 458fb679 | Gerd Hoffmann | qdev_prop_register_global(props+i); |
1172 | b6b61144 | Gerd Hoffmann | } |
1173 | 458fb679 | Gerd Hoffmann | } |
1174 | 458fb679 | Gerd Hoffmann | |
1175 | 458fb679 | Gerd Hoffmann | void qdev_prop_set_globals(DeviceState *dev)
|
1176 | 458fb679 | Gerd Hoffmann | { |
1177 | 458fb679 | Gerd Hoffmann | GlobalProperty *prop; |
1178 | 458fb679 | Gerd Hoffmann | |
1179 | 458fb679 | Gerd Hoffmann | QTAILQ_FOREACH(prop, &global_props, next) { |
1180 | f79f2bfc | Anthony Liguori | if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 && |
1181 | 4be9f0d1 | Anthony Liguori | strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
|
1182 | b6b61144 | Gerd Hoffmann | continue;
|
1183 | b6b61144 | Gerd Hoffmann | } |
1184 | b6b61144 | Gerd Hoffmann | if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { |
1185 | 9ef5c4bf | Gerd Hoffmann | exit(1);
|
1186 | b6b61144 | Gerd Hoffmann | } |
1187 | b6b61144 | Gerd Hoffmann | } |
1188 | b6b61144 | Gerd Hoffmann | } |
1189 | 25920d6a | Kevin Wolf | |
1190 | 25920d6a | Kevin Wolf | static int qdev_add_one_global(QemuOpts *opts, void *opaque) |
1191 | 25920d6a | Kevin Wolf | { |
1192 | 25920d6a | Kevin Wolf | GlobalProperty *g; |
1193 | 25920d6a | Kevin Wolf | |
1194 | 7267c094 | Anthony Liguori | g = g_malloc0(sizeof(*g));
|
1195 | 25920d6a | Kevin Wolf | g->driver = qemu_opt_get(opts, "driver");
|
1196 | 25920d6a | Kevin Wolf | g->property = qemu_opt_get(opts, "property");
|
1197 | 25920d6a | Kevin Wolf | g->value = qemu_opt_get(opts, "value");
|
1198 | 25920d6a | Kevin Wolf | qdev_prop_register_global(g); |
1199 | 25920d6a | Kevin Wolf | return 0; |
1200 | 25920d6a | Kevin Wolf | } |
1201 | 25920d6a | Kevin Wolf | |
1202 | 25920d6a | Kevin Wolf | void qemu_add_globals(void) |
1203 | 25920d6a | Kevin Wolf | { |
1204 | 3329f07b | Gerd Hoffmann | qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); |
1205 | 25920d6a | Kevin Wolf | } |