Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140220' into staging

target-arm queue:
 * Fix a bug causing an assertion in the NVIC on ARMv7M models
 * More A64 Neon instructions
 * Refactor cpreg API to separate out access check functions, as
   groundwork for AArch64 system mode
 * Fix bug in linux-user A64 store-exclusive of XZR

# gpg: Signature made Thu 20 Feb 2014 11:12:57 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140220: (30 commits)
  linux-user: AArch64: Fix exclusive store of the zero register
  target-arm: A64: Implement unprivileged load/store
  target-arm: A64: Implement narrowing three-reg-diff operations
  target-arm: A64: Implement the wide 3-reg-different operations
  target-arm: A64: Add most remaining three-reg-diff widening ops
  target-arm: A64: Add opcode comments to disas_simd_three_reg_diff
  target-arm: A64: Implement store-exclusive for system mode
  target-arm: Fix incorrect type for value argument to write_raw_cp_reg
  target-arm: Remove failure status return from read/write_raw_cp_reg
  target-arm: Remove unnecessary code now read/write fns can't fail
  target-arm: Drop success/fail return from cpreg read and write functions
  target-arm: Convert miscellaneous reginfo structs to accessfn
  target-arm: Convert generic timer reginfo to accessfn
  target-arm: Convert performance monitor reginfo to accessfn
  target-arm: Split cpreg access checks out from read/write functions
  target-arm: Stop underdecoding ARM946 PRBS registers
  target-arm: Log bad system register accesses with LOG_UNIMP
  target-arm: Remove unused ARMCPUState sr substruct
  target-arm: Restrict check_ap() use of S and R bits to v6 and earlier
  target-arm: Define names for SCTLR bits
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.gitignore b/.gitignore
index 6e48b5e..ff0ae64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,8 @@
 /trace/generated-tracers.dtrace
 /trace/generated-events.h
 /trace/generated-events.c
+/trace/generated-ust-provider.h
+/trace/generated-ust.c
 /libcacard/trace/generated-tracers.c
 *-timestamp
 /*-softmmu
diff --git a/Makefile b/Makefile
index 807054b..a443cd4 100644
--- a/Makefile
+++ b/Makefile
@@ -57,6 +57,11 @@
 endif
 GENERATED_SOURCES += trace/generated-tracers.c
 
+ifeq ($(TRACE_BACKEND),ust)
+GENERATED_HEADERS += trace/generated-ust-provider.h
+GENERATED_SOURCES += trace/generated-ust.c
+endif
+
 # Don't try to regenerate Makefile or configure
 # We don't generate any of them
 Makefile: ;
diff --git a/block.c b/block.c
index 8f718f9..6f4baca 100644
--- a/block.c
+++ b/block.c
@@ -421,7 +421,7 @@
     assert(cco->drv);
 
     ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(&cco->err, local_err);
     }
     cco->ret = ret;
@@ -460,7 +460,7 @@
 
     ret = cco.ret;
     if (ret < 0) {
-        if (error_is_set(&cco.err)) {
+        if (cco.err) {
             error_propagate(errp, cco.err);
         } else {
             error_setg_errno(errp, -ret, "Could not create image");
@@ -486,7 +486,7 @@
     }
 
     ret = bdrv_create(drv, filename, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
@@ -916,7 +916,7 @@
     }
 
     if (ret < 0) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
         } else if (bs->filename[0]) {
             error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename);
@@ -1037,7 +1037,7 @@
     /* Parse the filename and open it */
     if (drv->bdrv_parse_filename && filename) {
         drv->bdrv_parse_filename(filename, options, &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             ret = -EINVAL;
             goto fail;
@@ -1406,7 +1406,7 @@
     QDECREF(bs->options);
     QDECREF(options);
     bs->options = NULL;
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
@@ -1414,7 +1414,7 @@
 close_and_fail:
     bdrv_close(bs);
     QDECREF(options);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
@@ -5340,7 +5340,7 @@
     free_option_parameters(create_options);
     free_option_parameters(param);
 
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
 }
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 8eb0db0..ee10013 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -303,7 +303,7 @@
     }
 
     qemu_config_parse_qdict(options, config_groups, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto fail;
@@ -393,7 +393,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto out;
diff --git a/block/blkverify.c b/block/blkverify.c
index cfcbcf4..1563c88 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -128,7 +128,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto fail;
diff --git a/block/curl.c b/block/curl.c
index a807584..bb1fc4a 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -463,7 +463,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         goto out_noclean;
diff --git a/block/gluster.c b/block/gluster.c
index a009b15..58eab07 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -282,7 +282,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         ret = -EINVAL;
diff --git a/block/iscsi.c b/block/iscsi.c
index c97c040..f8e496f 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1127,7 +1127,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         ret = -EINVAL;
diff --git a/block/nbd.c b/block/nbd.c
index 327e913..abae506 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -209,7 +209,7 @@
                                       &error_abort);
 
     qemu_opts_absorb_qdict(s->socket_opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -EINVAL;
diff --git a/block/qapi.c b/block/qapi.c
index 8f4134b..8f2b4db 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -271,7 +271,7 @@
         p_image_info = &info->inserted->image;
         while (1) {
             bdrv_query_image_info(bs0, p_image_info, &local_err);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_propagate(errp, local_err);
                 goto err;
             }
@@ -336,7 +336,7 @@
      while ((bs = bdrv_next(bs))) {
         BlockInfoList *info = g_malloc0(sizeof(*info));
         bdrv_query_info(bs, &info->value, &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             goto err;
         }
diff --git a/block/qcow2.c b/block/qcow2.c
index 0b4335c..b1dbdb1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -671,7 +671,7 @@
     /* Enable lazy_refcounts according to image and command line options */
     opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto fail;
@@ -1605,7 +1605,7 @@
     ret = bdrv_open(bs, filename, NULL,
                     BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
                     drv, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         goto out;
     }
@@ -1685,7 +1685,7 @@
 
     ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
                         cluster_size, prealloc, options, version, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 126a634..161ea14 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -361,7 +361,7 @@
 
     opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto fail;
@@ -448,7 +448,7 @@
 
     s->type = FTYPE_FILE;
     ret = raw_open_common(bs, options, flags, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
@@ -1597,7 +1597,7 @@
 
     ret = raw_open_common(bs, options, flags, 0, &local_err);
     if (ret < 0) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
         }
         return ret;
@@ -1832,7 +1832,7 @@
     /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
     ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
     if (ret) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
         }
         return ret;
@@ -1961,7 +1961,7 @@
 
     /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
     ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
@@ -2078,7 +2078,7 @@
 
     ret = raw_open_common(bs, options, flags, 0, &local_err);
     if (ret) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
         }
         return ret;
diff --git a/block/raw-win32.c b/block/raw-win32.c
index beb7f23..ae1c8e6 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -279,7 +279,7 @@
 
     opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto fail;
@@ -594,7 +594,7 @@
     QemuOpts *opts = qemu_opts_create(&raw_runtime_opts, NULL, 0,
                                       &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         ret = -EINVAL;
         goto done;
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index af8706d..01ea692 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -146,7 +146,7 @@
     int ret;
 
     ret = bdrv_create_file(filename, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
     return ret;
diff --git a/block/rbd.c b/block/rbd.c
index 121fae2..dbc79f4 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -440,7 +440,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         qemu_opts_del(opts);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 672b9c9..e6c0376 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1385,7 +1385,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         ret = -EINVAL;
diff --git a/block/snapshot.c b/block/snapshot.c
index 9047f8d..85c52ff 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -345,7 +345,7 @@
         ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
     }
 
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
     }
 
diff --git a/block/vvfat.c b/block/vvfat.c
index 664941c..a19e4ca 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1085,7 +1085,7 @@
 
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         ret = -EINVAL;
diff --git a/blockdev.c b/blockdev.c
index dfb5ec7..3cc8cda 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -330,13 +330,13 @@
      * stay in bs_opts for processing by bdrv_open(). */
     id = qdict_get_try_str(bs_opts, "id");
     opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
-    if (error_is_set(&error)) {
+    if (error) {
         error_propagate(errp, error);
         return NULL;
     }
 
     qemu_opts_absorb_qdict(opts, bs_opts, &error);
-    if (error_is_set(&error)) {
+    if (error) {
         error_propagate(errp, error);
         goto early_err;
     }
@@ -437,7 +437,7 @@
     on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
     if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
         on_write_error = parse_block_error_action(buf, 0, &error);
-        if (error_is_set(&error)) {
+        if (error) {
             error_propagate(errp, error);
             goto early_err;
         }
@@ -446,7 +446,7 @@
     on_read_error = BLOCKDEV_ON_ERROR_REPORT;
     if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
         on_read_error = parse_block_error_action(buf, 1, &error);
-        if (error_is_set(&error)) {
+        if (error) {
             error_propagate(errp, error);
             goto early_err;
         }
@@ -691,7 +691,7 @@
     legacy_opts = qemu_opts_create(&qemu_legacy_drive_opts, NULL, 0,
                                    &error_abort);
     qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         goto fail;
@@ -779,6 +779,10 @@
             translation = BIOS_ATA_TRANSLATION_NONE;
         } else if (!strcmp(value, "lba")) {
             translation = BIOS_ATA_TRANSLATION_LBA;
+        } else if (!strcmp(value, "large")) {
+            translation = BIOS_ATA_TRANSLATION_LARGE;
+        } else if (!strcmp(value, "rechs")) {
+            translation = BIOS_ATA_TRANSLATION_RECHS;
         } else if (!strcmp(value, "auto")) {
             translation = BIOS_ATA_TRANSLATION_AUTO;
         } else {
@@ -899,13 +903,13 @@
     /* Actual block device init: Functionality shared with blockdev-add */
     dinfo = blockdev_init(filename, bs_opts, &local_err);
     if (dinfo == NULL) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             qerror_report_err(local_err);
             error_free(local_err);
         }
         goto fail;
     } else {
-        assert(!error_is_set(&local_err));
+        assert(!local_err);
     }
 
     /* Set legacy DriveInfo fields */
@@ -1042,7 +1046,7 @@
     }
 
     ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return NULL;
     }
@@ -1055,7 +1059,7 @@
     }
 
     bdrv_snapshot_delete(bs, id, name, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return NULL;
     }
@@ -1269,7 +1273,7 @@
     state->old_bs = bdrv_lookup_bs(has_device ? device : NULL,
                                    has_node_name ? node_name : NULL,
                                    &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -1314,7 +1318,7 @@
                         state->old_bs->filename,
                         state->old_bs->drv->format_name,
                         NULL, -1, flags, &local_err, false);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             return;
         }
@@ -1383,7 +1387,7 @@
                      backup->has_on_source_error, backup->on_source_error,
                      backup->has_on_target_error, backup->on_target_error,
                      &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         state->bs = NULL;
         state->job = NULL;
@@ -1475,7 +1479,7 @@
         QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry);
 
         state->ops->prepare(state, &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             goto delete_and_fail;
         }
@@ -1556,7 +1560,7 @@
     bs = bdrv_lookup_bs(has_device ? device : NULL,
                         has_node_name ? node_name : NULL,
                         &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -1621,7 +1625,7 @@
     }
 
     eject_device(bs, 0, &err);
-    if (error_is_set(&err)) {
+    if (err) {
         error_propagate(errp, err);
         return;
     }
@@ -1758,7 +1762,7 @@
     bs = bdrv_lookup_bs(has_device ? device : NULL,
                         has_node_name ? node_name : NULL,
                         &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -1851,7 +1855,7 @@
 
     stream_start(bs, base_bs, base, has_speed ? speed : 0,
                  on_error, block_job_cb, bs, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -2009,7 +2013,7 @@
         }
     }
 
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -2150,7 +2154,7 @@
         }
     }
 
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -2289,7 +2293,7 @@
 
     visit_type_BlockdevOptions(qmp_output_get_visitor(ov),
                                &options, NULL, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         goto fail;
     }
@@ -2300,7 +2304,7 @@
     qdict_flatten(qdict);
 
     blockdev_init(NULL, qdict, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         goto fail;
     }
diff --git a/blockjob.c b/blockjob.c
index 9e5fd5c..b3ce14c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -61,7 +61,7 @@
         Error *local_err = NULL;
 
         block_job_set_speed(job, speed, &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             bs->job = NULL;
             g_free(job);
             bdrv_set_in_use(bs, 0);
@@ -92,7 +92,7 @@
         return;
     }
     job->driver->set_speed(job, speed, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
diff --git a/configure b/configure
index 4648117..39f2a1a 100755
--- a/configure
+++ b/configure
@@ -3379,15 +3379,25 @@
 # For 'ust' backend, test if ust headers are present
 if test "$trace_backend" = "ust"; then
   cat > $TMPC << EOF
-#include <ust/tracepoint.h>
-#include <ust/marker.h>
+#include <lttng/tracepoint.h>
 int main(void) { return 0; }
 EOF
   if compile_prog "" "" ; then
-    LIBS="-lust -lurcu-bp $LIBS"
-    libs_qga="-lust -lurcu-bp $libs_qga"
+    if $pkg_config lttng-ust --exists; then
+      lttng_ust_libs=`$pkg_config --libs lttng-ust`
+    else
+      lttng_ust_libs="-llttng-ust"
+    fi
+    if $pkg_config liburcu-bp --exists; then
+      urcu_bp_libs=`$pkg_config --libs liburcu-bp`
+    else
+      urcu_bp_libs="-lurcu-bp"
+    fi
+
+    LIBS="$lttng_ust_libs $urcu_bp_libs $LIBS"
+    libs_qga="$lttng_ust_libs $urcu_bp_libs $libs_qga"
   else
-    error_exit "Trace backend 'ust' missing libust header files"
+    error_exit "Trace backend 'ust' missing lttng-ust header files"
   fi
 fi
 
@@ -3564,7 +3574,18 @@
 cat > $TMPC << EOF
 #include <cpuid.h>
 int main(void) {
-  return 0;
+    unsigned a, b, c, d;
+    int max = __get_cpuid_max(0, 0);
+
+    if (max >= 1) {
+        __cpuid(1, a, b, c, d);
+    }
+
+    if (max >= 7) {
+        __cpuid_count(7, 0, a, b, c, d);
+    }
+
+    return 0;
 }
 EOF
 if compile_prog "" "" ; then
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index f380ca4..e5f9d36 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -42,6 +42,7 @@
 CONFIG_XILINX_ETHLITE=y
 CONFIG_OPENPIC=y
 CONFIG_PREP=y
+CONFIG_MAC=y
 CONFIG_E500=y
 CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
 # For PReP
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index fcc0452..e2beac6 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -43,6 +43,7 @@
 CONFIG_OPENPIC=y
 CONFIG_PSERIES=y
 CONFIG_PREP=y
+CONFIG_MAC=y
 CONFIG_E500=y
 CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
 # For pSeries
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index fdf1e14..1e4fde2 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -3,30 +3,12 @@
 include pci.mak
 include sound.mak
 include usb.mak
-CONFIG_ISA_MMIO=y
-CONFIG_ESCC=y
 CONFIG_M48T59=y
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
 CONFIG_SERIAL=y
-CONFIG_I8254=y
-CONFIG_FDC=y
 CONFIG_I8257=y
 CONFIG_OPENPIC=y
-CONFIG_MACIO=y
-CONFIG_CUDA=y
-CONFIG_ADB=y
-CONFIG_MAC_NVRAM=y
-CONFIG_MAC_DBDMA=y
-CONFIG_HEATHROW_PIC=y
-CONFIG_GRACKLE_PCI=y
-CONFIG_UNIN_PCI=y
-CONFIG_DEC_PCI=y
-CONFIG_PPCE500_PCI=y
-CONFIG_IDE_ISA=y
-CONFIG_IDE_CMD646=y
-CONFIG_IDE_MACIO=y
-CONFIG_NE2000_ISA=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_PTIMER=y
@@ -34,5 +16,3 @@
 CONFIG_XILINX=y
 CONFIG_XILINX_ETHLITE=y
 CONFIG_OPENPIC=y
-CONFIG_E500=y
-CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
diff --git a/disas/i386.c b/disas/i386.c
index 044e02c..00ceca9 100644
--- a/disas/i386.c
+++ b/disas/i386.c
@@ -171,6 +171,7 @@
 static void print_displacement (char *, bfd_vma);
 static void OP_E (int, int);
 static void OP_G (int, int);
+static void OP_vvvv (int, int);
 static bfd_vma get64 (void);
 static bfd_signed_vma get32 (void);
 static bfd_signed_vma get32s (void);
@@ -264,6 +265,9 @@
    current instruction.  */
 static int used_prefixes;
 
+/* The VEX.vvvv register, unencoded.  */
+static int vex_reg;
+
 /* Flags stored in PREFIXES.  */
 #define PREFIX_REPZ 1
 #define PREFIX_REPNZ 2
@@ -278,6 +282,10 @@
 #define PREFIX_ADDR 0x400
 #define PREFIX_FWAIT 0x800
 
+#define PREFIX_VEX_0F    0x1000
+#define PREFIX_VEX_0F38  0x2000
+#define PREFIX_VEX_0F3A  0x4000
+
 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
    on error.  */
@@ -323,6 +331,7 @@
 
 #define XX { NULL, 0 }
 
+#define Bv { OP_vvvv, v_mode }
 #define Eb { OP_E, b_mode }
 #define Ev { OP_E, v_mode }
 #define Ed { OP_E, d_mode }
@@ -671,7 +680,8 @@
 #define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
 #define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
 #define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
-
+#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
+#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
 
 #define X86_64_0  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
 #define X86_64_1  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
@@ -1449,7 +1459,7 @@
   /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
   /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, /* df */
   /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+  /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
   /*       -------------------------------        */
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
@@ -1473,7 +1483,7 @@
   /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
   /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
   /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+  /* f0 */ 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
   /*       -------------------------------        */
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
@@ -1497,7 +1507,7 @@
   /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
   /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
   /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
+  /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, /* ff */
   /*       -------------------------------        */
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
@@ -2774,6 +2784,22 @@
     { "(bad)",	{ XX } },
   },
 
+  /* PREGRP105 */
+  {
+    { "andnS",	{ Gv, Bv, Ev } },
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+  },
+
+  /* PREGRP106 */
+  {
+    { "bextrS",	{ Gv, Ev, Bv } },
+    { "sarxS",	{ Gv, Ev, Bv } },
+    { "shlxS",	{ Gv, Ev, Bv } },
+    { "shrxS",	{ Gv, Ev, Bv } },
+  },
+
 };
 
 static const struct dis386 x86_64_table[][2] = {
@@ -3071,12 +3097,12 @@
     /* f0 */
     { PREGRP87 },
     { PREGRP88 },
+    { PREGRP105 },
     { "(bad)", { XX } },
     { "(bad)", { XX } },
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
+    { PREGRP106 },
     /* f8 */
     { "(bad)", { XX } },
     { "(bad)", { XX } },
@@ -3477,6 +3503,74 @@
     }
 }
 
+static void
+ckvexprefix (void)
+{
+    int op, vex2, vex3, newrex = 0, newpfx = prefixes;
+
+    if (address_mode == mode_16bit) {
+        return;
+    }
+
+    fetch_data(the_info, codep + 1);
+    op = *codep;
+
+    if (op != 0xc4 && op != 0xc5) {
+        return;
+    }
+
+    fetch_data(the_info, codep + 2);
+    vex2 = codep[1];
+
+    if (address_mode == mode_32bit && (vex2 & 0xc0) != 0xc0) {
+        return;
+    }
+
+    if (op == 0xc4) {
+        /* Three byte VEX prefix.  */
+        fetch_data(the_info, codep + 3);
+        vex3 = codep[2];
+
+        newrex |= (vex2 & 0x80 ? 0 : REX_R);
+        newrex |= (vex2 & 0x40 ? 0 : REX_X);
+        newrex |= (vex2 & 0x20 ? 0 : REX_B);
+        newrex |= (vex3 & 0x80 ? REX_W : 0);
+        switch (vex2 & 0x1f) {      /* VEX.m-mmmm */
+        case 1:
+            newpfx |= PREFIX_VEX_0F;
+            break;
+        case 2:
+            newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F38;
+            break;
+        case 3:
+            newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F3A;
+            break;
+        }
+        vex2 = vex3;
+        codep += 3;
+    } else {
+        /* Two byte VEX prefix.  */
+        newrex |= (vex2 & 0x80 ? 0 : REX_R);
+        codep += 2;
+    }
+
+    vex_reg = (~vex2 >> 3) & 15;     /* VEX.vvvv */
+    switch (vex2 & 3) {              /* VEX.pp */
+    case 1:
+        newpfx |= PREFIX_DATA;     /* 0x66 */
+        break;
+    case 2:
+        newpfx |= PREFIX_REPZ;     /* 0xf3 */
+        break;
+    case 3:
+        newpfx |= PREFIX_REPNZ;    /* 0xf2 */
+        break;
+    }
+
+    rex = newrex;
+    prefixes = newpfx;
+}
+
 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
    prefix byte.  */
 
@@ -3598,6 +3692,7 @@
   const char *p;
   struct dis_private priv;
   unsigned char op;
+  unsigned char threebyte;
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
       || info->mach == bfd_mach_x86_64)
@@ -3752,6 +3847,7 @@
 
   obufp = obuf;
   ckprefix ();
+  ckvexprefix ();
 
   insn_codep = codep;
   sizeflag = priv.orig_sizeflag;
@@ -3775,18 +3871,29 @@
     }
 
   op = 0;
+  if (prefixes & PREFIX_VEX_0F)
+    {
+      used_prefixes |= PREFIX_VEX_0F | PREFIX_VEX_0F38 | PREFIX_VEX_0F3A;
+      if (prefixes & PREFIX_VEX_0F38)
+        threebyte = 0x38;
+      else if (prefixes & PREFIX_VEX_0F3A)
+        threebyte = 0x3a;
+      else
+        threebyte = *codep++;
+      goto vex_opcode;
+    }
   if (*codep == 0x0f)
     {
-      unsigned char threebyte;
       fetch_data(info, codep + 2);
-      threebyte = *++codep;
+      threebyte = codep[1];
+      codep += 2;
+    vex_opcode:
       dp = &dis386_twobyte[threebyte];
-      need_modrm = twobyte_has_modrm[*codep];
-      uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
-      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
-      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
-      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
-      codep++;
+      need_modrm = twobyte_has_modrm[threebyte];
+      uses_DATA_prefix = twobyte_uses_DATA_prefix[threebyte];
+      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[threebyte];
+      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[threebyte];
+      uses_LOCK_prefix = (threebyte & ~0x02) == 0x20;
       if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
 	{
           fetch_data(info, codep + 2);
@@ -5291,6 +5398,17 @@
     }
 }
 
+static void
+OP_vvvv (int bytemode, int sizeflags)
+{
+    USED_REX (REX_W);
+    if (rex & REX_W) {
+        oappend(names64[vex_reg]);
+    } else {
+        oappend(names32[vex_reg]);
+    }
+}
+
 static bfd_vma
 get64 (void)
 {
diff --git a/docs/tracing.txt b/docs/tracing.txt
index bfc261b..bf2e15c 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -214,6 +214,42 @@
 monitor commands built into QEMU, instead UST utilities should be used to list,
 enable/disable, and dump traces.
 
+Package lttng-tools is required for userspace tracing. You must ensure that the
+current user belongs to the "tracing" group, or manually launch the
+lttng-sessiond daemon for the current user prior to running any instance of
+QEMU.
+
+While running an instrumented QEMU, LTTng should be able to list all available
+events:
+
+    lttng list -u
+
+Create tracing session:
+
+    lttng create mysession
+
+Enable events:
+
+    lttng enable-event qemu:g_malloc -u
+
+Where the events can either be a comma-separated list of events, or "-a" to
+enable all tracepoint events. Start and stop tracing as needed:
+
+    lttng start
+    lttng stop
+
+View the trace:
+
+    lttng view
+
+Destroy tracing session:
+
+    lttng destroy
+
+Babeltrace can be used at any later time to view the trace:
+
+    babeltrace $HOME/lttng-traces/mysession-<date>-<time>
+
 === SystemTap ===
 
 The "dtrace" backend uses DTrace sdt probes but has only been tested with
diff --git a/hmp.c b/hmp.c
index 1af0809..e3ddd46 100644
--- a/hmp.c
+++ b/hmp.c
@@ -881,7 +881,7 @@
     Error *errp = NULL;
 
     qmp_balloon(value, &errp);
-    if (error_is_set(&errp)) {
+    if (errp) {
         monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
         error_free(errp);
     }
@@ -1118,7 +1118,7 @@
     }
 
     qmp_change(device, target, !!arg, arg, &err);
-    if (error_is_set(&err) &&
+    if (err &&
         error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
         error_free(err);
         monitor_read_block_device_key(mon, device, NULL, NULL);
@@ -1234,7 +1234,8 @@
     MigrationInfo *info;
 
     info = qmp_query_migrate(NULL);
-    if (!info->has_status || strcmp(info->status, "active") == 0) {
+    if (!info->has_status || strcmp(info->status, "active") == 0 ||
+        strcmp(info->status, "setup") == 0) {
         if (info->has_disk) {
             int progress;
 
@@ -1335,12 +1336,12 @@
     QemuOpts *opts;
 
     opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
-    if (error_is_set(&err)) {
+    if (err) {
         goto out;
     }
 
     netdev_add(opts, &err);
-    if (error_is_set(&err)) {
+    if (err) {
         qemu_opts_del(opts);
     }
 
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d91b9cc..05a00dc 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -12,6 +12,7 @@
 devices-dirs-$(CONFIG_SOFTMMU) += ide/
 devices-dirs-$(CONFIG_SOFTMMU) += input/
 devices-dirs-$(CONFIG_SOFTMMU) += intc/
+devices-dirs-$(CONFIG_IPACK) += ipack/
 devices-dirs-$(CONFIG_SOFTMMU) += isa/
 devices-dirs-$(CONFIG_SOFTMMU) += misc/
 devices-dirs-$(CONFIG_SOFTMMU) += net/
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 9f21653..67dc075 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -439,9 +439,9 @@
     return o;
 }
 
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-                       qemu_irq sci_irq, qemu_irq smi_irq,
-                       int kvm_enabled, FWCfgState *fw_cfg)
+I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+                      qemu_irq sci_irq, qemu_irq smi_irq,
+                      int kvm_enabled, FWCfgState *fw_cfg)
 {
     DeviceState *dev;
     PIIX4PMState *s;
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 4ebb938..9f137e9 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -326,7 +326,7 @@
         busdev = SYS_BUS_DEVICE(dev);
         sysbus_connect_irq(busdev, 0, i2c_irq);
         sysbus_mmio_map(busdev, 0, addr);
-        s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+        s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
     }
 
 
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 023e875..50a3b8f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1593,7 +1593,7 @@
     DeviceState *key_dev;
     DeviceState *wm8750_dev;
     SysBusDevice *s;
-    i2c_bus *i2c;
+    I2CBus *i2c;
     int i;
     unsigned long flash_size;
     DriveInfo *dinfo;
@@ -1687,7 +1687,7 @@
     dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,
                                pic[MP_GPIO_IRQ]);
     i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
-    i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c");
+    i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");
 
     lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL);
     key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 9ef31ca..c28f895 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -202,7 +202,7 @@
 {
     DeviceState *dev;
     qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
-    i2c_bus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
+    I2CBus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
 
     /* Attach a menelaus PM chip */
     dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 64422f0..45a99c8 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1212,8 +1212,14 @@
 };
 
 /* I2C Interface */
-typedef struct {
-    I2CSlave i2c;
+
+#define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
+#define PXA2XX_I2C_SLAVE(obj) \
+    OBJECT_CHECK(PXA2xxI2CSlaveState, (obj), TYPE_PXA2XX_I2C_SLAVE)
+
+typedef struct PXA2xxI2CSlaveState {
+    I2CSlave parent_obj;
+
     PXA2xxI2CState *host;
 } PXA2xxI2CSlaveState;
 
@@ -1228,7 +1234,7 @@
 
     MemoryRegion iomem;
     PXA2xxI2CSlaveState *slave;
-    i2c_bus *bus;
+    I2CBus *bus;
     qemu_irq irq;
     uint32_t offset;
     uint32_t region_size;
@@ -1258,7 +1264,7 @@
 /* These are only stubs now.  */
 static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
 {
-    PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+    PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
     PXA2xxI2CState *s = slave->host;
 
     switch (event) {
@@ -1282,10 +1288,12 @@
 
 static int pxa2xx_i2c_rx(I2CSlave *i2c)
 {
-    PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+    PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
     PXA2xxI2CState *s = slave->host;
-    if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
+
+    if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
         return 0;
+    }
 
     if (s->status & (1 << 0)) {			/* RWM */
         s->status |= 1 << 6;			/* set ITE */
@@ -1297,10 +1305,12 @@
 
 static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
 {
-    PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
+    PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
     PXA2xxI2CState *s = slave->host;
-    if ((s->control & (1 << 14)) || !(s->control & (1 << 6)))
+
+    if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
         return 1;
+    }
 
     if (!(s->status & (1 << 0))) {		/* RWM */
         s->status |= 1 << 7;			/* set IRF */
@@ -1315,6 +1325,7 @@
                                 unsigned size)
 {
     PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
+    I2CSlave *slave;
 
     addr -= s->offset;
     switch (addr) {
@@ -1323,7 +1334,8 @@
     case ISR:
         return s->status | (i2c_bus_busy(s->bus) << 2);
     case ISAR:
-        return s->slave->i2c.address;
+        slave = I2C_SLAVE(s->slave);
+        return slave->address;
     case IDBR:
         return s->data;
     case IBMR:
@@ -1398,7 +1410,7 @@
         break;
 
     case ISAR:
-        i2c_set_slave_address(&s->slave->i2c, value & 0x7f);
+        i2c_set_slave_address(I2C_SLAVE(s->slave), value & 0x7f);
         break;
 
     case IDBR:
@@ -1422,7 +1434,7 @@
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField []) {
-        VMSTATE_I2C_SLAVE(i2c, PXA2xxI2CSlaveState),
+        VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -1460,7 +1472,7 @@
 }
 
 static const TypeInfo pxa2xx_i2c_slave_info = {
-    .name          = "pxa2xx-i2c-slave",
+    .name          = TYPE_PXA2XX_I2C_SLAVE,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(PXA2xxI2CSlaveState),
     .class_init    = pxa2xx_i2c_slave_class_init,
@@ -1472,7 +1484,7 @@
     DeviceState *dev;
     SysBusDevice *i2c_dev;
     PXA2xxI2CState *s;
-    i2c_bus *i2cbus;
+    I2CBus *i2cbus;
 
     dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
     qdev_prop_set_uint32(dev, "size", region_size + 1);
@@ -1486,8 +1498,8 @@
     s = PXA2XX_I2C(i2c_dev);
     /* FIXME: Should the slave device really be on a separate bus?  */
     i2cbus = i2c_init_bus(dev, "dummy");
-    dev = i2c_create_slave(i2cbus, "pxa2xx-i2c-slave", 0);
-    s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev));
+    dev = i2c_create_slave(i2cbus, TYPE_PXA2XX_I2C_SLAVE, 0);
+    s->slave = PXA2XX_I2C_SLAVE(dev);
     s->slave->host = s;
 
     return s;
@@ -1508,7 +1520,7 @@
     return 0;
 }
 
-i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
+I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
 {
     return s->bus;
 }
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 8d845dd..6ef7646 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -60,7 +60,7 @@
     qemu_irq mmc_irq[2];
     PCIBus *pci_bus = NULL;
     NICInfo *nd;
-    i2c_bus *i2c;
+    I2CBus *i2c;
     int n;
     int done_nic = 0;
     qemu_irq cpu_irq[4];
@@ -255,7 +255,7 @@
     }
 
     dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
-    i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+    i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
     i2c_create_slave(i2c, "ds1338", 0x68);
 
     /* Memory map for RealView Emulation Baseboard:  */
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index ba17283..2decff1 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -734,7 +734,7 @@
 static void spitz_i2c_setup(PXA2xxState *cpu)
 {
     /* Attach the CPU on one end of our I2C bus.  */
-    i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
+    I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
 
     DeviceState *wm;
 
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 3170d69..d6cc77b 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -692,7 +692,7 @@
 typedef struct {
     SysBusDevice parent_obj;
 
-    i2c_bus *bus;
+    I2CBus *bus;
     qemu_irq irq;
     MemoryRegion iomem;
     uint32_t msa;
@@ -868,7 +868,7 @@
 {
     DeviceState *dev = DEVICE(sbd);
     stellaris_i2c_state *s = STELLARIS_I2C(dev);
-    i2c_bus *bus;
+    I2CBus *bus;
 
     sysbus_init_irq(sbd, &s->irq);
     bus = i2c_init_bus(dev, "i2c");
@@ -1213,7 +1213,7 @@
     qemu_irq adc;
     int sram_size;
     int flash_size;
-    i2c_bus *i2c;
+    I2CBus *i2c;
     DeviceState *dev;
     int i;
     int j;
@@ -1256,7 +1256,7 @@
 
     if (board->dc2 & (1 << 12)) {
         dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, pic[8]);
-        i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+        i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
         if (board->peripherals & BP_OLED_I2C) {
             i2c_create_slave(i2c, "ssd0303", 0x3d);
         }
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index c00d8c2..2069f55 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -132,15 +132,20 @@
     return 0;
 }
 
+#define TYPE_TOSA_DAC "tosa_dac"
+#define TOSA_DAC(obj) OBJECT_CHECK(TosaDACState, (obj), TYPE_TOSA_DAC)
+
 typedef struct {
-    I2CSlave i2c;
+    I2CSlave parent_obj;
+
     int len;
     char buf[3];
 } TosaDACState;
 
 static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
 {
-    TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
+    TosaDACState *s = TOSA_DAC(i2c);
+
     s->buf[s->len] = data;
     if (s->len ++ > 2) {
 #ifdef VERBOSE
@@ -159,7 +164,8 @@
 
 static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
 {
-    TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
+    TosaDACState *s = TOSA_DAC(i2c);
+
     s->len = 0;
     switch (event) {
     case I2C_START_SEND:
@@ -194,8 +200,8 @@
 
 static void tosa_tg_init(PXA2xxState *cpu)
 {
-    i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
-    i2c_create_slave(bus, "tosa_dac", DAC_BASE);
+    I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
+    i2c_create_slave(bus, TYPE_TOSA_DAC, DAC_BASE);
     ssi_create_slave(cpu->ssp[1], "tosa-ssp");
 }
 
@@ -271,7 +277,7 @@
 }
 
 static const TypeInfo tosa_dac_info = {
-    .name          = "tosa_dac",
+    .name          = TYPE_TOSA_DAC,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(TosaDACState),
     .class_init    = tosa_dac_class_init,
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index aef2bde..e5493b4 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -185,7 +185,7 @@
     DeviceState *pl041;
     PCIBus *pci_bus;
     NICInfo *nd;
-    i2c_bus *i2c;
+    I2CBus *i2c;
     int n;
     int done_smc = 0;
     DriveInfo *dinfo;
@@ -288,7 +288,7 @@
     sysbus_create_simple("pl031", 0x101e8000, pic[10]);
 
     dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
-    i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+    i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
     i2c_create_slave(i2c, "ds1338", 0x68);
 
     /* Add PL041 AACI Interface to the LM4549 codec */
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 97367b1..67c1be8 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -193,15 +193,20 @@
     .class_init    = zipit_lcd_class_init,
 };
 
-typedef struct {
-    I2CSlave i2c;
+#define TYPE_AER915 "aer915"
+#define AER915(obj) OBJECT_CHECK(AER915State, (obj), TYPE_AER915)
+
+typedef struct AER915State {
+    I2CSlave parent_obj;
+
     int len;
     uint8_t buf[3];
 } AER915State;
 
 static int aer915_send(I2CSlave *i2c, uint8_t data)
 {
-    AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
+    AER915State *s = AER915(i2c);
+
     s->buf[s->len] = data;
     if (s->len++ > 2) {
         DPRINTF("%s: message too long (%i bytes)\n",
@@ -219,7 +224,8 @@
 
 static void aer915_event(I2CSlave *i2c, enum i2c_event event)
 {
-    AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
+    AER915State *s = AER915(i2c);
+
     switch (event) {
     case I2C_START_SEND:
         s->len = 0;
@@ -238,8 +244,8 @@
 
 static int aer915_recv(I2CSlave *slave)
 {
+    AER915State *s = AER915(slave);
     int retval = 0x00;
-    AER915State *s = FROM_I2C_SLAVE(AER915State, slave);
 
     switch (s->buf[0]) {
     /* Return hardcoded battery voltage,
@@ -290,7 +296,7 @@
 }
 
 static const TypeInfo aer915_info = {
-    .name          = "aer915",
+    .name          = TYPE_AER915,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(AER915State),
     .class_init    = aer915_class_init,
@@ -308,7 +314,7 @@
     DriveInfo *dinfo;
     int be;
     void *z2_lcd;
-    i2c_bus *bus;
+    I2CBus *bus;
     DeviceState *wm;
 
     if (!cpu_model) {
@@ -351,7 +357,7 @@
     type_register_static(&aer915_info);
     z2_lcd = ssi_create_slave(mpu->ssp[1], "zipit-lcd");
     bus = pxa2xx_i2c_bus(mpu->i2c[0]);
-    i2c_create_slave(bus, "aer915", 0x55);
+    i2c_create_slave(bus, TYPE_AER915, 0x55);
     wm = i2c_create_slave(bus, "wm8750", 0x1b);
     mpu->i2s->opaque = wm;
     mpu->i2s->codec_out = wm8750_dac_dat;
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index e88d2dd..28eed81 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -354,7 +354,7 @@
 }
 
 static Property adlib_properties[] = {
-    DEFINE_PROP_HEX32  ("iobase",  AdlibState, port, 0x220),
+    DEFINE_PROP_UINT32 ("iobase",  AdlibState, port, 0x220),
     DEFINE_PROP_UINT32 ("freq",    AdlibState, freq,  44100),
     DEFINE_PROP_END_OF_LIST (),
 };
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 666096b..a0ec17a 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -673,7 +673,7 @@
 }
 
 static Property cs4231a_properties[] = {
-    DEFINE_PROP_HEX32  ("iobase",  CSState, port, 0x534),
+    DEFINE_PROP_UINT32 ("iobase",  CSState, port, 0x534),
     DEFINE_PROP_UINT32 ("irq",     CSState, irq,  9),
     DEFINE_PROP_UINT32 ("dma",     CSState, dma,  3),
     DEFINE_PROP_END_OF_LIST (),
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 71be3c6..e29a571 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -304,7 +304,7 @@
 
 static Property gus_properties[] = {
     DEFINE_PROP_UINT32 ("freq",    GUSState, freq,        44100),
-    DEFINE_PROP_HEX32  ("iobase",  GUSState, port,        0x240),
+    DEFINE_PROP_UINT32 ("iobase",  GUSState, port,        0x240),
     DEFINE_PROP_UINT32 ("irq",     GUSState, emu.gusirq,  7),
     DEFINE_PROP_UINT32 ("dma",     GUSState, emu.gusdma,  3),
     DEFINE_PROP_END_OF_LIST (),
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index f980d66..1d81bbe 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -181,7 +181,7 @@
 }
 
 static Property pcspk_properties[] = {
-    DEFINE_PROP_HEX32("iobase", PCSpkState, iobase,  -1),
+    DEFINE_PROP_UINT32("iobase", PCSpkState, iobase,  -1),
     DEFINE_PROP_PTR("pit", PCSpkState, pit),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index db79131..bb24e00 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1399,8 +1399,8 @@
 }
 
 static Property sb16_properties[] = {
-    DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
-    DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
+    DEFINE_PROP_UINT32 ("version", SB16State, ver,  0x0405), /* 4.5 */
+    DEFINE_PROP_UINT32 ("iobase",  SB16State, port, 0x220),
     DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
     DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
     DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c
index 6b5a349..c18f245 100644
--- a/hw/audio/wm8750.c
+++ b/hw/audio/wm8750.c
@@ -23,8 +23,12 @@
     int dac_hz;
 } WMRate;
 
-typedef struct {
-    I2CSlave i2c;
+#define TYPE_WM8750 "wm8750"
+#define WM8750(obj) OBJECT_CHECK(WM8750State, (obj), TYPE_WM8750)
+
+typedef struct WM8750State {
+    I2CSlave parent_obj;
+
     uint8_t i2c_data[2];
     int i2c_len;
     QEMUSoundCard card;
@@ -256,7 +260,8 @@
 
 static void wm8750_reset(I2CSlave *i2c)
 {
-    WM8750State *s = (WM8750State *) i2c;
+    WM8750State *s = WM8750(i2c);
+
     s->rate = &wm_rate_table[0];
     s->enable = 0;
     wm8750_clk_update(s, 1);
@@ -299,7 +304,7 @@
 
 static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
 {
-    WM8750State *s = (WM8750State *) i2c;
+    WM8750State *s = WM8750(i2c);
 
     switch (event) {
     case I2C_START_SEND:
@@ -356,7 +361,7 @@
 
 static int wm8750_tx(I2CSlave *i2c, uint8_t data)
 {
-    WM8750State *s = (WM8750State *) i2c;
+    WM8750State *s = WM8750(i2c);
     uint8_t cmd;
     uint16_t value;
 
@@ -542,7 +547,7 @@
         break;
 
     case WM8750_RESET:	/* Reset */
-        wm8750_reset(&s->i2c);
+        wm8750_reset(I2C_SLAVE(s));
         break;
 
 #ifdef VERBOSE
@@ -604,17 +609,17 @@
         VMSTATE_UINT8(format, WM8750State),
         VMSTATE_UINT8(power, WM8750State),
         VMSTATE_UINT8(rate_vmstate, WM8750State),
-        VMSTATE_I2C_SLAVE(i2c, WM8750State),
+        VMSTATE_I2C_SLAVE(parent_obj, WM8750State),
         VMSTATE_END_OF_LIST()
     }
 };
 
 static int wm8750_init(I2CSlave *i2c)
 {
-    WM8750State *s = FROM_I2C_SLAVE(WM8750State, i2c);
+    WM8750State *s = WM8750(i2c);
 
     AUD_register_card(CODEC, &s->card);
-    wm8750_reset(&s->i2c);
+    wm8750_reset(I2C_SLAVE(s));
 
     return 0;
 }
@@ -622,8 +627,9 @@
 #if 0
 static void wm8750_fini(I2CSlave *i2c)
 {
-    WM8750State *s = (WM8750State *) i2c;
-    wm8750_reset(&s->i2c);
+    WM8750State *s = WM8750(i2c);
+
+    wm8750_reset(I2C_SLAVE(s));
     AUD_remove_card(&s->card);
     g_free(s);
 }
@@ -632,7 +638,8 @@
 void wm8750_data_req_set(DeviceState *dev,
                 void (*data_req)(void *, int, int), void *opaque)
 {
-    WM8750State *s = FROM_I2C_SLAVE(WM8750State, I2C_SLAVE(dev));
+    WM8750State *s = WM8750(dev);
+
     s->data_req = data_req;
     s->opaque = opaque;
 }
@@ -702,7 +709,7 @@
 }
 
 static const TypeInfo wm8750_info = {
-    .name          = "wm8750",
+    .name          = TYPE_WM8750,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(WM8750State),
     .class_init    = wm8750_class_init,
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 592b58f..1651007 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2216,7 +2216,7 @@
 };
 
 static Property isa_fdc_properties[] = {
-    DEFINE_PROP_HEX32("iobase", FDCtrlISABus, iobase, 0x3f0),
+    DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
     DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
     DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
     DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
diff --git a/hw/block/nand.c b/hw/block/nand.c
index a871ce0..6d7c804 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -632,7 +632,7 @@
     if (nand_flash_ids[chip_id].size == 0) {
         hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
     }
-    dev = qdev_create(NULL, "nand");
+    dev = DEVICE(object_new(TYPE_NAND));
     qdev_prop_set_uint8(dev, "manufacturer_id", manf_id);
     qdev_prop_set_uint8(dev, "chip_id", chip_id);
     if (bdrv) {
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index be2a7d9..317385d 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-$(CONFIG_IPACK) += tpci200.o ipoctal232.o ipack.o
+common-obj-$(CONFIG_IPACK) += ipoctal232.o
 common-obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_PL011) += pl011.o
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 02d0d57..36f1c4a 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -110,9 +110,9 @@
 }
 
 static Property debugcon_isa_properties[] = {
-    DEFINE_PROP_HEX32("iobase", ISADebugconState, iobase, 0xe9),
+    DEFINE_PROP_UINT32("iobase", ISADebugconState, iobase, 0xe9),
     DEFINE_PROP_CHR("chardev",  ISADebugconState, state.chr),
-    DEFINE_PROP_HEX32("readback", ISADebugconState, state.readback, 0xe9),
+    DEFINE_PROP_UINT32("readback", ISADebugconState, state.readback, 0xe9),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 88e2cca..f9c388e 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -8,7 +8,7 @@
  * later version.
  */
 
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
 #include "qemu/bitops.h"
 #include "sysemu/char.h"
 
@@ -108,7 +108,8 @@
 };
 
 struct IPOctalState {
-    IPackDevice dev;
+    IPackDevice parent_obj;
+
     SCC2698Channel ch[N_CHANNELS];
     SCC2698Block blk[N_BLOCKS];
     uint8_t irq_vector;
@@ -154,7 +155,7 @@
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField[]) {
-        VMSTATE_IPACK_DEVICE(dev, IPOctalState),
+        VMSTATE_IPACK_DEVICE(parent_obj, IPOctalState),
         VMSTATE_STRUCT_ARRAY(ch, IPOctalState, N_CHANNELS, 1,
                              vmstate_scc2698_channel, SCC2698Channel),
         VMSTATE_STRUCT_ARRAY(blk, IPOctalState, N_BLOCKS, 1,
@@ -172,6 +173,7 @@
 
 static void update_irq(IPOctalState *dev, unsigned block)
 {
+    IPackDevice *idev = IPACK_DEVICE(dev);
     /* Blocks A and B interrupt on INT0#, C and D on INT1#.
        Thus, to get the status we have to check two blocks. */
     SCC2698Block *blk0 = &dev->blk[block];
@@ -179,9 +181,9 @@
     unsigned intno = block / 2;
 
     if ((blk0->isr & blk0->imr) || (blk1->isr & blk1->imr)) {
-        qemu_irq_raise(dev->dev.irq[intno]);
+        qemu_irq_raise(idev->irq[intno]);
     } else {
-        qemu_irq_lower(dev->dev.irq[intno]);
+        qemu_irq_lower(idev->irq[intno]);
     }
 }
 
@@ -534,9 +536,9 @@
     }
 }
 
-static int ipoctal_init(IPackDevice *ip)
+static void ipoctal_realize(DeviceState *dev, Error **errp)
 {
-    IPOctalState *s = IPOCTAL(ip);
+    IPOctalState *s = IPOCTAL(dev);
     unsigned i;
 
     for (i = 0; i < N_CHANNELS; i++) {
@@ -552,8 +554,6 @@
             DPRINTF("Could not redirect channel %u, no chardev set\n", i);
         }
     }
-
-    return 0;
 }
 
 static Property ipoctal_properties[] = {
@@ -573,7 +573,7 @@
     DeviceClass *dc = DEVICE_CLASS(klass);
     IPackDeviceClass *ic = IPACK_DEVICE_CLASS(klass);
 
-    ic->init        = ipoctal_init;
+    ic->realize     = ipoctal_realize;
     ic->io_read     = io_read;
     ic->io_write    = io_write;
     ic->id_read     = id_read;
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 7a3b264..7ac90a5 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -595,7 +595,7 @@
 
 static Property parallel_isa_properties[] = {
     DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
-    DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
+    DEFINE_PROP_UINT32("iobase", ISAParallelState, iobase,  -1),
     DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
     DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 5cb77b3..c9fcb27 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -88,7 +88,7 @@
 
 static Property serial_isa_properties[] = {
     DEFINE_PROP_UINT32("index",  ISASerialState, index,   -1),
-    DEFINE_PROP_HEX32("iobase",  ISASerialState, iobase,  -1),
+    DEFINE_PROP_UINT32("iobase",  ISASerialState, iobase,  -1),
     DEFINE_PROP_UINT32("irq",    ISASerialState, isairq,  -1),
     DEFINE_PROP_CHR("chardev",   ISASerialState, state.chr),
     DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 3f29b49..5f5957e 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -109,7 +109,8 @@
 }
 
 PropertyInfo qdev_prop_drive = {
-    .name  = "drive",
+    .name  = "str",
+    .legacy_name  = "drive",
     .get   = get_drive,
     .set   = set_drive,
     .release = release_drive,
@@ -164,7 +165,8 @@
 }
 
 PropertyInfo qdev_prop_chr = {
-    .name  = "chr",
+    .name  = "str",
+    .legacy_name  = "chr",
     .get   = get_chr,
     .set   = set_chr,
     .release = release_chr,
@@ -242,7 +244,8 @@
 }
 
 PropertyInfo qdev_prop_netdev = {
-    .name  = "netdev",
+    .name  = "str",
+    .legacy_name  = "netdev",
     .get   = get_netdev,
     .set   = set_netdev,
 };
@@ -321,7 +324,8 @@
 }
 
 PropertyInfo qdev_prop_vlan = {
-    .name  = "vlan",
+    .name  = "int32",
+    .legacy_name  = "vlan",
     .print = print_vlan,
     .get   = get_vlan,
     .set   = set_vlan,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index b949f0e..77d0c66 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -74,13 +74,6 @@
     }
 }
 
-static int prop_print_bit(DeviceState *dev, Property *prop, char *dest,
-                          size_t len)
-{
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
-}
-
 static void prop_get_bit(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
@@ -114,9 +107,8 @@
 }
 
 PropertyInfo qdev_prop_bit = {
-    .name  = "boolean",
+    .name  = "bool",
     .legacy_name  = "on/off",
-    .print = prop_print_bit,
     .get   = prop_get_bit,
     .set   = prop_set_bit,
 };
@@ -149,7 +141,7 @@
 }
 
 PropertyInfo qdev_prop_bool = {
-    .name  = "boolean",
+    .name  = "bool",
     .get   = get_bool,
     .set   = set_bool,
 };
@@ -187,40 +179,6 @@
     .set   = set_uint8,
 };
 
-/* --- 8bit hex value --- */
-
-static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
-{
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx8, *ptr);
-}
-
-PropertyInfo qdev_prop_hex8 = {
-    .name  = "uint8",
-    .legacy_name  = "hex8",
-    .parse = parse_hex8,
-    .print = print_hex8,
-    .get   = get_uint8,
-    .set   = set_uint8,
-};
-
 /* --- 16bit integer --- */
 
 static void get_uint16(Object *obj, Visitor *v, void *opaque,
@@ -318,40 +276,6 @@
     .set   = set_int32,
 };
 
-/* --- 32bit hex value --- */
-
-static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
-{
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx32, *ptr);
-}
-
-PropertyInfo qdev_prop_hex32 = {
-    .name  = "uint32",
-    .legacy_name  = "hex32",
-    .parse = parse_hex32,
-    .print = print_hex32,
-    .get   = get_uint32,
-    .set   = set_uint32,
-};
-
 /* --- 64bit integer --- */
 
 static void get_uint64(Object *obj, Visitor *v, void *opaque,
@@ -385,40 +309,6 @@
     .set   = set_uint64,
 };
 
-/* --- 64bit hex value --- */
-
-static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
-{
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoull(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx64, *ptr);
-}
-
-PropertyInfo qdev_prop_hex64 = {
-    .name  = "uint64",
-    .legacy_name  = "hex64",
-    .parse = parse_hex64,
-    .print = print_hex64,
-    .get   = get_uint64,
-    .set   = set_uint64,
-};
-
 /* --- string --- */
 
 static void release_string(Object *obj, const char *name, void *opaque)
@@ -427,16 +317,6 @@
     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
 }
 
-static int print_string(DeviceState *dev, Property *prop, char *dest,
-                        size_t len)
-{
-    char **ptr = qdev_get_prop_ptr(dev, prop);
-    if (!*ptr) {
-        return snprintf(dest, len, "<null>");
-    }
-    return snprintf(dest, len, "\"%s\"", *ptr);
-}
-
 static void get_string(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
@@ -478,8 +358,7 @@
 }
 
 PropertyInfo qdev_prop_string = {
-    .name  = "string",
-    .print = print_string,
+    .name  = "str",
     .release = release_string,
     .get   = get_string,
     .set   = set_string,
@@ -563,41 +442,31 @@
 }
 
 PropertyInfo qdev_prop_macaddr = {
-    .name  = "macaddr",
+    .name  = "str",
+    .legacy_name  = "macaddr",
     .get   = get_mac,
     .set   = set_mac,
 };
 
 /* --- lost tick policy --- */
 
-static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
-    [LOST_TICK_DISCARD] = "discard",
-    [LOST_TICK_DELAY] = "delay",
-    [LOST_TICK_MERGE] = "merge",
-    [LOST_TICK_SLEW] = "slew",
-    [LOST_TICK_MAX] = NULL,
-};
-
 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 
 PropertyInfo qdev_prop_losttickpolicy = {
     .name  = "LostTickPolicy",
-    .enum_table  = lost_tick_policy_table,
+    .enum_table  = LostTickPolicy_lookup,
     .get   = get_enum,
     .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",
-};
+QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
 
 PropertyInfo qdev_prop_bios_chs_trans = {
-    .name = "bios-chs-trans",
-    .enum_table = bios_chs_trans_table,
+    .name = "BiosAtaTranslation",
+    .legacy_name = "bios-chs-trans",
+    .enum_table = BiosAtaTranslation_lookup,
     .get = get_enum,
     .set = set_enum,
 };
@@ -715,7 +584,8 @@
 }
 
 PropertyInfo qdev_prop_blocksize = {
-    .name  = "blocksize",
+    .name  = "uint16",
+    .legacy_name  = "blocksize",
     .get   = get_uint16,
     .set   = set_blocksize,
 };
@@ -822,7 +692,8 @@
 }
 
 PropertyInfo qdev_prop_pci_host_devaddr = {
-    .name = "pci-host-devaddr",
+    .name = "str",
+    .legacy_name = "pci-host-devaddr",
     .get = get_pci_host_devaddr,
     .set = set_pci_host_devaddr,
 };
@@ -987,20 +858,6 @@
     }
 }
 
-void qdev_prop_parse(DeviceState *dev, const char *name, const char *value,
-                     Error **errp)
-{
-    char *legacy_name;
-
-    legacy_name = g_strdup_printf("legacy-%s", name);
-    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
-        object_property_parse(OBJECT(dev), value, legacy_name, errp);
-    } else {
-        object_property_parse(OBJECT(dev), value, name, errp);
-    }
-    g_free(legacy_name);
-}
-
 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
 {
     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
@@ -1093,7 +950,7 @@
         if (strcmp(typename, prop->driver) != 0) {
             continue;
         }
-        qdev_prop_parse(dev, prop->property, prop->value, &err);
+        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
         if (err != NULL) {
             error_propagate(errp, err);
             return;
@@ -1140,39 +997,8 @@
     visit_type_size(v, ptr, name, errp);
 }
 
-static int parse_size(DeviceState *dev, Property *prop, const char *str)
-{
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (str != NULL) {
-        parse_option_size(prop->name, str, ptr, &error_abort);
-    }
-    return 0;
-}
-
-static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
-    uint64_t div, val = *(uint64_t *)qdev_get_prop_ptr(dev, prop);
-    int i;
-
-    /* Compute floor(log2(val)).  */
-    i = 64 - clz64(val);
-
-    /* Find the power of 1024 that we'll display as the units.  */
-    i /= 10;
-    if (i >= ARRAY_SIZE(suffixes)) {
-        i = ARRAY_SIZE(suffixes) - 1;
-    }
-    div = 1ULL << (i * 10);
-
-    return snprintf(dest, len, "%0.03f%c", (double)val/div, suffixes[i]);
-}
-
 PropertyInfo qdev_prop_size = {
     .name  = "size",
-    .parse = parse_size,
-    .print = print_size,
     .get = get_size,
     .set = set_size,
 };
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 64b66e0..c0b857f 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -588,31 +588,6 @@
     visit_type_str(v, &ptr, name, errp);
 }
 
-static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
-                                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    Error *local_err = NULL;
-    char *ptr = NULL;
-    int ret;
-
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
-    visit_type_str(v, &ptr, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    ret = prop->info->parse(dev, prop, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
-    g_free(ptr);
-}
-
 /**
  * @qdev_add_legacy_property - adds a legacy property
  *
@@ -625,25 +600,20 @@
 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                               Error **errp)
 {
-    gchar *name, *type;
+    gchar *name;
 
     /* Register pointer properties as legacy properties */
-    if (!prop->info->print && !prop->info->parse &&
-        (prop->info->set || prop->info->get)) {
+    if (!prop->info->print && prop->info->get) {
         return;
     }
 
     name = g_strdup_printf("legacy-%s", prop->name);
-    type = g_strdup_printf("legacy<%s>",
-                           prop->info->legacy_name ?: prop->info->name);
-
-    object_property_add(OBJECT(dev), name, type,
+    object_property_add(OBJECT(dev), name, "str",
                         prop->info->print ? qdev_get_legacy_property : prop->info->get,
-                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
+                        NULL,
                         NULL,
                         prop, errp);
 
-    g_free(type);
     g_free(name);
 }
 
diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
index 7082171..bc909bb 100644
--- a/hw/display/g364fb.c
+++ b/hw/display/g364fb.c
@@ -524,7 +524,7 @@
 }
 
 static Property g364fb_sysbus_properties[] = {
-    DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+    DEFINE_PROP_UINT32("vram_size", G364SysBusState, g364.vram_size,
     8 * 1024 * 1024),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c
index beea5bf..89804e1 100644
--- a/hw/display/ssd0303.c
+++ b/hw/display/ssd0303.c
@@ -41,8 +41,12 @@
     SSD0303_CMD_SKIP1
 };
 
+#define TYPE_SSD0303 "ssd0303"
+#define SSD0303(obj) OBJECT_CHECK(ssd0303_state, (obj), TYPE_SSD0303)
+
 typedef struct {
-    I2CSlave i2c;
+    I2CSlave parent_obj;
+
     QemuConsole *con;
     int row;
     int col;
@@ -65,8 +69,9 @@
 
 static int ssd0303_send(I2CSlave *i2c, uint8_t data)
 {
-    ssd0303_state *s = (ssd0303_state *)i2c;
+    ssd0303_state *s = SSD0303(i2c);
     enum ssd0303_cmd old_cmd_state;
+
     switch (s->mode) {
     case SSD0303_IDLE:
         DPRINTF("byte 0x%02x\n", data);
@@ -175,7 +180,8 @@
 
 static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
 {
-    ssd0303_state *s = (ssd0303_state *)i2c;
+    ssd0303_state *s = SSD0303(i2c);
+
     switch (event) {
     case I2C_FINISH:
         s->mode = SSD0303_IDLE;
@@ -279,7 +285,7 @@
         VMSTATE_UINT32(mode, ssd0303_state),
         VMSTATE_UINT32(cmd_state, ssd0303_state),
         VMSTATE_BUFFER(framebuffer, ssd0303_state),
-        VMSTATE_I2C_SLAVE(i2c, ssd0303_state),
+        VMSTATE_I2C_SLAVE(parent_obj, ssd0303_state),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -291,7 +297,7 @@
 
 static int ssd0303_init(I2CSlave *i2c)
 {
-    ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
+    ssd0303_state *s = SSD0303(i2c);
 
     s->con = graphic_console_init(DEVICE(i2c), &ssd0303_ops, s);
     qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
@@ -311,7 +317,7 @@
 }
 
 static const TypeInfo ssd0303_info = {
-    .name          = "ssd0303",
+    .name          = TYPE_SSD0303,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(ssd0303_state),
     .class_init    = ssd0303_class_init,
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 873b82c..e60769c 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -617,11 +617,11 @@
 }
 
 static Property tcx_properties[] = {
-    DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
+    DEFINE_PROP_UINT32("vram_size", TCXState, vram_size, -1),
     DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
     DEFINE_PROP_UINT16("height",   TCXState, height,    -1),
     DEFINE_PROP_UINT16("depth",    TCXState, depth,     -1),
-    DEFINE_PROP_HEX64("prom_addr", TCXState, prom_addr, -1),
+    DEFINE_PROP_UINT64("prom_addr", TCXState, prom_addr, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index a5b891f..dc7a767 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -149,7 +149,7 @@
 }
 
 static Property i82374_properties[] = {
-    DEFINE_PROP_HEX32("iobase", ISAi82374State, iobase, 0x400),
+    DEFINE_PROP_UINT32("iobase", ISAi82374State, iobase, 0x400),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c
index 723f66d..899d454 100644
--- a/hw/dma/sun4m_iommu.c
+++ b/hw/dma/sun4m_iommu.c
@@ -362,7 +362,7 @@
 }
 
 static Property iommu_properties[] = {
-    DEFINE_PROP_HEX32("version", IOMMUState, version, 0),
+    DEFINE_PROP_UINT32("version", IOMMUState, version, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
index 59b2877..cfcd89c 100644
--- a/hw/gpio/max7310.c
+++ b/hw/gpio/max7310.c
@@ -9,8 +9,12 @@
 
 #include "hw/i2c/i2c.h"
 
-typedef struct {
-    I2CSlave i2c;
+#define TYPE_MAX7310 "max7310"
+#define MAX7310(obj) OBJECT_CHECK(MAX7310State, (obj), TYPE_MAX7310)
+
+typedef struct MAX7310State {
+    I2CSlave parent_obj;
+
     int i2c_command_byte;
     int len;
 
@@ -25,7 +29,8 @@
 
 static void max7310_reset(DeviceState *dev)
 {
-    MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, I2C_SLAVE(dev));
+    MAX7310State *s = MAX7310(dev);
+
     s->level &= s->direction;
     s->direction = 0xff;
     s->polarity = 0xf0;
@@ -35,7 +40,7 @@
 
 static int max7310_rx(I2CSlave *i2c)
 {
-    MAX7310State *s = (MAX7310State *) i2c;
+    MAX7310State *s = MAX7310(i2c);
 
     switch (s->command) {
     case 0x00:	/* Input port */
@@ -70,7 +75,7 @@
 
 static int max7310_tx(I2CSlave *i2c, uint8_t data)
 {
-    MAX7310State *s = (MAX7310State *) i2c;
+    MAX7310State *s = MAX7310(i2c);
     uint8_t diff;
     int line;
 
@@ -125,7 +130,7 @@
 
 static void max7310_event(I2CSlave *i2c, enum i2c_event event)
 {
-    MAX7310State *s = (MAX7310State *) i2c;
+    MAX7310State *s = MAX7310(i2c);
     s->len = 0;
 
     switch (event) {
@@ -156,7 +161,7 @@
         VMSTATE_UINT8(polarity, MAX7310State),
         VMSTATE_UINT8(status, MAX7310State),
         VMSTATE_UINT8(command, MAX7310State),
-        VMSTATE_I2C_SLAVE(i2c, MAX7310State),
+        VMSTATE_I2C_SLAVE(parent_obj, MAX7310State),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -177,7 +182,7 @@
  * but also accepts sequences that are not SMBus so return an I2C device.  */
 static int max7310_init(I2CSlave *i2c)
 {
-    MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c);
+    MAX7310State *s = MAX7310(i2c);
 
     qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8);
     qdev_init_gpio_out(&i2c->qdev, s->handler, 8);
@@ -199,7 +204,7 @@
 }
 
 static const TypeInfo max7310_info = {
-    .name          = "max7310",
+    .name          = TYPE_MAX7310,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(MAX7310State),
     .class_init    = max7310_class_init,
diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c
index ca59456..6d1bb03 100644
--- a/hw/i2c/bitbang_i2c.c
+++ b/hw/i2c/bitbang_i2c.c
@@ -46,7 +46,7 @@
 } bitbang_i2c_state;
 
 struct bitbang_i2c_interface {
-    i2c_bus *bus;
+    I2CBus *bus;
     bitbang_i2c_state state;
     int last_data;
     int last_clock;
@@ -170,7 +170,7 @@
     abort();
 }
 
-bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus)
+bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus)
 {
     bitbang_i2c_interface *s;
 
@@ -213,7 +213,7 @@
 {
     DeviceState *dev = DEVICE(sbd);
     GPIOI2CState *s = GPIO_I2C(dev);
-    i2c_bus *bus;
+    I2CBus *bus;
 
     memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0);
     sysbus_init_mmio(sbd, &s->dummy_iomem);
diff --git a/hw/i2c/bitbang_i2c.h b/hw/i2c/bitbang_i2c.h
index 2866ac3..3a7126d 100644
--- a/hw/i2c/bitbang_i2c.h
+++ b/hw/i2c/bitbang_i2c.h
@@ -8,7 +8,7 @@
 #define BITBANG_I2C_SDA 0
 #define BITBANG_I2C_SCL 1
 
-bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus);
+bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus);
 int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level);
 
 #endif
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index c97e7f7..efd8b4f 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -9,7 +9,7 @@
 
 #include "hw/i2c/i2c.h"
 
-struct i2c_bus
+struct I2CBus
 {
     BusState qbus;
     I2CSlave *current_dev;
@@ -23,24 +23,24 @@
 };
 
 #define TYPE_I2C_BUS "i2c-bus"
-#define I2C_BUS(obj) OBJECT_CHECK(i2c_bus, (obj), TYPE_I2C_BUS)
+#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
 
 static const TypeInfo i2c_bus_info = {
     .name = TYPE_I2C_BUS,
     .parent = TYPE_BUS,
-    .instance_size = sizeof(i2c_bus),
+    .instance_size = sizeof(I2CBus),
 };
 
 static void i2c_bus_pre_save(void *opaque)
 {
-    i2c_bus *bus = opaque;
+    I2CBus *bus = opaque;
 
     bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
 }
 
 static int i2c_bus_post_load(void *opaque, int version_id)
 {
-    i2c_bus *bus = opaque;
+    I2CBus *bus = opaque;
 
     /* The bus is loaded before attached devices, so load and save the
        current device id.  Devices will check themselves as loaded.  */
@@ -56,15 +56,15 @@
     .pre_save = i2c_bus_pre_save,
     .post_load = i2c_bus_post_load,
     .fields      = (VMStateField []) {
-        VMSTATE_UINT8(saved_address, i2c_bus),
+        VMSTATE_UINT8(saved_address, I2CBus),
         VMSTATE_END_OF_LIST()
     }
 };
 
 /* Create a new I2C bus.  */
-i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
+I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
 {
-    i2c_bus *bus;
+    I2CBus *bus;
 
     bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
     vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
@@ -77,14 +77,14 @@
 }
 
 /* Return nonzero if bus is busy.  */
-int i2c_bus_busy(i2c_bus *bus)
+int i2c_bus_busy(I2CBus *bus)
 {
     return bus->current_dev != NULL;
 }
 
 /* Returns non-zero if the address is not valid.  */
 /* TODO: Make this handle multiple masters.  */
-int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
+int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
 {
     BusChild *kid;
     I2CSlave *slave = NULL;
@@ -113,7 +113,7 @@
     return 0;
 }
 
-void i2c_end_transfer(i2c_bus *bus)
+void i2c_end_transfer(I2CBus *bus)
 {
     I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
@@ -130,7 +130,7 @@
     bus->current_dev = NULL;
 }
 
-int i2c_send(i2c_bus *bus, uint8_t data)
+int i2c_send(I2CBus *bus, uint8_t data)
 {
     I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
@@ -147,7 +147,7 @@
     return -1;
 }
 
-int i2c_recv(i2c_bus *bus)
+int i2c_recv(I2CBus *bus)
 {
     I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
@@ -164,7 +164,7 @@
     return -1;
 }
 
-void i2c_nack(i2c_bus *bus)
+void i2c_nack(I2CBus *bus)
 {
     I2CSlave *dev = bus->current_dev;
     I2CSlaveClass *sc;
@@ -182,7 +182,7 @@
 static int i2c_slave_post_load(void *opaque, int version_id)
 {
     I2CSlave *dev = opaque;
-    i2c_bus *bus;
+    I2CBus *bus;
     bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
     if (bus->saved_address == dev->address) {
         bus->current_dev = dev;
@@ -210,7 +210,7 @@
     return sc->init(s);
 }
 
-DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
+DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
 {
     DeviceState *dev;
 
diff --git a/hw/i2c/exynos4210_i2c.c b/hw/i2c/exynos4210_i2c.c
index ce5f849..fb99dfd 100644
--- a/hw/i2c/exynos4210_i2c.c
+++ b/hw/i2c/exynos4210_i2c.c
@@ -83,7 +83,7 @@
     SysBusDevice parent_obj;
 
     MemoryRegion iomem;
-    i2c_bus *bus;
+    I2CBus *bus;
     qemu_irq irq;
 
     uint8_t i2ccon;
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index 2d8e2b7..d63278d 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -30,7 +30,7 @@
     MemoryRegion iomem;
     qemu_irq irq;
     qemu_irq drq[2];
-    i2c_bus *bus;
+    I2CBus *bus;
 
     uint8_t revision;
     void *iclk;
@@ -491,7 +491,7 @@
     type_register_static(&omap_i2c_info);
 }
 
-i2c_bus *omap_i2c_bus(DeviceState *omap_i2c)
+I2CBus *omap_i2c_bus(DeviceState *omap_i2c)
 {
     OMAPI2CState *s = OMAP_I2C(omap_i2c);
     return s->bus;
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index c98e447..9f50067 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -59,7 +59,7 @@
     uint8_t read = s->smb_addr & 0x01;
     uint8_t cmd = s->smb_cmd;
     uint8_t addr = s->smb_addr >> 1;
-    i2c_bus *bus = s->smbus;
+    I2CBus *bus = s->smbus;
 
     SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
     /* Transaction isn't exec if STS_DEV_ERR bit set */
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 25d2d04..3febf3c 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -208,13 +208,13 @@
 }
 
 /* Master device commands.  */
-void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read)
+void smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
 {
     i2c_start_transfer(bus, addr, read);
     i2c_end_transfer(bus);
 }
 
-uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr)
+uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr)
 {
     uint8_t data;
 
@@ -225,14 +225,14 @@
     return data;
 }
 
-void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data)
+void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
 {
     i2c_start_transfer(bus, addr, 0);
     i2c_send(bus, data);
     i2c_end_transfer(bus);
 }
 
-uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command)
+uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
 {
     uint8_t data;
     i2c_start_transfer(bus, addr, 0);
@@ -244,7 +244,7 @@
     return data;
 }
 
-void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data)
+void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
 {
     i2c_start_transfer(bus, addr, 0);
     i2c_send(bus, command);
@@ -252,7 +252,7 @@
     i2c_end_transfer(bus);
 }
 
-uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command)
+uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
 {
     uint16_t data;
     i2c_start_transfer(bus, addr, 0);
@@ -265,7 +265,7 @@
     return data;
 }
 
-void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data)
+void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
 {
     i2c_start_transfer(bus, addr, 0);
     i2c_send(bus, command);
@@ -274,7 +274,7 @@
     i2c_end_transfer(bus);
 }
 
-int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data)
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
 {
     int len;
     int i;
@@ -292,7 +292,7 @@
     return len;
 }
 
-void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
                        int len)
 {
     int i;
diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 0218f8a..86f35c1 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -139,7 +139,7 @@
 
 type_init(smbus_eeprom_register_types)
 
-void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
                        const uint8_t *eeprom_spd, int eeprom_spd_size)
 {
     int i;
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 8d47eaf..295b62e 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -108,7 +108,7 @@
     dc->cannot_instantiate_with_device_add_yet = true;
 }
 
-i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
+I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
 {
     PCIDevice *d =
         pci_create_simple_multifunction(bus, devfn, true, TYPE_ICH9_SMB_DEVICE);
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
index 02e9f17..3c0c2c1 100644
--- a/hw/i2c/versatile_i2c.c
+++ b/hw/i2c/versatile_i2c.c
@@ -81,7 +81,7 @@
 {
     DeviceState *dev = DEVICE(sbd);
     VersatileI2CState *s = VERSATILE_I2C(dev);
-    i2c_bus *bus;
+    I2CBus *bus;
 
     bus = i2c_init_bus(dev, "i2c");
     s->bitbang = bitbang_i2c_init(bus);
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 20b6457..59373aa 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -268,9 +268,9 @@
         return;
     }
     switch (s->lost_tick_policy) {
-    case LOST_TICK_DELAY:
+    case LOST_TICK_POLICY_DELAY:
         break; /* enabled by default */
-    case LOST_TICK_DISCARD:
+    case LOST_TICK_POLICY_DISCARD:
         if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
             struct kvm_reinject_control control = { .pit_reinject = 0 };
 
@@ -298,9 +298,9 @@
 }
 
 static Property kvm_pit_properties[] = {
-    DEFINE_PROP_HEX32("iobase", PITCommonState, iobase,  -1),
+    DEFINE_PROP_UINT32("iobase", PITCommonState, iobase,  -1),
     DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
-                               lost_tick_policy, LOST_TICK_DELAY),
+                               lost_tick_policy, LOST_TICK_POLICY_DELAY),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1acd2b2..d5dc1ef 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -236,7 +236,7 @@
     }
 
     if (pci_enabled && acpi_enabled) {
-        i2c_bus *smbus;
+        I2CBus *smbus;
 
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index afc24d4..d2cabc1 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -104,8 +104,8 @@
 }
 
 static Property isa_ide_properties[] = {
-    DEFINE_PROP_HEX32("iobase",  ISAIDEState, iobase,  0x1f0),
-    DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
+    DEFINE_PROP_UINT32("iobase",  ISAIDEState, iobase,  0x1f0),
+    DEFINE_PROP_UINT32("iobase2", ISAIDEState, iobase2, 0x3f6),
     DEFINE_PROP_UINT32("irq",    ISAIDEState, isairq,  14),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 18c4b7e..6e475e6 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -206,7 +206,7 @@
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
     DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
-    DEFINE_PROP_HEX64("wwn",  IDEDrive, dev.wwn, 0),    \
+    DEFINE_PROP_UINT64("wwn",  IDEDrive, dev.wwn, 0),    \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
     DEFINE_PROP_STRING("model", IDEDrive, dev.model)
 
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
index f583cf0..4ae1cd9 100644
--- a/hw/input/lm832x.c
+++ b/hw/input/lm832x.c
@@ -23,8 +23,12 @@
 #include "qemu/timer.h"
 #include "ui/console.h"
 
+#define TYPE_LM8323 "lm8323"
+#define LM8323(obj) OBJECT_CHECK(LM823KbdState, (obj), TYPE_LM8323)
+
 typedef struct {
-    I2CSlave i2c;
+    I2CSlave parent_obj;
+
     uint8_t i2c_dir;
     uint8_t i2c_cycle;
     uint8_t reg;
@@ -380,7 +384,7 @@
 
 static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
 {
-    LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+    LM823KbdState *s = LM8323(i2c);
 
     switch (event) {
     case I2C_START_RECV:
@@ -396,14 +400,14 @@
 
 static int lm_i2c_rx(I2CSlave *i2c)
 {
-    LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+    LM823KbdState *s = LM8323(i2c);
 
     return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
 }
 
 static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
 {
-    LM823KbdState *s = (LM823KbdState *) i2c;
+    LM823KbdState *s = LM8323(i2c);
 
     if (!s->i2c_cycle)
         s->reg = data;
@@ -431,7 +435,7 @@
     .minimum_version_id_old = 0,
     .post_load = lm_kbd_post_load,
     .fields      = (VMStateField []) {
-        VMSTATE_I2C_SLAVE(i2c, LM823KbdState),
+        VMSTATE_I2C_SLAVE(parent_obj, LM823KbdState),
         VMSTATE_UINT8(i2c_dir, LM823KbdState),
         VMSTATE_UINT8(i2c_cycle, LM823KbdState),
         VMSTATE_UINT8(reg, LM823KbdState),
@@ -460,13 +464,13 @@
 
 static int lm8323_init(I2CSlave *i2c)
 {
-    LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
+    LM823KbdState *s = LM8323(i2c);
 
     s->model = 0x8323;
     s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
     s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
     s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
-    qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
+    qdev_init_gpio_out(DEVICE(i2c), &s->nirq, 1);
 
     lm_kbd_reset(s);
 
@@ -476,7 +480,7 @@
 
 void lm832x_key_event(DeviceState *dev, int key, int state)
 {
-    LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, I2C_SLAVE(dev));
+    LM823KbdState *s = LM8323(dev);
 
     if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
         return;
@@ -507,7 +511,7 @@
 }
 
 static const TypeInfo lm8323_info = {
-    .name          = "lm8323",
+    .name          = TYPE_LM8323,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(LM823KbdState),
     .class_init    = lm8323_class_init,
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index 9d29399..61381c4 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -123,9 +123,9 @@
 };
 
 static Property pic_properties_common[] = {
-    DEFINE_PROP_HEX32("iobase", PICCommonState, iobase,  -1),
-    DEFINE_PROP_HEX32("elcr_addr", PICCommonState, elcr_addr,  -1),
-    DEFINE_PROP_HEX8("elcr_mask", PICCommonState, elcr_mask,  -1),
+    DEFINE_PROP_UINT32("iobase", PICCommonState, iobase,  -1),
+    DEFINE_PROP_UINT32("elcr_addr", PICCommonState, elcr_addr,  -1),
+    DEFINE_PROP_UINT8("elcr_mask", PICCommonState, elcr_mask,  -1),
     DEFINE_PROP_BIT("master", PICCommonState, master,  0, false),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/ipack/Makefile.objs b/hw/ipack/Makefile.objs
new file mode 100644
index 0000000..8b9bdcb
--- /dev/null
+++ b/hw/ipack/Makefile.objs
@@ -0,0 +1,2 @@
+common-obj-$(CONFIG_IPACK) += ipack.o
+common-obj-$(CONFIG_IPACK) += tpci200.o
diff --git a/hw/char/ipack.c b/hw/ipack/ipack.c
similarity index 72%
rename from hw/char/ipack.c
rename to hw/ipack/ipack.c
index b7e45be..ed63d2a 100644
--- a/hw/char/ipack.c
+++ b/hw/ipack/ipack.c
@@ -8,7 +8,7 @@
  * later version.
  */
 
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
 
 IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
 {
@@ -34,37 +34,39 @@
     bus->set_irq = handler;
 }
 
-static int ipack_device_dev_init(DeviceState *qdev)
+static void ipack_device_realize(DeviceState *dev, Error **errp)
 {
-    IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev));
-    IPackDevice *dev = IPACK_DEVICE(qdev);
+    IPackDevice *idev = IPACK_DEVICE(dev);
+    IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(dev));
     IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
 
-    if (dev->slot < 0) {
-        dev->slot = bus->free_slot;
+    if (idev->slot < 0) {
+        idev->slot = bus->free_slot;
     }
-    if (dev->slot >= bus->n_slots) {
-        return -1;
+    if (idev->slot >= bus->n_slots) {
+        error_setg(errp, "Only %" PRIu8 " slots available.", bus->n_slots);
+        return;
     }
-    bus->free_slot = dev->slot + 1;
+    bus->free_slot = idev->slot + 1;
 
-    dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2);
+    idev->irq = qemu_allocate_irqs(bus->set_irq, idev, 2);
 
-    return k->init(dev);
+    k->realize(dev, errp);
 }
 
-static int ipack_device_dev_exit(DeviceState *qdev)
+static void ipack_device_unrealize(DeviceState *dev, Error **errp)
 {
-    IPackDevice *dev = IPACK_DEVICE(qdev);
+    IPackDevice *idev = IPACK_DEVICE(dev);
     IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
+    Error *err = NULL;
 
-    if (k->exit) {
-        k->exit(dev);
+    if (k->unrealize) {
+        k->unrealize(dev, &err);
+        error_propagate(errp, err);
+        return;
     }
 
-    qemu_free_irqs(dev->irq);
-
-    return 0;
+    qemu_free_irqs(idev->irq);
 }
 
 static Property ipack_device_props[] = {
@@ -75,10 +77,11 @@
 static void ipack_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
+
     set_bit(DEVICE_CATEGORY_INPUT, k->categories);
     k->bus_type = TYPE_IPACK_BUS;
-    k->init = ipack_device_dev_init;
-    k->exit = ipack_device_dev_exit;
+    k->realize = ipack_device_realize;
+    k->unrealize = ipack_device_unrealize;
     k->props = ipack_device_props;
 }
 
diff --git a/hw/char/tpci200.c b/hw/ipack/tpci200.c
similarity index 99%
rename from hw/char/tpci200.c
rename to hw/ipack/tpci200.c
index a49d2ed..e1b69b4 100644
--- a/hw/char/tpci200.c
+++ b/hw/ipack/tpci200.c
@@ -8,7 +8,7 @@
  * later version.
  */
 
-#include "ipack.h"
+#include "hw/ipack/ipack.h"
 #include "hw/pci/pci.h"
 #include "qemu/bitops.h"
 #include <stdio.h>
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index 46a23fb..b352b49 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -369,7 +369,7 @@
 };
 
 static Property pc87312_properties[] = {
-    DEFINE_PROP_HEX32("iobase", PC87312State, iobase, 0x398),
+    DEFINE_PROP_UINT32("iobase", PC87312State, iobase, 0x398),
     DEFINE_PROP_UINT8("config", PC87312State, config, 1),
     DEFINE_PROP_END_OF_LIST()
 };
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index e639357..1a93afd 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -369,8 +369,8 @@
     return 0;
 }
 
-i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-                       qemu_irq sci_irq)
+I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+                          qemu_irq sci_irq)
 {
     PCIDevice *dev;
     VT686PMState *s;
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 9ef3a97..e1551aa 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -276,7 +276,7 @@
     qemu_irq *cpu_exit_irq;
     PCIBus *pci_bus;
     ISABus *isa_bus;
-    i2c_bus *smbus;
+    I2CBus *smbus;
     int i;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     MIPSCPU *cpu;
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 05c8771..ac5ec44 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -900,7 +900,7 @@
     qemu_irq *isa_irq;
     qemu_irq *cpu_exit_irq;
     int piix4_devfn;
-    i2c_bus *smbus;
+    I2CBus *smbus;
     int i;
     DriveInfo *dinfo;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 627adb9..6a56b07 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -249,7 +249,7 @@
 }
 
 static Property applesmc_isa_properties[] = {
-    DEFINE_PROP_HEX32("iobase", AppleSMCState, iobase,
+    DEFINE_PROP_UINT32("iobase", AppleSMCState, iobase,
                       APPLESMC_DEFAULT_IOBASE),
     DEFINE_PROP_STRING("osk", AppleSMCState, osk),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 9db5680..69a1b00 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -47,8 +47,8 @@
 }
 
 static Property debug_exit_properties[] = {
-    DEFINE_PROP_HEX32("iobase", ISADebugExitState, iobase, 0x501),
-    DEFINE_PROP_HEX32("iosize", ISADebugExitState, iosize, 0x02),
+    DEFINE_PROP_UINT32("iobase", ISADebugExitState, iobase, 0x501),
+    DEFINE_PROP_UINT32("iosize", ISADebugExitState, iosize, 0x02),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/misc/eccmemctl.c b/hw/misc/eccmemctl.c
index 96a69d4..549431c 100644
--- a/hw/misc/eccmemctl.c
+++ b/hw/misc/eccmemctl.c
@@ -314,7 +314,7 @@
 }
 
 static Property ecc_properties[] = {
-    DEFINE_PROP_HEX32("version", ECCState, version, -1),
+    DEFINE_PROP_UINT32("version", ECCState, version, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 26b83ce..c660e58 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -86,7 +86,7 @@
 }
 
 static Property ne2000_isa_properties[] = {
-    DEFINE_PROP_HEX32("iobase", ISANE2000State, iobase, 0x300),
+    DEFINE_PROP_UINT32("iobase", ISANE2000State, iobase, 0x300),
     DEFINE_PROP_UINT32("irq",   ISANE2000State, isairq, 9),
     DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index ee96c16..cb36dc2 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -584,8 +584,8 @@
 }
 
 static Property fw_cfg_properties[] = {
-    DEFINE_PROP_HEX32("ctl_iobase", FWCfgState, ctl_iobase, -1),
-    DEFINE_PROP_HEX32("data_iobase", FWCfgState, data_iobase, -1),
+    DEFINE_PROP_UINT32("ctl_iobase", FWCfgState, ctl_iobase, -1),
+    DEFINE_PROP_UINT32("data_iobase", FWCfgState, data_iobase, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index 8dbc3c1..cf2caeb 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -90,7 +90,7 @@
     qemu_opt_set(opts, "type", "nic");
 
     ret = net_client_init(opts, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return NULL;
@@ -322,7 +322,7 @@
     }
 
     qdev_unplug(&d->qdev, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         monitor_printf(mon, "%s\n", error_get_pretty(local_err));
         error_free(local_err);
         return -1;
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 2dd5284..ea747f0 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -10,9 +10,9 @@
 # PReP
 obj-$(CONFIG_PREP) += prep.o
 # OldWorld PowerMac
-obj-y += mac_oldworld.o
+obj-$(CONFIG_MAC) += mac_oldworld.o
 # NewWorld PowerMac
-obj-y += mac_newworld.o
+obj-$(CONFIG_MAC) += mac_newworld.o
 # e500
 obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o
 obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index ec00300..4c7c3ae 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -651,14 +651,14 @@
 
 static Property spapr_phb_properties[] = {
     DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1),
-    DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, -1),
-    DEFINE_PROP_HEX32("liobn", sPAPRPHBState, dma_liobn, -1),
-    DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
-    DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size,
-                      SPAPR_PCI_MMIO_WIN_SIZE),
-    DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
-    DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size,
-                      SPAPR_PCI_IO_WIN_SIZE),
+    DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
+    DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn, -1),
+    DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
+    DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
+                       SPAPR_PCI_MMIO_WIN_SIZE),
+    DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
+    DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
+                       SPAPR_PCI_IO_WIN_SIZE),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 59570e2..e6e1ffd 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2195,7 +2195,7 @@
     DEFINE_PROP_UINT32("max_cmds", MegasasState, fw_cmds,
                        MEGASAS_DEFAULT_FRAMES),
     DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
-    DEFINE_PROP_HEX64("sas_address", MegasasState, sas_addr, 0),
+    DEFINE_PROP_UINT64("sas_address", MegasasState, sas_addr, 0),
 #ifdef USE_MSIX
     DEFINE_PROP_BIT("use_msix", MegasasState, flags,
                     MEGASAS_FLAG_USE_MSIX, false),
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a8d0f15..b4fadd2 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2535,7 +2535,7 @@
                     SCSI_DISK_F_REMOVABLE, false),
     DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
                     SCSI_DISK_F_DPOFUA, false),
-    DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+    DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
     DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
                        DEFAULT_MAX_UNMAP_SIZE),
     DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
@@ -2583,7 +2583,7 @@
 
 static Property scsi_cd_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
-    DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+    DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2646,7 +2646,7 @@
                     SCSI_DISK_F_REMOVABLE, false),
     DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
                     SCSI_DISK_F_DPOFUA, false),
-    DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+    DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
     DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
                        DEFAULT_MAX_UNMAP_SIZE),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index a0b90ba..843e697 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1233,9 +1233,9 @@
 /* Capabilities registers provide information on supported features of this
  * specific host controller implementation */
 static Property sdhci_properties[] = {
-    DEFINE_PROP_HEX32("capareg", SDHCIState, capareg,
+    DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
             SDHC_CAPAB_REG_DEFAULT),
-    DEFINE_PROP_HEX32("maxcurr", SDHCIState, maxcurr, 0),
+    DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c
index 8987cdc9..bb2f8ee 100644
--- a/hw/timer/ds1338.c
+++ b/hw/timer/ds1338.c
@@ -23,8 +23,12 @@
 #define HOURS_PM   0x20
 #define CTRL_OSF   0x20
 
-typedef struct {
-    I2CSlave i2c;
+#define TYPE_DS1338 "ds1338"
+#define DS1338(obj) OBJECT_CHECK(DS1338State, (obj), TYPE_DS1338)
+
+typedef struct DS1338State {
+    I2CSlave parent_obj;
+
     int64_t offset;
     uint8_t wday_offset;
     uint8_t nvram[NVRAM_SIZE];
@@ -38,7 +42,7 @@
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_I2C_SLAVE(i2c, DS1338State),
+        VMSTATE_I2C_SLAVE(parent_obj, DS1338State),
         VMSTATE_INT64(offset, DS1338State),
         VMSTATE_UINT8_V(wday_offset, DS1338State, 2),
         VMSTATE_UINT8_ARRAY(nvram, DS1338State, NVRAM_SIZE),
@@ -90,7 +94,7 @@
 
 static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
 {
-    DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+    DS1338State *s = DS1338(i2c);
 
     switch (event) {
     case I2C_START_RECV:
@@ -111,7 +115,7 @@
 
 static int ds1338_recv(I2CSlave *i2c)
 {
-    DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+    DS1338State *s = DS1338(i2c);
     uint8_t res;
 
     res  = s->nvram[s->ptr];
@@ -121,7 +125,8 @@
 
 static int ds1338_send(I2CSlave *i2c, uint8_t data)
 {
-    DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
+    DS1338State *s = DS1338(i2c);
+
     if (s->addr_byte) {
         s->ptr = data & (NVRAM_SIZE - 1);
         s->addr_byte = false;
@@ -198,7 +203,7 @@
 
 static void ds1338_reset(DeviceState *dev)
 {
-    DS1338State *s = FROM_I2C_SLAVE(DS1338State, I2C_SLAVE(dev));
+    DS1338State *s = DS1338(dev);
 
     /* The clock is running and synchronized with the host */
     s->offset = 0;
@@ -222,7 +227,7 @@
 }
 
 static const TypeInfo ds1338_info = {
-    .name          = "ds1338",
+    .name          = TYPE_DS1338,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(DS1338State),
     .class_init    = ds1338_class_init,
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index cdbf481..28152d8 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -342,7 +342,7 @@
 }
 
 static Property pit_properties[] = {
-    DEFINE_PROP_HEX32("iobase", PITCommonState, iobase,  -1),
+    DEFINE_PROP_UINT32("iobase", PITCommonState, iobase,  -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 3cfb18a..7cf8684 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -741,7 +741,7 @@
 static Property m48t59_isa_properties[] = {
     DEFINE_PROP_UINT32("size",    M48t59ISAState, state.size,    -1),
     DEFINE_PROP_UINT32("model",   M48t59ISAState, state.model,   -1),
-    DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base,  0),
+    DEFINE_PROP_UINT32("io_base", M48t59ISAState, state.io_base,  0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -766,7 +766,7 @@
 static Property m48t59_properties[] = {
     DEFINE_PROP_UINT32("size",    M48t59SysBusState, state.size,    -1),
     DEFINE_PROP_UINT32("model",   M48t59SysBusState, state.model,   -1),
-    DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base,  0),
+    DEFINE_PROP_UINT32("io_base", M48t59SysBusState, state.io_base,  0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 6fb124f..8509309 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -185,7 +185,7 @@
     if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
         s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
 #ifdef TARGET_I386
-        if (s->lost_tick_policy == LOST_TICK_SLEW) {
+        if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
             if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                 s->irq_reinject_on_ack_count = 0;		
             apic_reset_irq_delivered();
@@ -708,7 +708,7 @@
 
 #ifdef TARGET_I386
     if (version_id >= 2) {
-        if (s->lost_tick_policy == LOST_TICK_SLEW) {
+        if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
             rtc_coalesced_timer_update(s);
         }
     }
@@ -749,7 +749,7 @@
     periodic_timer_update(s, now);
     check_update_timer(s);
 #ifdef TARGET_I386
-    if (s->lost_tick_policy == LOST_TICK_SLEW) {
+    if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
         rtc_coalesced_timer_update(s);
     }
 #endif
@@ -774,7 +774,7 @@
     qemu_irq_lower(s->irq);
 
 #ifdef TARGET_I386
-    if (s->lost_tick_policy == LOST_TICK_SLEW) {
+    if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
         s->irq_coalesced = 0;
     }
 #endif
@@ -835,11 +835,11 @@
 
 #ifdef TARGET_I386
     switch (s->lost_tick_policy) {
-    case LOST_TICK_SLEW:
+    case LOST_TICK_POLICY_SLEW:
         s->coalesced_timer =
             timer_new_ns(rtc_clock, rtc_coalesced_timer, s);
         break;
-    case LOST_TICK_DISCARD:
+    case LOST_TICK_POLICY_DISCARD:
         break;
     default:
         error_setg(errp, "Invalid lost tick policy.");
@@ -890,7 +890,7 @@
 static Property mc146818rtc_properties[] = {
     DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
     DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
-                               lost_tick_policy, LOST_TICK_DISCARD),
+                               lost_tick_policy, LOST_TICK_POLICY_DISCARD),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c
index f3ea365..85d5990 100644
--- a/hw/timer/twl92230.c
+++ b/hw/timer/twl92230.c
@@ -27,8 +27,11 @@
 
 #define VERBOSE 1
 
-typedef struct {
-    I2CSlave i2c;
+#define TYPE_TWL92230 "twl92230"
+#define TWL92230(obj) OBJECT_CHECK(MenelausState, (obj), TYPE_TWL92230)
+
+typedef struct MenelausState {
+    I2CSlave parent_obj;
 
     int firstbyte;
     uint8_t reg;
@@ -127,7 +130,8 @@
 
 static void menelaus_reset(I2CSlave *i2c)
 {
-    MenelausState *s = (MenelausState *) i2c;
+    MenelausState *s = TWL92230(i2c);
+
     s->reg = 0x00;
 
     s->vcore[0] = 0x0c;	/* XXX: X-loader needs 0x8c? check!  */
@@ -492,8 +496,9 @@
         break;
 
     case MENELAUS_DEVICE_OFF:
-        if (value & 1)
-            menelaus_reset(&s->i2c);
+        if (value & 1) {
+            menelaus_reset(I2C_SLAVE(s));
+        }
         break;
 
     case MENELAUS_OSC_CTRL:
@@ -708,7 +713,7 @@
 
 static void menelaus_event(I2CSlave *i2c, enum i2c_event event)
 {
-    MenelausState *s = (MenelausState *) i2c;
+    MenelausState *s = TWL92230(i2c);
 
     if (event == I2C_START_SEND)
         s->firstbyte = 1;
@@ -716,7 +721,8 @@
 
 static int menelaus_tx(I2CSlave *i2c, uint8_t data)
 {
-    MenelausState *s = (MenelausState *) i2c;
+    MenelausState *s = TWL92230(i2c);
+
     /* Interpret register address byte */
     if (s->firstbyte) {
         s->reg = data;
@@ -729,7 +735,7 @@
 
 static int menelaus_rx(I2CSlave *i2c)
 {
-    MenelausState *s = (MenelausState *) i2c;
+    MenelausState *s = TWL92230(i2c);
 
     return menelaus_read(s, s->reg ++);
 }
@@ -834,23 +840,24 @@
         VMSTATE_STRUCT(rtc.alm, MenelausState, 0, vmstate_menelaus_tm,
                        struct tm),
         VMSTATE_UINT8(pwrbtn_state, MenelausState),
-        VMSTATE_I2C_SLAVE(i2c, MenelausState),
+        VMSTATE_I2C_SLAVE(parent_obj, MenelausState),
         VMSTATE_END_OF_LIST()
     }
 };
 
 static int twl92230_init(I2CSlave *i2c)
 {
-    MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
+    DeviceState *dev = DEVICE(i2c);
+    MenelausState *s = TWL92230(i2c);
 
     s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s);
     /* Three output pins plus one interrupt pin.  */
-    qdev_init_gpio_out(&i2c->qdev, s->out, 4);
+    qdev_init_gpio_out(dev, s->out, 4);
 
     /* Three input pins plus one power-button pin.  */
-    qdev_init_gpio_in(&i2c->qdev, menelaus_gpio_set, 4);
+    qdev_init_gpio_in(dev, menelaus_gpio_set, 4);
 
-    menelaus_reset(&s->i2c);
+    menelaus_reset(i2c);
 
     return 0;
 }
@@ -868,7 +875,7 @@
 }
 
 static const TypeInfo twl92230_info = {
-    .name          = "twl92230",
+    .name          = TYPE_TWL92230,
     .parent        = TYPE_I2C_SLAVE,
     .instance_size = sizeof(MenelausState),
     .class_init    = twl92230_class_init,
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index f133ddb..ab48691 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -759,7 +759,7 @@
          * We return the same value that a configured device would return if
          * it used the first configuration.
          */
-        if (config->bmAttributes & 0x40) {
+        if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) {
             data[0] |= 1 << USB_DEVICE_SELF_POWERED;
         }
         if (dev->remote_wakeup) {
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index c5420eb..bfebfe9 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -224,7 +224,7 @@
             .bNumInterfaces        = 2,
             .bConfigurationValue   = DEV_CONFIG_VALUE,
             .iConfiguration        = STRING_CONFIG,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .bMaxPower             = 0x32,
             .nif = ARRAY_SIZE(desc_iface),
             .ifs = desc_iface,
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index 7f292b1..a9661d2 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -229,7 +229,7 @@
         {
             .bNumInterfaces        = 2,
             .bConfigurationValue   = 1,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .bMaxPower             = 0,
             .nif = ARRAY_SIZE(desc_iface_bluetooth),
             .ifs = desc_iface_bluetooth,
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 2966066..f36e617 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -202,7 +202,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_MOUSE,
-            .bmAttributes          = 0xa0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface_mouse,
@@ -219,7 +219,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_TABLET,
-            .bmAttributes          = 0xa0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface_tablet,
@@ -236,7 +236,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_TABLET,
-            .bmAttributes          = 0xa0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface_tablet2,
@@ -253,7 +253,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_KEYBOARD,
-            .bmAttributes          = 0xa0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface_keyboard,
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 58647b4..bc03531 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -119,7 +119,8 @@
         {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
-            .bmAttributes          = 0xe0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
+                                     USB_CFG_ATT_WAKEUP,
             .nif = 1,
             .ifs = &desc_iface_hub,
         },
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 4c532b7..518d536 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -266,7 +266,7 @@
             .bNumInterfaces        = 2,
             .bConfigurationValue   = DEV_RNDIS_CONFIG_VALUE,
             .iConfiguration        = STRING_RNDIS,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .bMaxPower             = 0x32,
             .nif = ARRAY_SIZE(desc_iface_rndis),
             .ifs = desc_iface_rndis,
@@ -274,7 +274,7 @@
             .bNumInterfaces        = 2,
             .bConfigurationValue   = DEV_CONFIG_VALUE,
             .iConfiguration        = STRING_CDC,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .bMaxPower             = 0x32,
             .nif = ARRAY_SIZE(desc_iface_cdc),
             .ifs = desc_iface_cdc,
@@ -1391,7 +1391,7 @@
     qemu_opt_set(opts, "model", "usb");
 
     idx = net_client_init(opts, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return NULL;
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 0b150d4..d360614 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -144,7 +144,7 @@
         {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
-            .bmAttributes          = 0x80,
+            .bmAttributes          = USB_CFG_ATT_ONE,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface0,
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 8c7a61e..470e69f 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -463,7 +463,8 @@
         {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
-            .bmAttributes          = 0xe0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
+                                     USB_CFG_ATT_WAKEUP,
             .bMaxPower             = 50,
             .nif = 1,
             .ifs = &desc_iface0,
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index c434c56..2852669 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -117,7 +117,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_FULL,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .nif = 1,
             .ifs = &desc_iface_full,
         },
@@ -152,7 +152,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_HIGH,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .nif = 1,
             .ifs = &desc_iface_high,
         },
@@ -189,7 +189,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_SUPER,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .nif = 1,
             .ifs = &desc_iface_super,
         },
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 997b715..9832385 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -286,7 +286,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_HIGH,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .nif = 1,
             .ifs = &desc_iface_high,
         },
@@ -302,7 +302,7 @@
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .iConfiguration        = STR_CONFIG_SUPER,
-            .bmAttributes          = 0xc0,
+            .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
             .nif = 1,
             .ifs = &desc_iface_super,
         },
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 1b09235..1b73fd0 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -107,7 +107,7 @@
         {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
-            .bmAttributes          = 0x80,
+            .bmAttributes          = USB_CFG_ATT_ONE,
             .bMaxPower             = 40,
             .nif = 1,
             .ifs = &desc_iface_wacom,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index ad814b5..0820244 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -252,9 +252,11 @@
                               uint32_t td_addr, bool queuing)
 {
     UHCIAsync *first = QTAILQ_FIRST(&queue->asyncs);
+    uint32_t queue_token_addr = (queue->token >> 8) & 0x7f;
 
     return queue->qh_addr == qh_addr &&
            queue->token == uhci_queue_token(td) &&
+           queue_token_addr == queue->ep->dev->addr &&
            (queuing || !(td->ctrl & TD_CTRL_ACTIVE) || first == NULL ||
             first->td_addr == td_addr);
 }
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 0fa814e..ef3177a 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -807,7 +807,7 @@
 static void xhci_die(XHCIState *xhci)
 {
     xhci->usbsts |= USBSTS_HCE;
-    fprintf(stderr, "xhci: asserted controller error\n");
+    DPRINTF("xhci: asserted controller error\n");
 }
 
 static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
@@ -854,8 +854,8 @@
     erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
     if (erdp < intr->er_start ||
         erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) {
-        fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
-        fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
+        DPRINTF("xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
+        DPRINTF("xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
                 v, intr->er_start, intr->er_size);
         xhci_die(xhci);
         return;
@@ -923,7 +923,7 @@
     if (intr->er_full) {
         DPRINTF("xhci_event(): ER full, queueing\n");
         if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) {
-            fprintf(stderr, "xhci: event queue full, dropping event!\n");
+            DPRINTF("xhci: event queue full, dropping event!\n");
             return;
         }
         intr->ev_buffer[intr->ev_buffer_put++] = *event;
@@ -936,8 +936,8 @@
     erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
     if (erdp < intr->er_start ||
         erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) {
-        fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
-        fprintf(stderr, "xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
+        DPRINTF("xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp);
+        DPRINTF("xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
                 v, intr->er_start, intr->er_size);
         xhci_die(xhci);
         return;
@@ -954,7 +954,7 @@
 #endif
         intr->er_full = 1;
         if (((intr->ev_buffer_put+1) % EV_QUEUE) == intr->ev_buffer_get) {
-            fprintf(stderr, "xhci: event queue full, dropping event!\n");
+            DPRINTF("xhci: event queue full, dropping event!\n");
             return;
         }
         intr->ev_buffer[intr->ev_buffer_put++] = *event;
@@ -1072,7 +1072,7 @@
     }
     /* cache the (sole) event ring segment location */
     if (intr->erstsz != 1) {
-        fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", intr->erstsz);
+        DPRINTF("xhci: invalid value for ERSTSZ: %d\n", intr->erstsz);
         xhci_die(xhci);
         return;
     }
@@ -1082,7 +1082,7 @@
     le32_to_cpus(&seg.addr_high);
     le32_to_cpus(&seg.size);
     if (seg.size < 16 || seg.size > 4096) {
-        fprintf(stderr, "xhci: invalid value for segment size: %d\n", seg.size);
+        DPRINTF("xhci: invalid value for segment size: %d\n", seg.size);
         xhci_die(xhci);
         return;
     }
@@ -1248,7 +1248,7 @@
 
     r = usb_device_alloc_streams(eps[0]->dev, eps, nr_eps, req_nr_streams);
     if (r != 0) {
-        fprintf(stderr, "xhci: alloc streams failed\n");
+        DPRINTF("xhci: alloc streams failed\n");
         return CC_RESOURCE_ERROR;
     }
 
@@ -1532,7 +1532,7 @@
     assert(slotid >= 1 && slotid <= xhci->numslots);
 
     if (epid < 1 || epid > 31) {
-        fprintf(stderr, "xhci: bad ep %d\n", epid);
+        DPRINTF("xhci: bad ep %d\n", epid);
         return CC_TRB_ERROR;
     }
 
@@ -1544,7 +1544,7 @@
     }
 
     if (xhci_ep_nuke_xfers(xhci, slotid, epid, CC_STOPPED) > 0) {
-        fprintf(stderr, "xhci: FIXME: endpoint stopped w/ xfers running, "
+        DPRINTF("xhci: FIXME: endpoint stopped w/ xfers running, "
                 "data might be lost\n");
     }
 
@@ -1569,7 +1569,7 @@
     assert(slotid >= 1 && slotid <= xhci->numslots);
 
     if (epid < 1 || epid > 31) {
-        fprintf(stderr, "xhci: bad ep %d\n", epid);
+        DPRINTF("xhci: bad ep %d\n", epid);
         return CC_TRB_ERROR;
     }
 
@@ -1583,13 +1583,13 @@
     epctx = slot->eps[epid-1];
 
     if (epctx->state != EP_HALTED) {
-        fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n",
+        DPRINTF("xhci: reset EP while EP %d not halted (%d)\n",
                 epid, epctx->state);
         return CC_CONTEXT_STATE_ERROR;
     }
 
     if (xhci_ep_nuke_xfers(xhci, slotid, epid, 0) > 0) {
-        fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, "
+        DPRINTF("xhci: FIXME: endpoint reset w/ xfers running, "
                 "data might be lost\n");
     }
 
@@ -1626,7 +1626,7 @@
     assert(slotid >= 1 && slotid <= xhci->numslots);
 
     if (epid < 1 || epid > 31) {
-        fprintf(stderr, "xhci: bad ep %d\n", epid);
+        DPRINTF("xhci: bad ep %d\n", epid);
         return CC_TRB_ERROR;
     }
 
@@ -1643,7 +1643,7 @@
     epctx = slot->eps[epid-1];
 
     if (epctx->state != EP_STOPPED) {
-        fprintf(stderr, "xhci: set EP dequeue pointer while EP %d not stopped\n", epid);
+        DPRINTF("xhci: set EP dequeue pointer while EP %d not stopped\n", epid);
         return CC_CONTEXT_STATE_ERROR;
     }
 
@@ -1685,7 +1685,7 @@
         switch (TRB_TYPE(*trb)) {
         case TR_DATA:
             if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) {
-                fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n");
+                DPRINTF("xhci: data direction mismatch for TR_DATA\n");
                 goto err;
             }
             /* fallthrough */
@@ -1695,7 +1695,7 @@
             chunk = trb->status & 0x1ffff;
             if (trb->control & TRB_TR_IDT) {
                 if (chunk > 8 || in_xfer) {
-                    fprintf(stderr, "xhci: invalid immediate data TRB\n");
+                    DPRINTF("xhci: invalid immediate data TRB\n");
                     goto err;
                 }
                 qemu_sglist_add(&xfer->sgl, trb->addr, chunk);
@@ -1824,7 +1824,7 @@
     } else {
         ep = xhci_epid_to_usbep(xhci, xfer->slotid, xfer->epid);
         if (!ep) {
-            fprintf(stderr, "xhci: slot %d has no device\n",
+            DPRINTF("xhci: slot %d has no device\n",
                     xfer->slotid);
             return -1;
         }
@@ -1887,7 +1887,7 @@
         xhci_stall_ep(xfer);
         break;
     default:
-        fprintf(stderr, "%s: FIXME: status = %d\n", __func__,
+        DPRINTF("%s: FIXME: status = %d\n", __func__,
                 xfer->packet.status);
         FIXME("unhandled USB_RET_*");
     }
@@ -1911,21 +1911,21 @@
 
     /* do some sanity checks */
     if (TRB_TYPE(*trb_setup) != TR_SETUP) {
-        fprintf(stderr, "xhci: ep0 first TD not SETUP: %d\n",
+        DPRINTF("xhci: ep0 first TD not SETUP: %d\n",
                 TRB_TYPE(*trb_setup));
         return -1;
     }
     if (TRB_TYPE(*trb_status) != TR_STATUS) {
-        fprintf(stderr, "xhci: ep0 last TD not STATUS: %d\n",
+        DPRINTF("xhci: ep0 last TD not STATUS: %d\n",
                 TRB_TYPE(*trb_status));
         return -1;
     }
     if (!(trb_setup->control & TRB_TR_IDT)) {
-        fprintf(stderr, "xhci: Setup TRB doesn't have IDT set\n");
+        DPRINTF("xhci: Setup TRB doesn't have IDT set\n");
         return -1;
     }
     if ((trb_setup->status & 0x1ffff) != 8) {
-        fprintf(stderr, "xhci: Setup TRB has bad length (%d)\n",
+        DPRINTF("xhci: Setup TRB has bad length (%d)\n",
                 (trb_setup->status & 0x1ffff));
         return -1;
     }
@@ -1974,10 +1974,10 @@
             xfer->mfindex_kick = asap;
         }
     } else {
-        xfer->mfindex_kick = (xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT)
-            & TRB_TR_FRAMEID_MASK;
+        xfer->mfindex_kick = ((xfer->trbs[0].control >> TRB_TR_FRAMEID_SHIFT)
+                              & TRB_TR_FRAMEID_MASK) << 3;
         xfer->mfindex_kick |= mfindex & ~0x3fff;
-        if (xfer->mfindex_kick < mfindex) {
+        if (xfer->mfindex_kick + 0x100 < mfindex) {
             xfer->mfindex_kick += 0x4000;
         }
     }
@@ -2038,9 +2038,7 @@
         }
         break;
     default:
-        fprintf(stderr, "xhci: unknown or unhandled EP "
-                "(type %d, in %d, ep %02x)\n",
-                epctx->type, xfer->in_xfer, xfer->epid);
+        trace_usb_xhci_unimplemented("endpoint type", epctx->type);
         return -1;
     }
 
@@ -2078,12 +2076,12 @@
     assert(epid >= 1 && epid <= 31);
 
     if (!xhci->slots[slotid-1].enabled) {
-        fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid);
+        DPRINTF("xhci: xhci_kick_ep for disabled slot %d\n", slotid);
         return;
     }
     epctx = xhci->slots[slotid-1].eps[epid-1];
     if (!epctx) {
-        fprintf(stderr, "xhci: xhci_kick_ep for disabled endpoint %d,%d\n",
+        DPRINTF("xhci: xhci_kick_ep for disabled endpoint %d,%d\n",
                 epid, slotid);
         return;
     }
@@ -2188,14 +2186,14 @@
                 epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
                 ep = xfer->packet.ep;
             } else {
-                fprintf(stderr, "xhci: error firing CTL transfer\n");
+                DPRINTF("xhci: error firing CTL transfer\n");
             }
         } else {
             if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) {
                 epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
             } else {
                 if (!xfer->timed_xfer) {
-                    fprintf(stderr, "xhci: error firing data transfer\n");
+                    DPRINTF("xhci: error firing data transfer\n");
                 }
             }
         }
@@ -2298,7 +2296,7 @@
     xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
 
     if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) {
-        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+        DPRINTF("xhci: invalid input context control %08x %08x\n",
                 ictl_ctx[0], ictl_ctx[1]);
         return CC_TRB_ERROR;
     }
@@ -2314,14 +2312,14 @@
 
     uport = xhci_lookup_uport(xhci, slot_ctx);
     if (uport == NULL) {
-        fprintf(stderr, "xhci: port not found\n");
+        DPRINTF("xhci: port not found\n");
         return CC_TRB_ERROR;
     }
     trace_usb_xhci_slot_address(slotid, uport->path);
 
     dev = uport->dev;
     if (!dev || !dev->attached) {
-        fprintf(stderr, "xhci: port %s not connected\n", uport->path);
+        DPRINTF("xhci: port %s not connected\n", uport->path);
         return CC_USB_TRANSACTION_ERROR;
     }
 
@@ -2330,7 +2328,7 @@
             continue;
         }
         if (xhci->slots[i].uport == uport) {
-            fprintf(stderr, "xhci: port %s already assigned to slot %d\n",
+            DPRINTF("xhci: port %s already assigned to slot %d\n",
                     uport->path, i+1);
             return CC_TRB_ERROR;
         }
@@ -2414,7 +2412,7 @@
     xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
 
     if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) {
-        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+        DPRINTF("xhci: invalid input context control %08x %08x\n",
                 ictl_ctx[0], ictl_ctx[1]);
         return CC_TRB_ERROR;
     }
@@ -2423,7 +2421,7 @@
     xhci_dma_read_u32s(xhci, octx, slot_ctx, sizeof(slot_ctx));
 
     if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) {
-        fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]);
+        DPRINTF("xhci: invalid slot state %08x\n", slot_ctx[3]);
         return CC_CONTEXT_STATE_ERROR;
     }
 
@@ -2496,7 +2494,7 @@
     xhci_dma_read_u32s(xhci, ictx, ictl_ctx, sizeof(ictl_ctx));
 
     if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) {
-        fprintf(stderr, "xhci: invalid input context control %08x %08x\n",
+        DPRINTF("xhci: invalid input context control %08x %08x\n",
                 ictl_ctx[0], ictl_ctx[1]);
         return CC_TRB_ERROR;
     }
@@ -2575,11 +2573,11 @@
     unsigned int slotid;
     slotid = (trb->control >> TRB_CR_SLOTID_SHIFT) & TRB_CR_SLOTID_MASK;
     if (slotid < 1 || slotid > xhci->numslots) {
-        fprintf(stderr, "xhci: bad slot id %d\n", slotid);
+        DPRINTF("xhci: bad slot id %d\n", slotid);
         event->ccode = CC_TRB_ERROR;
         return 0;
     } else if (!xhci->slots[slotid-1].enabled) {
-        fprintf(stderr, "xhci: slot id %d not enabled\n", slotid);
+        DPRINTF("xhci: slot id %d not enabled\n", slotid);
         event->ccode = CC_SLOT_NOT_ENABLED_ERROR;
         return 0;
     }
@@ -2695,7 +2693,7 @@
                 }
             }
             if (i >= xhci->numslots) {
-                fprintf(stderr, "xhci: no device slots available\n");
+                DPRINTF("xhci: no device slots available\n");
                 event.ccode = CC_NO_SLOTS_ERROR;
             } else {
                 slotid = i+1;
@@ -2887,7 +2885,7 @@
 
     trace_usb_xhci_reset();
     if (!(xhci->usbsts & USBSTS_HCH)) {
-        fprintf(stderr, "xhci: reset while running!\n");
+        DPRINTF("xhci: reset while running!\n");
     }
 
     xhci->usbcmd = 0;
@@ -3065,7 +3063,7 @@
                 /* windows does this for some reason, don't spam stderr */
                 break;
             default:
-                fprintf(stderr, "%s: ignore pls write (old %d, new %d)\n",
+                DPRINTF("%s: ignore pls write (old %d, new %d)\n",
                         __func__, old_pls, new_pls);
                 break;
             }
@@ -3316,7 +3314,7 @@
     trace_usb_xhci_doorbell_write(reg, val);
 
     if (!xhci_running(xhci)) {
-        fprintf(stderr, "xhci: wrote doorbell while xHC stopped or paused\n");
+        DPRINTF("xhci: wrote doorbell while xHC stopped or paused\n");
         return;
     }
 
@@ -3326,16 +3324,16 @@
         if (val == 0) {
             xhci_process_commands(xhci);
         } else {
-            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n",
+            DPRINTF("xhci: bad doorbell 0 write: 0x%x\n",
                     (uint32_t)val);
         }
     } else {
         epid = val & 0xff;
         streamid = (val >> 16) & 0xffff;
         if (reg > xhci->numslots) {
-            fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg);
+            DPRINTF("xhci: bad doorbell %d\n", (int)reg);
         } else if (epid > 31) {
-            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n",
+            DPRINTF("xhci: bad doorbell %d write: 0x%x\n",
                     (int)reg, (uint32_t)val);
         } else {
             xhci_kick_ep(xhci, reg, epid, streamid);
@@ -3636,7 +3634,7 @@
         slot->uport = xhci_lookup_uport(xhci, slot_ctx);
         assert(slot->uport && slot->uport->dev);
 
-        for (epid = 1; epid <= 32; epid++) {
+        for (epid = 1; epid <= 31; epid++) {
             pctx = slot->ctx + 32 * epid;
             xhci_dma_read_u32s(xhci, pctx, ep_ctx, sizeof(ep_ctx));
             state = ep_ctx[0] & EP_STATE_MASK;
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index fd320cd8..57bed09 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1324,8 +1324,8 @@
     DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
     DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
     DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
-    DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
-    DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
+    DEFINE_PROP_UINT32("vendorid",  USBHostDevice, match.vendor_id,  0),
+    DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
     DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
     DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames,   32),
     DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex,        -1),
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 30c9f2b..7b91841 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1063,7 +1063,7 @@
 /* virtio-blk-pci */
 
 static Property virtio_blk_pci_properties[] = {
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
     DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                     VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
@@ -1275,7 +1275,7 @@
 
 static Property virtio_balloon_pci_properties[] = {
     DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -1376,7 +1376,7 @@
     DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                     VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
     DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
     DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index bb9a1dd..5c1820f 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -97,7 +97,7 @@
     MemoryRegion dram1_mem;
     MemoryRegion boot_secondary;
     MemoryRegion bootreg_mem;
-    i2c_bus *i2c_if[EXYNOS4210_I2C_NUMBER];
+    I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
 } Exynos4210State;
 
 void exynos4210_write_secondary(ARMCPU *cpu,
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index 188cda8..b9655ee 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -765,7 +765,7 @@
 void omap_mmc_enable(struct omap_mmc_s *s, int enable);
 
 /* omap_i2c.c */
-i2c_bus *omap_i2c_bus(DeviceState *omap_i2c);
+I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
 
 # define cpu_is_omap310(cpu)		(cpu->mpu_model == omap310)
 # define cpu_is_omap1510(cpu)		(cpu->mpu_model == omap1510)
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index 7ca330a..c507906 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -116,7 +116,7 @@
 typedef struct PXA2xxI2CState PXA2xxI2CState;
 PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
                 qemu_irq irq, uint32_t page_size);
-i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
+I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
 
 typedef struct PXA2xxI2SState PXA2xxI2SState;
 typedef struct PXA2xxFIrState PXA2xxFIrState;
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index dd11532..7c3d6c8 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -65,12 +65,6 @@
 
 /* Hard disk geometry */
 
-#define BIOS_ATA_TRANSLATION_AUTO   0
-#define BIOS_ATA_TRANSLATION_NONE   1
-#define BIOS_ATA_TRANSLATION_LBA    2
-#define BIOS_ATA_TRANSLATION_LARGE  3
-#define BIOS_ATA_TRANSLATION_RECHS  4
-
 void hd_geometry_guess(BlockDriverState *bs,
                        uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
                        int *ptrans);
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 461392f..4986ebc 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -50,18 +50,16 @@
     uint8_t address;
 };
 
-i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
+I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
 void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
-int i2c_bus_busy(i2c_bus *bus);
-int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv);
-void i2c_end_transfer(i2c_bus *bus);
-void i2c_nack(i2c_bus *bus);
-int i2c_send(i2c_bus *bus, uint8_t data);
-int i2c_recv(i2c_bus *bus);
+int i2c_bus_busy(I2CBus *bus);
+int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
+void i2c_end_transfer(I2CBus *bus);
+void i2c_nack(I2CBus *bus);
+int i2c_send(I2CBus *bus, uint8_t data);
+int i2c_recv(I2CBus *bus);
 
-#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
-
-DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
+DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
 
 /* wm8750.c */
 void wm8750_data_req_set(DeviceState *dev,
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index e3069bf..926603f 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -2,7 +2,7 @@
 #define PM_SMBUS_H
 
 typedef struct PMSMBus {
-    i2c_bus *smbus;
+    I2CBus *smbus;
     MemoryRegion io;
 
     uint8_t smb_stat;
diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h
index d764d75..63f0cc4 100644
--- a/include/hw/i2c/smbus.h
+++ b/include/hw/i2c/smbus.h
@@ -66,18 +66,18 @@
 };
 
 /* Master device commands.  */
-void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
-uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr);
-void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data);
-uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command);
-void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data);
-uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command);
-void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data);
-int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data);
-void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
+void smbus_quick_command(I2CBus *bus, uint8_t addr, int read);
+uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr);
+void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data);
+uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command);
+void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data);
+uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command);
+void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data);
+int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data);
+void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
                        int len);
 
-void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom,
                        const uint8_t *eeprom_spd, int size);
 
 #endif
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index 4a68b35..9e4a0e4 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -20,7 +20,7 @@
 PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
 void ich9_lpc_pm_init(PCIDevice *pci_lpc);
 PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus);
-i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
+I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
 
 #define ICH9_CC_SIZE                            (16 * 1024)     /* 16KB */
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3e1e81b..9010246 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -165,9 +165,9 @@
 
 /* acpi_piix.c */
 
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-                       qemu_irq sci_irq, qemu_irq smi_irq,
-                       int kvm_enabled, FWCfgState *fw_cfg);
+I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+                      qemu_irq sci_irq, qemu_irq smi_irq,
+                      int kvm_enabled, FWCfgState *fw_cfg);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 
 /* hpet.c */
diff --git a/hw/char/ipack.h b/include/hw/ipack/ipack.h
similarity index 91%
rename from hw/char/ipack.h
rename to include/hw/ipack/ipack.h
index f8dc0f2..e95ffe8 100644
--- a/hw/char/ipack.h
+++ b/include/hw/ipack/ipack.h
@@ -19,7 +19,9 @@
 #define IPACK_BUS(obj) OBJECT_CHECK(IPackBus, (obj), TYPE_IPACK_BUS)
 
 struct IPackBus {
-    BusState qbus;
+    /*< private >*/
+    BusState parent_obj;
+
     /* All fields are private */
     uint8_t n_slots;
     uint8_t free_slot;
@@ -38,10 +40,12 @@
      OBJECT_GET_CLASS(IPackDeviceClass, (obj), TYPE_IPACK_DEVICE)
 
 struct IPackDeviceClass {
+    /*< private >*/
     DeviceClass parent_class;
+    /*< public >*/
 
-    int (*init)(IPackDevice *dev);
-    int (*exit)(IPackDevice *dev);
+    DeviceRealize realize;
+    DeviceUnrealize unrealize;
 
     uint16_t (*io_read)(IPackDevice *dev, uint8_t addr);
     void (*io_write)(IPackDevice *dev, uint8_t addr, uint16_t val);
@@ -60,7 +64,10 @@
 };
 
 struct IPackDevice {
-    DeviceState qdev;
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
     int32_t slot;
     /* IRQ objects for the IndustryPack INT0# and INT1# */
     qemu_irq *irq;
diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index 6ef876d..471b5e9 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -5,7 +5,7 @@
 ISABus *vt82c686b_init(PCIBus * bus, int devfn);
 void vt82c686b_ac97_init(PCIBus *bus, int devfn);
 void vt82c686b_mc97_init(PCIBus *bus, int devfn);
-i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-            qemu_irq sci_irq);
+I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+                          qemu_irq sci_irq);
 
 #endif
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 08d329d..276b336 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -217,7 +217,6 @@
     const char *name;
     const char *legacy_name;
     const char **enum_table;
-    int (*parse)(DeviceState *dev, Property *prop, const char *str);
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
diff --git a/include/hw/qdev-dma.h b/include/hw/qdev-dma.h
index 6812735..8cfb0f3 100644
--- a/include/hw/qdev-dma.h
+++ b/include/hw/qdev-dma.h
@@ -7,4 +7,4 @@
  * See the COPYING file in the top-level directory.
  */
 #define DEFINE_PROP_DMAADDR(_n, _s, _f, _d)                               \
-    DEFINE_PROP_HEX64(_n, _s, _f, _d)
+    DEFINE_PROP_UINT64(_n, _s, _f, _d)
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 77c6f7c..0c0babf 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -12,9 +12,6 @@
 extern PropertyInfo qdev_prop_uint32;
 extern PropertyInfo qdev_prop_int32;
 extern PropertyInfo qdev_prop_uint64;
-extern PropertyInfo qdev_prop_hex8;
-extern PropertyInfo qdev_prop_hex32;
-extern PropertyInfo qdev_prop_hex64;
 extern PropertyInfo qdev_prop_size;
 extern PropertyInfo qdev_prop_string;
 extern PropertyInfo qdev_prop_chr;
@@ -111,12 +108,6 @@
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
 #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
-#define DEFINE_PROP_HEX8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
-#define DEFINE_PROP_HEX32(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
-#define DEFINE_PROP_HEX64(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
 #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
@@ -168,8 +159,6 @@
 
 /* Set properties between creation and init.  */
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
-void qdev_prop_parse(DeviceState *dev, const char *name, const char *value,
-                     Error **errp);
 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 3ef7af7..1919bdc 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -157,6 +157,11 @@
 #define USB_DEV_CAP_USB2_EXT            0x02
 #define USB_DEV_CAP_SUPERSPEED          0x03
 
+#define USB_CFG_ATT_ONE              (1 << 7) /* should always be set */
+#define USB_CFG_ATT_SELFPOWER        (1 << 6)
+#define USB_CFG_ATT_WAKEUP           (1 << 5)
+#define USB_CFG_ATT_BATTERY          (1 << 4)
+
 #define USB_ENDPOINT_XFER_CONTROL	0
 #define USB_ENDPOINT_XFER_ISOC		1
 #define USB_ENDPOINT_XFER_BULK		2
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
index ec81e42..d99717f 100644
--- a/include/qapi/string-output-visitor.h
+++ b/include/qapi/string-output-visitor.h
@@ -17,7 +17,7 @@
 
 typedef struct StringOutputVisitor StringOutputVisitor;
 
-StringOutputVisitor *string_output_visitor_new(void);
+StringOutputVisitor *string_output_visitor_new(bool human);
 void string_output_visitor_cleanup(StringOutputVisitor *v);
 
 char *string_output_get_string(StringOutputVisitor *v);
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 5054836..b0e34b2 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -261,14 +261,6 @@
 
 typedef uint64_t pcibus_t;
 
-typedef enum LostTickPolicy {
-    LOST_TICK_DISCARD,
-    LOST_TICK_DELAY,
-    LOST_TICK_MERGE,
-    LOST_TICK_SLEW,
-    LOST_TICK_MAX
-} LostTickPolicy;
-
 typedef struct PCIHostDeviceAddress {
     unsigned int domain;
     unsigned int bus;
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5b4e333..83c9b16 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -43,7 +43,7 @@
 typedef struct CharDriverState CharDriverState;
 typedef struct MACAddr MACAddr;
 typedef struct NetClientState NetClientState;
-typedef struct i2c_bus i2c_bus;
+typedef struct I2CBus I2CBus;
 typedef struct ISABus ISABus;
 typedef struct ISADevice ISADevice;
 typedef struct SMBusDevice SMBusDevice;
diff --git a/include/qom/object.h b/include/qom/object.h
index e0ff212..9c7c361 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -946,12 +946,13 @@
  * object_property_print:
  * @obj: the object
  * @name: the name of the property
+ * @human: if true, print for human consumption
  * @errp: returns an error if this function fails
  *
  * Returns a string representation of the value of the property.  The
  * caller shall free the string.
  */
-char *object_property_print(Object *obj, const char *name,
+char *object_property_print(Object *obj, const char *name, bool human,
                             Error **errp);
 
 /**
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 6aca8e4..28f4875 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -15,6 +15,7 @@
 #define QTEST_H
 
 #include "qemu-common.h"
+#include "qapi/error.h"
 
 extern bool qtest_allowed;
 
@@ -26,7 +27,7 @@
 bool qtest_driver(void);
 
 int qtest_init_accel(void);
-void qtest_init(const char *qtest_chrdev, const char *qtest_log);
+void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
 
 static inline int qtest_available(void)
 {
diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index d52d76e..625f301 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -433,3 +433,10 @@
 #define TARGET_NR_open_by_handle_at             498
 #define TARGET_NR_clock_adjtime                 499
 #define TARGET_NR_syncfs                        500
+#define TARGET_NR_setns                         501
+#define TARGET_NR_accept4                       502
+#define TARGET_NR_sendmmsg                      503
+#define TARGET_NR_process_vm_readv              504
+#define TARGET_NR_process_vm_writev             505
+#define TARGET_NR_kcmp                          506
+#define TARGET_NR_finit_module                  507
diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 42d6855..bef847c 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -378,3 +378,9 @@
 #define TARGET_NR_open_by_handle_at            (371)
 #define TARGET_NR_clock_adjtime                (372)
 #define TARGET_NR_syncfs                       (373)
+#define TARGET_NR_sendmmsg                     (374)
+#define TARGET_NR_setns                        (375)
+#define TARGET_NR_process_vm_readv             (376)
+#define TARGET_NR_process_vm_writev            (377)
+#define TARGET_NR_kcmp                         (378)
+#define TARGET_NR_finit_module                 (379)
diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h
index 98f1a0b..694bd02 100644
--- a/linux-user/cris/syscall_nr.h
+++ b/linux-user/cris/syscall_nr.h
@@ -335,3 +335,4 @@
 #define TARGET_NR_inotify_init1      332
 #define TARGET_NR_preadv             333
 #define TARGET_NR_pwritev            334
+#define TARGET_NR_setns              335
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5902f16..c0687e3 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2636,6 +2636,16 @@
     info->notes_size += note_size(&ets->notes[0]);
 }
 
+static void init_note_info(struct elf_note_info *info)
+{
+    /* Initialize the elf_note_info structure so that it is at
+     * least safe to call free_note_info() on it. Must be
+     * called before calling fill_note_info().
+     */
+    memset(info, 0, sizeof (*info));
+    QTAILQ_INIT(&info->thread_list);
+}
+
 static int fill_note_info(struct elf_note_info *info,
                           long signr, const CPUArchState *env)
 {
@@ -2644,10 +2654,6 @@
     TaskState *ts = (TaskState *)env->opaque;
     int i;
 
-    (void) memset(info, 0, sizeof (*info));
-
-    QTAILQ_INIT(&info->thread_list);
-
     info->notes = g_malloc0(NUMNOTES * sizeof (struct memelfnote));
     if (info->notes == NULL)
         return (-ENOMEM);
@@ -2781,6 +2787,8 @@
     int segs = 0;
     int fd = -1;
 
+    init_note_info(&info);
+
     errno = 0;
     getrlimit(RLIMIT_CORE, &dumpsize);
     if (dumpsize.rlim_cur == 0)
diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h
index f080305..c8f7302 100644
--- a/linux-user/i386/syscall_nr.h
+++ b/linux-user/i386/syscall_nr.h
@@ -347,3 +347,9 @@
 #define TARGET_NR_open_by_handle_at     342
 #define TARGET_NR_clock_adjtime         343
 #define TARGET_NR_syncfs                344
+#define TARGET_NR_sendmmsg              345
+#define TARGET_NR_setns                 346
+#define TARGET_NR_process_vm_readv      347
+#define TARGET_NR_process_vm_writev     348
+#define TARGET_NR_kcmp                  349
+#define TARGET_NR_finit_module          350
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 7381012..309fb21 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -77,6 +77,7 @@
      IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
      IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
      IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
+     IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
 #ifdef FIBMAP
      IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
 #endif
diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h
index 4d0937e..25f8521 100644
--- a/linux-user/m68k/syscall_nr.h
+++ b/linux-user/m68k/syscall_nr.h
@@ -344,3 +344,8 @@
 #define TARGET_NR_open_by_handle_at     341
 #define TARGET_NR_clock_adjtime         342
 #define TARGET_NR_syncfs                343
+#define TARGET_NR_setns                 344
+#define TARGET_NR_process_vm_readv      345
+#define TARGET_NR_process_vm_writev     346
+#define TARGET_NR_kcmp                  347
+#define TARGET_NR_finit_module          348
diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h
index f1fe0e7..6f530f9 100644
--- a/linux-user/microblaze/syscall_nr.h
+++ b/linux-user/microblaze/syscall_nr.h
@@ -376,4 +376,9 @@
 #define TARGET_NR_open_by_handle_at     372
 #define TARGET_NR_clock_adjtime         373
 #define TARGET_NR_syncfs                374
-
+#define TARGET_NR_setns                 375
+#define TARGET_NR_sendmmsg              376
+#define TARGET_NR_process_vm_readv      377
+#define TARGET_NR_process_vm_writev     378
+#define TARGET_NR_kcmp                  379
+#define TARGET_NR_finit_module          380
diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index fbdc348..2d1a13e 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -345,3 +345,9 @@
 #define TARGET_NR_open_by_handle_at     (TARGET_NR_Linux + 340)
 #define TARGET_NR_clock_adjtime         (TARGET_NR_Linux + 341)
 #define TARGET_NR_syncfs                (TARGET_NR_Linux + 342)
+#define TARGET_NR_sendmmsg              (TARGET_NR_Linux + 343)
+#define TARGET_NR_setns                 (TARGET_NR_Linux + 344)
+#define TARGET_NR_process_vm_readv      (TARGET_NR_Linux + 345)
+#define TARGET_NR_process_vm_writev     (TARGET_NR_Linux + 346)
+#define TARGET_NR_kcmp                  (TARGET_NR_Linux + 347)
+#define TARGET_NR_finit_module          (TARGET_NR_Linux + 348)
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index 0f4a6b1..004232a 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -310,6 +310,12 @@
 #define TARGET_NR_open_by_handle_at     (TARGET_NR_Linux + 304)
 #define TARGET_NR_clock_adjtime         (TARGET_NR_Linux + 305)
 #define TARGET_NR_syncfs                (TARGET_NR_Linux + 306)
+#define TARGET_NR_sendmmsg              (TARGET_NR_Linux + 307)
+#define TARGET_NR_setns                 (TARGET_NR_Linux + 308)
+#define TARGET_NR_process_vm_readv      (TARGET_NR_Linux + 309)
+#define TARGET_NR_process_vm_writev     (TARGET_NR_Linux + 310)
+#define TARGET_NR_kcmp                  (TARGET_NR_Linux + 311)
+#define TARGET_NR_finit_module          (TARGET_NR_Linux + 312)
 #else
 /*
  * Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -617,4 +623,11 @@
 #define TARGET_NR_open_by_handle_at     (TARGET_NR_Linux + 299)
 #define TARGET_NR_clock_adjtime         (TARGET_NR_Linux + 300)
 #define TARGET_NR_syncfs                (TARGET_NR_Linux + 301)
+#define TARGET_NR_sendmmsg              (TARGET_NR_Linux + 302)
+#define TARGET_NR_setns                 (TARGET_NR_Linux + 303)
+#define TARGET_NR_process_vm_readv      (TARGET_NR_Linux + 304)
+#define TARGET_NR_process_vm_writev     (TARGET_NR_Linux + 305)
+#define TARGET_NR_kcmp                  (TARGET_NR_Linux + 306)
+#define TARGET_NR_finit_module          (TARGET_NR_Linux + 307)
+#define TARGET_NR_getdents64            (TARGET_NR_Linux + 308)
 #endif
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
index f4ac91e..4c386ea 100644
--- a/linux-user/openrisc/syscall_nr.h
+++ b/linux-user/openrisc/syscall_nr.h
@@ -378,9 +378,13 @@
 #define TARGET_NR_syncfs 267
 #define TARGET_NR_setns 268
 #define TARGET_NR_sendmmsg 269
+#define TARGET_NR_process_vm_readv 270
+#define TARGET_NR_process_vm_writev 271
+#define TARGET_NR_kcmp 272
+#define TARGET_NR_finit_module 273
 
 #undef TARGET_NR_syscalls
-#define TARGET_NR_syscalls 270
+#define TARGET_NR_syscalls 274
 
 /*
  * All syscalls below here should go away really,
diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h
index 0673b7d..1e1736e 100644
--- a/linux-user/ppc/syscall_nr.h
+++ b/linux-user/ppc/syscall_nr.h
@@ -362,3 +362,9 @@
 #define TARGET_NR_open_by_handle_at     346
 #define TARGET_NR_clock_adjtime         347
 #define TARGET_NR_syncfs                348
+#define TARGET_NR_sendmmsg              349
+#define TARGET_NR_setns                 350
+#define TARGET_NR_process_vm_readv      351
+#define TARGET_NR_process_vm_writev     352
+#define TARGET_NR_finit_module          353
+#define TARGET_NR_kcmp                  354
diff --git a/linux-user/s390x/syscall_nr.h b/linux-user/s390x/syscall_nr.h
index d4529ac..7c0b8b2 100644
--- a/linux-user/s390x/syscall_nr.h
+++ b/linux-user/s390x/syscall_nr.h
@@ -265,6 +265,12 @@
 #define TARGET_NR_open_by_handle_at     336
 #define TARGET_NR_clock_adjtime         337
 #define TARGET_NR_syncfs                338
+#define TARGET_NR_setns                 339
+#define TARGET_NR_process_vm_readv      340
+#define TARGET_NR_process_vm_writev     341
+#define TARGET_NR_s390_runtime_instr    342
+#define TARGET_NR_kcmp                  343
+#define TARGET_NR_finit_module          344
 
 /*
  * There are some system calls that are not present on 64 bit, some
@@ -355,4 +361,3 @@
 #define TARGET_NR_newfstatat		293
 
 #endif
-
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 365db58..bdf8742 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -366,3 +366,9 @@
 #define TARGET_NR_open_by_handle_at     360
 #define TARGET_NR_clock_adjtime         361
 #define TARGET_NR_syncfs                362
+#define TARGET_NR_sendmmsg              363
+#define TARGET_NR_setns                 364
+#define TARGET_NR_process_vm_readv      365
+#define TARGET_NR_process_vm_writev     366
+#define TARGET_NR_kcmp                  367
+#define TARGET_NR_finit_module          368
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 82e8592..04638e2 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -420,6 +420,7 @@
      * it to arrive. */
     sigfillset(&act.sa_mask);
     act.sa_handler = SIG_DFL;
+    act.sa_flags = 0;
     sigaction(host_sig, &act, NULL);
 
     /* For some reason raise(host_sig) doesn't send the signal when
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index 534e6e9..181cd32 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -302,3 +302,10 @@
 #define TARGET_NR_open_by_handle_at     333
 #define TARGET_NR_clock_adjtime         334
 #define TARGET_NR_syncfs                335
+#define TARGET_NR_sendmmsg              336
+#define TARGET_NR_setns                 337
+#define TARGET_NR_process_vm_readv      338
+#define TARGET_NR_process_vm_writev     339
+#define TARGET_NR_kern_features         340
+#define TARGET_NR_kcmp                  341
+#define TARGET_NR_finit_module          342
diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h
index 70988b2..34a984c 100644
--- a/linux-user/sparc64/syscall_nr.h
+++ b/linux-user/sparc64/syscall_nr.h
@@ -334,3 +334,10 @@
 #define TARGET_NR_open_by_handle_at     333
 #define TARGET_NR_clock_adjtime         334
 #define TARGET_NR_syncfs                335
+#define TARGET_NR_sendmmsg              336
+#define TARGET_NR_setns                 337
+#define TARGET_NR_process_vm_readv      338
+#define TARGET_NR_process_vm_writev     339
+#define TARGET_NR_kern_features         340
+#define TARGET_NR_kcmp                  341
+#define TARGET_NR_finit_module          342
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f370087..1407b7a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -107,6 +107,7 @@
 #include <linux/reboot.h>
 #include <linux/route.h>
 #include <linux/filter.h>
+#include <linux/blkpg.h>
 #include "linux_loop.h"
 #include "cpu-uname.h"
 
@@ -1707,6 +1708,7 @@
     struct iovec *vec;
     abi_ulong total_len, max_len;
     int i;
+    int err = 0;
 
     if (count == 0) {
         errno = 0;
@@ -1726,7 +1728,7 @@
     target_vec = lock_user(VERIFY_READ, target_addr,
                            count * sizeof(struct target_iovec), 1);
     if (target_vec == NULL) {
-        errno = EFAULT;
+        err = EFAULT;
         goto fail2;
     }
 
@@ -1740,7 +1742,7 @@
         abi_long len = tswapal(target_vec[i].iov_len);
 
         if (len < 0) {
-            errno = EINVAL;
+            err = EINVAL;
             goto fail;
         } else if (len == 0) {
             /* Zero length pointer is ignored.  */
@@ -1748,7 +1750,7 @@
         } else {
             vec[i].iov_base = lock_user(type, base, len, copy);
             if (!vec[i].iov_base) {
-                errno = EFAULT;
+                err = EFAULT;
                 goto fail;
             }
             if (len > max_len - total_len) {
@@ -1763,9 +1765,10 @@
     return vec;
 
  fail:
-    free(vec);
- fail2:
     unlock_user(target_vec, target_addr, 0);
+ fail2:
+    free(vec);
+    errno = err;
     return NULL;
 }
 
@@ -2427,10 +2430,15 @@
     nsems = semid_ds.sem_nsems;
 
     *host_array = malloc(nsems*sizeof(unsigned short));
+    if (!*host_array) {
+        return -TARGET_ENOMEM;
+    }
     array = lock_user(VERIFY_READ, target_addr,
                       nsems*sizeof(unsigned short), 1);
-    if (!array)
+    if (!array) {
+        free(*host_array);
         return -TARGET_EFAULT;
+    }
 
     for(i=0; i<nsems; i++) {
         __get_user((*host_array)[i], &array[i]);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index ae30476..3c8869e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -901,6 +901,7 @@
 #define TARGET_BLKSECTSET TARGET_IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
 #define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
 #define TARGET_BLKSSZGET  TARGET_IO(0x12,104)/* get block device sector size */
+#define TARGET_BLKPG      TARGET_IO(0x12,105)/* Partition table and disk geometry handling */
 /* A jump here: 108-111 have been used for various private purposes. */
 #define TARGET_BLKBSZGET  TARGET_IOR(0x12, 112, abi_ulong)
 #define TARGET_BLKBSZSET  TARGET_IOW(0x12, 113, abi_ulong)
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 44b6a58..9d0c92d 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -240,3 +240,16 @@
        TYPE_INT, /* fm_mapped_extents */
        TYPE_INT, /* fm_extent_count */
        TYPE_INT) /* fm_reserved */
+
+STRUCT(blkpg_partition,
+       TYPE_LONGLONG, /* start */
+       TYPE_LONGLONG, /* length */
+       TYPE_INT, /* pno */
+       MK_ARRAY(TYPE_CHAR, BLKPG_DEVNAMELTH), /* devname */
+       MK_ARRAY(TYPE_CHAR, BLKPG_VOLNAMELTH)) /* volname */
+
+STRUCT(blkpg_ioctl_arg,
+       TYPE_INT, /* op */
+       TYPE_INT, /* flags */
+       TYPE_INT, /* datalen */
+       MK_PTR(MK_STRUCT(STRUCT_blkpg_partition))) /* data */
diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h
index 947e961..7c59e3a 100644
--- a/linux-user/x86_64/syscall_nr.h
+++ b/linux-user/x86_64/syscall_nr.h
@@ -305,3 +305,10 @@
 #define TARGET_NR_open_by_handle_at     304
 #define TARGET_NR_clock_adjtime         305
 #define TARGET_NR_syncfs                306
+#define TARGET_NR_sendmmsg              307
+#define TARGET_NR_setns                 308
+#define TARGET_NR_getcpu                309
+#define TARGET_NR_process_vm_readv      310
+#define TARGET_NR_process_vm_writev     311
+#define TARGET_NR_kcmp                  312
+#define TARGET_NR_finit_module          313
diff --git a/monitor.c b/monitor.c
index 690c152..de90fba 100644
--- a/monitor.c
+++ b/monitor.c
@@ -56,6 +56,7 @@
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/json-streamer.h"
 #include "qapi/qmp/json-parser.h"
+#include <qom/object_interfaces.h>
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "trace.h"
@@ -4254,6 +4255,87 @@
     return (p != NULL ? ++p : typestr);
 }
 
+static void device_add_completion(ReadLineState *rs, const char *str)
+{
+    GSList *list, *elt;
+    size_t len;
+
+    len = strlen(str);
+    readline_set_completion_index(rs, len);
+    list = elt = object_class_get_list(TYPE_DEVICE, false);
+    while (elt) {
+        const char *name;
+        DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
+                                             TYPE_DEVICE);
+        name = object_class_get_name(OBJECT_CLASS(dc));
+        if (!strncmp(name, str, len)) {
+            readline_add_completion(rs, name);
+        }
+        elt = elt->next;
+    }
+    g_slist_free(list);
+}
+
+static void object_add_completion(ReadLineState *rs, const char *str)
+{
+    GSList *list, *elt;
+    size_t len;
+
+    len = strlen(str);
+    readline_set_completion_index(rs, len);
+    list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
+    while (elt) {
+        const char *name;
+
+        name = object_class_get_name(OBJECT_CLASS(elt->data));
+        if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) {
+            readline_add_completion(rs, name);
+        }
+        elt = elt->next;
+    }
+    g_slist_free(list);
+}
+
+static void device_del_completion(ReadLineState *rs, BusState *bus,
+                                  const char *str, size_t len)
+{
+    BusChild *kid;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
+        BusState *dev_child;
+
+        if (dev->id && !strncmp(str, dev->id, len)) {
+            readline_add_completion(rs, dev->id);
+        }
+
+        QLIST_FOREACH(dev_child, &dev->child_bus, sibling) {
+            device_del_completion(rs, dev_child, str, len);
+        }
+    }
+}
+
+static void object_del_completion(ReadLineState *rs, const char *str)
+{
+    ObjectPropertyInfoList *list, *start;
+    size_t len;
+
+    len = strlen(str);
+    readline_set_completion_index(rs, len);
+
+    start = list = qmp_qom_list("/objects", NULL);
+    while (list) {
+        ObjectPropertyInfo *info = list->value;
+
+        if (!strncmp(info->type, "child<", 5)
+            && !strncmp(info->name, str, len)) {
+            readline_add_completion(rs, info->name);
+        }
+        list = list->next;
+    }
+    qapi_free_ObjectPropertyInfoList(start);
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
                                              const mon_cmd_t *cmd_table,
                                              char **args,
@@ -4317,6 +4399,13 @@
             readline_set_completion_index(mon->rs, strlen(str));
             bdrv_iterate(block_completion_it, &mbs);
             break;
+        case 'O':
+            if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
+                device_add_completion(mon->rs, str);
+            } else if (!strcmp(cmd->name, "object_add") && nb_args == 2) {
+                object_add_completion(mon->rs, str);
+            }
+            break;
         case 's':
         case 'S':
             if (!strcmp(cmd->name, "sendkey")) {
@@ -4330,6 +4419,12 @@
             } else if (!strcmp(cmd->name, "help|?")) {
                 monitor_find_completion_by_table(mon, cmd_table,
                                                  &args[1], nb_args - 1);
+            } else if (!strcmp(cmd->name, "device_del") && nb_args == 2) {
+                size_t len = strlen(str);
+                readline_set_completion_index(mon->rs, len);
+                device_del_completion(mon->rs, sysbus_get_default(), str, len);
+            } else if (!strcmp(cmd->name, "object_del") && nb_args == 2) {
+                object_del_completion(mon->rs, str);
             }
             break;
         default:
diff --git a/net/net.c b/net/net.c
index 2c3af20..41b3883 100644
--- a/net/net.c
+++ b/net/net.c
@@ -882,7 +882,7 @@
     qemu_opt_set(opts, "type", device);
 
     net_client_init(opts, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         monitor_printf(mon, "adding host network device %s failed\n", device);
@@ -918,17 +918,17 @@
     QemuOpts *opts;
 
     opts_list = qemu_find_opts_err("netdev", &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         goto exit_err;
     }
 
     opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         goto exit_err;
     }
 
     netdev_add(opts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qemu_opts_del(opts);
         goto exit_err;
     }
@@ -1152,7 +1152,7 @@
     Error *local_err = NULL;
 
     net_client_init(opts, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
@@ -1167,7 +1167,7 @@
     int ret;
 
     ret = net_client_init(opts, 1, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
diff --git a/qapi-schema.json b/qapi-schema.json
index 7cfb5e5..473c096 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -28,7 +28,65 @@
   'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
             'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
 
+
 ##
+# LostTickPolicy:
+#
+# Policy for handling lost ticks in timer devices.
+#
+# @discard: throw away the missed tick(s) and continue with future injection
+#           normally.  Guest time may be delayed, unless the OS has explicit
+#           handling of lost ticks
+#
+# @delay: continue to deliver ticks at the normal rate.  Guest time will be
+#         delayed due to the late tick
+#
+# @merge: merge the missed tick(s) into one tick and inject.  Guest time
+#         may be delayed, depending on how the OS reacts to the merging
+#         of ticks
+#
+# @slew: deliver ticks at a higher rate to catch up with the missed tick. The
+#        guest time should not be delayed once catchup is complete.
+#
+# Since: 2.0
+##
+{ 'enum': 'LostTickPolicy',
+  'data': ['discard', 'delay', 'merge', 'slew' ] }
+
+##
+# BiosAtaTranslation:
+#
+# Policy that BIOS should use to interpret cylinder/head/sector
+# addresses.  Note that Bochs BIOS and SeaBIOS will not actually
+# translate logical CHS to physical; instead, they will use logical
+# block addressing.
+#
+# @auto: If cylinder/heads/sizes are passed, choose between none and LBA
+#        depending on the size of the disk.  If they are not passed,
+#        choose none if QEMU can guess that the disk had 16 or fewer
+#        heads, large if QEMU can guess that the disk had 131072 or
+#        fewer tracks across all heads (i.e. cylinders*heads<131072),
+#        otherwise LBA.
+#
+# @none: The physical disk geometry is equal to the logical geometry.
+#
+# @lba: Assume 63 sectors per track and one of 16, 32, 64, 128 or 255
+#       heads (if fewer than 255 are enough to cover the whole disk
+#       with 1024 cylinders/head).  The number of cylinders/head is
+#       then computed based on the number of sectors and heads.
+#
+# @large: The number of cylinders per head is scaled down to 1024
+#         by correspondingly scaling up the number of heads.
+#
+# @rechs: Same as @large, but first convert a 16-head geometry to
+#         15-head, by proportionally scaling up the number of
+#         cylinders/head.
+#
+# Since: 2.0
+##
+{ 'enum': 'BiosAtaTranslation',
+  'data': ['auto', 'none', 'lba', 'large', 'rechs']}
+
 # @add_client
 #
 # Allow client connections for VNC, Spice and socket based
@@ -437,6 +495,28 @@
 { 'command': 'query-chardev', 'returns': ['ChardevInfo'] }
 
 ##
+# @ChardevBackendInfo:
+#
+# Information about a character device backend
+#
+# @name: The backend name
+#
+# Since: 2.0
+##
+{ 'type': 'ChardevBackendInfo', 'data': {'name': 'str'} }
+
+##
+# @query-chardev-backends:
+#
+# Returns information about character device backends.
+#
+# Returns: a list of @ChardevBackendInfo
+#
+# Since: 2.0
+##
+{ 'command': 'query-chardev-backends', 'returns': ['ChardevBackendInfo'] }
+
+##
 # @DataFormat:
 #
 # An enumeration of data format.
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8f1bc41..793548a 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -14,6 +14,7 @@
 #include "qapi/string-input-visitor.h"
 #include "qapi/visitor-impl.h"
 #include "qapi/qmp/qerror.h"
+#include "qemu/option.h"
 
 struct StringInputVisitor
 {
@@ -41,6 +42,28 @@
     *obj = val;
 }
 
+static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
+                            Error **errp)
+{
+    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+    Error *err = NULL;
+    uint64_t val;
+
+    if (siv->string) {
+        parse_option_size(name, siv->string, &val, &err);
+    } else {
+        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+                  "size");
+        return;
+    }
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    *obj = val;
+}
+
 static void parse_type_bool(Visitor *v, bool *obj, const char *name,
                             Error **errp)
 {
@@ -128,6 +151,7 @@
 
     v->visitor.type_enum = input_type_enum;
     v->visitor.type_int = parse_type_int;
+    v->visitor.type_size = parse_type_size;
     v->visitor.type_bool = parse_type_bool;
     v->visitor.type_str = parse_type_str;
     v->visitor.type_number = parse_type_number;
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index 921653d..fb1d2e8 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -14,10 +14,13 @@
 #include "qapi/string-output-visitor.h"
 #include "qapi/visitor-impl.h"
 #include "qapi/qmp/qerror.h"
+#include "qemu/host-utils.h"
+#include <math.h>
 
 struct StringOutputVisitor
 {
     Visitor visitor;
+    bool human;
     char *string;
 };
 
@@ -31,7 +34,45 @@
                            Error **errp)
 {
     StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
-    string_output_set(sov, g_strdup_printf("%lld", (long long) *obj));
+    char *out;
+
+    if (sov->human) {
+        out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
+    } else {
+        out = g_strdup_printf("%lld", (long long) *obj);
+    }
+    string_output_set(sov, out);
+}
+
+static void print_type_size(Visitor *v, uint64_t *obj, const char *name,
+                           Error **errp)
+{
+    StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
+    static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E' };
+    uint64_t div, val;
+    char *out;
+    int i;
+
+    if (!sov->human) {
+        out = g_strdup_printf("%"PRIu64, *obj);
+        string_output_set(sov, out);
+        return;
+    }
+
+    val = *obj;
+
+    /* The exponent (returned in i) minus one gives us
+     * floor(log2(val * 1024 / 1000).  The correction makes us
+     * switch to the higher power when the integer part is >= 1000.
+     */
+    frexp(val / (1000.0 / 1024.0), &i);
+    i = (i - 1) / 10;
+    assert(i < ARRAY_SIZE(suffixes));
+    div = 1ULL << (i * 10);
+
+    out = g_strdup_printf("%"PRIu64" (%0.3g %c%s)", val,
+                          (double)val/div, suffixes[i], i ? "iB" : "");
+    string_output_set(sov, out);
 }
 
 static void print_type_bool(Visitor *v, bool *obj, const char *name,
@@ -45,7 +86,14 @@
                            Error **errp)
 {
     StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
-    string_output_set(sov, g_strdup(*obj ? *obj : ""));
+    char *out;
+
+    if (sov->human) {
+        out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup("<null>");
+    } else {
+        out = g_strdup(*obj ? *obj : "");
+    }
+    string_output_set(sov, out);
 }
 
 static void print_type_number(Visitor *v, double *obj, const char *name,
@@ -73,14 +121,16 @@
     g_free(sov);
 }
 
-StringOutputVisitor *string_output_visitor_new(void)
+StringOutputVisitor *string_output_visitor_new(bool human)
 {
     StringOutputVisitor *v;
 
     v = g_malloc0(sizeof(*v));
 
+    v->human = human;
     v->visitor.type_enum = output_type_enum;
     v->visitor.type_int = print_type_int;
+    v->visitor.type_size = print_type_size;
     v->visitor.type_bool = print_type_bool;
     v->visitor.type_str = print_type_str;
     v->visitor.type_number = print_type_number;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 1d3b68d..3a7dc0d 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -145,7 +145,7 @@
 
 static int set_property(const char *name, const char *value, void *opaque)
 {
-    DeviceState *dev = opaque;
+    Object *obj = opaque;
     Error *err = NULL;
 
     if (strcmp(name, "driver") == 0)
@@ -153,7 +153,7 @@
     if (strcmp(name, "bus") == 0)
         return 0;
 
-    qdev_prop_parse(dev, name, value, &err);
+    object_property_parse(obj, value, name, &err);
     if (err != NULL) {
         qerror_report_err(err);
         error_free(err);
@@ -577,7 +577,7 @@
         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
         } else {
-            value = object_property_print(OBJECT(dev), props->name, &err);
+            value = object_property_print(OBJECT(dev), props->name, true, &err);
         }
         g_free(legacy_name);
 
@@ -656,7 +656,7 @@
     DeviceState *dev;
 
     opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
diff --git a/qemu-char.c b/qemu-char.c
index 30c5a6a..4d50838 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2725,7 +2725,7 @@
 
     chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
                                   is_waitconnect, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         goto fail;
     }
     return chr;
@@ -2938,7 +2938,7 @@
     Error *local_err = NULL;
 
     opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return NULL;
@@ -3323,7 +3323,7 @@
         return NULL;
 
     chr = qemu_chr_new_from_opts(opts, init, &err);
-    if (error_is_set(&err)) {
+    if (err) {
         error_report("%s", error_get_pretty(err));
         error_free(err);
     }
@@ -3432,6 +3432,25 @@
     return chr_list;
 }
 
+ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
+{
+    ChardevBackendInfoList *backend_list = NULL;
+    CharDriver *c = NULL;
+    GSList *i = NULL;
+
+    for (i = backends; i; i = i->next) {
+        ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
+        c = i->data;
+        info->value = g_malloc0(sizeof(*info->value));
+        info->value->name = g_strdup(c->name);
+
+        info->next = backend_list;
+        backend_list = info;
+    }
+
+    return backend_list;
+}
+
 CharDriverState *qemu_chr_find(const char *name)
 {
     CharDriverState *chr;
diff --git a/qemu-img.c b/qemu-img.c
index c989850..0927b09 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -419,7 +419,7 @@
 
     bdrv_img_create(filename, fmt, base_filename, base_fmt,
                     options, img_size, BDRV_O_FLAGS, &local_err, quiet);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_report("%s: %s", filename, error_get_pretty(local_err));
         error_free(local_err);
         return 1;
@@ -1289,7 +1289,7 @@
 
         bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err);
     }
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_report("Failed to load snapshot: %s",
                      error_get_pretty(local_err));
         error_free(local_err);
@@ -1775,7 +1775,7 @@
         }
 
         bdrv_query_image_info(bs, &info, &err);
-        if (error_is_set(&err)) {
+        if (err) {
             error_report("%s", error_get_pretty(err));
             error_free(err);
             goto err;
@@ -2184,7 +2184,7 @@
 
     case SNAPSHOT_DELETE:
         bdrv_snapshot_delete_by_id_or_name(bs, snapshot_name, &err);
-        if (error_is_set(&err)) {
+        if (err) {
             error_report("Could not delete snapshot '%s': (%s)",
                          snapshot_name, error_get_pretty(err));
             error_free(err);
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 8100bee..cae4171 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -108,7 +108,7 @@
     }
 
     ga_wait_child(pid, &status, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return;
     }
@@ -181,7 +181,7 @@
     }
 
     ga_wait_child(pid, &status, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
@@ -669,7 +669,7 @@
     }
 
     ga_wait_child(pid, &status, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return;
     }
@@ -713,14 +713,14 @@
     slog("guest-fsfreeze called");
 
     execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return -1;
     }
 
     QTAILQ_INIT(&mounts);
     build_fs_mount_list(&mounts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return -1;
     }
@@ -780,7 +780,7 @@
 
     QTAILQ_INIT(&mounts);
     build_fs_mount_list(&mounts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return 0;
     }
@@ -861,7 +861,7 @@
 
     QTAILQ_INIT(&mounts);
     build_fs_mount_list(&mounts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         return;
     }
@@ -957,7 +957,7 @@
     }
 
     ga_wait_child(pid, &status, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         goto out;
     }
@@ -1034,7 +1034,7 @@
     }
 
     ga_wait_child(pid, &status, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(err, local_err);
         goto out;
     }
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index a6a0af2..50094dd 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -197,7 +197,7 @@
 
 error:
     qmp_guest_fsfreeze_thaw(&local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         g_debug("cleanup thaw: %s", error_get_pretty(local_err));
         error_free(local_err);
     }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index cce6b81..8a0e832 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1924,6 +1924,47 @@
     },
 
 SQMP
+query-chardev-backends
+-------------
+
+List available character device backends.
+
+Each backend is represented by a json-object, the returned value is a json-array
+of all backends.
+
+Each json-object contains:
+
+- "name": backend name (json-string)
+
+Example:
+
+-> { "execute": "query-chardev-backends" }
+<- {
+      "return":[
+         {
+            "name":"udp"
+         },
+         {
+            "name":"tcp"
+         },
+         {
+            "name":"unix"
+         },
+         {
+            "name":"spiceport"
+         }
+      ]
+   }
+
+EQMP
+
+    {
+        .name       = "query-chardev-backends",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_query_chardev_backends,
+    },
+
+SQMP
 query-block
 -----------
 
diff --git a/qom/object.c b/qom/object.c
index 62e7e41..660859c 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -948,13 +948,13 @@
     string_input_visitor_cleanup(mi);
 }
 
-char *object_property_print(Object *obj, const char *name,
+char *object_property_print(Object *obj, const char *name, bool human,
                             Error **errp)
 {
     StringOutputVisitor *mo;
     char *string;
 
-    mo = string_output_visitor_new();
+    mo = string_output_visitor_new(human);
     object_property_get(obj, string_output_get_visitor(mo), name, errp);
     string = string_output_get_string(mo);
     string_output_visitor_cleanup(mo);
diff --git a/qtest.c b/qtest.c
index a738afc..ae941d6 100644
--- a/qtest.c
+++ b/qtest.c
@@ -507,12 +507,18 @@
     return 0;
 }
 
-void qtest_init(const char *qtest_chrdev, const char *qtest_log)
+void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
 {
     CharDriverState *chr;
 
     chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
 
+    if (chr == NULL) {
+        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
+                   qtest_chrdev);
+        return;
+    }
+
     qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
     qemu_chr_fe_set_echo(chr, true);
 
diff --git a/savevm.c b/savevm.c
index a7dbe18..7329fc5 100644
--- a/savevm.c
+++ b/savevm.c
@@ -880,7 +880,7 @@
         if (bdrv_can_snapshot(bs) &&
             bdrv_snapshot_find(bs, snapshot, name) >= 0) {
             bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
-            if (error_is_set(&err)) {
+            if (err) {
                 monitor_printf(mon,
                                "Error while deleting snapshot on device '%s':"
                                " %s\n",
@@ -1115,7 +1115,7 @@
     while ((bs1 = bdrv_next(bs1))) {
         if (bdrv_can_snapshot(bs1)) {
             bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
-            if (error_is_set(&err)) {
+            if (err) {
                 monitor_printf(mon,
                                "Error while deleting snapshot on device '%s':"
                                " %s\n",
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index d6b420f..d374b35 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -31,6 +31,7 @@
 # (QEMU)
 
 import qmp
+import json
 import readline
 import sys
 import pprint
@@ -107,6 +108,8 @@
                     value = True
                 elif opt[1] == 'false':
                     value = False
+                elif opt[1].startswith('{'):
+                    value = json.loads(opt[1])
                 else:
                     value = opt[1]
             qmpcmd['arguments'][opt[0]] = value
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index ea36995..41c1c75 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -18,76 +18,65 @@
 
 PUBLIC = True
 
-
 def c(events):
-    out('#include <ust/marker.h>',
-        '#undef mutex_lock',
-        '#undef mutex_unlock',
-        '#undef inline',
-        '#undef wmb',
-        '#include "trace.h"')
-
-    for e in events:
-        argnames = ", ".join(e.args.names())
-        if len(e.args) > 0:
-            argnames = ', ' + argnames
-
-            out('DEFINE_TRACE(ust_%(name)s);',
-                '',
-                'static void ust_%(name)s_probe(%(args)s)',
-                '{',
-                '    trace_mark(ust, %(name)s, %(fmt)s%(argnames)s);',
-                '}',
-                name = e.name,
-                args = e.args,
-                fmt = e.fmt,
-                argnames = argnames,
-                )
-
-        else:
-            out('DEFINE_TRACE(ust_%(name)s);',
-                '',
-                'static void ust_%(name)s_probe(%(args)s)',
-                '{',
-                '    trace_mark(ust, %(name)s, UST_MARKER_NOARGS);',
-                '}',
-                name = e.name,
-                args = e.args,
-                )
-
-    # register probes
-    out('',
-        'static void __attribute__((constructor)) trace_init(void)',
-        '{')
-
-    for e in events:
-        out('    register_trace_ust_%(name)s(ust_%(name)s_probe);',
-            name = e.name,
-            )
-
-    out('}')
+    pass
 
 
 def h(events):
-    out('#include <ust/tracepoint.h>',
-        '#undef mutex_lock',
-        '#undef mutex_unlock',
-        '#undef inline',
-        '#undef wmb')
+    out('#include <lttng/tracepoint.h>',
+        '#include "trace/generated-ust-provider.h"',
+        '')
+    for e in events:
+        argnames = ", ".join(e.args.names())
+        if len(e.args) > 0:
+            argnames = ", " + argnames
 
+        out('static inline void trace_%(name)s(%(args)s)',
+            '{',
+            '    tracepoint(qemu, %(name)s%(tp_args)s);',
+            '}',
+            '',
+            name = e.name,
+            args = e.args,
+            tp_args = argnames,
+            )
+
+def ust_events_c(events):
+    pass
+
+def ust_events_h(events):
     for e in events:
         if len(e.args) > 0:
-            out('DECLARE_TRACE(ust_%(name)s, TP_PROTO(%(args)s), TP_ARGS(%(argnames)s));',
-                '#define trace_%(name)s trace_ust_%(name)s',
+            out('TRACEPOINT_EVENT(',
+                '   qemu,',
+                '   %(name)s,',
+                '   TP_ARGS(%(args)s),',
+                '   TP_FIELDS(',
                 name = e.name,
-                args = e.args,
-                argnames = ", ".join(e.args.names()),
+                args = ", ".join(", ".join(i) for i in e.args),
                 )
 
+            for t,n in e.args:
+                if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
+                    out('       ctf_integer(' + t + ', ' + n + ', ' + n + ')')
+                elif ('double' in t) or ('float' in t):
+                    out('       ctf_float(' + t + ', ' + n + ', ' + n + ')')
+                elif ('char *' in t) or ('char*' in t):
+                    out('       ctf_string(' + n + ', ' + n + ')')
+                elif ('void *' in t) or ('void*' in t):
+                    out('       ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
+
+            out('   )',
+                ')',
+                '')
+
         else:
-            out('_DECLARE_TRACEPOINT_NOARGS(ust_%(name)s);',
-                '#define trace_%(name)s trace_ust_%(name)s',
+            out('TRACEPOINT_EVENT(',
+                '   qemu,',
+                '   %(name)s,',
+                '   TP_ARGS(void),',
+                '   TP_FIELDS()',
+                ')',
+                '',
                 name = e.name,
-                )
-
-    out()
+                )
\ No newline at end of file
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
new file mode 100644
index 0000000..116e713
--- /dev/null
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .c for LTTng ust event description.
+"""
+
+__author__     = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__copyright__  = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefanha@redhat.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+    out('/* This file is autogenerated by tracetool, do not edit. */',
+        '',
+        '#define TRACEPOINT_DEFINE',
+        '#define TRACEPOINT_CREATE_PROBES',
+        '',
+        '/* If gcc version 4.7 or older is used, LTTng ust gives a warning when compiling with',
+        '   -Wredundant-decls.',
+        ' */',
+        '#pragma GCC diagnostic ignored "-Wredundant-decls"',
+        '',
+        '#include "generated-ust-provider.h"')
diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py
new file mode 100644
index 0000000..f206eca
--- /dev/null
+++ b/scripts/tracetool/format/ust_events_h.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .h for LTTng ust event description.
+"""
+
+__author__     = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__copyright__  = "Copyright 2012, Mohamad Gebai <mohamad.gebai@polymtl.ca>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefanha@redhat.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+    out('/* This file is autogenerated by tracetool, do not edit. */',
+        '',
+        '#undef TRACEPOINT_PROVIDER',
+        '#define TRACEPOINT_PROVIDER qemu',
+        '',
+        '#undef TRACEPOINT_INCLUDE_FILE',
+        '#define TRACEPOINT_INCLUDE_FILE ./generated-ust-provider.h',
+        '',
+        '#if !defined (TRACE__GENERATED_UST_H) || defined(TRACEPOINT_HEADER_MULTI_READ)',
+        '#define TRACE__GENERATED_UST_H',
+        '',
+        '#include "qemu-common.h"',
+        '#include <lttng/tracepoint.h>',
+        '',
+        '/*',
+        ' * LTTng ust 2.0 does not allow you to use TP_ARGS(void) for tracepoints',
+        ' * requiring no arguments. We define these macros introduced in more recent'
+        ' * versions of LTTng ust as a workaround',
+        ' */',
+        '#ifndef _TP_EXPROTO1',
+        '#define _TP_EXPROTO1(a)               void',
+        '#endif',
+        '#ifndef _TP_EXDATA_PROTO1',
+        '#define _TP_EXDATA_PROTO1(a)          void *__tp_data',
+        '#endif',
+        '#ifndef _TP_EXDATA_VAR1',
+        '#define _TP_EXDATA_VAR1(a)            __tp_data',
+        '#endif',
+        '#ifndef _TP_EXVAR1',
+        '#define _TP_EXVAR1(a)',
+        '#endif',
+        '')
+
+def end(events):
+    out('#endif /* TRACE__GENERATED_UST_H */',
+        '',
+        '/* This part must be outside ifdef protection */',
+        '#include <lttng/tracepoint-event.h>')
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b0f2279..5dd2450 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6284,6 +6284,7 @@
     case 0xe5:
         ot = mo_b_d32(b, dflag);
         val = cpu_ldub_code(env, s->pc++);
+        tcg_gen_movi_tl(cpu_T[0], val);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
         if (use_icount)
@@ -6300,6 +6301,7 @@
     case 0xe7:
         ot = mo_b_d32(b, dflag);
         val = cpu_ldub_code(env, s->pc++);
+        tcg_gen_movi_tl(cpu_T[0], val);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      svm_is_rep(prefixes));
         gen_op_mov_v_reg(ot, cpu_T[1], R_EAX);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index c030a20..445c360 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7960,6 +7960,17 @@
     return 0;
 }
 
+static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
+{
+#ifdef TARGET_PPCEMB
+    return pcc->mmu_model == POWERPC_MMU_BOOKE ||
+           pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
+           pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
+#else
+    return true;
+#endif
+}
+
 static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -7991,8 +8002,8 @@
     }
 
 #if defined(TARGET_PPCEMB)
-    if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
-        error_setg(errp, "CPU does not possess a BookE MMU. "
+    if (!ppc_cpu_is_valid(pcc)) {
+        error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
                    "Please use qemu-system-ppc or qemu-system-ppc64 instead "
                    "or choose another CPU model.");
         return;
@@ -8209,11 +8220,9 @@
         return -1;
     }
 
-#if defined(TARGET_PPCEMB)
-    if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+    if (!ppc_cpu_is_valid(pcc)) {
         return -1;
     }
-#endif
 
     return pcc->pvr == pvr ? 0 : -1;
 }
@@ -8246,11 +8255,10 @@
         return -1;
     }
 
-#if defined(TARGET_PPCEMB)
-    if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+    if (!ppc_cpu_is_valid(pcc)) {
         return -1;
     }
-#endif
+
     ret = (((pcc->pvr & pcc->pvr_mask) == (pvr & pcc->pvr_mask)) ? 0 : -1);
 
     return ret;
@@ -8275,14 +8283,10 @@
 {
     ObjectClass *oc = (ObjectClass *)a;
     const char *name = b;
-#if defined(TARGET_PPCEMB)
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-#endif
 
     if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
-#if defined(TARGET_PPCEMB)
-        pcc->mmu_model == POWERPC_MMU_BOOKE &&
-#endif
+        ppc_cpu_is_valid(pcc) &&
         strcmp(object_class_get_name(oc) + strlen(name),
                "-" TYPE_POWERPC_CPU) == 0) {
         return 0;
@@ -8414,11 +8418,9 @@
     char *name;
     int i;
 
-#if defined(TARGET_PPCEMB)
-    if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+    if (!ppc_cpu_is_valid(pcc)) {
         return;
     }
-#endif
     if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
         return;
     }
@@ -8466,13 +8468,11 @@
     const char *typename;
     CpuDefinitionInfoList *entry;
     CpuDefinitionInfo *info;
-#if defined(TARGET_PPCEMB)
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
 
-    if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+    if (!ppc_cpu_is_valid(pcc)) {
         return;
     }
-#endif
 
     typename = object_class_get_name(oc);
     info = g_malloc0(sizeof(*info));
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 82658a1..c8884b3 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1866,7 +1866,7 @@
                             SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
                             SHIFT_IMM_LSL(0));
         } else {
-            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[1], 0x20);
+            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[2], 0x20);
             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
                             SHIFT_REG_ROR(TCG_REG_TMP));
         }
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 5d4cf93..f832282 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -88,6 +88,11 @@
 #endif
 };
 
+/* Constants we accept.  */
+#define TCG_CT_CONST_S32 0x100
+#define TCG_CT_CONST_U32 0x200
+#define TCG_CT_CONST_I32 0x400
+
 /* Registers used with L constraint, which are the first argument 
    registers on x86_64, and two random call clobbered registers on
    i386. */
@@ -110,7 +115,7 @@
    is available.  */
 #if TCG_TARGET_REG_BITS == 64
 # define have_cmov 1
-#elif defined(CONFIG_CPUID_H)
+#elif defined(CONFIG_CPUID_H) && defined(bit_CMOV)
 static bool have_cmov;
 #else
 # define have_cmov 0
@@ -124,6 +129,16 @@
 # define have_movbe 0
 #endif
 
+/* We need this symbol in tcg-target.h, and we can't properly conditionalize
+   it there.  Therefore we always define the variable.  */
+bool have_bmi1;
+
+#if defined(CONFIG_CPUID_H) && defined(bit_BMI2)
+static bool have_bmi2;
+#else
+# define have_bmi2 0
+#endif
+
 static uint8_t *tb_ret_addr;
 
 static void patch_reloc(uint8_t *code_ptr, int type,
@@ -166,6 +181,7 @@
         tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
         break;
     case 'c':
+    case_c:
         ct->ct |= TCG_CT_REG;
         tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
         break;
@@ -194,6 +210,7 @@
         tcg_regset_set32(ct->u.regs, 0, 0xf);
         break;
     case 'r':
+    case_r:
         ct->ct |= TCG_CT_REG;
         if (TCG_TARGET_REG_BITS == 64) {
             tcg_regset_set32(ct->u.regs, 0, 0xffff);
@@ -201,6 +218,13 @@
             tcg_regset_set32(ct->u.regs, 0, 0xff);
         }
         break;
+    case 'C':
+        /* With SHRX et al, we need not use ECX as shift count register.  */
+        if (have_bmi2) {
+            goto case_r;
+        } else {
+            goto case_c;
+        }
 
         /* qemu_ld/st address constraint */
     case 'L':
@@ -220,6 +244,9 @@
     case 'Z':
         ct->ct |= TCG_CT_CONST_U32;
         break;
+    case 'I':
+        ct->ct |= TCG_CT_CONST_I32;
+        break;
 
     default:
         return -1;
@@ -243,6 +270,9 @@
     if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
+        return 1;
+    }
     return 0;
 }
 
@@ -268,10 +298,13 @@
 # define P_REXB_RM	0
 # define P_GS           0
 #endif
+#define P_SIMDF3        0x10000         /* 0xf3 opcode prefix */
+#define P_SIMDF2        0x20000         /* 0xf2 opcode prefix */
 
 #define OPC_ARITH_EvIz	(0x81)
 #define OPC_ARITH_EvIb	(0x83)
 #define OPC_ARITH_GvEv	(0x03)		/* ... plus (ARITH_FOO << 3) */
+#define OPC_ANDN        (0xf2 | P_EXT38)
 #define OPC_ADD_GvEv	(OPC_ARITH_GvEv | (ARITH_ADD << 3))
 #define OPC_BSWAP	(0xc8 | P_EXT)
 #define OPC_CALL_Jz	(0xe8)
@@ -309,6 +342,9 @@
 #define OPC_SHIFT_1	(0xd1)
 #define OPC_SHIFT_Ib	(0xc1)
 #define OPC_SHIFT_cl	(0xd3)
+#define OPC_SARX        (0xf7 | P_EXT38 | P_SIMDF3)
+#define OPC_SHLX        (0xf7 | P_EXT38 | P_DATA16)
+#define OPC_SHRX        (0xf7 | P_EXT38 | P_SIMDF2)
 #define OPC_TESTL	(0x85)
 #define OPC_XCHG_ax_r32	(0x90)
 
@@ -398,9 +434,9 @@
 
     rex = 0;
     rex |= (opc & P_REXW) ? 0x8 : 0x0;  /* REX.W */
-    rex |= (r & 8) >> 1;		/* REX.R */
-    rex |= (x & 8) >> 2;		/* REX.X */
-    rex |= (rm & 8) >> 3;		/* REX.B */
+    rex |= (r & 8) >> 1;                /* REX.R */
+    rex |= (x & 8) >> 2;                /* REX.X */
+    rex |= (rm & 8) >> 3;               /* REX.B */
 
     /* P_REXB_{R,RM} indicates that the given register is the low byte.
        For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
@@ -449,6 +485,48 @@
     tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
 }
 
+static void tcg_out_vex_modrm(TCGContext *s, int opc, int r, int v, int rm)
+{
+    int tmp;
+
+    if ((opc & (P_REXW | P_EXT | P_EXT38)) || (rm & 8)) {
+        /* Three byte VEX prefix.  */
+        tcg_out8(s, 0xc4);
+
+        /* VEX.m-mmmm */
+        if (opc & P_EXT38) {
+            tmp = 2;
+        } else if (opc & P_EXT) {
+            tmp = 1;
+        } else {
+            tcg_abort();
+        }
+        tmp |= 0x40;                       /* VEX.X */
+        tmp |= (r & 8 ? 0 : 0x80);         /* VEX.R */
+        tmp |= (rm & 8 ? 0 : 0x20);        /* VEX.B */
+        tcg_out8(s, tmp);
+
+        tmp = (opc & P_REXW ? 0x80 : 0);   /* VEX.W */
+    } else {
+        /* Two byte VEX prefix.  */
+        tcg_out8(s, 0xc5);
+
+        tmp = (r & 8 ? 0 : 0x80);          /* VEX.R */
+    }
+    /* VEX.pp */
+    if (opc & P_DATA16) {
+        tmp |= 1;                          /* 0x66 */
+    } else if (opc & P_SIMDF3) {
+        tmp |= 2;                          /* 0xf3 */
+    } else if (opc & P_SIMDF2) {
+        tmp |= 3;                          /* 0xf2 */
+    }
+    tmp |= (~v & 15) << 3;                 /* VEX.vvvv */
+    tcg_out8(s, tmp);
+    tcg_out8(s, opc);
+    tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
+}
+
 /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
    We handle either RM and INDEX missing with a negative value.  In 64-bit
    mode for absolute addresses, ~RM is the size of the immediate operand
@@ -1638,7 +1716,7 @@
 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
                               const TCGArg *args, const int *const_args)
 {
-    int c, rexw = 0;
+    int c, vexop, rexw = 0;
 
 #if TCG_TARGET_REG_BITS == 64
 # define OP_32_64(x) \
@@ -1774,6 +1852,16 @@
         }
         break;
 
+    OP_32_64(andc):
+        if (const_args[2]) {
+            tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32,
+                        args[0], args[1]);
+            tgen_arithi(s, ARITH_AND + rexw, args[0], ~args[2], 0);
+        } else {
+            tcg_out_vex_modrm(s, OPC_ANDN + rexw, args[0], args[2], args[1]);
+        }
+        break;
+
     OP_32_64(mul):
         if (const_args[2]) {
             int32_t val;
@@ -1799,19 +1887,28 @@
 
     OP_32_64(shl):
         c = SHIFT_SHL;
-        goto gen_shift;
+        vexop = OPC_SHLX;
+        goto gen_shift_maybe_vex;
     OP_32_64(shr):
         c = SHIFT_SHR;
-        goto gen_shift;
+        vexop = OPC_SHRX;
+        goto gen_shift_maybe_vex;
     OP_32_64(sar):
         c = SHIFT_SAR;
-        goto gen_shift;
+        vexop = OPC_SARX;
+        goto gen_shift_maybe_vex;
     OP_32_64(rotl):
         c = SHIFT_ROL;
         goto gen_shift;
     OP_32_64(rotr):
         c = SHIFT_ROR;
         goto gen_shift;
+    gen_shift_maybe_vex:
+        if (have_bmi2 && !const_args[2]) {
+            tcg_out_vex_modrm(s, vexop + rexw, args[0], args[2], args[1]);
+            break;
+        }
+        /* FALLTHRU */
     gen_shift:
         if (const_args[2]) {
             tcg_out_shifti(s, c + rexw, args[0], args[2]);
@@ -2002,10 +2099,11 @@
     { INDEX_op_and_i32, { "r", "0", "ri" } },
     { INDEX_op_or_i32, { "r", "0", "ri" } },
     { INDEX_op_xor_i32, { "r", "0", "ri" } },
+    { INDEX_op_andc_i32, { "r", "r", "ri" } },
 
-    { INDEX_op_shl_i32, { "r", "0", "ci" } },
-    { INDEX_op_shr_i32, { "r", "0", "ci" } },
-    { INDEX_op_sar_i32, { "r", "0", "ci" } },
+    { INDEX_op_shl_i32, { "r", "0", "Ci" } },
+    { INDEX_op_shr_i32, { "r", "0", "Ci" } },
+    { INDEX_op_sar_i32, { "r", "0", "Ci" } },
     { INDEX_op_rotl_i32, { "r", "0", "ci" } },
     { INDEX_op_rotr_i32, { "r", "0", "ci" } },
 
@@ -2059,10 +2157,11 @@
     { INDEX_op_and_i64, { "r", "0", "reZ" } },
     { INDEX_op_or_i64, { "r", "0", "re" } },
     { INDEX_op_xor_i64, { "r", "0", "re" } },
+    { INDEX_op_andc_i64, { "r", "r", "rI" } },
 
-    { INDEX_op_shl_i64, { "r", "0", "ci" } },
-    { INDEX_op_shr_i64, { "r", "0", "ci" } },
-    { INDEX_op_sar_i64, { "r", "0", "ci" } },
+    { INDEX_op_shl_i64, { "r", "0", "Ci" } },
+    { INDEX_op_shr_i64, { "r", "0", "Ci" } },
+    { INDEX_op_sar_i64, { "r", "0", "Ci" } },
     { INDEX_op_rotl_i64, { "r", "0", "ci" } },
     { INDEX_op_rotr_i64, { "r", "0", "ci" } },
 
@@ -2196,23 +2295,34 @@
 
 static void tcg_target_init(TCGContext *s)
 {
-#if !(defined(have_cmov) && defined(have_movbe))
-    {
-        unsigned a, b, c, d;
-        int ret = __get_cpuid(1, &a, &b, &c, &d);
+#ifdef CONFIG_CPUID_H
+    unsigned a, b, c, d;
+    int max = __get_cpuid_max(0, 0);
 
-# ifndef have_cmov
+    if (max >= 1) {
+        __cpuid(1, a, b, c, d);
+#ifndef have_cmov
         /* For 32-bit, 99% certainty that we're running on hardware that
            supports cmov, but we still need to check.  In case cmov is not
            available, we'll use a small forward branch.  */
-        have_cmov = ret && (d & bit_CMOV);
-# endif
-
-# ifndef have_movbe
+        have_cmov = (d & bit_CMOV) != 0;
+#endif
+#ifndef have_movbe
         /* MOVBE is only available on Intel Atom and Haswell CPUs, so we
            need to probe for it.  */
-        have_movbe = ret && (c & bit_MOVBE);
-# endif
+        have_movbe = (c & bit_MOVBE) != 0;
+#endif
+    }
+
+    if (max >= 7) {
+        /* BMI1 is available on AMD Piledriver and Intel Haswell CPUs.  */
+        __cpuid_count(7, 0, a, b, c, d);
+#ifdef bit_BMI
+        have_bmi1 = (b & bit_BMI) != 0;
+#endif
+#ifndef have_bmi2
+        have_bmi2 = (b & bit_BMI2) != 0;
+#endif
     }
 #endif
 
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 92c0fcd..bdf2222 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -64,9 +64,6 @@
     TCG_REG_RDI = TCG_REG_EDI,
 } TCGReg;
 
-#define TCG_CT_CONST_S32 0x100
-#define TCG_CT_CONST_U32 0x200
-
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_ESP 
 #define TCG_TARGET_STACK_ALIGN 16
@@ -76,6 +73,8 @@
 #define TCG_TARGET_CALL_STACK_OFFSET 0
 #endif
 
+extern bool have_bmi1;
+
 /* optional instructions */
 #define TCG_TARGET_HAS_div2_i32         1
 #define TCG_TARGET_HAS_rot_i32          1
@@ -87,7 +86,7 @@
 #define TCG_TARGET_HAS_bswap32_i32      1
 #define TCG_TARGET_HAS_neg_i32          1
 #define TCG_TARGET_HAS_not_i32          1
-#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_andc_i32         have_bmi1
 #define TCG_TARGET_HAS_orc_i32          0
 #define TCG_TARGET_HAS_eqv_i32          0
 #define TCG_TARGET_HAS_nand_i32         0
@@ -115,7 +114,7 @@
 #define TCG_TARGET_HAS_bswap64_i64      1
 #define TCG_TARGET_HAS_neg_i64          1
 #define TCG_TARGET_HAS_not_i64          1
-#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_andc_i64         have_bmi1
 #define TCG_TARGET_HAS_orc_i64          0
 #define TCG_TARGET_HAS_eqv_i64          0
 #define TCG_TARGET_HAS_nand_i64         0
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 89e2d6a..7777743 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -655,11 +655,68 @@
                 }
             }
             break;
+        CASE_OP_32_64(xor):
+        CASE_OP_32_64(nand):
+            if (temps[args[1]].state != TCG_TEMP_CONST
+                && temps[args[2]].state == TCG_TEMP_CONST
+                && temps[args[2]].val == -1) {
+                i = 1;
+                goto try_not;
+            }
+            break;
+        CASE_OP_32_64(nor):
+            if (temps[args[1]].state != TCG_TEMP_CONST
+                && temps[args[2]].state == TCG_TEMP_CONST
+                && temps[args[2]].val == 0) {
+                i = 1;
+                goto try_not;
+            }
+            break;
+        CASE_OP_32_64(andc):
+            if (temps[args[2]].state != TCG_TEMP_CONST
+                && temps[args[1]].state == TCG_TEMP_CONST
+                && temps[args[1]].val == -1) {
+                i = 2;
+                goto try_not;
+            }
+            break;
+        CASE_OP_32_64(orc):
+        CASE_OP_32_64(eqv):
+            if (temps[args[2]].state != TCG_TEMP_CONST
+                && temps[args[1]].state == TCG_TEMP_CONST
+                && temps[args[1]].val == 0) {
+                i = 2;
+                goto try_not;
+            }
+            break;
+        try_not:
+            {
+                TCGOpcode not_op;
+                bool have_not;
+
+                if (def->flags & TCG_OPF_64BIT) {
+                    not_op = INDEX_op_not_i64;
+                    have_not = TCG_TARGET_HAS_not_i64;
+                } else {
+                    not_op = INDEX_op_not_i32;
+                    have_not = TCG_TARGET_HAS_not_i32;
+                }
+                if (!have_not) {
+                    break;
+                }
+                s->gen_opc_buf[op_index] = not_op;
+                reset_temp(args[0]);
+                gen_args[0] = args[0];
+                gen_args[1] = args[i];
+                args += 3;
+                gen_args += 2;
+                continue;
+            }
         default:
             break;
         }
 
-        /* Simplify expression for "op r, a, 0 => mov r, a" cases */
+        /* Simplify expression for "op r, a, const => mov r, a" cases */
         switch (op) {
         CASE_OP_32_64(add):
         CASE_OP_32_64(sub):
@@ -670,28 +727,38 @@
         CASE_OP_32_64(rotr):
         CASE_OP_32_64(or):
         CASE_OP_32_64(xor):
-            if (temps[args[1]].state == TCG_TEMP_CONST) {
-                /* Proceed with possible constant folding. */
-                break;
-            }
-            if (temps[args[2]].state == TCG_TEMP_CONST
+        CASE_OP_32_64(andc):
+            if (temps[args[1]].state != TCG_TEMP_CONST
+                && temps[args[2]].state == TCG_TEMP_CONST
                 && temps[args[2]].val == 0) {
-                if (temps_are_copies(args[0], args[1])) {
-                    s->gen_opc_buf[op_index] = INDEX_op_nop;
-                } else {
-                    s->gen_opc_buf[op_index] = op_to_mov(op);
-                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
-                    gen_args += 2;
-                }
-                args += 3;
-                continue;
+                goto do_mov3;
             }
             break;
+        CASE_OP_32_64(and):
+        CASE_OP_32_64(orc):
+        CASE_OP_32_64(eqv):
+            if (temps[args[1]].state != TCG_TEMP_CONST
+                && temps[args[2]].state == TCG_TEMP_CONST
+                && temps[args[2]].val == -1) {
+                goto do_mov3;
+            }
+            break;
+        do_mov3:
+            if (temps_are_copies(args[0], args[1])) {
+                s->gen_opc_buf[op_index] = INDEX_op_nop;
+            } else {
+                s->gen_opc_buf[op_index] = op_to_mov(op);
+                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+                gen_args += 2;
+            }
+            args += 3;
+            continue;
         default:
             break;
         }
 
-        /* Simplify using known-zero bits */
+        /* Simplify using known-zero bits. Currently only ops with a single
+           output argument is supported. */
         mask = -1;
         affected = -1;
         switch (op) {
@@ -726,16 +793,36 @@
             mask = temps[args[1]].mask & mask;
             break;
 
-        CASE_OP_32_64(sar):
+        CASE_OP_32_64(andc):
+            /* Known-zeros does not imply known-ones.  Therefore unless
+               args[2] is constant, we can't infer anything from it.  */
             if (temps[args[2]].state == TCG_TEMP_CONST) {
-                mask = ((tcg_target_long)temps[args[1]].mask
-                        >> temps[args[2]].val);
+                mask = ~temps[args[2]].mask;
+                goto and_const;
+            }
+            /* But we certainly know nothing outside args[1] may be set. */
+            mask = temps[args[1]].mask;
+            break;
+
+        case INDEX_op_sar_i32:
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = (int32_t)temps[args[1]].mask >> temps[args[2]].val;
+            }
+            break;
+        case INDEX_op_sar_i64:
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = (int64_t)temps[args[1]].mask >> temps[args[2]].val;
             }
             break;
 
-        CASE_OP_32_64(shr):
+        case INDEX_op_shr_i32:
             if (temps[args[2]].state == TCG_TEMP_CONST) {
-                mask = temps[args[1]].mask >> temps[args[2]].val;
+                mask = (uint32_t)temps[args[1]].mask >> temps[args[2]].val;
+            }
+            break;
+        case INDEX_op_shr_i64:
+            if (temps[args[2]].state == TCG_TEMP_CONST) {
+                mask = (uint64_t)temps[args[1]].mask >> temps[args[2]].val;
             }
             break;
 
@@ -769,10 +856,40 @@
             mask = temps[args[3]].mask | temps[args[4]].mask;
             break;
 
+        CASE_OP_32_64(ld8u):
+        case INDEX_op_qemu_ld8u:
+            mask = 0xff;
+            break;
+        CASE_OP_32_64(ld16u):
+        case INDEX_op_qemu_ld16u:
+            mask = 0xffff;
+            break;
+        case INDEX_op_ld32u_i64:
+#if TCG_TARGET_REG_BITS == 64
+        case INDEX_op_qemu_ld32u:
+#endif
+            mask = 0xffffffffu;
+            break;
+
+        CASE_OP_32_64(qemu_ld):
+            {
+                TCGMemOp mop = args[def->nb_oargs + def->nb_iargs];
+                if (!(mop & MO_SIGN)) {
+                    mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1;
+                }
+            }
+            break;
+
         default:
             break;
         }
 
+        /* 32-bit ops (non 64-bit ops and non load/store ops) generate 32-bit
+           results */
+        if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_64BIT))) {
+            mask &= 0xffffffffu;
+        }
+
         if (mask == 0) {
             assert(def->nb_oargs == 1);
             s->gen_opc_buf[op_index] = op_to_movi(op);
@@ -839,6 +956,7 @@
 
         /* Simplify expression for "op r, a, a => movi r, 0" cases */
         switch (op) {
+        CASE_OP_32_64(andc):
         CASE_OP_32_64(sub):
         CASE_OP_32_64(xor):
             if (temps_are_copies(args[1], args[2])) {
@@ -1140,6 +1258,11 @@
             } else {
                 for (i = 0; i < def->nb_oargs; i++) {
                     reset_temp(args[i]);
+                    /* Save the corresponding known-zero bits mask for the
+                       first output argument (only one supported so far). */
+                    if (i == 0) {
+                        temps[args[i]].mask = mask;
+                    }
                 }
             }
             for (i = 0; i < def->nb_args; i++) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index acd02b9..ffc851e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -526,7 +526,7 @@
             ts->temp_local = temp_local;
             ts->name = NULL;
             ts++;
-            ts->base_type = TCG_TYPE_I32;
+            ts->base_type = type;
             ts->type = TCG_TYPE_I32;
             ts->temp_allocated = 1;
             ts->temp_local = temp_local;
diff --git a/tests/Makefile b/tests/Makefile
index 9a7d2f1..b17d41e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,5 +1,9 @@
 export SRC_PATH
 
+# Get the list of all supported sysemu targets
+SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
+   $(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
+
 check-unit-y = tests/check-qdict$(EXESUF)
 gcov-files-check-qdict-y = qobject/qdict.c
 check-unit-y += tests/check-qfloat$(EXESUF)
@@ -60,64 +64,78 @@
 
 # All QTests for now are POSIX-only, but the dependencies are
 # really in libqtest, not in the testcases themselves.
+
+gcov-files-ipack-y += hw/ipack/ipack.c
+check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
+gcov-files-ipack-y += hw/char/ipoctal232.c
+
+gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
+check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
+
+check-qtest-pci-y += tests/e1000-test$(EXESUF)
+gcov-files-pci-y += hw/net/e1000.c
+check-qtest-pci-y += tests/rtl8139-test$(EXESUF)
+gcov-files-pci-y += hw/net/rtl8139.c
+check-qtest-pci-y += tests/pcnet-test$(EXESUF)
+gcov-files-pci-y += hw/net/pcnet.c
+gcov-files-pci-y += hw/net/pcnet-pci.c
+check-qtest-pci-y += tests/eepro100-test$(EXESUF)
+gcov-files-pci-y += hw/net/eepro100.c
+check-qtest-pci-y += tests/ne2000-test$(EXESUF)
+gcov-files-pci-y += hw/net/ne2000.c
+check-qtest-pci-y += $(check-qtest-virtio-y)
+gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
+check-qtest-pci-y += tests/tpci200-test$(EXESUF)
+gcov-files-pci-y += hw/char/tpci200.c
+check-qtest-pci-y += $(check-qtest-ipack-y)
+gcov-files-pci-y += $(gcov-files-ipack-y) hw/ipack/tpci200.c
+
 check-qtest-i386-y = tests/endianness-test$(EXESUF)
 check-qtest-i386-y += tests/fdc-test$(EXESUF)
-gcov-files-i386-y = hw/fdc.c
+gcov-files-i386-y = hw/block/fdc.c
 check-qtest-i386-y += tests/ide-test$(EXESUF)
 check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
-gcov-files-i386-y += hw/hd-geometry.c
+gcov-files-i386-y += hw/block/hd-geometry.c
 check-qtest-i386-y += tests/boot-order-test$(EXESUF)
 check-qtest-i386-y += tests/acpi-test$(EXESUF)
 check-qtest-i386-y += tests/rtc-test$(EXESUF)
 check-qtest-i386-y += tests/i440fx-test$(EXESUF)
 check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
-check-qtest-i386-y += tests/qom-test$(EXESUF)
 check-qtest-i386-y += tests/blockdev-test$(EXESUF)
 check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF)
+check-qtest-i386-y += $(check-qtest-pci-y)
+gcov-files-i386-y += $(gcov-files-pci-y)
+check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
+gcov-files-i386-y += hw/net/vmxnet3.c
+gcov-files-i386-y += hw/net/vmxnet_rx_pkt.c
+gcov-files-i386-y += hw/net/vmxnet_tx_pkt.c
 check-qtest-x86_64-y = $(check-qtest-i386-y)
-gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c
+gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
 check-qtest-mips-y = tests/endianness-test$(EXESUF)
 check-qtest-mips64-y = tests/endianness-test$(EXESUF)
 check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
-check-qtest-mips-y += tests/qom-test$(EXESUF)
-check-qtest-mipsel-y += tests/qom-test$(EXESUF)
-check-qtest-mips64-y += tests/qom-test$(EXESUF)
-check-qtest-mips64el-y += tests/qom-test$(EXESUF)
 check-qtest-ppc-y = tests/endianness-test$(EXESUF)
 check-qtest-ppc64-y = tests/endianness-test$(EXESUF)
 check-qtest-sh4-y = tests/endianness-test$(EXESUF)
 check-qtest-sh4eb-y = tests/endianness-test$(EXESUF)
-check-qtest-sh4-y += tests/qom-test$(EXESUF)
-check-qtest-sh4eb-y += tests/qom-test$(EXESUF)
 check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
 #check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
 #check-qtest-sparc64-y += tests/m48t59-test$(EXESUF)
-gcov-files-sparc-y += hw/m48t59.c
-gcov-files-sparc64-y += hw/m48t59.c
-check-qtest-sparc-y += tests/qom-test$(EXESUF)
-check-qtest-sparc64-y += tests/qom-test$(EXESUF)
+gcov-files-sparc-y += hw/timer/m48t59.c
+gcov-files-sparc64-y += hw/timer/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
-gcov-files-arm-y += hw/tmp105.c
-check-qtest-arm-y += tests/qom-test$(EXESUF)
+gcov-files-arm-y += hw/misc/tmp105.c
 check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
-check-qtest-ppc-y += tests/qom-test$(EXESUF)
-check-qtest-ppc64-y += tests/qom-test$(EXESUF)
-check-qtest-ppcemb-y += tests/qom-test$(EXESUF)
-check-qtest-alpha-y += tests/qom-test$(EXESUF)
-check-qtest-cris-y += tests/qom-test$(EXESUF)
-check-qtest-lm32-y += tests/qom-test$(EXESUF)
-check-qtest-m68k-y += tests/qom-test$(EXESUF)
-check-qtest-microblaze-y += tests/qom-test$(EXESUF)
 check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
-check-qtest-moxie-y += tests/qom-test$(EXESUF)
-check-qtest-or32-y += tests/qom-test$(EXESUF)
-check-qtest-s390x-y += tests/qom-test$(EXESUF)
-check-qtest-unicore32-y += tests/qom-test$(EXESUF)
-check-qtest-xtensa-y += tests/qom-test$(EXESUF)
 check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
 
+# qom-test works for all sysemu architectures:
+$(foreach target,$(SYSEMU_TARGET_LIST), \
+    $(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF)))
+
 check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
         comments.json empty.json funny-char.json indented-expr.json \
         missing-colon.json missing-comma-list.json \
@@ -211,6 +229,15 @@
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
+tests/e1000-test$(EXESUF): tests/e1000-test.o
+tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o
+tests/pcnet-test$(EXESUF): tests/pcnet-test.o
+tests/eepro100-test$(EXESUF): tests/eepro100-test.o
+tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
+tests/ne2000-test$(EXESUF): tests/ne2000-test.o
+tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
+tests/tpci200-test$(EXESUF): tests/tpci200-test.o
+tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
 tests/qom-test$(EXESUF): tests/qom-test.o
 tests/blockdev-test$(EXESUF): tests/blockdev-test.o $(libqos-pc-obj-y)
 tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
diff --git a/tests/e1000-test.c b/tests/e1000-test.c
new file mode 100644
index 0000000..a8ba2fc
--- /dev/null
+++ b/tests/e1000-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for e1000 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/e1000/nop", nop);
+
+    qtest_start("-device e1000");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/eepro100-test.c b/tests/eepro100-test.c
new file mode 100644
index 0000000..bf82526
--- /dev/null
+++ b/tests/eepro100-test.c
@@ -0,0 +1,63 @@
+/*
+ * QTest testcase for eepro100 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+static void test_device(gconstpointer data)
+{
+    const char *model = data;
+    QTestState *s;
+    char *args;
+
+    args = g_strdup_printf("-device %s", model);
+    s = qtest_start(args);
+
+    /* Tests only initialization so far. TODO: Implement functional tests */
+
+    if (s) {
+        qtest_quit(s);
+    }
+    g_free(args);
+}
+
+static const char *models[] = {
+    "i82550",
+    "i82551",
+    "i82557a",
+    "i82557b",
+    "i82557c",
+    "i82558a",
+    "i82558b",
+    "i82559a",
+    "i82559b",
+    "i82559c",
+    "i82559er",
+    "i82562",
+    "i82801",
+};
+
+int main(int argc, char **argv)
+{
+    int i;
+
+    g_test_init(&argc, &argv, NULL);
+
+    for (i = 0; i < ARRAY_SIZE(models); i++) {
+        char *path;
+
+        path = g_strdup_printf("/%s/eepro100/%s",
+                               qtest_get_arch(), models[i]);
+        g_test_add_data_func(path, models[i], test_device);
+    }
+
+    return g_test_run();
+}
diff --git a/tests/endianness-test.c b/tests/endianness-test.c
index 646df7d..92e17d2 100644
--- a/tests/endianness-test.c
+++ b/tests/endianness-test.c
@@ -10,7 +10,6 @@
  * See the COPYING file in the top-level directory.
  *
  */
-#include "libqtest.h"
 
 #include <glib.h>
 #include <stdio.h>
@@ -18,6 +17,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "libqtest.h"
 #include "qemu/bswap.h"
 
 typedef struct TestCase TestCase;
diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c
index e4f355ce3..5c8f8d6 100644
--- a/tests/fw_cfg-test.c
+++ b/tests/fw_cfg-test.c
@@ -10,15 +10,14 @@
  * See the COPYING file in the top-level directory.
  */
 
-#define NO_QEMU_PROTOS
-
-#include "libqtest.h"
-#include "hw/nvram/fw_cfg.h"
-#include "libqos/fw_cfg.h"
-
 #include <string.h>
 #include <glib.h>
 
+#include "libqtest.h"
+#define NO_QEMU_PROTOS
+#include "hw/nvram/fw_cfg.h"
+#include "libqos/fw_cfg.h"
+
 static uint64_t ram_size = 128 << 20;
 static uint16_t nb_cpus = 1;
 static uint16_t max_cpus = 1;
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index bcd2181..ad232b5 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -12,12 +12,6 @@
  * See the COPYING file in the top-level directory.
  */
 
-#include "libqos/pci.h"
-#include "libqos/pci-pc.h"
-#include "libqtest.h"
-
-#include "hw/pci/pci_regs.h"
-
 #include <glib.h>
 #include <string.h>
 #include <stdio.h>
@@ -26,6 +20,11 @@
 #include <sys/mman.h>
 #include <stdlib.h>
 
+#include "libqtest.h"
+#include "libqos/pci.h"
+#include "libqos/pci-pc.h"
+#include "hw/pci/pci_regs.h"
+
 #define BROKEN 1
 
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
diff --git a/tests/ipoctal232-test.c b/tests/ipoctal232-test.c
new file mode 100644
index 0000000..3ac1714
--- /dev/null
+++ b/tests/ipoctal232-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for IndustryPack Octal-RS232
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/ipoctal232/tpci200/nop", nop);
+
+    qtest_start("-device tpci200,id=ipack0 -device ipoctal232,bus=ipack0.0");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/libqtest.c b/tests/libqtest.c
index c9a4f89..f587d36 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -43,8 +43,8 @@
     int qmp_fd;
     bool irq_level[MAX_IRQ];
     GString *rx;
-    int child_pid;   /* Child process created to execute QEMU */
-    pid_t qemu_pid;  /* QEMU process spawned by our child */
+    pid_t qemu_pid;  /* our child QEMU process */
+    struct sigaction sigact_old; /* restored on exit */
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -89,20 +89,17 @@
     return ret;
 }
 
-static pid_t read_pid_file(const char *pid_file)
+static void kill_qemu(QTestState *s)
 {
-    FILE *f;
-    char buffer[1024];
-    pid_t pid = -1;
-
-    f = fopen(pid_file, "r");
-    if (f) {
-        if (fgets(buffer, sizeof(buffer), f)) {
-            pid = atoi(buffer);
-        }
-        fclose(f);
+    if (s->qemu_pid != -1) {
+        kill(s->qemu_pid, SIGTERM);
+        waitpid(s->qemu_pid, NULL, 0);
     }
-    return pid;
+}
+
+static void sigabrt_handler(int signo)
+{
+    kill_qemu(global_qtest);
 }
 
 QTestState *qtest_init(const char *extra_args)
@@ -111,10 +108,9 @@
     int sock, qmpsock, i;
     gchar *socket_path;
     gchar *qmp_socket_path;
-    gchar *pid_file;
     gchar *command;
     const char *qemu_binary;
-    pid_t pid;
+    struct sigaction sigact;
 
     qemu_binary = getenv("QTEST_QEMU_BINARY");
     g_assert(qemu_binary != NULL);
@@ -123,22 +119,28 @@
 
     socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
     qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
-    pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
 
     sock = init_socket(socket_path);
     qmpsock = init_socket(qmp_socket_path);
 
-    pid = fork();
-    if (pid == 0) {
-        command = g_strdup_printf("%s "
+    /* Catch SIGABRT to clean up on g_assert() failure */
+    sigact = (struct sigaction){
+        .sa_handler = sigabrt_handler,
+        .sa_flags = SA_RESETHAND,
+    };
+    sigemptyset(&sigact.sa_mask);
+    sigaction(SIGABRT, &sigact, &s->sigact_old);
+
+    s->qemu_pid = fork();
+    if (s->qemu_pid == 0) {
+        command = g_strdup_printf("exec %s "
                                   "-qtest unix:%s,nowait "
                                   "-qtest-log /dev/null "
                                   "-qmp unix:%s,nowait "
-                                  "-pidfile %s "
                                   "-machine accel=qtest "
                                   "-display none "
                                   "%s", qemu_binary, socket_path,
-                                  qmp_socket_path, pid_file,
+                                  qmp_socket_path,
                                   extra_args ?: "");
         execlp("/bin/sh", "sh", "-c", command, NULL);
         exit(1);
@@ -152,7 +154,6 @@
     g_free(qmp_socket_path);
 
     s->rx = g_string_new("");
-    s->child_pid = pid;
     for (i = 0; i < MAX_IRQ; i++) {
         s->irq_level[i] = false;
     }
@@ -161,10 +162,6 @@
     qtest_qmp_discard_response(s, "");
     qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
 
-    s->qemu_pid = read_pid_file(pid_file);
-    unlink(pid_file);
-    g_free(pid_file);
-
     if (getenv("QTEST_STOP")) {
         kill(s->qemu_pid, SIGSTOP);
     }
@@ -174,13 +171,9 @@
 
 void qtest_quit(QTestState *s)
 {
-    int status;
+    sigaction(SIGABRT, &s->sigact_old, NULL);
 
-    if (s->qemu_pid != -1) {
-        kill(s->qemu_pid, SIGTERM);
-        waitpid(s->qemu_pid, &status, 0);
-    }
-
+    kill_qemu(s);
     close(s->fd);
     close(s->qmp_fd);
     g_string_free(s->rx, true);
diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c
index 6abc4c8..71b4f28 100644
--- a/tests/m48t59-test.c
+++ b/tests/m48t59-test.c
@@ -11,7 +11,6 @@
  * See the COPYING file in the top-level directory.
  *
  */
-#include "libqtest.h"
 
 #include <glib.h>
 #include <stdio.h>
@@ -19,6 +18,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "libqtest.h"
+
 #define RTC_SECONDS             0x9
 #define RTC_MINUTES             0xa
 #define RTC_HOURS               0xb
diff --git a/tests/ne2000-test.c b/tests/ne2000-test.c
new file mode 100644
index 0000000..61a678a
--- /dev/null
+++ b/tests/ne2000-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for ne2000 NIC
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/ne2000/pci/nop", pci_nop);
+
+    qtest_start("-device ne2k_pci");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/pcnet-test.c b/tests/pcnet-test.c
new file mode 100644
index 0000000..84af4f3
--- /dev/null
+++ b/tests/pcnet-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for PC-Net NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/pcnet/pci/nop", pci_nop);
+
+    qtest_start("-device pcnet");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/qom-test.c b/tests/qom-test.c
index 5e5af7a..b6671fb 100644
--- a/tests/qom-test.c
+++ b/tests/qom-test.c
@@ -6,250 +6,94 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
-#include "libqtest.h"
 
 #include <glib.h>
 #include <string.h>
-#include "qemu/osdep.h"
 
-static void test_nop(gconstpointer data)
+#include "libqtest.h"
+#include "qemu/osdep.h"
+#include "qapi/qmp/types.h"
+
+static const char *blacklist_x86[] = {
+    "xenfv", "xenpv", NULL
+};
+
+static const struct {
+    const char *arch;
+    const char **machine;
+} blacklists[] = {
+    { "i386", blacklist_x86 },
+    { "x86_64", blacklist_x86 },
+};
+
+static bool is_blacklisted(const char *arch, const char *mach)
 {
-    QTestState *s;
+    int i;
+    const char **p;
+
+    for (i = 0; i < ARRAY_SIZE(blacklists); i++) {
+        if (!strcmp(blacklists[i].arch, arch)) {
+            for (p = blacklists[i].machine; *p; p++) {
+                if (!strcmp(*p, mach)) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+static void test_machine(gconstpointer data)
+{
     const char *machine = data;
     char *args;
+    QDict *response;
 
     args = g_strdup_printf("-machine %s", machine);
-    s = qtest_start(args);
-    if (s) {
-        qtest_quit(s);
-    }
+    qtest_start(args);
+    response = qmp("{ 'execute': 'quit' }");
+    g_assert(qdict_haskey(response, "return"));
+    qtest_end();
     g_free(args);
 }
 
-static const char *x86_machines[] = {
-    "pc",
-    "isapc",
-    "q35",
-};
-
-static const char *alpha_machines[] = {
-    "clipper",
-};
-
-static const char *arm_machines[] = {
-    "integratorcp",
-    "versatilepb",
-    "versatileab",
-    "lm3s811evb",
-    "lm3s6965evb",
-    "collie",
-    "akita",
-    "spitz",
-    "borzoi",
-    "terrier",
-    "tosa",
-    "cheetah",
-    "sx1-v1",
-    "sx1",
-    "realview-eb",
-    "realview-eb-mpcore",
-    "realview-pb-a8",
-    "realview-pbx-a9",
-    "musicpal",
-    "mainstone",
-    "connex",
-    "verdex",
-    "z2",
-    "n800",
-    "n810",
-    "kzm",
-    "vexpress-a9",
-    "vexpress-a15",
-    "smdkc210",
-    "nuri",
-    "xilinx-zynq-a9",
-    "highbank",
-    "midway",
-    "canon-a1100",
-    "cubieboard",
-};
-
-static const char *cris_machines[] = {
-    "axis-dev88",
-};
-
-static const char *lm32_machines[] = {
-    "lm32-evr",
-    "lm32-uclinux",
-    "milkymist",
-};
-
-static const char *m68k_machines[] = {
-    "mcf5208evb",
-    "an5206",
-    "dummy",
-};
-
-static const char *microblaze_machines[] = {
-    "petalogix-ml605",
-    "petalogix-s3adsp1800",
-};
-
-static const char *mips_machines[] = {
-    "malta",
-    "magnum",
-    "mips",
-    "mipssim",
-    "pica61",
-};
-
-static const char *moxie_machines[] = {
-    "moxiesim",
-};
-
-static const char *openrisc_machines[] = {
-    "or32-sim",
-};
-
-static const char *ppc_machines[] = {
-    "g3beige",
-    "mac99",
-    "prep",
-    "mpc8544ds",
-    "ppce500",
-};
-
-static const char *ppc64_machines[] = {
-    "pseries",
-};
-
-static const char *ppc405_machines[] = {
-    "ref405ep",
-    "taihu",
-};
-
-static const char *ppc440_machines[] = {
-    "bamboo",
-    "virtex-ml507",
-};
-
-static const char *s390_machines[] = {
-    "s390-virtio",
-    "s390-ccw-virtio",
-};
-
-static const char *superh_machines[] = {
-    "r2d",
-    "shix",
-};
-
-static const char *sparc_machines[] = {
-    "SS-4",
-    "SS-5",
-    "SS-10",
-    "SS-20",
-    "SS-600MP",
-    "LX",
-    "SPARCClassic",
-    "SPARCbook",
-    "leon3_generic",
-};
-
-static const char *sparc64_machines[] = {
-    "sun4u",
-    "sun4v",
-    "Niagara",
-};
-
-static const char *unicore32_machines[] = {
-    "puv3",
-};
-
-static const char *xtensa_machines[] = {
-    "sim",
-    "lx60",
-    "lx200",
-};
-
-static void add_test_cases(const char *arch, const char *machine)
+static void add_machine_test_cases(void)
 {
-    char *path;
-    path = g_strdup_printf("/%s/qom/%s", arch, machine);
-    g_test_add_data_func(path, machine, test_nop);
-}
+    const char *arch = qtest_get_arch();
+    QDict *response, *minfo;
+    QList *list;
+    const QListEntry *p;
+    QObject *qobj;
+    QString *qstr;
+    const char *mname, *path;
 
-#define ADD_MACHINE_TESTS(arch, array) do { \
-    int i; \
-    for (i = 0; i < ARRAY_SIZE(array); i++) { \
-        add_test_cases((arch), (array)[i]); \
-    } \
-} while (false)
+    qtest_start("-machine none");
+    response = qmp("{ 'execute': 'query-machines' }");
+    g_assert(response);
+    list = qdict_get_qlist(response, "return");
+    g_assert(list);
+
+    for (p = qlist_first(list); p; p = qlist_next(p)) {
+        minfo = qobject_to_qdict(qlist_entry_obj(p));
+        g_assert(minfo);
+        qobj = qdict_get(minfo, "name");
+        g_assert(qobj);
+        qstr = qobject_to_qstring(qobj);
+        g_assert(qstr);
+        mname = qstring_get_str(qstr);
+        if (!is_blacklisted(arch, mname)) {
+            path = g_strdup_printf("/%s/qom/%s", arch, mname);
+            g_test_add_data_func(path, mname, test_machine);
+        }
+    }
+    qtest_end();
+}
 
 int main(int argc, char **argv)
 {
-    const char *arch = qtest_get_arch();
-
     g_test_init(&argc, &argv, NULL);
 
-    add_test_cases(arch, "none");
-
-    if (strcmp(arch, "i386") == 0 ||
-        strcmp(arch, "x86_64") == 0) {
-        ADD_MACHINE_TESTS(arch, x86_machines);
-    } else if (strcmp(arch, "alpha") == 0) {
-        ADD_MACHINE_TESTS(arch, alpha_machines);
-    } else if (strcmp(arch, "arm") == 0) {
-        ADD_MACHINE_TESTS(arch, arm_machines);
-    } else if (strcmp(arch, "cris") == 0) {
-        ADD_MACHINE_TESTS(arch, cris_machines);
-    } else if (strcmp(arch, "lm32") == 0) {
-        ADD_MACHINE_TESTS(arch, lm32_machines);
-    } else if (strcmp(arch, "m68k") == 0) {
-        ADD_MACHINE_TESTS(arch, m68k_machines);
-    } else if (strcmp(arch, "microblaze") == 0 ||
-               strcmp(arch, "microblazeel") == 0) {
-        ADD_MACHINE_TESTS(arch, microblaze_machines);
-    } else if (strcmp(arch, "mips") == 0 ||
-               strcmp(arch, "mipsel") == 0 ||
-               strcmp(arch, "mips64") == 0) {
-        ADD_MACHINE_TESTS(arch, mips_machines);
-    } else if (strcmp(arch, "mips64el") == 0) {
-        ADD_MACHINE_TESTS(arch, mips_machines);
-        add_test_cases(arch, "fulong2e");
-    } else if (strcmp(arch, "moxie") == 0) {
-        ADD_MACHINE_TESTS(arch, moxie_machines);
-    } else if (strcmp(arch, "or32") == 0) {
-        ADD_MACHINE_TESTS(arch, openrisc_machines);
-    } else if (strcmp(arch, "ppcemb") == 0) {
-#if 0
-        /* XXX Available in ppcemb but don't work */
-        ADD_MACHINE_TESTS(arch, ppc405_machines);
-#endif
-        ADD_MACHINE_TESTS(arch, ppc440_machines);
-    } else if (strcmp(arch, "ppc") == 0) {
-        ADD_MACHINE_TESTS(arch, ppc405_machines);
-        ADD_MACHINE_TESTS(arch, ppc440_machines);
-        ADD_MACHINE_TESTS(arch, ppc_machines);
-    } else if (strcmp(arch, "ppc64") == 0) {
-        ADD_MACHINE_TESTS(arch, ppc405_machines);
-        ADD_MACHINE_TESTS(arch, ppc440_machines);
-        ADD_MACHINE_TESTS(arch, ppc_machines);
-        ADD_MACHINE_TESTS(arch, ppc64_machines);
-    } else if (strcmp(arch, "s390x") == 0) {
-        ADD_MACHINE_TESTS(arch, s390_machines);
-    } else if (strcmp(arch, "sh4") == 0 ||
-               strcmp(arch, "sh4eb") == 0) {
-        ADD_MACHINE_TESTS(arch, superh_machines);
-    } else if (strcmp(arch, "sparc") == 0) {
-        ADD_MACHINE_TESTS(arch, sparc_machines);
-    } else if (strcmp(arch, "sparc64") == 0) {
-        ADD_MACHINE_TESTS(arch, sparc64_machines);
-    } else if (strcmp(arch, "unicore32") == 0) {
-        ADD_MACHINE_TESTS(arch, unicore32_machines);
-    } else if (strcmp(arch, "xtensa") == 0 ||
-               strcmp(arch, "xtensaeb") == 0) {
-        ADD_MACHINE_TESTS(arch, xtensa_machines);
-    }
+    add_machine_test_cases();
 
     return g_test_run();
 }
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index f1b123f..4243624 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -10,8 +10,6 @@
  * See the COPYING file in the top-level directory.
  *
  */
-#include "libqtest.h"
-#include "hw/timer/mc146818rtc_regs.h"
 
 #include <glib.h>
 #include <stdio.h>
@@ -19,6 +17,9 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "libqtest.h"
+#include "hw/timer/mc146818rtc_regs.h"
+
 static uint8_t base = 0x70;
 
 static int bcd2dec(int value)
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
new file mode 100644
index 0000000..f6a1be3
--- /dev/null
+++ b/tests/rtl8139-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for Realtek 8139 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/rtl8139/nop", nop);
+
+    qtest_start("-device rtl8139");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 6f68963..38bdf5e 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -92,7 +92,7 @@
     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 
     visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_free(p->string);
     g_free(p);
 }
@@ -107,7 +107,7 @@
     v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
 
     visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     qapi_free_UserDefNested(udp);
 }
 
@@ -121,7 +121,7 @@
     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 
     visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     qapi_free_UserDefOneList(head);
 }
 
@@ -135,7 +135,7 @@
     v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
 
     visit_type_UserDefUnion(v, &tmp, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     qapi_free_UserDefUnion(tmp);
 }
 
@@ -149,7 +149,7 @@
     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
 
     visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     if (p) {
         g_free(p->string);
     }
@@ -166,7 +166,7 @@
     v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
 
     visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     qapi_free_UserDefNested(udp);
 }
 
@@ -180,7 +180,7 @@
     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
 
     visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     qapi_free_UserDefOneList(head);
 }
 
@@ -194,7 +194,7 @@
     v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
 
     visit_type_UserDefUnion(v, &tmp, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     qapi_free_UserDefUnion(tmp);
 }
 
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 1e1c6fa..6eb7dc5 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -96,7 +96,7 @@
     v = visitor_input_test_init(data, "%" PRId64, value);
 
     visit_type_int(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, value);
 }
 
@@ -114,7 +114,7 @@
     v = visitor_input_test_init(data, "%f", DBL_MAX);
 
     visit_type_int(v, &res, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     error_free(errp);
 }
 
@@ -128,7 +128,7 @@
     v = visitor_input_test_init(data, "true");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, true);
 }
 
@@ -142,7 +142,7 @@
     v = visitor_input_test_init(data, "%f", value);
 
     visit_type_number(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpfloat(res, ==, value);
 }
 
@@ -156,7 +156,7 @@
     v = visitor_input_test_init(data, "%s", value);
 
     visit_type_str(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpstr(res, ==, value);
 
     g_free(res);
@@ -175,7 +175,7 @@
         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
 
         visit_type_EnumOne(v, &res, NULL, &errp);
-        g_assert(!error_is_set(&errp));
+        g_assert(!errp);
         g_assert_cmpint(i, ==, res);
 
         visitor_input_teardown(data, NULL);
@@ -223,7 +223,7 @@
     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 
     visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(p->integer, ==, -42);
     g_assert(p->boolean == true);
     g_assert_cmpstr(p->string, ==, "foo");
@@ -248,7 +248,7 @@
     v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
 
     visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
 
     check_and_free_str(udp->string0, "string0");
     check_and_free_str(udp->dict1.string1, "string1");
@@ -272,7 +272,7 @@
     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 
     visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert(head != NULL);
 
     for (i = 0, item = head; item; item = item->next, i++) {
@@ -601,7 +601,7 @@
     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
 
     visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(error_is_set(&errp));
+    g_assert(errp);
     g_assert(p->string == NULL);
 
     error_free(errp);
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index e073d83..f31d168 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -49,7 +49,7 @@
     QObject *obj;
 
     visit_type_int(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -67,7 +67,7 @@
     QObject *obj;
 
     visit_type_bool(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -85,7 +85,7 @@
     QObject *obj;
 
     visit_type_number(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -103,7 +103,7 @@
     QObject *obj;
 
     visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -122,7 +122,7 @@
 
     /* A null string should return "" */
     visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -141,7 +141,7 @@
 
     for (i = 0; i < ENUM_ONE_MAX; i++) {
         visit_type_EnumOne(data->ov, &i, "unused", &errp);
-        g_assert(!error_is_set(&errp));
+        g_assert(!errp);
 
         obj = qmp_output_get_qobject(data->qov);
         g_assert(obj != NULL);
@@ -161,7 +161,7 @@
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
         errp = NULL;
         visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
-        g_assert(error_is_set(&errp) == true);
+        g_assert(errp);
         error_free(errp);
     }
 }
@@ -198,7 +198,7 @@
     QDict *qdict;
 
     visit_type_TestStruct(data->ov, &p, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -241,7 +241,7 @@
     ud2->dict1.dict3.string3 = g_strdup(strings[3]);
 
     visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -288,7 +288,7 @@
         u.has_enum1 = true;
         u.enum1 = bad_values[i];
         visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
-        g_assert(error_is_set(&errp) == true);
+        g_assert(errp);
         error_free(errp);
     }
 }
@@ -343,7 +343,7 @@
     }
 
     visit_type_TestStructList(data->ov, &head, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 5989f81..d406263 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -60,7 +60,7 @@
     v = visitor_input_test_init(data, "-42");
 
     visit_type_int(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, value);
 }
 
@@ -74,42 +74,42 @@
     v = visitor_input_test_init(data, "true");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "yes");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "on");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "false");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, false);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "no");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, false);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "off");
 
     visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpint(res, ==, false);
 }
 
@@ -123,7 +123,7 @@
     v = visitor_input_test_init(data, "3.14");
 
     visit_type_number(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpfloat(res, ==, value);
 }
 
@@ -137,7 +137,7 @@
     v = visitor_input_test_init(data, value);
 
     visit_type_str(v, &res, NULL, &errp);
-    g_assert(!error_is_set(&errp));
+    g_assert(!errp);
     g_assert_cmpstr(res, ==, value);
 
     g_free(res);
@@ -156,7 +156,7 @@
         v = visitor_input_test_init(data, EnumOne_lookup[i]);
 
         visit_type_EnumOne(v, &res, NULL, &errp);
-        g_assert(!error_is_set(&errp));
+        g_assert(!errp);
         g_assert_cmpint(i, ==, res);
 
         visitor_input_teardown(data, NULL);
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 79d815f..22363d1 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -26,7 +26,7 @@
 static void visitor_output_setup(TestOutputVisitorData *data,
                                  const void *unused)
 {
-    data->sov = string_output_visitor_new();
+    data->sov = string_output_visitor_new(false);
     g_assert(data->sov != NULL);
 
     data->ov = string_output_get_visitor(data->sov);
@@ -49,7 +49,7 @@
     char *str;
 
     visit_type_int(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -65,7 +65,7 @@
     char *str;
 
     visit_type_bool(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -81,7 +81,7 @@
     char *str;
 
     visit_type_number(data->ov, &value, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -97,7 +97,7 @@
     char *str;
 
     visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -114,7 +114,7 @@
 
     /* A null string should return "" */
     visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(error_is_set(&errp) == 0);
+    g_assert(!errp);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -131,7 +131,7 @@
 
     for (i = 0; i < ENUM_ONE_MAX; i++) {
         visit_type_EnumOne(data->ov, &i, "unused", &errp);
-        g_assert(!error_is_set(&errp));
+        g_assert(!errp);
 
         str = string_output_get_string(data->sov);
         g_assert(str != NULL);
@@ -149,7 +149,7 @@
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
         errp = NULL;
         visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
-        g_assert(error_is_set(&errp) == true);
+        g_assert(errp);
         error_free(errp);
     }
 }
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 9aaa587..6bff950 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -1083,7 +1083,7 @@
 {
     StringSerializeData *d = g_malloc0(sizeof(*d));
 
-    d->sov = string_output_visitor_new();
+    d->sov = string_output_visitor_new(false);
     visit(string_output_get_visitor(d->sov), &native_in, errp);
     *datap = d;
 }
diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
index 5ac48e2..0834219 100644
--- a/tests/tmp105-test.c
+++ b/tests/tmp105-test.c
@@ -6,12 +6,13 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
+
+#include <glib.h>
+
 #include "libqtest.h"
 #include "libqos/i2c.h"
 #include "hw/misc/tmp105_regs.h"
 
-#include <glib.h>
-
 #define OMAP2_I2C_1_BASE 0x48070000
 
 #define N8X0_ADDR 0x48
diff --git a/tests/tpci200-test.c b/tests/tpci200-test.c
new file mode 100644
index 0000000..9ae0127
--- /dev/null
+++ b/tests/tpci200-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for tpci200 PCI-IndustryPack bridge
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/tpci200/nop", nop);
+
+    qtest_start("-device tpci200");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
new file mode 100644
index 0000000..df99343
--- /dev/null
+++ b/tests/virtio-net-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for VirtIO NIC
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/virtio/net/pci/nop", pci_nop);
+
+    qtest_start("-device virtio-net-pci");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tests/vmxnet3-test.c b/tests/vmxnet3-test.c
new file mode 100644
index 0000000..a2ebed3
--- /dev/null
+++ b/tests/vmxnet3-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for vmxnet3 NIC
+ *
+ * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/vmxnet3/nop", nop);
+
+    qtest_start("-device vmxnet3");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
diff --git a/tpm.c b/tpm.c
index d68d69f..c371023 100644
--- a/tpm.c
+++ b/tpm.c
@@ -161,7 +161,7 @@
 
     /* validate backend specific opts */
     qemu_opts_validate(opts, be->opts, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return 1;
diff --git a/trace-events b/trace-events
index ab11f97..3713063 100644
--- a/trace-events
+++ b/trace-events
@@ -495,10 +495,10 @@
 qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64
 
 # block/qcow2-cluster.c
-qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offet %" PRIx64 " num %d"
-qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
-qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offet %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
+qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offset %" PRIx64 " num %d"
+qcow2_handle_copied(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_handle_alloc(void *co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " bytes %" PRIx64
+qcow2_do_alloc_clusters_offset(void *co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters) "co %p guest_offset %" PRIx64 " host_offset %" PRIx64 " nb_clusters %d"
 qcow2_cluster_alloc_phys(void *co) "co %p"
 qcow2_cluster_link_l2(void *co, int nb_clusters) "co %p nb_clusters %d"
 
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 3b88e49..d321946 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -1,6 +1,30 @@
 # -*- mode: makefile -*-
 
 ######################################################################
+# Auto-generated event descriptions for LTTng ust code
+
+ifeq ($(TRACE_BACKEND),ust)
+$(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
+$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events
+	$(call quiet-command,$(TRACETOOL) \
+		--format=ust-events-h \
+		--backend=$(TRACE_BACKEND) \
+		< $< > $@,"  GEN   $(patsubst %-timestamp,%,$@)")
+	@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
+$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events
+	$(call quiet-command,$(TRACETOOL) \
+		--format=ust-events-c \
+		--backend=$(TRACE_BACKEND) \
+		< $< > $@,"  GEN   $(patsubst %-timestamp,%,$@)")
+	@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+$(obj)/generated-events.h: $(obj)/generated-ust-provider.h
+$(obj)/generated-events.c: $(obj)/generated-ust.c
+endif
+
+######################################################################
 # Auto-generated event descriptions
 
 $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
@@ -77,5 +101,6 @@
 util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
 util-obj-$(CONFIG_TRACE_STDERR) += stderr.o
 util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
+util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
 util-obj-y += control.o
 util-obj-y += generated-tracers.o
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 9298f55..797df71 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -31,7 +31,7 @@
     Error *local_err = NULL;
 
     ret = find_list(vm_config_groups, group, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_report("%s", error_get_pretty(local_err));
         error_free(local_err);
     }
@@ -295,7 +295,7 @@
         if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
             /* group with id */
             list = find_list(lists, group, &local_err);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_report("%s", error_get_pretty(local_err));
                 error_free(local_err);
                 goto out;
@@ -306,7 +306,7 @@
         if (sscanf(line, "[%63[^]]]", group) == 1) {
             /* group without id */
             list = find_list(lists, group, &local_err);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_report("%s", error_get_pretty(local_err));
                 error_free(local_err);
                 goto out;
@@ -376,13 +376,13 @@
     }
 
     subopts = qemu_opts_create(opts, NULL, 0, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         goto out;
     }
 
     qemu_opts_absorb_qdict(subopts, subqdict, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         goto out;
     }
@@ -416,13 +416,13 @@
             opt_name = g_strdup_printf("%s.%u", opts->name, i++);
             subopts = qemu_opts_create(opts, opt_name, 1, &local_err);
             g_free(opt_name);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_propagate(errp, local_err);
                 goto out;
             }
 
             qemu_opts_absorb_qdict(subopts, section, &local_err);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_propagate(errp, local_err);
                 qemu_opts_del(subopts);
                 goto out;
@@ -450,7 +450,7 @@
 
     for (i = 0; lists[i]; i++) {
         config_parse_qdict_section(options, lists[i], &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             return;
         }
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 668e5d9..fd76cd2 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -246,7 +246,7 @@
     switch (list->type) {
     case OPT_FLAG:
         parse_option_bool(name, value, &flag, &local_err);
-        if (!error_is_set(&local_err)) {
+        if (!local_err) {
             list->value.n = flag;
         }
         break;
@@ -269,7 +269,7 @@
         return -1;
     }
 
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
@@ -640,7 +640,7 @@
     opt->desc = desc;
     opt->str = g_strdup(value);
     qemu_opt_parse(opt, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         qemu_opt_del(opt);
     }
@@ -651,7 +651,7 @@
     Error *local_err = NULL;
 
     opt_set(opts, name, value, false, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
@@ -812,7 +812,7 @@
     Error *local_err = NULL;
 
     opts = qemu_opts_create(list, id, 1, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         qerror_report_err(local_err);
         error_free(local_err);
         return -1;
@@ -897,7 +897,7 @@
         if (strcmp(option, "id") != 0) {
             /* store and parse */
             opt_set(opts, option, value, prepend, &local_err);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 qerror_report_err(local_err);
                 error_free(local_err);
                 return -1;
@@ -945,7 +945,7 @@
     assert(!defaults || list->merge_lists);
     opts = qemu_opts_create(list, id, !defaults, &local_err);
     if (opts == NULL) {
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             qerror_report_err(local_err);
             error_free(local_err);
         }
@@ -1034,7 +1034,7 @@
 
     opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
                             &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         return NULL;
     }
@@ -1044,7 +1044,7 @@
     state.errp = &local_err;
     state.opts = opts;
     qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_propagate(errp, local_err);
         qemu_opts_del(opts);
         return NULL;
@@ -1075,7 +1075,7 @@
 
         if (find_desc_by_name(opts->list->desc, entry->key)) {
             qemu_opts_from_qdict_1(entry->key, entry->value, &state);
-            if (error_is_set(&local_err)) {
+            if (local_err) {
                 error_propagate(errp, local_err);
                 return;
             } else {
@@ -1129,7 +1129,7 @@
         }
 
         qemu_opt_parse(opt, &local_err);
-        if (error_is_set(&local_err)) {
+        if (local_err) {
             error_propagate(errp, local_err);
             return;
         }
diff --git a/vl.c b/vl.c
index 316de54..9379d33 100644
--- a/vl.c
+++ b/vl.c
@@ -2268,7 +2268,7 @@
     Error *local_err = NULL;
 
     qemu_chr_new_from_opts(opts, NULL, &local_err);
-    if (error_is_set(&local_err)) {
+    if (local_err) {
         error_report("%s", error_get_pretty(local_err));
         error_free(local_err);
         return -1;
@@ -3020,14 +3020,19 @@
                         goto chs_fail;
                     if (*p == ',') {
                         p++;
-                        if (!strcmp(p, "none"))
+                        if (!strcmp(p, "large")) {
+                            translation = BIOS_ATA_TRANSLATION_LARGE;
+                        } else if (!strcmp(p, "rechs")) {
+                            translation = BIOS_ATA_TRANSLATION_RECHS;
+                        } else if (!strcmp(p, "none")) {
                             translation = BIOS_ATA_TRANSLATION_NONE;
-                        else if (!strcmp(p, "lba"))
+                        } else if (!strcmp(p, "lba")) {
                             translation = BIOS_ATA_TRANSLATION_LBA;
-                        else if (!strcmp(p, "auto"))
+                        } else if (!strcmp(p, "auto")) {
                             translation = BIOS_ATA_TRANSLATION_AUTO;
-                        else
+                        } else {
                             goto chs_fail;
+                        }
                     } else if (*p != '\0') {
                     chs_fail:
                         fprintf(stderr, "qemu: invalid physical CHS format\n");
@@ -3041,10 +3046,15 @@
                         qemu_opt_set(hda_opts, "heads", num);
                         snprintf(num, sizeof(num), "%d", secs);
                         qemu_opt_set(hda_opts, "secs", num);
-                        if (translation == BIOS_ATA_TRANSLATION_LBA)
+                        if (translation == BIOS_ATA_TRANSLATION_LARGE) {
+                            qemu_opt_set(hda_opts, "trans", "large");
+                        } else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
+                            qemu_opt_set(hda_opts, "trans", "rechs");
+                        } else if (translation == BIOS_ATA_TRANSLATION_LBA) {
                             qemu_opt_set(hda_opts, "trans", "lba");
-                        if (translation == BIOS_ATA_TRANSLATION_NONE)
+                        } else if (translation == BIOS_ATA_TRANSLATION_NONE) {
                             qemu_opt_set(hda_opts, "trans", "none");
+                        }
                     }
                 }
                 break;
@@ -4025,7 +4035,13 @@
     configure_accelerator();
 
     if (qtest_chrdev) {
-        qtest_init(qtest_chrdev, qtest_log);
+        Error *local_err = NULL;
+        qtest_init(qtest_chrdev, qtest_log, &local_err);
+        if (local_err) {
+            error_report("%s", error_get_pretty(local_err));
+            error_free(local_err);
+            exit(1);
+        }
     }
 
     machine_opts = qemu_get_machine_opts();