]> git.proxmox.com Git - qemu.git/blobdiff - hw/qdev-properties.c
softmmu: move include files to include/sysemu/
[qemu.git] / hw / qdev-properties.c
index c5545dcd37f15c783ae4f9d508a75b603bdf3328..1cb97ea594988025d43d22d7790391b1dd0c56d6 100644 (file)
@@ -1,7 +1,11 @@
-#include "net.h"
+#include "net/net.h"
 #include "qdev.h"
-#include "qerror.h"
-#include "blockdev.h"
+#include "qapi/qmp/qerror.h"
+#include "sysemu/blockdev.h"
+#include "hw/block-common.h"
+#include "net/hub.h"
+#include "qapi/visitor.h"
+#include "qemu-char.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -10,6 +14,78 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
     return ptr;
 }
 
+static void get_pointer(Object *obj, Visitor *v, Property *prop,
+                        const char *(*print)(void *ptr),
+                        const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    void **ptr = qdev_get_prop_ptr(dev, prop);
+    char *p;
+
+    p = (char *) (*ptr ? print(*ptr) : "");
+    visit_type_str(v, &p, name, errp);
+}
+
+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);
+}
+
+static void get_enum(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+static void set_enum(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+/* Bit */
+
 static uint32_t qdev_get_prop_mask(Property *prop)
 {
     assert(prop->info == &qdev_prop_bit);
@@ -26,8 +102,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
         *p &= ~mask;
 }
 
-/* Bit */
-
 static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
     uint32_t *p = qdev_get_prop_ptr(dev, prop);
@@ -76,52 +150,35 @@ PropertyInfo qdev_prop_bit = {
 
 /* --- 8bit integer --- */
 
-static void get_int8(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
+static void get_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    int64_t value;
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    value = *ptr;
-    visit_type_int(v, &value, name, errp);
+    visit_type_uint8(v, ptr, name, errp);
 }
 
-static void set_int8(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
+static void set_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    int64_t value;
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     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) {
-        *ptr = value;
-    } else {
-        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, value, prop->info->min,
-                  prop->info->max);
-    }
+    visit_type_uint8(v, ptr, name, errp);
 }
 
 PropertyInfo qdev_prop_uint8 = {
     .name  = "uint8",
-    .get   = get_int8,
-    .set   = set_int8,
-    .min   = 0,
-    .max   = 255,
+    .get   = get_uint8,
+    .set   = set_uint8,
 };
 
 /* --- 8bit hex value --- */
@@ -154,74 +211,78 @@ PropertyInfo qdev_prop_hex8 = {
     .legacy_name  = "hex8",
     .parse = parse_hex8,
     .print = print_hex8,
-    .get   = get_int8,
-    .set   = set_int8,
-    .min   = 0,
-    .max   = 255,
+    .get   = get_uint8,
+    .set   = set_uint8,
 };
 
 /* --- 16bit integer --- */
 
-static void get_int16(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
+static void get_uint16(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);
-    int64_t value;
+    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    value = *ptr;
-    visit_type_int(v, &value, name, errp);
+    visit_type_uint16(v, ptr, name, errp);
 }
 
-static void set_int16(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
+static void set_uint16(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;
+    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     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) {
-        *ptr = value;
-    } else {
-        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, value, prop->info->min,
-                  prop->info->max);
-    }
+    visit_type_uint16(v, ptr, name, errp);
 }
 
 PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
-    .get   = get_int16,
-    .set   = set_int16,
-    .min   = 0,
-    .max   = 65535,
+    .get   = get_uint16,
+    .set   = set_uint16,
 };
 
 /* --- 32bit integer --- */
 
+static void get_uint32(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);
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
+static void set_uint32(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);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
 static void get_int32(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
-    int64_t value;
 
-    value = *ptr;
-    visit_type_int(v, &value, name, errp);
+    visit_type_int32(v, ptr, name, errp);
 }
 
 static void set_int32(Object *obj, Visitor *v, void *opaque,
@@ -230,42 +291,25 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_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) {
-        *ptr = value;
-    } else {
-        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, value, prop->info->min,
-                  prop->info->max);
-    }
+    visit_type_int32(v, ptr, name, errp);
 }
 
 PropertyInfo qdev_prop_uint32 = {
     .name  = "uint32",
-    .get   = get_int32,
-    .set   = set_int32,
-    .min   = 0,
-    .max   = 0xFFFFFFFFULL,
+    .get   = get_uint32,
+    .set   = set_uint32,
 };
 
 PropertyInfo qdev_prop_int32 = {
     .name  = "int32",
     .get   = get_int32,
     .set   = set_int32,
-    .min   = -0x80000000LL,
-    .max   = 0x7FFFFFFFLL,
 };
 
 /* --- 32bit hex value --- */
@@ -298,43 +342,41 @@ PropertyInfo qdev_prop_hex32 = {
     .legacy_name  = "hex32",
     .parse = parse_hex32,
     .print = print_hex32,
-    .get   = get_int32,
-    .set   = set_int32,
-    .min   = 0,
-    .max   = 0xFFFFFFFFULL,
+    .get   = get_uint32,
+    .set   = set_uint32,
 };
 
 /* --- 64bit integer --- */
 
-static void get_int64(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
+static void get_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
-    visit_type_int(v, ptr, name, errp);
+    visit_type_uint64(v, ptr, name, errp);
 }
 
-static void set_int64(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
+static void set_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     if (dev->state != DEV_STATE_CREATED) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
 
-    visit_type_int(v, ptr, name, errp);
+    visit_type_uint64(v, ptr, name, errp);
 }
 
 PropertyInfo qdev_prop_uint64 = {
     .name  = "uint64",
-    .get   = get_int64,
-    .set   = set_int64,
+    .get   = get_uint64,
+    .set   = set_uint64,
 };
 
 /* --- 64bit hex value --- */
@@ -367,8 +409,8 @@ PropertyInfo qdev_prop_hex64 = {
     .legacy_name  = "hex64",
     .parse = parse_hex64,
     .print = print_hex64,
-    .get   = get_int64,
-    .set   = set_int64,
+    .get   = get_uint64,
+    .set   = set_uint64,
 };
 
 /* --- string --- */
@@ -467,48 +509,6 @@ static const char *print_drive(void *ptr)
     return bdrv_get_device_name(ptr);
 }
 
-static void get_pointer(Object *obj, Visitor *v, Property *prop,
-                        const char *(*print)(void *ptr),
-                        const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    void **ptr = qdev_get_prop_ptr(dev, prop);
-    char *p;
-
-    p = (char *) (*ptr ? print(*ptr) : "");
-    visit_type_str(v, &p, name, errp);
-}
-
-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);
-}
-
 static void get_drive(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
@@ -586,7 +586,7 @@ PropertyInfo qdev_prop_chr = {
 
 static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
 {
-    VLANClientState *netdev = qemu_find_netdev(str);
+    NetClientState *netdev = qemu_find_netdev(str);
 
     if (netdev == NULL) {
         return -ENOENT;
@@ -600,7 +600,7 @@ static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
 
 static const char *print_netdev(void *ptr)
 {
-    VLANClientState *netdev = ptr;
+    NetClientState *netdev = ptr;
 
     return netdev->name ? netdev->name : "";
 }
@@ -627,13 +627,16 @@ PropertyInfo qdev_prop_netdev = {
 
 static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr) {
-        return snprintf(dest, len, "%d", (*ptr)->id);
-    } else {
-        return snprintf(dest, len, "<null>");
+        int id;
+        if (!net_hub_id_for_client(*ptr, &id)) {
+            return snprintf(dest, len, "%d", id);
+        }
     }
+
+    return snprintf(dest, len, "<null>");
 }
 
 static void get_vlan(Object *obj, Visitor *v, void *opaque,
@@ -641,11 +644,17 @@ static void get_vlan(Object *obj, Visitor *v, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
-    int64_t id;
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t id = -1;
 
-    id = *ptr ? (*ptr)->id : -1;
-    visit_type_int(v, &id, name, errp);
+    if (*ptr) {
+        int hub_id;
+        if (!net_hub_id_for_client(*ptr, &hub_id)) {
+            id = hub_id;
+        }
+    }
+
+    visit_type_int32(v, &id, name, errp);
 }
 
 static void set_vlan(Object *obj, Visitor *v, void *opaque,
@@ -653,17 +662,17 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
-    int64_t id;
-    VLANState *vlan;
+    int32_t id;
+    NetClientState *hubport;
 
     if (dev->state != DEV_STATE_CREATED) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
 
-    visit_type_int(v, &id, name, &local_err);
+    visit_type_int32(v, &id, name, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -672,13 +681,14 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
         *ptr = NULL;
         return;
     }
-    vlan = qemu_find_vlan(id, 1);
-    if (!vlan) {
+
+    hubport = net_hub_port_find(id);
+    if (!hubport) {
         error_set(errp, QERR_INVALID_PARAMETER_VALUE,
                   name, prop->info->name);
         return;
     }
-    *ptr = vlan;
+    *ptr = hubport;
 }
 
 PropertyInfo qdev_prop_vlan = {
@@ -753,10 +763,12 @@ static void set_mac(Object *obj, Visitor *v, void *opaque,
         }
         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);
 }
 
 PropertyInfo qdev_prop_macaddr = {
@@ -765,7 +777,6 @@ PropertyInfo qdev_prop_macaddr = {
     .set   = set_mac,
 };
 
-
 /* --- lost tick policy --- */
 
 static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
@@ -778,33 +789,6 @@ static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
 
 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 
-static void get_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
-static void set_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
 PropertyInfo qdev_prop_losttickpolicy = {
     .name  = "LostTickPolicy",
     .enum_table  = lost_tick_policy_table,
@@ -812,6 +796,21 @@ PropertyInfo qdev_prop_losttickpolicy = {
     .set   = set_enum,
 };
 
+/* --- BIOS CHS translation */
+
+static const char *bios_chs_trans_table[] = {
+    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
+    [BIOS_ATA_TRANSLATION_NONE] = "none",
+    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
+};
+
+PropertyInfo qdev_prop_bios_chs_trans = {
+    .name = "bios-chs-trans",
+    .enum_table = bios_chs_trans_table,
+    .get = get_enum,
+    .set = set_enum,
+};
+
 /* --- pci address --- */
 
 /*
@@ -822,10 +821,10 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
     unsigned int slot, fn, n;
     Error *local_err = NULL;
-    char *str = (char *)"";
+    char *str;
 
     if (dev->state != DEV_STATE_CREATED) {
         error_set(errp, QERR_PERMISSION_DENIED);
@@ -835,7 +834,17 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
     visit_type_str(v, &str, name, &local_err);
     if (local_err) {
         error_free(local_err);
-        return set_int32(obj, v, opaque, name, errp);
+        local_err = NULL;
+        visit_type_int32(v, &value, name, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        } else if (value < -1 || value > 255) {
+            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
+                      "pci_devfn");
+        } else {
+            *ptr = value;
+        }
+        return;
     }
 
     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
@@ -848,15 +857,17 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
         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 int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -871,11 +882,6 @@ PropertyInfo qdev_prop_pci_devfn = {
     .print = print_pci_devfn,
     .get   = get_int32,
     .set   = set_pci_devfn,
-    /* FIXME: this should be -1...255, but the address is stored
-     * into an uint32_t rather than int32_t.
-     */
-    .min   = 0,
-    .max   = 0xFFFFFFFFULL,
 };
 
 /* --- blocksize --- */
@@ -885,31 +891,31 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
-    int64_t value;
+    const int64_t min = 512;
+    const int64_t max = 32768;
 
     if (dev->state != DEV_STATE_CREATED) {
         error_set(errp, QERR_PERMISSION_DENIED);
         return;
     }
 
-    visit_type_int(v, &value, name, &local_err);
+    visit_type_uint16(v, &value, name, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
-    if (value < prop->info->min || value > prop->info->max) {
+    if (value < min || value > max) {
         error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, value, prop->info->min,
-                  prop->info->max);
+                  dev->id?:"", name, (int64_t)value, min, 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);
+                  dev->id?:"", name, (int64_t)value);
         return;
     }
 
@@ -918,10 +924,115 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
 
 PropertyInfo qdev_prop_blocksize = {
     .name  = "blocksize",
-    .get   = get_int16,
+    .get   = get_uint16,
     .set   = set_blocksize,
-    .min   = 512,
-    .max   = 65024,
+};
+
+/* --- pci host address --- */
+
+static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
+                                 const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    char buffer[] = "xxxx:xx:xx.x";
+    char *p = buffer;
+    int rc = 0;
+
+    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
+                  addr->domain, addr->bus, addr->slot, addr->function);
+    assert(rc == sizeof(buffer) - 1);
+
+    visit_type_str(v, &p, name, errp);
+}
+
+/*
+ * Parse [<domain>:]<bus>:<slot>.<func>
+ *   if <domain> is not supplied, it's assumed to be 0.
+ */
+static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
+                                 const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str, *p;
+    char *e;
+    unsigned long val;
+    unsigned long dom = 0, bus = 0;
+    unsigned int slot = 0, func = 0;
+
+    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;
+    }
+
+    p = str;
+    val = strtoul(p, &e, 16);
+    if (e == p || *e != ':') {
+        goto inval;
+    }
+    bus = val;
+
+    p = e + 1;
+    val = strtoul(p, &e, 16);
+    if (e == p) {
+        goto inval;
+    }
+    if (*e == ':') {
+        dom = bus;
+        bus = val;
+        p = e + 1;
+        val = strtoul(p, &e, 16);
+        if (e == p) {
+            goto inval;
+        }
+    }
+    slot = val;
+
+    if (*e != '.') {
+        goto inval;
+    }
+    p = e + 1;
+    val = strtoul(p, &e, 10);
+    if (e == p) {
+        goto inval;
+    }
+    func = val;
+
+    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
+        goto inval;
+    }
+
+    if (*e) {
+        goto inval;
+    }
+
+    addr->domain = dom;
+    addr->bus = bus;
+    addr->slot = slot;
+    addr->function = func;
+
+    g_free(str);
+    return;
+
+inval:
+    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    g_free(str);
+}
+
+PropertyInfo qdev_prop_pci_host_devaddr = {
+    .name = "pci-host-devaddr",
+    .get = get_pci_host_devaddr,
+    .set = set_pci_host_devaddr,
 };
 
 /* --- public helpers --- */
@@ -940,26 +1051,22 @@ static Property *qdev_prop_walk(Property *props, const char *name)
 
 static Property *qdev_prop_find(DeviceState *dev, const char *name)
 {
+    ObjectClass *class;
     Property *prop;
 
     /* device properties */
-    prop = qdev_prop_walk(qdev_get_props(dev), name);
-    if (prop)
-        return prop;
-
-    /* bus properties */
-    prop = qdev_prop_walk(dev->parent_bus->info->props, name);
-    if (prop)
-        return prop;
+    class = object_get_class(OBJECT(dev));
+    do {
+        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
+        if (prop) {
+            return prop;
+        }
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_DEVICE));
 
     return NULL;
 }
 
-int qdev_prop_exists(DeviceState *dev, const char *name)
-{
-    return qdev_prop_find(dev, name) ? true : false;
-}
-
 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
                                     Property *prop, const char *value)
 {
@@ -1045,7 +1152,7 @@ void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
     assert_no_error(errp);
 }
 
-void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
+void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
 {
     Error *errp = NULL;
     object_property_set_str(OBJECT(dev), value, name, &errp);
@@ -1081,7 +1188,7 @@ void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *valu
     assert_no_error(errp);
 }
 
-void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
+void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value)
 {
     Error *errp = NULL;
     assert(!value || value->name);
@@ -1090,13 +1197,6 @@ void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *v
     assert_no_error(errp);
 }
 
-void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
-    assert_no_error(errp);
-}
-
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
     Error *errp = NULL;
@@ -1130,28 +1230,6 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
     *ptr = value;
 }
 
-void qdev_prop_set_defaults(DeviceState *dev, Property *props)
-{
-    Object *obj = OBJECT(dev);
-    if (!props)
-        return;
-    for (; props->name; props++) {
-        Error *errp = NULL;
-        if (props->qtype == QTYPE_NONE) {
-            continue;
-        }
-        if (props->qtype == QTYPE_QBOOL) {
-            object_property_set_bool(obj, props->defval, props->name, &errp);
-        } else if (props->info->enum_table) {
-            object_property_set_str(obj, props->info->enum_table[props->defval],
-                                    props->name, &errp);
-        } else if (props->qtype == QTYPE_QINT) {
-            object_property_set_int(obj, props->defval, props->name, &errp);
-        }
-        assert_no_error(errp);
-    }
-}
-
 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
 
 static void qdev_prop_register_global(GlobalProperty *prop)
@@ -1170,17 +1248,20 @@ void qdev_prop_register_global_list(GlobalProperty *props)
 
 void qdev_prop_set_globals(DeviceState *dev)
 {
-    GlobalProperty *prop;
-
-    QTAILQ_FOREACH(prop, &global_props, next) {
-        if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
-            strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
-            continue;
+    ObjectClass *class = object_get_class(OBJECT(dev));
+
+    do {
+        GlobalProperty *prop;
+        QTAILQ_FOREACH(prop, &global_props, next) {
+            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
+                continue;
+            }
+            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
+                exit(1);
+            }
         }
-        if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
-            exit(1);
-        }
-    }
+        class = object_class_get_parent(class);
+    } while (class);
 }
 
 static int qdev_add_one_global(QemuOpts *opts, void *opaque)