static void set_generic(DeviceState *dev, Visitor *v, void *opaque, const char *name, Error **errp) { Property *prop = opaque; Error *local_err = NULL; char *str; int ret; if (dev->state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } visit_type_str(v, &str, name, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (!*str) { g_free(str); error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); return; } ret = prop->info->parse(dev, prop, str); error_set_from_qdev_prop_error(errp, ret, dev, prop, str); g_free(str); }
/* * bus-local address, i.e. "$slot" or "$slot.$fn" */ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; uint32_t *ptr = qdev_get_prop_ptr(dev, prop); unsigned int slot, fn, n; Error *local_err = NULL; char *str = (char *)""; if (dev->state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } visit_type_str(v, &str, name, &local_err); if (local_err) { return set_int32(obj, v, opaque, name, errp); } 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; return; invalid: error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); }
static void set_pointer(Object *obj, Visitor *v, Property *prop, int (*parse)(DeviceState *dev, const char *str, void **ptr), const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Error *local_err = NULL; void **ptr = qdev_get_prop_ptr(dev, prop); char *str; int ret; if (dev->state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } visit_type_str(v, &str, name, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (!*str) { g_free(str); *ptr = NULL; return; } ret = parse(dev, str, ptr); error_set_from_qdev_prop_error(errp, ret, dev, prop, str); g_free(str); }
/* * bus-local address, i.e. "$slot" or "$slot.$fn" */ static void set_pci_devfn(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); unsigned int slot, fn, n; Error *local_err = NULL; char *str; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } visit_type_str(v, name, &str, &local_err); if (local_err) { error_free(local_err); local_err = NULL; visit_type_int32(v, name, &value, &local_err); if (local_err) { error_propagate(errp, local_err); } else if (value < -1 || value > 255) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", "pci_devfn"); } else { *ptr = value; } return; } 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; g_free(str); return; invalid: error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); g_free(str); }
static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; MACAddr *mac = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; int i, pos; char *str, *p; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } visit_type_str(v, name, &str, &local_err); if (local_err) { error_propagate(errp, local_err); return; } for (i = 0, pos = 0; i < 6; i++, pos += 3) { if (!qemu_isxdigit(str[pos])) { goto inval; } if (!qemu_isxdigit(str[pos+1])) { goto inval; } if (i == 5) { if (str[pos+2] != '\0') { goto inval; } } else { if (str[pos+2] != ':' && str[pos+2] != '-') { goto inval; } } mac->a[i] = strtol(str+pos, &p, 16); } g_free(str); return; inval: error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); g_free(str); }
static void set_mac(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; MACAddr *mac = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; int i, pos; char *str, *p; if (dev->state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } visit_type_str(v, &str, name, &local_err); if (local_err) { error_propagate(errp, local_err); return; } for (i = 0, pos = 0; i < 6; i++, pos += 3) { if (!qemu_isxdigit(str[pos])) goto inval; if (!qemu_isxdigit(str[pos+1])) goto inval; if (i == 5) { if (str[pos+2] != '\0') goto inval; } else { if (str[pos+2] != ':' && str[pos+2] != '-') goto inval; } mac->a[i] = strtol(str+pos, &p, 16); } return; inval: error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); }
static void set_vlan(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop); NetClientState **ptr = &peers_ptr->ncs[0]; Error *local_err = NULL; int32_t id; NetClientState *hubport; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } visit_type_int32(v, name, &id, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (id == -1) { *ptr = NULL; return; } if (*ptr) { error_set_from_qdev_prop_error(errp, -EINVAL, dev, prop, name); return; } hubport = net_hub_port_find(id); if (!hubport) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, prop->info->name); return; } *ptr = hubport; }
static void set_netdev(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop); NetClientState **ncs = peers_ptr->ncs; NetClientState *peers[MAX_QUEUE_NUM]; Error *local_err = NULL; int queues, err = 0, i = 0; char *str; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } visit_type_str(v, name, &str, &local_err); if (local_err) { error_propagate(errp, local_err); return; } queues = qemu_find_net_clients_except(str, peers, NET_CLIENT_DRIVER_NIC, MAX_QUEUE_NUM); if (queues == 0) { err = -ENOENT; goto out; } if (queues > MAX_QUEUE_NUM) { error_setg(errp, "queues of backend '%s'(%d) exceeds QEMU limitation(%d)", str, queues, MAX_QUEUE_NUM); goto out; } for (i = 0; i < queues; i++) { if (peers[i] == NULL) { err = -ENOENT; goto out; } if (peers[i]->peer) { err = -EEXIST; goto out; } if (ncs[i]) { err = -EINVAL; goto out; } ncs[i] = peers[i]; ncs[i]->queue_index = i; } peers_ptr->queues = queues; out: error_set_from_qdev_prop_error(errp, err, dev, prop, str); g_free(str); }