4 void *qdev_get_prop_ptr(DeviceState
*dev
, Property
*prop
)
11 /* --- 8bit integer --- */
13 static int parse_uint8(DeviceState
*dev
, Property
*prop
, const char *str
)
15 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
18 /* accept both hex and decimal */
19 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx8
: "%" PRIu8
;
20 if (sscanf(str
, fmt
, ptr
) != 1)
25 static int print_uint8(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
27 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
28 return snprintf(dest
, len
, "%" PRIu8
, *ptr
);
31 PropertyInfo qdev_prop_uint8
= {
33 .type
= PROP_TYPE_UINT8
,
34 .size
= sizeof(uint8_t),
39 /* --- 16bit integer --- */
41 static int parse_uint16(DeviceState
*dev
, Property
*prop
, const char *str
)
43 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
46 /* accept both hex and decimal */
47 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx16
: "%" PRIu16
;
48 if (sscanf(str
, fmt
, ptr
) != 1)
53 static int print_uint16(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
55 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
56 return snprintf(dest
, len
, "%" PRIu16
, *ptr
);
59 PropertyInfo qdev_prop_uint16
= {
61 .type
= PROP_TYPE_UINT16
,
62 .size
= sizeof(uint16_t),
63 .parse
= parse_uint16
,
64 .print
= print_uint16
,
67 /* --- 32bit integer --- */
69 static int parse_uint32(DeviceState
*dev
, Property
*prop
, const char *str
)
71 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
74 /* accept both hex and decimal */
75 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx32
: "%" PRIu32
;
76 if (sscanf(str
, fmt
, ptr
) != 1)
81 static int print_uint32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
83 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
84 return snprintf(dest
, len
, "%" PRIu32
, *ptr
);
87 PropertyInfo qdev_prop_uint32
= {
89 .type
= PROP_TYPE_UINT32
,
90 .size
= sizeof(uint32_t),
91 .parse
= parse_uint32
,
92 .print
= print_uint32
,
95 static int parse_int32(DeviceState
*dev
, Property
*prop
, const char *str
)
97 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
99 if (sscanf(str
, "%" PRId32
, ptr
) != 1)
104 static int print_int32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
106 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
107 return snprintf(dest
, len
, "%" PRId32
, *ptr
);
110 PropertyInfo qdev_prop_int32
= {
112 .type
= PROP_TYPE_INT32
,
113 .size
= sizeof(int32_t),
114 .parse
= parse_int32
,
115 .print
= print_int32
,
118 /* --- 32bit hex value --- */
120 static int parse_hex32(DeviceState
*dev
, Property
*prop
, const char *str
)
122 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
124 if (sscanf(str
, "%" PRIx32
, ptr
) != 1)
129 static int print_hex32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
131 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
132 return snprintf(dest
, len
, "0x%" PRIx32
, *ptr
);
135 PropertyInfo qdev_prop_hex32
= {
137 .type
= PROP_TYPE_UINT32
,
138 .size
= sizeof(uint32_t),
139 .parse
= parse_hex32
,
140 .print
= print_hex32
,
143 /* --- 64bit integer --- */
145 static int parse_uint64(DeviceState
*dev
, Property
*prop
, const char *str
)
147 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
150 /* accept both hex and decimal */
151 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx64
: "%" PRIu64
;
152 if (sscanf(str
, fmt
, ptr
) != 1)
157 static int print_uint64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
159 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
160 return snprintf(dest
, len
, "%" PRIu64
, *ptr
);
163 PropertyInfo qdev_prop_uint64
= {
165 .type
= PROP_TYPE_UINT64
,
166 .size
= sizeof(uint64_t),
167 .parse
= parse_uint64
,
168 .print
= print_uint64
,
171 /* --- 64bit hex value --- */
173 static int parse_hex64(DeviceState
*dev
, Property
*prop
, const char *str
)
175 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
177 if (sscanf(str
, "%" PRIx64
, ptr
) != 1)
182 static int print_hex64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
184 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
185 return snprintf(dest
, len
, "0x%" PRIx64
, *ptr
);
188 PropertyInfo qdev_prop_hex64
= {
190 .type
= PROP_TYPE_UINT64
,
191 .size
= sizeof(uint64_t),
192 .parse
= parse_hex64
,
193 .print
= print_hex64
,
198 static int parse_string(DeviceState
*dev
, Property
*prop
, const char *str
)
200 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
204 *ptr
= qemu_strdup(str
);
208 static int print_string(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
210 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
212 return snprintf(dest
, len
, "<null>");
213 return snprintf(dest
, len
, "\"%s\"", *ptr
);
216 PropertyInfo qdev_prop_string
= {
218 .type
= PROP_TYPE_STRING
,
219 .size
= sizeof(char*),
220 .parse
= parse_string
,
221 .print
= print_string
,
226 static int parse_drive(DeviceState
*dev
, Property
*prop
, const char *str
)
228 DriveInfo
**ptr
= qdev_get_prop_ptr(dev
, prop
);
230 *ptr
= drive_get_by_id(str
);
236 static int print_drive(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
238 DriveInfo
**ptr
= qdev_get_prop_ptr(dev
, prop
);
239 return snprintf(dest
, len
, "%s", (*ptr
) ? (*ptr
)->id
: "<null>");
242 PropertyInfo qdev_prop_drive
= {
244 .type
= PROP_TYPE_DRIVE
,
245 .size
= sizeof(DriveInfo
*),
246 .parse
= parse_drive
,
247 .print
= print_drive
,
250 /* --- character device --- */
252 static int parse_chr(DeviceState
*dev
, Property
*prop
, const char *str
)
254 CharDriverState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
256 *ptr
= qemu_chr_find(str
);
262 static int print_chr(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
264 CharDriverState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
266 if (*ptr
&& (*ptr
)->label
) {
267 return snprintf(dest
, len
, "%s", (*ptr
)->label
);
269 return snprintf(dest
, len
, "<null>");
273 PropertyInfo qdev_prop_chr
= {
275 .type
= PROP_TYPE_CHR
,
276 .size
= sizeof(CharDriverState
*),
281 /* --- pointer --- */
283 static int print_ptr(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
285 void **ptr
= qdev_get_prop_ptr(dev
, prop
);
286 return snprintf(dest
, len
, "<%p>", *ptr
);
289 PropertyInfo qdev_prop_ptr
= {
291 .type
= PROP_TYPE_PTR
,
292 .size
= sizeof(void*),
296 /* --- mac address --- */
299 * accepted syntax versions:
303 static int parse_mac(DeviceState
*dev
, Property
*prop
, const char *str
)
305 uint8_t *mac
= qdev_get_prop_ptr(dev
, prop
);
309 for (i
= 0, pos
= 0; i
< 6; i
++, pos
+= 3) {
310 if (!qemu_isxdigit(str
[pos
]))
312 if (!qemu_isxdigit(str
[pos
+1]))
314 if (i
== 5 && str
[pos
+2] != '\0')
316 if (str
[pos
+2] != ':' && str
[pos
+2] != '-')
318 mac
[i
] = strtol(str
+pos
, &p
, 16);
323 static int print_mac(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
325 uint8_t *mac
= qdev_get_prop_ptr(dev
, prop
);
326 return snprintf(dest
, len
, "%02x:%02x:%02x:%02x:%02x:%02x",
327 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
330 PropertyInfo qdev_prop_macaddr
= {
332 .type
= PROP_TYPE_MACADDR
,
338 /* --- pci address --- */
341 * bus-local address, i.e. "$slot" or "$slot.$fn"
343 static int parse_pci_devfn(DeviceState
*dev
, Property
*prop
, const char *str
)
345 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
346 unsigned int slot
, fn
, n
;
348 if (sscanf(str
, "%x.%x%n", &slot
, &fn
, &n
) != 2) {
350 if (sscanf(str
, "%x%n", &slot
, &n
) != 1) {
358 *ptr
= slot
<< 3 | fn
;
362 static int print_pci_devfn(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
364 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
367 return snprintf(dest
, len
, "<unset>");
369 return snprintf(dest
, len
, "%02x.%x", *ptr
>> 3, *ptr
& 7);
373 PropertyInfo qdev_prop_pci_devfn
= {
375 .type
= PROP_TYPE_UINT32
,
376 .size
= sizeof(uint32_t),
377 .parse
= parse_pci_devfn
,
378 .print
= print_pci_devfn
,
381 /* --- public helpers --- */
383 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
387 while (props
->name
) {
388 if (strcmp(props
->name
, name
) == 0)
395 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
399 /* device properties */
400 prop
= qdev_prop_walk(dev
->info
->props
, name
);
405 prop
= qdev_prop_walk(dev
->parent_bus
->info
->props
, name
);
412 int qdev_prop_parse(DeviceState
*dev
, const char *name
, const char *value
)
416 prop
= qdev_prop_find(dev
, name
);
418 fprintf(stderr
, "property \"%s.%s\" not found\n",
419 dev
->info
->name
, name
);
422 if (!prop
->info
->parse
) {
423 fprintf(stderr
, "property \"%s.%s\" has no parser\n",
424 dev
->info
->name
, name
);
427 return prop
->info
->parse(dev
, prop
, value
);
430 void qdev_prop_set(DeviceState
*dev
, const char *name
, void *src
, enum PropertyType type
)
435 prop
= qdev_prop_find(dev
, name
);
437 fprintf(stderr
, "%s: property \"%s.%s\" not found\n",
438 __FUNCTION__
, dev
->info
->name
, name
);
441 if (prop
->info
->type
!= type
) {
442 fprintf(stderr
, "%s: property \"%s.%s\" type mismatch\n",
443 __FUNCTION__
, dev
->info
->name
, name
);
446 dst
= qdev_get_prop_ptr(dev
, prop
);
447 memcpy(dst
, src
, prop
->info
->size
);
450 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
452 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT8
);
455 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
457 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT16
);
460 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
462 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT32
);
465 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
467 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_INT32
);
470 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
472 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT64
);
475 void qdev_prop_set_drive(DeviceState
*dev
, const char *name
, DriveInfo
*value
)
477 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_DRIVE
);
480 void qdev_prop_set_chr(DeviceState
*dev
, const char *name
, CharDriverState
*value
)
482 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_CHR
);
485 void qdev_prop_set_ptr(DeviceState
*dev
, const char *name
, void *value
)
487 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_PTR
);
490 void qdev_prop_set_defaults(DeviceState
*dev
, Property
*props
)
496 while (props
->name
) {
498 dst
= qdev_get_prop_ptr(dev
, props
);
499 memcpy(dst
, props
->defval
, props
->info
->size
);
505 static CompatProperty
*compat_props
;
507 void qdev_prop_register_compat(CompatProperty
*props
)
509 compat_props
= props
;
512 void qdev_prop_set_compat(DeviceState
*dev
)
514 CompatProperty
*prop
;
519 for (prop
= compat_props
; prop
->driver
!= NULL
; prop
++) {
520 if (strcmp(dev
->info
->name
, prop
->driver
) != 0) {
523 if (qdev_prop_parse(dev
, prop
->property
, prop
->value
) != 0) {