3 void *qdev_get_prop_ptr(DeviceState
*dev
, Property
*prop
)
10 /* --- 16bit integer --- */
12 static int parse_uint16(DeviceState
*dev
, Property
*prop
, const char *str
)
14 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
17 /* accept both hex and decimal */
18 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx16
: "%" PRIu16
;
19 if (sscanf(str
, fmt
, ptr
) != 1)
24 static int print_uint16(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
26 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
27 return snprintf(dest
, len
, "%" PRIu16
, *ptr
);
30 PropertyInfo qdev_prop_uint16
= {
32 .type
= PROP_TYPE_UINT16
,
33 .size
= sizeof(uint16_t),
34 .parse
= parse_uint16
,
35 .print
= print_uint16
,
38 /* --- 32bit integer --- */
40 static int parse_uint32(DeviceState
*dev
, Property
*prop
, const char *str
)
42 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
45 /* accept both hex and decimal */
46 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx32
: "%" PRIu32
;
47 if (sscanf(str
, fmt
, ptr
) != 1)
52 static int print_uint32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
54 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
55 return snprintf(dest
, len
, "%" PRIu32
, *ptr
);
58 PropertyInfo qdev_prop_uint32
= {
60 .type
= PROP_TYPE_UINT32
,
61 .size
= sizeof(uint32_t),
62 .parse
= parse_uint32
,
63 .print
= print_uint32
,
66 /* --- 32bit hex value --- */
68 static int parse_hex32(DeviceState
*dev
, Property
*prop
, const char *str
)
70 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
72 if (sscanf(str
, "%" PRIx32
, ptr
) != 1)
77 static int print_hex32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
79 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
80 return snprintf(dest
, len
, "0x%" PRIx32
, *ptr
);
83 PropertyInfo qdev_prop_hex32
= {
85 .type
= PROP_TYPE_UINT32
,
86 .size
= sizeof(uint32_t),
91 /* --- 64bit integer --- */
93 static int parse_uint64(DeviceState
*dev
, Property
*prop
, const char *str
)
95 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
98 /* accept both hex and decimal */
99 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx64
: "%" PRIu64
;
100 if (sscanf(str
, fmt
, ptr
) != 1)
105 static int print_uint64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
107 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
108 return snprintf(dest
, len
, "%" PRIu64
, *ptr
);
111 PropertyInfo qdev_prop_uint64
= {
113 .type
= PROP_TYPE_UINT64
,
114 .size
= sizeof(uint64_t),
115 .parse
= parse_uint64
,
116 .print
= print_uint64
,
119 /* --- 64bit hex value --- */
121 static int parse_hex64(DeviceState
*dev
, Property
*prop
, const char *str
)
123 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
125 if (sscanf(str
, "%" PRIx64
, ptr
) != 1)
130 static int print_hex64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
132 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
133 return snprintf(dest
, len
, "0x%" PRIx64
, *ptr
);
136 PropertyInfo qdev_prop_hex64
= {
138 .type
= PROP_TYPE_UINT64
,
139 .size
= sizeof(uint64_t),
140 .parse
= parse_hex64
,
141 .print
= print_hex64
,
144 /* --- pointer --- */
146 static int print_ptr(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
148 void **ptr
= qdev_get_prop_ptr(dev
, prop
);
149 return snprintf(dest
, len
, "<%p>", *ptr
);
152 PropertyInfo qdev_prop_ptr
= {
154 .type
= PROP_TYPE_PTR
,
155 .size
= sizeof(void*),
159 /* --- mac address --- */
162 * accepted syntax versions:
166 static int parse_mac(DeviceState
*dev
, Property
*prop
, const char *str
)
168 uint8_t *mac
= qdev_get_prop_ptr(dev
, prop
);
172 for (i
= 0, pos
= 0; i
< 6; i
++, pos
+= 3) {
173 if (!qemu_isxdigit(str
[pos
]))
175 if (!qemu_isxdigit(str
[pos
+1]))
177 if (i
== 5 && str
[pos
+2] != '\0')
179 if (str
[pos
+2] != ':' && str
[pos
+2] != '-')
181 mac
[i
] = strtol(str
+pos
, &p
, 16);
186 static int print_mac(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
188 uint8_t *mac
= qdev_get_prop_ptr(dev
, prop
);
189 return snprintf(dest
, len
, "%02x:%02x:%02x:%02x:%02x:%02x",
190 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
193 PropertyInfo qdev_prop_macaddr
= {
195 .type
= PROP_TYPE_MACADDR
,
201 /* --- pci address --- */
204 * bus-local address, i.e. "$slot" or "$slot.$fn"
206 static int parse_pci_devfn(DeviceState
*dev
, Property
*prop
, const char *str
)
208 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
209 unsigned int slot
, fn
, n
;
211 if (sscanf(str
, "%x.%x%n", &slot
, &fn
, &n
) != 2) {
213 if (sscanf(str
, "%x%n", &slot
, &n
) != 1) {
221 *ptr
= slot
<< 3 | fn
;
225 static int print_pci_devfn(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
227 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
230 return snprintf(dest
, len
, "<unset>");
232 return snprintf(dest
, len
, "%02x.%x", *ptr
>> 3, *ptr
& 7);
236 PropertyInfo qdev_prop_pci_devfn
= {
238 .type
= PROP_TYPE_UINT32
,
239 .size
= sizeof(uint32_t),
240 .parse
= parse_pci_devfn
,
241 .print
= print_pci_devfn
,
244 /* --- public helpers --- */
246 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
250 while (props
->name
) {
251 if (strcmp(props
->name
, name
) == 0)
258 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
262 /* device properties */
263 prop
= qdev_prop_walk(dev
->info
->props
, name
);
268 prop
= qdev_prop_walk(dev
->parent_bus
->info
->props
, name
);
275 int qdev_prop_parse(DeviceState
*dev
, const char *name
, const char *value
)
279 prop
= qdev_prop_find(dev
, name
);
281 fprintf(stderr
, "property \"%s.%s\" not found\n",
282 dev
->info
->name
, name
);
285 if (!prop
->info
->parse
) {
286 fprintf(stderr
, "property \"%s.%s\" has no parser\n",
287 dev
->info
->name
, name
);
290 return prop
->info
->parse(dev
, prop
, value
);
293 void qdev_prop_set(DeviceState
*dev
, const char *name
, void *src
, enum PropertyType type
)
298 prop
= qdev_prop_find(dev
, name
);
300 fprintf(stderr
, "%s: property \"%s.%s\" not found\n",
301 __FUNCTION__
, dev
->info
->name
, name
);
304 if (prop
->info
->type
!= type
) {
305 fprintf(stderr
, "%s: property \"%s.%s\" type mismatch\n",
306 __FUNCTION__
, dev
->info
->name
, name
);
309 dst
= qdev_get_prop_ptr(dev
, prop
);
310 memcpy(dst
, src
, prop
->info
->size
);
313 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
315 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT16
);
318 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
320 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT32
);
323 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
325 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT64
);
328 void qdev_prop_set_ptr(DeviceState
*dev
, const char *name
, void *value
)
330 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_PTR
);
333 void qdev_prop_set_defaults(DeviceState
*dev
, Property
*props
)
339 while (props
->name
) {
341 dst
= qdev_get_prop_ptr(dev
, props
);
342 memcpy(dst
, props
->defval
, props
->info
->size
);
348 static CompatProperty
*compat_props
;
350 void qdev_prop_register_compat(CompatProperty
*props
)
352 compat_props
= props
;
355 void qdev_prop_set_compat(DeviceState
*dev
)
357 CompatProperty
*prop
;
362 for (prop
= compat_props
; prop
->driver
!= NULL
; prop
++) {
363 if (strcmp(dev
->info
->name
, prop
->driver
) != 0) {
366 if (qdev_prop_parse(dev
, prop
->property
, prop
->value
) != 0) {