|
@@ -816,39 +816,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
|
|
void *opaque, Error **errp)
|
|
void *opaque, Error **errp)
|
|
{
|
|
{
|
|
Property *prop = opaque;
|
|
Property *prop = opaque;
|
|
|
|
+ g_autofree GenericAlternate *alt;
|
|
int32_t value, *ptr = object_field_prop_ptr(obj, prop);
|
|
int32_t value, *ptr = object_field_prop_ptr(obj, prop);
|
|
unsigned int slot, fn, n;
|
|
unsigned int slot, fn, n;
|
|
- char *str;
|
|
|
|
|
|
+ g_autofree char *str = NULL;
|
|
|
|
+
|
|
|
|
+ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (alt->type) {
|
|
|
|
+ case QTYPE_QSTRING:
|
|
|
|
+ if (!visit_type_str(v, name, &str, errp)) {
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
|
|
- if (!visit_type_str(v, name, &str, NULL)) {
|
|
|
|
|
|
+ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
|
|
|
|
+ fn = 0;
|
|
|
|
+ if (sscanf(str, "%x%n", &slot, &n) != 1) {
|
|
|
|
+ goto invalid;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (str[n] != '\0' || fn > 7 || slot > 31) {
|
|
|
|
+ goto invalid;
|
|
|
|
+ }
|
|
|
|
+ *ptr = slot << 3 | fn;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case QTYPE_QNUM:
|
|
if (!visit_type_int32(v, name, &value, errp)) {
|
|
if (!visit_type_int32(v, name, &value, errp)) {
|
|
- return;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
if (value < -1 || value > 255) {
|
|
if (value < -1 || value > 255) {
|
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
|
name ? name : "null", "a value between -1 and 255");
|
|
name ? name : "null", "a value between -1 and 255");
|
|
- return;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
*ptr = value;
|
|
*ptr = value;
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
|
|
|
|
- fn = 0;
|
|
|
|
- if (sscanf(str, "%x%n", &slot, &n) != 1) {
|
|
|
|
- goto invalid;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (str[n] != '\0' || fn > 7 || slot > 31) {
|
|
|
|
- goto invalid;
|
|
|
|
|
|
+ default:
|
|
|
|
+ error_setg(errp, "Invalid parameter type for '%s', expected int or str",
|
|
|
|
+ name ? name : "null");
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
- *ptr = slot << 3 | fn;
|
|
|
|
- g_free(str);
|
|
|
|
- return;
|
|
|
|
|
|
+
|
|
|
|
+ goto out;
|
|
|
|
|
|
invalid:
|
|
invalid:
|
|
error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
|
|
error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
|
|
- g_free(str);
|
|
|
|
|
|
+out:
|
|
|
|
+ visit_end_alternate(v, (void **) &alt);
|
|
}
|
|
}
|
|
|
|
|
|
static int print_pci_devfn(Object *obj, Property *prop, char *dest,
|
|
static int print_pci_devfn(Object *obj, Property *prop, char *dest,
|