diff options
-rw-r--r-- | hw/qdev-properties.c | 46 | ||||
-rw-r--r-- | hw/qdev.h | 3 | ||||
-rw-r--r-- | qerror.c | 5 | ||||
-rw-r--r-- | qerror.h | 4 |
4 files changed, 58 insertions, 0 deletions
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index bff9152df5..98dd06aeba 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -877,6 +877,52 @@ PropertyInfo qdev_prop_pci_devfn = { .max = 0xFFFFFFFFULL, }; +/* --- blocksize --- */ + +static void set_blocksize(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int16_t *ptr = qdev_get_prop_ptr(dev, prop); + Error *local_err = NULL; + int64_t value; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_int(v, &value, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + if (value < prop->info->min || value > prop->info->max) { + error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, + dev->id?:"", name, value, prop->info->min, + prop->info->max); + return; + } + + /* We rely on power-of-2 blocksizes for bitmasks */ + if ((value & (value - 1)) != 0) { + error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2, + dev->id?:"", name, value); + return; + } + + *ptr = value; +} + +PropertyInfo qdev_prop_blocksize = { + .name = "blocksize", + .get = get_int16, + .set = set_blocksize, + .min = 512, + .max = 65024, +}; + /* --- public helpers --- */ static Property *qdev_prop_walk(Property *props, const char *name) @@ -223,6 +223,7 @@ extern PropertyInfo qdev_prop_drive; extern PropertyInfo qdev_prop_netdev; extern PropertyInfo qdev_prop_vlan; extern PropertyInfo qdev_prop_pci_devfn; +extern PropertyInfo qdev_prop_blocksize; #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name = (_name), \ @@ -284,6 +285,8 @@ extern PropertyInfo qdev_prop_pci_devfn; #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \ LostTickPolicy) +#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t) #define DEFINE_PROP_END_OF_LIST() \ {} @@ -241,6 +241,11 @@ static const QErrorStringTable qerror_table[] = { .desc = "Property '%(device).%(property)' can't find value '%(value)'", }, { + .error_fmt = QERR_PROPERTY_VALUE_NOT_POWER_OF_2, + .desc = "Property '%(device).%(property)' doesn't take " + "value '%(value)', it's not a power of 2", + }, + { .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE, .desc = "Property '%(device).%(property)' doesn't take " "value %(value) (minimum: %(min), maximum: %(max))", @@ -202,6 +202,10 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_PROPERTY_VALUE_NOT_FOUND \ "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }" +#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \ + "{ 'class': 'PropertyValueNotPowerOf2', 'data': { " \ + "'device': %s, 'property': %s, 'value': %"PRId64" } }" + #define QERR_PROPERTY_VALUE_OUT_OF_RANGE \ "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }" |