virtio: removed previous virtio modules.
authorKitae Kim <kt920.kim@samsung.com>
Tue, 9 Jul 2013 07:41:16 +0000 (16:41 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Tue, 9 Jul 2013 07:41:16 +0000 (16:41 +0900)
Change-Id: Ie34a7dcea9a0f607a05437ed30f9b6f9d5fb1c23
Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
16 files changed:
hw/virtio-balloon.c [deleted file]
hw/virtio-balloon.h [deleted file]
hw/virtio-blk.c [deleted file]
hw/virtio-blk.h [deleted file]
hw/virtio-net.c [deleted file]
hw/virtio-net.h [deleted file]
hw/virtio-pci-new.c [deleted file]
hw/virtio-pci.c [deleted file]
hw/virtio-pci.h [deleted file]
hw/virtio-serial-bus.c [deleted file]
hw/virtio-serial.h [deleted file]
hw/virtio-transport.c [deleted file]
hw/virtio-transport.h [deleted file]
hw/virtio.c [deleted file]
hw/virtio.h [deleted file]
hw/virtio/virtio-mmio.c [moved from hw/virtio-mmio.c with 100% similarity]

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
deleted file mode 100644 (file)
index d6fe2aa..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Virtio Balloon Device
- *
- * Copyright IBM, Corp. 2008
- * Copyright (C) 2011 Red Hat, Inc.
- * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "iov.h"
-#include "qemu-common.h"
-#include "virtio.h"
-#include "pc.h"
-#include "cpu.h"
-#include "balloon.h"
-#include "virtio-balloon.h"
-#include "virtio-transport.h"
-#include "kvm.h"
-#include "exec-memory.h"
-
-#if defined(__linux__)
-#include <sys/mman.h>
-#endif
-
-typedef struct VirtIOBalloon
-{
-    VirtIODevice vdev;
-    VirtQueue *ivq, *dvq, *svq;
-    uint32_t num_pages;
-    uint32_t actual;
-    uint64_t stats[VIRTIO_BALLOON_S_NR];
-    VirtQueueElement stats_vq_elem;
-    size_t stats_vq_offset;
-    DeviceState *qdev;
-} VirtIOBalloon;
-
-static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev)
-{
-    return (VirtIOBalloon *)vdev;
-}
-
-static void balloon_page(void *addr, int deflate)
-{
-#if defined(__linux__)
-    if (!kvm_enabled() || kvm_has_sync_mmu())
-        qemu_madvise(addr, TARGET_PAGE_SIZE,
-                deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
-#endif
-}
-
-/*
- * reset_stats - Mark all items in the stats array as unset
- *
- * This function needs to be called at device intialization and before
- * before updating to a set of newly-generated stats.  This will ensure that no
- * stale values stick around in case the guest reports a subset of the supported
- * statistics.
- */
-static inline void reset_stats(VirtIOBalloon *dev)
-{
-    int i;
-    for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
-}
-
-static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOBalloon *s = to_virtio_balloon(vdev);
-    VirtQueueElement elem;
-    MemoryRegionSection section;
-
-    while (virtqueue_pop(vq, &elem)) {
-        size_t offset = 0;
-        uint32_t pfn;
-
-        while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) {
-            ram_addr_t pa;
-            ram_addr_t addr;
-
-            pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT;
-            offset += 4;
-
-            /* FIXME: remove get_system_memory(), but how? */
-            section = memory_region_find(get_system_memory(), pa, 1);
-            if (!section.size || !memory_region_is_ram(section.mr))
-                continue;
-
-            /* Using memory_region_get_ram_ptr is bending the rules a bit, but
-               should be OK because we only want a single page.  */
-            addr = section.offset_within_region;
-            balloon_page(memory_region_get_ram_ptr(section.mr) + addr,
-                         !!(vq == s->dvq));
-        }
-
-        virtqueue_push(vq, &elem, offset);
-        virtio_notify(vdev, vq);
-    }
-}
-
-static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev);
-    VirtQueueElement *elem = &s->stats_vq_elem;
-    VirtIOBalloonStat stat;
-    size_t offset = 0;
-
-    if (!virtqueue_pop(vq, elem)) {
-        return;
-    }
-
-    /* Initialize the stats to get rid of any stale values.  This is only
-     * needed to handle the case where a guest supports fewer stats than it
-     * used to (ie. it has booted into an old kernel).
-     */
-    reset_stats(s);
-
-    while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat))
-           == sizeof(stat)) {
-        uint16_t tag = tswap16(stat.tag);
-        uint64_t val = tswap64(stat.val);
-
-        offset += sizeof(stat);
-        if (tag < VIRTIO_BALLOON_S_NR)
-            s->stats[tag] = val;
-    }
-    s->stats_vq_offset = offset;
-}
-
-static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
-{
-    VirtIOBalloon *dev = to_virtio_balloon(vdev);
-    struct virtio_balloon_config config;
-
-    config.num_pages = cpu_to_le32(dev->num_pages);
-    config.actual = cpu_to_le32(dev->actual);
-
-    memcpy(config_data, &config, 8);
-}
-
-static void virtio_balloon_set_config(VirtIODevice *vdev,
-                                      const uint8_t *config_data)
-{
-    VirtIOBalloon *dev = to_virtio_balloon(vdev);
-    struct virtio_balloon_config config;
-    uint32_t oldactual = dev->actual;
-    memcpy(&config, config_data, 8);
-    dev->actual = le32_to_cpu(config.actual);
-    if (dev->actual != oldactual) {
-        qemu_balloon_changed(ram_size -
-                             (dev->actual << VIRTIO_BALLOON_PFN_SHIFT));
-    }
-}
-
-static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
-{
-    f |= (1 << VIRTIO_BALLOON_F_STATS_VQ);
-    return f;
-}
-
-static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
-{
-    VirtIOBalloon *dev = opaque;
-
-#if 0
-    /* Disable guest-provided stats for now. For more details please check:
-     * https://bugzilla.redhat.com/show_bug.cgi?id=623903
-     *
-     * If you do enable it (which is probably not going to happen as we
-     * need a new command for it), remember that you also need to fill the
-     * appropriate members of the BalloonInfo structure so that the stats
-     * are returned to the client.
-     */
-    if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) {
-        virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
-        virtio_notify(&dev->vdev, dev->svq);
-        return;
-    }
-#endif
-
-    /* Stats are not supported.  Clear out any stale values that might
-     * have been set by a more featureful guest kernel.
-     */
-    reset_stats(dev);
-
-    info->actual = ram_size - ((uint64_t) dev->actual <<
-                               VIRTIO_BALLOON_PFN_SHIFT);
-}
-
-static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
-{
-    VirtIOBalloon *dev = opaque;
-
-    if (target > ram_size) {
-        target = ram_size;
-    }
-    if (target) {
-        dev->num_pages = (ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT;
-        virtio_notify_config(&dev->vdev);
-    }
-}
-
-static void virtio_balloon_save(QEMUFile *f, void *opaque)
-{
-    VirtIOBalloon *s = opaque;
-
-    virtio_save(&s->vdev, f);
-
-    qemu_put_be32(f, s->num_pages);
-    qemu_put_be32(f, s->actual);
-}
-
-static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
-{
-    VirtIOBalloon *s = opaque;
-    int ret;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    ret = virtio_load(&s->vdev, f);
-    if (ret) {
-        return ret;
-    }
-
-    s->num_pages = qemu_get_be32(f);
-    s->actual = qemu_get_be32(f);
-    return 0;
-}
-
-VirtIODevice *virtio_balloon_init(DeviceState *dev)
-{
-    VirtIOBalloon *s;
-    int ret;
-
-    s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
-                                            VIRTIO_ID_BALLOON,
-                                            8, sizeof(VirtIOBalloon));
-
-    s->vdev.get_config = virtio_balloon_get_config;
-    s->vdev.set_config = virtio_balloon_set_config;
-    s->vdev.get_features = virtio_balloon_get_features;
-
-    ret = qemu_add_balloon_handler(virtio_balloon_to_target,
-                                   virtio_balloon_stat, s);
-    if (ret < 0) {
-        virtio_cleanup(&s->vdev);
-        return NULL;
-    }
-
-    s->ivq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output);
-    s->dvq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output);
-    s->svq = virtio_add_queue(&s->vdev, 128, virtio_balloon_receive_stats);
-
-    reset_stats(s);
-
-    s->qdev = dev;
-    register_savevm(dev, "virtio-balloon", -1, 1,
-                    virtio_balloon_save, virtio_balloon_load, s);
-
-    return &s->vdev;
-}
-
-void virtio_balloon_exit(VirtIODevice *vdev)
-{
-    VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev);
-
-    qemu_remove_balloon_handler(s);
-    unregister_savevm(s->qdev, "virtio-balloon", s);
-    virtio_cleanup(vdev);
-}
-
-/******************** VirtIOBaloon Device **********************/
-
-static int virtio_balloondev_init(DeviceState *dev)
-{
-    VirtIODevice *vdev;
-    VirtIOBaloonState *s = VIRTIO_BALLOON_FROM_QDEV(dev);
-    vdev = virtio_balloon_init(dev);
-    if (!vdev) {
-        return -1;
-    }
-
-    assert(s->trl != NULL);
-
-    return virtio_call_backend_init_cb(dev, s->trl, vdev);
-}
-
-static Property virtio_balloon_properties[] = {
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_balloon_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->init = virtio_balloondev_init;
-    dc->props = virtio_balloon_properties;
-}
-
-static TypeInfo virtio_balloon_info = {
-    .name = "virtio-balloon",
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(VirtIOBaloonState),
-    .class_init = virtio_balloon_class_init,
-};
-
-static void virtio_baloon_register_types(void)
-{
-    type_register_static(&virtio_balloon_info);
-}
-
-type_init(virtio_baloon_register_types)
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
deleted file mode 100644 (file)
index b925186..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Virtio Support
- *
- * Copyright IBM, Corp. 2007-2008
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Rusty Russell     <rusty@rustcorp.com.au>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef _QEMU_VIRTIO_BALLOON_H
-#define _QEMU_VIRTIO_BALLOON_H
-
-#include "sysbus.h"
-#include "virtio.h"
-#include "pci.h"
-#include "virtio-transport.h"
-
-/* from Linux's linux/virtio_balloon.h */
-
-/* The ID for virtio_balloon */
-#define VIRTIO_ID_BALLOON 5
-
-/* The feature bitmap for virtio balloon */
-#define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */
-#define VIRTIO_BALLOON_F_STATS_VQ 1       /* Memory stats virtqueue */
-
-/* Size of a PFN in the balloon interface. */
-#define VIRTIO_BALLOON_PFN_SHIFT 12
-
-struct virtio_balloon_config
-{
-    /* Number of pages host wants Guest to give up. */
-    uint32_t num_pages;
-    /* Number of pages we've actually got in balloon. */
-    uint32_t actual;
-};
-
-/* Memory Statistics */
-#define VIRTIO_BALLOON_S_SWAP_IN  0   /* Amount of memory swapped in */
-#define VIRTIO_BALLOON_S_SWAP_OUT 1   /* Amount of memory swapped out */
-#define VIRTIO_BALLOON_S_MAJFLT   2   /* Number of major faults */
-#define VIRTIO_BALLOON_S_MINFLT   3   /* Number of minor faults */
-#define VIRTIO_BALLOON_S_MEMFREE  4   /* Total amount of free memory */
-#define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
-#define VIRTIO_BALLOON_S_NR       6
-
-typedef struct VirtIOBalloonStat {
-    uint16_t tag;
-    uint64_t val;
-} QEMU_PACKED VirtIOBalloonStat;
-
-typedef struct {
-    DeviceState qdev;
-    VirtIOTransportLink *trl;
-} VirtIOBaloonState;
-
-#define VIRTIO_BALLOON_FROM_QDEV(dev) DO_UPCAST(VirtIOBaloonState, qdev, dev)
-
-#endif
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
deleted file mode 100644 (file)
index 0a23352..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Virtio Block Device
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "qemu-error.h"
-#include "trace.h"
-#include "hw/block-common.h"
-#include "blockdev.h"
-#include "virtio-transport.h"
-#include "virtio-pci.h"
-#include "virtio-blk.h"
-#include "scsi-defs.h"
-#ifdef __linux__
-# include <scsi/sg.h>
-#endif
-
-typedef struct VirtIOBlock
-{
-    VirtIODevice vdev;
-    BlockDriverState *bs;
-    VirtQueue *vq;
-    void *rq;
-    QEMUBH *bh;
-    BlockConf *conf;
-    VirtIOBlkConf *blk;
-    unsigned short sector_mask;
-    DeviceState *qdev;
-} VirtIOBlock;
-
-static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
-{
-    return (VirtIOBlock *)vdev;
-}
-
-typedef struct VirtIOBlockReq
-{
-    VirtIOBlock *dev;
-    VirtQueueElement elem;
-    struct virtio_blk_inhdr *in;
-    struct virtio_blk_outhdr *out;
-    struct virtio_scsi_inhdr *scsi;
-    QEMUIOVector qiov;
-    struct VirtIOBlockReq *next;
-    BlockAcctCookie acct;
-} VirtIOBlockReq;
-
-static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
-{
-    VirtIOBlock *s = req->dev;
-
-    trace_virtio_blk_req_complete(req, status);
-
-    stb_p(&req->in->status, status);
-    virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
-    virtio_notify(&s->vdev, s->vq);
-}
-
-static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
-    int is_read)
-{
-    BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
-    VirtIOBlock *s = req->dev;
-
-    if (action == BLOCK_ERR_IGNORE) {
-        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_IGNORE, is_read);
-        return 0;
-    }
-
-    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
-            || action == BLOCK_ERR_STOP_ANY) {
-        req->next = s->rq;
-        s->rq = req;
-        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_STOP, is_read);
-        vm_stop(RUN_STATE_IO_ERROR);
-        bdrv_iostatus_set_err(s->bs, error);
-    } else {
-        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
-        bdrv_acct_done(s->bs, &req->acct);
-        g_free(req);
-        bdrv_emit_qmp_error_event(s->bs, BDRV_ACTION_REPORT, is_read);
-    }
-
-    return 1;
-}
-
-static void virtio_blk_rw_complete(void *opaque, int ret)
-{
-    VirtIOBlockReq *req = opaque;
-
-    trace_virtio_blk_rw_complete(req, ret);
-
-    if (ret) {
-        int is_read = !(ldl_p(&req->out->type) & VIRTIO_BLK_T_OUT);
-        if (virtio_blk_handle_rw_error(req, -ret, is_read))
-            return;
-    }
-
-    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
-    bdrv_acct_done(req->dev->bs, &req->acct);
-    g_free(req);
-}
-
-static void virtio_blk_flush_complete(void *opaque, int ret)
-{
-    VirtIOBlockReq *req = opaque;
-
-    if (ret) {
-        if (virtio_blk_handle_rw_error(req, -ret, 0)) {
-            return;
-        }
-    }
-
-    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
-    bdrv_acct_done(req->dev->bs, &req->acct);
-    g_free(req);
-}
-
-static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
-{
-    VirtIOBlockReq *req = g_malloc(sizeof(*req));
-    req->dev = s;
-    req->qiov.size = 0;
-    req->next = NULL;
-    return req;
-}
-
-static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
-{
-    VirtIOBlockReq *req = virtio_blk_alloc_request(s);
-
-    if (req != NULL) {
-        if (!virtqueue_pop(s->vq, &req->elem)) {
-            g_free(req);
-            return NULL;
-        }
-    }
-
-    return req;
-}
-
-static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
-{
-#ifdef __linux__
-    int ret;
-    int i;
-#endif
-    int status = VIRTIO_BLK_S_OK;
-
-    /*
-     * We require at least one output segment each for the virtio_blk_outhdr
-     * and the SCSI command block.
-     *
-     * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
-     * and the sense buffer pointer in the input segments.
-     */
-    if (req->elem.out_num < 2 || req->elem.in_num < 3) {
-        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
-        g_free(req);
-        return;
-    }
-
-    /*
-     * The scsi inhdr is placed in the second-to-last input segment, just
-     * before the regular inhdr.
-     */
-    req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
-
-    if (!req->dev->blk->scsi) {
-        status = VIRTIO_BLK_S_UNSUPP;
-        goto fail;
-    }
-
-    /*
-     * No support for bidirection commands yet.
-     */
-    if (req->elem.out_num > 2 && req->elem.in_num > 3) {
-        status = VIRTIO_BLK_S_UNSUPP;
-        goto fail;
-    }
-
-#ifdef __linux__
-    struct sg_io_hdr hdr;
-    memset(&hdr, 0, sizeof(struct sg_io_hdr));
-    hdr.interface_id = 'S';
-    hdr.cmd_len = req->elem.out_sg[1].iov_len;
-    hdr.cmdp = req->elem.out_sg[1].iov_base;
-    hdr.dxfer_len = 0;
-
-    if (req->elem.out_num > 2) {
-        /*
-         * If there are more than the minimally required 2 output segments
-         * there is write payload starting from the third iovec.
-         */
-        hdr.dxfer_direction = SG_DXFER_TO_DEV;
-        hdr.iovec_count = req->elem.out_num - 2;
-
-        for (i = 0; i < hdr.iovec_count; i++)
-            hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len;
-
-        hdr.dxferp = req->elem.out_sg + 2;
-
-    } else if (req->elem.in_num > 3) {
-        /*
-         * If we have more than 3 input segments the guest wants to actually
-         * read data.
-         */
-        hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-        hdr.iovec_count = req->elem.in_num - 3;
-        for (i = 0; i < hdr.iovec_count; i++)
-            hdr.dxfer_len += req->elem.in_sg[i].iov_len;
-
-        hdr.dxferp = req->elem.in_sg;
-    } else {
-        /*
-         * Some SCSI commands don't actually transfer any data.
-         */
-        hdr.dxfer_direction = SG_DXFER_NONE;
-    }
-
-    hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base;
-    hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len;
-
-    ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
-    if (ret) {
-        status = VIRTIO_BLK_S_UNSUPP;
-        goto fail;
-    }
-
-    /*
-     * From SCSI-Generic-HOWTO: "Some lower level drivers (e.g. ide-scsi)
-     * clear the masked_status field [hence status gets cleared too, see
-     * block/scsi_ioctl.c] even when a CHECK_CONDITION or COMMAND_TERMINATED
-     * status has occurred.  However they do set DRIVER_SENSE in driver_status
-     * field. Also a (sb_len_wr > 0) indicates there is a sense buffer.
-     */
-    if (hdr.status == 0 && hdr.sb_len_wr > 0) {
-        hdr.status = CHECK_CONDITION;
-    }
-
-    stl_p(&req->scsi->errors,
-          hdr.status | (hdr.msg_status << 8) |
-          (hdr.host_status << 16) | (hdr.driver_status << 24));
-    stl_p(&req->scsi->residual, hdr.resid);
-    stl_p(&req->scsi->sense_len, hdr.sb_len_wr);
-    stl_p(&req->scsi->data_len, hdr.dxfer_len);
-
-    virtio_blk_req_complete(req, status);
-    g_free(req);
-    return;
-#else
-    abort();
-#endif
-
-fail:
-    /* Just put anything nonzero so that the ioctl fails in the guest.  */
-    stl_p(&req->scsi->errors, 255);
-    virtio_blk_req_complete(req, status);
-    g_free(req);
-}
-
-typedef struct MultiReqBuffer {
-    BlockRequest        blkreq[32];
-    unsigned int        num_writes;
-} MultiReqBuffer;
-
-static void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
-{
-    int i, ret;
-
-    if (!mrb->num_writes) {
-        return;
-    }
-
-    ret = bdrv_aio_multiwrite(bs, mrb->blkreq, mrb->num_writes);
-    if (ret != 0) {
-        for (i = 0; i < mrb->num_writes; i++) {
-            if (mrb->blkreq[i].error) {
-                virtio_blk_rw_complete(mrb->blkreq[i].opaque, -EIO);
-            }
-        }
-    }
-
-    mrb->num_writes = 0;
-}
-
-static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
-{
-    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
-
-    /*
-     * Make sure all outstanding writes are posted to the backing device.
-     */
-    virtio_submit_multiwrite(req->dev->bs, mrb);
-    bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
-}
-
-static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
-{
-    BlockRequest *blkreq;
-    uint64_t sector;
-
-    sector = ldq_p(&req->out->sector);
-
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
-
-    trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
-
-    if (sector & req->dev->sector_mask) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-    if (req->qiov.size % req->dev->conf->logical_block_size) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-
-    if (mrb->num_writes == 32) {
-        virtio_submit_multiwrite(req->dev->bs, mrb);
-    }
-
-    blkreq = &mrb->blkreq[mrb->num_writes];
-    blkreq->sector = sector;
-    blkreq->nb_sectors = req->qiov.size / BDRV_SECTOR_SIZE;
-    blkreq->qiov = &req->qiov;
-    blkreq->cb = virtio_blk_rw_complete;
-    blkreq->opaque = req;
-    blkreq->error = 0;
-
-    mrb->num_writes++;
-}
-
-static void virtio_blk_handle_read(VirtIOBlockReq *req)
-{
-    uint64_t sector;
-
-    sector = ldq_p(&req->out->sector);
-
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
-
-    trace_virtio_blk_handle_read(req, sector, req->qiov.size / 512);
-
-    if (sector & req->dev->sector_mask) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-    if (req->qiov.size % req->dev->conf->logical_block_size) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-    bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
-                   req->qiov.size / BDRV_SECTOR_SIZE,
-                   virtio_blk_rw_complete, req);
-}
-
-static void virtio_blk_handle_request(VirtIOBlockReq *req,
-    MultiReqBuffer *mrb)
-{
-    uint32_t type;
-
-    if (req->elem.out_num < 1 || req->elem.in_num < 1) {
-        error_report("virtio-blk missing headers");
-        exit(1);
-    }
-
-    if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
-        req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
-        error_report("virtio-blk header not in correct element");
-        exit(1);
-    }
-
-    req->out = (void *)req->elem.out_sg[0].iov_base;
-    req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
-
-    type = ldl_p(&req->out->type);
-
-    if (type & VIRTIO_BLK_T_FLUSH) {
-        virtio_blk_handle_flush(req, mrb);
-    } else if (type & VIRTIO_BLK_T_SCSI_CMD) {
-        virtio_blk_handle_scsi(req);
-    } else if (type & VIRTIO_BLK_T_GET_ID) {
-        VirtIOBlock *s = req->dev;
-
-        /*
-         * NB: per existing s/n string convention the string is
-         * terminated by '\0' only when shorter than buffer.
-         */
-        strncpy(req->elem.in_sg[0].iov_base,
-                s->blk->serial ? s->blk->serial : "",
-                MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
-        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
-        g_free(req);
-    } else if (type & VIRTIO_BLK_T_OUT) {
-        qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
-                                 req->elem.out_num - 1);
-        virtio_blk_handle_write(req, mrb);
-    } else {
-        qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
-                                 req->elem.in_num - 1);
-        virtio_blk_handle_read(req);
-    }
-}
-
-static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-    VirtIOBlockReq *req;
-    MultiReqBuffer mrb = {
-        .num_writes = 0,
-    };
-
-    while ((req = virtio_blk_get_request(s))) {
-        virtio_blk_handle_request(req, &mrb);
-    }
-
-    virtio_submit_multiwrite(s->bs, &mrb);
-
-    /*
-     * FIXME: Want to check for completions before returning to guest mode,
-     * so cached reads and writes are reported as quickly as possible. But
-     * that should be done in the generic block layer.
-     */
-}
-
-static void virtio_blk_dma_restart_bh(void *opaque)
-{
-    VirtIOBlock *s = opaque;
-    VirtIOBlockReq *req = s->rq;
-    MultiReqBuffer mrb = {
-        .num_writes = 0,
-    };
-
-    qemu_bh_delete(s->bh);
-    s->bh = NULL;
-
-    s->rq = NULL;
-
-    while (req) {
-        virtio_blk_handle_request(req, &mrb);
-        req = req->next;
-    }
-
-    virtio_submit_multiwrite(s->bs, &mrb);
-}
-
-static void virtio_blk_dma_restart_cb(void *opaque, int running,
-                                      RunState state)
-{
-    VirtIOBlock *s = opaque;
-
-    if (!running)
-        return;
-
-    if (!s->bh) {
-        s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);
-        qemu_bh_schedule(s->bh);
-    }
-}
-
-static void virtio_blk_reset(VirtIODevice *vdev)
-{
-    /*
-     * This should cancel pending requests, but can't do nicely until there
-     * are per-device request lists.
-     */
-    bdrv_drain_all();
-}
-
-/* coalesce internal state, copy to pci i/o region 0
- */
-static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-    struct virtio_blk_config blkcfg;
-    uint64_t capacity;
-    int blk_size = s->conf->logical_block_size;
-
-    bdrv_get_geometry(s->bs, &capacity);
-    memset(&blkcfg, 0, sizeof(blkcfg));
-    stq_raw(&blkcfg.capacity, capacity);
-    stl_raw(&blkcfg.seg_max, 128 - 2);
-    stw_raw(&blkcfg.cylinders, s->conf->cyls);
-    stl_raw(&blkcfg.blk_size, blk_size);
-    stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
-    stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
-    blkcfg.heads = s->conf->heads;
-    /*
-     * We must ensure that the block device capacity is a multiple of
-     * the logical block size. If that is not the case, lets use
-     * sector_mask to adopt the geometry to have a correct picture.
-     * For those devices where the capacity is ok for the given geometry
-     * we dont touch the sector value of the geometry, since some devices
-     * (like s390 dasd) need a specific value. Here the capacity is already
-     * cyls*heads*secs*blk_size and the sector value is not block size
-     * divided by 512 - instead it is the amount of blk_size blocks
-     * per track (cylinder).
-     */
-    if (bdrv_getlength(s->bs) /  s->conf->heads / s->conf->secs % blk_size) {
-        blkcfg.sectors = s->conf->secs & ~s->sector_mask;
-    } else {
-        blkcfg.sectors = s->conf->secs;
-    }
-    blkcfg.size_max = 0;
-    blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
-    blkcfg.alignment_offset = 0;
-    blkcfg.wce = bdrv_enable_write_cache(s->bs);
-    memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
-}
-
-static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-    struct virtio_blk_config blkcfg;
-
-    memcpy(&blkcfg, config, sizeof(blkcfg));
-    bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
-}
-
-static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-
-    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
-    features |= (1 << VIRTIO_BLK_F_GEOMETRY);
-    features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
-    features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
-    features |= (1 << VIRTIO_BLK_F_SCSI);
-
-    if (bdrv_enable_write_cache(s->bs))
-        features |= (1 << VIRTIO_BLK_F_WCE);
-
-    if (bdrv_is_read_only(s->bs))
-        features |= 1 << VIRTIO_BLK_F_RO;
-
-    return features;
-}
-
-static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-    uint32_t features;
-
-    if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-        return;
-    }
-
-    features = vdev->guest_features;
-    bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
-}
-
-static void virtio_blk_save(QEMUFile *f, void *opaque)
-{
-    VirtIOBlock *s = opaque;
-    VirtIOBlockReq *req = s->rq;
-
-    virtio_save(&s->vdev, f);
-    
-    while (req) {
-        qemu_put_sbyte(f, 1);
-        qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
-        req = req->next;
-    }
-    qemu_put_sbyte(f, 0);
-}
-
-static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
-{
-    VirtIOBlock *s = opaque;
-    int ret;
-
-    if (version_id != 2)
-        return -EINVAL;
-
-    ret = virtio_load(&s->vdev, f);
-    if (ret) {
-        return ret;
-    }
-
-    while (qemu_get_sbyte(f)) {
-        VirtIOBlockReq *req = virtio_blk_alloc_request(s);
-        qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
-        req->next = s->rq;
-        s->rq = req;
-
-        virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
-            req->elem.in_num, 1);
-        virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
-            req->elem.out_num, 0);
-    }
-
-    return 0;
-}
-
-static void virtio_blk_resize(void *opaque)
-{
-    VirtIOBlock *s = opaque;
-
-    virtio_notify_config(&s->vdev);
-}
-
-static const BlockDevOps virtio_block_ops = {
-    .resize_cb = virtio_blk_resize,
-};
-
-VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk)
-{
-    VirtIOBlock *s;
-    static int virtio_blk_id;
-
-    if (!blk->conf.bs) {
-        error_report("drive property not set");
-        return NULL;
-    }
-    if (!bdrv_is_inserted(blk->conf.bs)) {
-        error_report("Device needs media, but drive is empty");
-        return NULL;
-    }
-
-    blkconf_serial(&blk->conf, &blk->serial);
-    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
-        return NULL;
-    }
-
-    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
-                                          sizeof(struct virtio_blk_config),
-                                          sizeof(VirtIOBlock));
-
-    s->vdev.get_config = virtio_blk_update_config;
-    s->vdev.set_config = virtio_blk_set_config;
-    s->vdev.get_features = virtio_blk_get_features;
-    s->vdev.set_status = virtio_blk_set_status;
-    s->vdev.reset = virtio_blk_reset;
-    s->bs = blk->conf.bs;
-    s->conf = &blk->conf;
-    s->blk = blk;
-    s->rq = NULL;
-    s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
-
-    s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
-
-    qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
-    s->qdev = dev;
-    register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
-                    virtio_blk_save, virtio_blk_load, s);
-    bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
-    bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size);
-
-    bdrv_iostatus_enable(s->bs);
-    add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
-
-    return &s->vdev;
-}
-
-void virtio_blk_exit(VirtIODevice *vdev)
-{
-    VirtIOBlock *s = to_virtio_blk(vdev);
-    unregister_savevm(s->qdev, "virtio-blk", s);
-    blockdev_mark_auto_del(s->bs);
-    virtio_cleanup(vdev);
-}
-
-/******************** VirtIOBlk Device **********************/
-
-static int virtio_blkdev_init(DeviceState *dev)
-{
-    VirtIODevice *vdev;
-    VirtIOBlockState *s = VIRTIO_BLK_FROM_QDEV(dev);
-
-    assert(s->trl != NULL);
-
-    vdev = virtio_blk_init(dev, &s->blk);
-    if (!vdev) {
-        return -1;
-    }
-
-    /* Pass default host_features to transport */
-    s->trl->host_features = s->host_features;
-
-    if (virtio_call_backend_init_cb(dev, s->trl, vdev) != 0) {
-        return -1;
-    }
-
-    /* Binding should be ready here, let's get final features */
-    if (vdev->binding->get_features) {
-       s->host_features = vdev->binding->get_features(vdev->binding_opaque);
-    }
-    return 0;
-}
-
-static Property virtio_blkdev_properties[] = {
-    DEFINE_BLOCK_PROPERTIES(VirtIOBlockState, blk.conf),
-    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlockState, blk.conf),
-    DEFINE_PROP_STRING("serial", VirtIOBlockState, blk.serial),
-#ifdef __linux__
-    DEFINE_PROP_BIT("scsi", VirtIOBlockState, blk.scsi, 0, true),
-#endif
-    DEFINE_PROP_BIT("config-wce", VirtIOBlockState, blk.config_wce, 0, true),
-    DEFINE_VIRTIO_BLK_FEATURES(VirtIOBlockState, host_features),
-
-    DEFINE_PROP_TRANSPORT("transport", VirtIOBlockState, trl),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_blkdev_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->init = virtio_blkdev_init;
-    dc->props = virtio_blkdev_properties;
-}
-
-static TypeInfo virtio_blkdev_info = {
-    .name = "virtio-blk",
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(VirtIOBlockState),
-    .class_init = virtio_blkdev_class_init,
-};
-
-static void virtio_blk_register_types(void)
-{
-    type_register_static(&virtio_blkdev_info);
-}
-
-type_init(virtio_blk_register_types)
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
deleted file mode 100644 (file)
index 0886818..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Virtio Block Device
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef _QEMU_VIRTIO_BLK_H
-#define _QEMU_VIRTIO_BLK_H
-
-#include "sysbus.h"
-#include "virtio.h"
-#include "virtio-transport.h"
-#include "hw/block-common.h"
-
-/* from Linux's linux/virtio_blk.h */
-
-/* The ID for virtio_block */
-#define VIRTIO_ID_BLOCK 2
-
-/* Feature bits */
-#define VIRTIO_BLK_F_BARRIER    0       /* Does host support barriers? */
-#define VIRTIO_BLK_F_SIZE_MAX   1       /* Indicates maximum segment size */
-#define VIRTIO_BLK_F_SEG_MAX    2       /* Indicates maximum # of segments */
-#define VIRTIO_BLK_F_GEOMETRY   4       /* Indicates support of legacy geometry */
-#define VIRTIO_BLK_F_RO         5       /* Disk is read-only */
-#define VIRTIO_BLK_F_BLK_SIZE   6       /* Block size of disk is available*/
-#define VIRTIO_BLK_F_SCSI       7       /* Supports scsi command passthru */
-/* #define VIRTIO_BLK_F_IDENTIFY   8       ATA IDENTIFY supported, DEPRECATED */
-#define VIRTIO_BLK_F_WCE        9       /* write cache enabled */
-#define VIRTIO_BLK_F_TOPOLOGY   10      /* Topology information is available */
-#define VIRTIO_BLK_F_CONFIG_WCE 11      /* write cache configurable */
-
-#define VIRTIO_BLK_ID_BYTES     20      /* ID string length */
-
-struct virtio_blk_config
-{
-    uint64_t capacity;
-    uint32_t size_max;
-    uint32_t seg_max;
-    uint16_t cylinders;
-    uint8_t heads;
-    uint8_t sectors;
-    uint32_t blk_size;
-    uint8_t physical_block_exp;
-    uint8_t alignment_offset;
-    uint16_t min_io_size;
-    uint32_t opt_io_size;
-    uint8_t wce;
-} QEMU_PACKED;
-
-/* These two define direction. */
-#define VIRTIO_BLK_T_IN         0
-#define VIRTIO_BLK_T_OUT        1
-
-/* This bit says it's a scsi command, not an actual read or write. */
-#define VIRTIO_BLK_T_SCSI_CMD   2
-
-/* Flush the volatile write cache */
-#define VIRTIO_BLK_T_FLUSH      4
-
-/* return the device ID string */
-#define VIRTIO_BLK_T_GET_ID     8
-
-/* Barrier before this op. */
-#define VIRTIO_BLK_T_BARRIER    0x80000000
-
-/* This is the first element of the read scatter-gather list. */
-struct virtio_blk_outhdr
-{
-    /* VIRTIO_BLK_T* */
-    uint32_t type;
-    /* io priority. */
-    uint32_t ioprio;
-    /* Sector (ie. 512 byte offset) */
-    uint64_t sector;
-};
-
-#define VIRTIO_BLK_S_OK         0
-#define VIRTIO_BLK_S_IOERR      1
-#define VIRTIO_BLK_S_UNSUPP     2
-
-/* This is the last element of the write scatter-gather list */
-struct virtio_blk_inhdr
-{
-    unsigned char status;
-};
-
-/* SCSI pass-through header */
-struct virtio_scsi_inhdr
-{
-    uint32_t errors;
-    uint32_t data_len;
-    uint32_t sense_len;
-    uint32_t residual;
-};
-
-struct VirtIOBlkConf
-{
-    BlockConf conf;
-    char *serial;
-    uint32_t scsi;
-    uint32_t config_wce;
-};
-
-#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
-        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
-        DEFINE_PROP_BIT("config-wce", _state, _field, VIRTIO_BLK_F_CONFIG_WCE, true)
-
-
-typedef struct {
-    DeviceState qdev;
-    /* virtio-blk */
-    VirtIOBlkConf blk;
-
-    uint32_t host_features;
-
-    VirtIOTransportLink *trl;
-} VirtIOBlockState;
-
-#define VIRTIO_BLK_FROM_QDEV(dev) DO_UPCAST(VirtIOBlockState, qdev, dev)
-
-#endif
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
deleted file mode 100644 (file)
index b7cfb1c..0000000
+++ /dev/null
@@ -1,1141 +0,0 @@
-/*
- * Virtio Network Device
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "iov.h"
-#include "virtio.h"
-#include "virtio-transport.h"
-#include "virtio-pci.h"
-#include "net.h"
-#include "net/checksum.h"
-#include "net/tap.h"
-#include "qemu-error.h"
-#include "qemu-timer.h"
-#include "virtio-net.h"
-#include "vhost_net.h"
-
-#define VIRTIO_NET_VM_VERSION    11
-
-#define MAC_TABLE_ENTRIES    64
-#define MAX_VLAN    (1 << 12)   /* Per 802.1Q definition */
-
-typedef struct VirtIONet
-{
-    VirtIODevice vdev;
-    uint8_t mac[ETH_ALEN];
-    uint16_t status;
-    VirtQueue *rx_vq;
-    VirtQueue *tx_vq;
-    VirtQueue *ctrl_vq;
-    NICState *nic;
-    QEMUTimer *tx_timer;
-    QEMUBH *tx_bh;
-    uint32_t tx_timeout;
-    int32_t tx_burst;
-    int tx_waiting;
-    uint32_t has_vnet_hdr;
-    uint8_t has_ufo;
-    struct {
-        VirtQueueElement elem;
-        ssize_t len;
-    } async_tx;
-    int mergeable_rx_bufs;
-    uint8_t promisc;
-    uint8_t allmulti;
-    uint8_t alluni;
-    uint8_t nomulti;
-    uint8_t nouni;
-    uint8_t nobcast;
-    uint8_t vhost_started;
-    struct {
-        int in_use;
-        int first_multi;
-        uint8_t multi_overflow;
-        uint8_t uni_overflow;
-        uint8_t *macs;
-    } mac_table;
-    uint32_t *vlans;
-    DeviceState *qdev;
-} VirtIONet;
-
-/* TODO
- * - we could suppress RX interrupt if we were so inclined.
- */
-
-static VirtIONet *to_virtio_net(VirtIODevice *vdev)
-{
-    return (VirtIONet *)vdev;
-}
-
-static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-    struct virtio_net_config netcfg;
-
-    stw_p(&netcfg.status, n->status);
-    memcpy(netcfg.mac, n->mac, ETH_ALEN);
-    memcpy(config, &netcfg, sizeof(netcfg));
-}
-
-static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-    struct virtio_net_config netcfg;
-
-    memcpy(&netcfg, config, sizeof(netcfg));
-
-    if (memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
-        memcpy(n->mac, netcfg.mac, ETH_ALEN);
-        qemu_format_nic_info_str(&n->nic->nc, n->mac);
-    }
-}
-
-static bool virtio_net_started(VirtIONet *n, uint8_t status)
-{
-    return (status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-        (n->status & VIRTIO_NET_S_LINK_UP) && n->vdev.vm_running;
-}
-
-static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
-{
-    if (!n->nic->nc.peer) {
-        return;
-    }
-    if (n->nic->nc.peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
-        return;
-    }
-
-    if (!tap_get_vhost_net(n->nic->nc.peer)) {
-        return;
-    }
-    if (!!n->vhost_started == virtio_net_started(n, status) &&
-                              !n->nic->nc.peer->link_down) {
-        return;
-    }
-    if (!n->vhost_started) {
-        int r;
-        if (!vhost_net_query(tap_get_vhost_net(n->nic->nc.peer), &n->vdev)) {
-            return;
-        }
-        r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), &n->vdev);
-        if (r < 0) {
-            error_report("unable to start vhost net: %d: "
-                         "falling back on userspace virtio", -r);
-        } else {
-            n->vhost_started = 1;
-        }
-    } else {
-        vhost_net_stop(tap_get_vhost_net(n->nic->nc.peer), &n->vdev);
-        n->vhost_started = 0;
-    }
-}
-
-static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    virtio_net_vhost_status(n, status);
-
-    if (!n->tx_waiting) {
-        return;
-    }
-
-    if (virtio_net_started(n, status) && !n->vhost_started) {
-        if (n->tx_timer) {
-            qemu_mod_timer(n->tx_timer,
-                           qemu_get_clock_ns(vm_clock) + n->tx_timeout);
-        } else {
-            qemu_bh_schedule(n->tx_bh);
-        }
-    } else {
-        if (n->tx_timer) {
-            qemu_del_timer(n->tx_timer);
-        } else {
-            qemu_bh_cancel(n->tx_bh);
-        }
-    }
-}
-
-static void virtio_net_set_link_status(NetClientState *nc)
-{
-    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
-    uint16_t old_status = n->status;
-
-    if (nc->link_down)
-        n->status &= ~VIRTIO_NET_S_LINK_UP;
-    else
-        n->status |= VIRTIO_NET_S_LINK_UP;
-
-    if (n->status != old_status)
-        virtio_notify_config(&n->vdev);
-
-    virtio_net_set_status(&n->vdev, n->vdev.status);
-}
-
-static void virtio_net_reset(VirtIODevice *vdev)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    /* Reset back to compatibility mode */
-    n->promisc = 1;
-    n->allmulti = 0;
-    n->alluni = 0;
-    n->nomulti = 0;
-    n->nouni = 0;
-    n->nobcast = 0;
-
-    /* Flush any MAC and VLAN filter table state */
-    n->mac_table.in_use = 0;
-    n->mac_table.first_multi = 0;
-    n->mac_table.multi_overflow = 0;
-    n->mac_table.uni_overflow = 0;
-    memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
-    memset(n->vlans, 0, MAX_VLAN >> 3);
-}
-
-static int peer_has_vnet_hdr(VirtIONet *n)
-{
-    if (!n->nic->nc.peer)
-        return 0;
-
-    if (n->nic->nc.peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP)
-        return 0;
-
-    n->has_vnet_hdr = tap_has_vnet_hdr(n->nic->nc.peer);
-
-    return n->has_vnet_hdr;
-}
-
-static int peer_has_ufo(VirtIONet *n)
-{
-    if (!peer_has_vnet_hdr(n))
-        return 0;
-
-    n->has_ufo = tap_has_ufo(n->nic->nc.peer);
-
-    return n->has_ufo;
-}
-
-static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    features |= (1 << VIRTIO_NET_F_MAC);
-
-    if (peer_has_vnet_hdr(n)) {
-        tap_using_vnet_hdr(n->nic->nc.peer, 1);
-    } else {
-        features &= ~(0x1 << VIRTIO_NET_F_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
-
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
-    }
-
-    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
-        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
-        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
-    }
-
-    if (!n->nic->nc.peer ||
-        n->nic->nc.peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
-        return features;
-    }
-    if (!tap_get_vhost_net(n->nic->nc.peer)) {
-        return features;
-    }
-    return vhost_net_get_features(tap_get_vhost_net(n->nic->nc.peer), features);
-}
-
-static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
-{
-    uint32_t features = 0;
-
-    /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
-     * but also these: */
-    features |= (1 << VIRTIO_NET_F_MAC);
-    features |= (1 << VIRTIO_NET_F_CSUM);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO4);
-    features |= (1 << VIRTIO_NET_F_HOST_TSO6);
-    features |= (1 << VIRTIO_NET_F_HOST_ECN);
-
-    return features;
-}
-
-static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF));
-
-    if (n->has_vnet_hdr) {
-        tap_set_offload(n->nic->nc.peer,
-                        (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                        (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                        (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
-    }
-    if (!n->nic->nc.peer ||
-        n->nic->nc.peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
-        return;
-    }
-    if (!tap_get_vhost_net(n->nic->nc.peer)) {
-        return;
-    }
-    vhost_net_ack_features(tap_get_vhost_net(n->nic->nc.peer), features);
-}
-
-static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
-                                     VirtQueueElement *elem)
-{
-    uint8_t on;
-
-    if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(on)) {
-        error_report("virtio-net ctrl invalid rx mode command");
-        exit(1);
-    }
-
-    on = ldub_p(elem->out_sg[1].iov_base);
-
-    if (cmd == VIRTIO_NET_CTRL_RX_MODE_PROMISC)
-        n->promisc = on;
-    else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLMULTI)
-        n->allmulti = on;
-    else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLUNI)
-        n->alluni = on;
-    else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOMULTI)
-        n->nomulti = on;
-    else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOUNI)
-        n->nouni = on;
-    else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOBCAST)
-        n->nobcast = on;
-    else
-        return VIRTIO_NET_ERR;
-
-    return VIRTIO_NET_OK;
-}
-
-static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
-                                 VirtQueueElement *elem)
-{
-    struct virtio_net_ctrl_mac mac_data;
-
-    if (cmd != VIRTIO_NET_CTRL_MAC_TABLE_SET || elem->out_num != 3 ||
-        elem->out_sg[1].iov_len < sizeof(mac_data) ||
-        elem->out_sg[2].iov_len < sizeof(mac_data))
-        return VIRTIO_NET_ERR;
-
-    n->mac_table.in_use = 0;
-    n->mac_table.first_multi = 0;
-    n->mac_table.uni_overflow = 0;
-    n->mac_table.multi_overflow = 0;
-    memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
-
-    mac_data.entries = ldl_p(elem->out_sg[1].iov_base);
-
-    if (sizeof(mac_data.entries) +
-        (mac_data.entries * ETH_ALEN) > elem->out_sg[1].iov_len)
-        return VIRTIO_NET_ERR;
-
-    if (mac_data.entries <= MAC_TABLE_ENTRIES) {
-        memcpy(n->mac_table.macs, elem->out_sg[1].iov_base + sizeof(mac_data),
-               mac_data.entries * ETH_ALEN);
-        n->mac_table.in_use += mac_data.entries;
-    } else {
-        n->mac_table.uni_overflow = 1;
-    }
-
-    n->mac_table.first_multi = n->mac_table.in_use;
-
-    mac_data.entries = ldl_p(elem->out_sg[2].iov_base);
-
-    if (sizeof(mac_data.entries) +
-        (mac_data.entries * ETH_ALEN) > elem->out_sg[2].iov_len)
-        return VIRTIO_NET_ERR;
-
-    if (mac_data.entries) {
-        if (n->mac_table.in_use + mac_data.entries <= MAC_TABLE_ENTRIES) {
-            memcpy(n->mac_table.macs + (n->mac_table.in_use * ETH_ALEN),
-                   elem->out_sg[2].iov_base + sizeof(mac_data),
-                   mac_data.entries * ETH_ALEN);
-            n->mac_table.in_use += mac_data.entries;
-        } else {
-            n->mac_table.multi_overflow = 1;
-        }
-    }
-
-    return VIRTIO_NET_OK;
-}
-
-static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd,
-                                        VirtQueueElement *elem)
-{
-    uint16_t vid;
-
-    if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(vid)) {
-        error_report("virtio-net ctrl invalid vlan command");
-        return VIRTIO_NET_ERR;
-    }
-
-    vid = lduw_p(elem->out_sg[1].iov_base);
-
-    if (vid >= MAX_VLAN)
-        return VIRTIO_NET_ERR;
-
-    if (cmd == VIRTIO_NET_CTRL_VLAN_ADD)
-        n->vlans[vid >> 5] |= (1U << (vid & 0x1f));
-    else if (cmd == VIRTIO_NET_CTRL_VLAN_DEL)
-        n->vlans[vid >> 5] &= ~(1U << (vid & 0x1f));
-    else
-        return VIRTIO_NET_ERR;
-
-    return VIRTIO_NET_OK;
-}
-
-static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-    struct virtio_net_ctrl_hdr ctrl;
-    virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
-    VirtQueueElement elem;
-
-    while (virtqueue_pop(vq, &elem)) {
-        if ((elem.in_num < 1) || (elem.out_num < 1)) {
-            error_report("virtio-net ctrl missing headers");
-            exit(1);
-        }
-
-        if (elem.out_sg[0].iov_len < sizeof(ctrl) ||
-            elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) {
-            error_report("virtio-net ctrl header not in correct element");
-            exit(1);
-        }
-
-        ctrl.class = ldub_p(elem.out_sg[0].iov_base);
-        ctrl.cmd = ldub_p(elem.out_sg[0].iov_base + sizeof(ctrl.class));
-
-        if (ctrl.class == VIRTIO_NET_CTRL_RX_MODE)
-            status = virtio_net_handle_rx_mode(n, ctrl.cmd, &elem);
-        else if (ctrl.class == VIRTIO_NET_CTRL_MAC)
-            status = virtio_net_handle_mac(n, ctrl.cmd, &elem);
-        else if (ctrl.class == VIRTIO_NET_CTRL_VLAN)
-            status = virtio_net_handle_vlan_table(n, ctrl.cmd, &elem);
-
-        stb_p(elem.in_sg[elem.in_num - 1].iov_base, status);
-
-        virtqueue_push(vq, &elem, sizeof(status));
-        virtio_notify(vdev, vq);
-    }
-}
-
-/* RX */
-
-static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    qemu_flush_queued_packets(&n->nic->nc);
-
-    /* We now have RX buffers, signal to the IO thread to break out of the
-     * select to re-poll the tap file descriptor */
-    qemu_notify_event();
-}
-
-static int virtio_net_can_receive(NetClientState *nc)
-{
-    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
-    if (!n->vdev.vm_running) {
-        return 0;
-    }
-
-    if (!virtio_queue_ready(n->rx_vq) ||
-        !(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
-        return 0;
-
-    return 1;
-}
-
-static int virtio_net_has_buffers(VirtIONet *n, int bufsize)
-{
-    if (virtio_queue_empty(n->rx_vq) ||
-        (n->mergeable_rx_bufs &&
-         !virtqueue_avail_bytes(n->rx_vq, bufsize, 0))) {
-        virtio_queue_set_notification(n->rx_vq, 1);
-
-        /* To avoid a race condition where the guest has made some buffers
-         * available after the above check but before notification was
-         * enabled, check for available buffers again.
-         */
-        if (virtio_queue_empty(n->rx_vq) ||
-            (n->mergeable_rx_bufs &&
-             !virtqueue_avail_bytes(n->rx_vq, bufsize, 0)))
-            return 0;
-    }
-
-    virtio_queue_set_notification(n->rx_vq, 0);
-    return 1;
-}
-
-/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
- * it never finds out that the packets don't have valid checksums.  This
- * causes dhclient to get upset.  Fedora's carried a patch for ages to
- * fix this with Xen but it hasn't appeared in an upstream release of
- * dhclient yet.
- *
- * To avoid breaking existing guests, we catch udp packets and add
- * checksums.  This is terrible but it's better than hacking the guest
- * kernels.
- *
- * N.B. if we introduce a zero-copy API, this operation is no longer free so
- * we should provide a mechanism to disable it to avoid polluting the host
- * cache.
- */
-static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
-                                        const uint8_t *buf, size_t size)
-{
-    if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
-        (size > 27 && size < 1500) && /* normal sized MTU */
-        (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
-        (buf[23] == 17) && /* ip.protocol == UDP */
-        (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
-        /* FIXME this cast is evil */
-        net_checksum_calculate((uint8_t *)buf, size);
-        hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
-    }
-}
-
-static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt,
-                          const void *buf, size_t size, size_t hdr_len)
-{
-    struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)iov[0].iov_base;
-    int offset = 0;
-
-    hdr->flags = 0;
-    hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
-
-    if (n->has_vnet_hdr) {
-        memcpy(hdr, buf, sizeof(*hdr));
-        offset = sizeof(*hdr);
-        work_around_broken_dhclient(hdr, buf + offset, size - offset);
-    }
-
-    /* We only ever receive a struct virtio_net_hdr from the tapfd,
-     * but we may be passing along a larger header to the guest.
-     */
-    iov[0].iov_base += hdr_len;
-    iov[0].iov_len  -= hdr_len;
-
-    return offset;
-}
-
-static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
-{
-    static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-    static const uint8_t vlan[] = {0x81, 0x00};
-    uint8_t *ptr = (uint8_t *)buf;
-    int i;
-
-    if (n->promisc)
-        return 1;
-
-    if (n->has_vnet_hdr) {
-        ptr += sizeof(struct virtio_net_hdr);
-    }
-
-    if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
-        int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
-        if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
-            return 0;
-    }
-
-    if (ptr[0] & 1) { // multicast
-        if (!memcmp(ptr, bcast, sizeof(bcast))) {
-            return !n->nobcast;
-        } else if (n->nomulti) {
-            return 0;
-        } else if (n->allmulti || n->mac_table.multi_overflow) {
-            return 1;
-        }
-
-        for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) {
-            if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) {
-                return 1;
-            }
-        }
-    } else { // unicast
-        if (n->nouni) {
-            return 0;
-        } else if (n->alluni || n->mac_table.uni_overflow) {
-            return 1;
-        } else if (!memcmp(ptr, n->mac, ETH_ALEN)) {
-            return 1;
-        }
-
-        for (i = 0; i < n->mac_table.first_multi; i++) {
-            if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) {
-                return 1;
-            }
-        }
-    }
-
-    return 0;
-}
-
-static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size)
-{
-    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
-    struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
-    size_t guest_hdr_len, offset, i, host_hdr_len;
-
-    if (!virtio_net_can_receive(&n->nic->nc))
-        return -1;
-
-    /* hdr_len refers to the header we supply to the guest */
-    guest_hdr_len = n->mergeable_rx_bufs ?
-        sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
-
-
-    host_hdr_len = n->has_vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
-    if (!virtio_net_has_buffers(n, size + guest_hdr_len - host_hdr_len))
-        return 0;
-
-    if (!receive_filter(n, buf, size))
-        return size;
-
-    offset = i = 0;
-
-    while (offset < size) {
-        VirtQueueElement elem;
-        int len, total;
-        struct iovec sg[VIRTQUEUE_MAX_SIZE];
-
-        total = 0;
-
-        if (virtqueue_pop(n->rx_vq, &elem) == 0) {
-            if (i == 0)
-                return -1;
-            error_report("virtio-net unexpected empty queue: "
-                    "i %zd mergeable %d offset %zd, size %zd, "
-                    "guest hdr len %zd, host hdr len %zd guest features 0x%x",
-                    i, n->mergeable_rx_bufs, offset, size,
-                    guest_hdr_len, host_hdr_len, n->vdev.guest_features);
-            exit(1);
-        }
-
-        if (elem.in_num < 1) {
-            error_report("virtio-net receive queue contains no in buffers");
-            exit(1);
-        }
-
-        if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) {
-            error_report("virtio-net header not in first element");
-            exit(1);
-        }
-
-        memcpy(&sg, &elem.in_sg[0], sizeof(sg[0]) * elem.in_num);
-
-        if (i == 0) {
-            if (n->mergeable_rx_bufs)
-                mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base;
-
-            offset += receive_header(n, sg, elem.in_num,
-                                     buf + offset, size - offset, guest_hdr_len);
-            total += guest_hdr_len;
-        }
-
-        /* copy in packet.  ugh */
-        len = iov_from_buf(sg, elem.in_num, 0,
-                           buf + offset, size - offset);
-        total += len;
-        offset += len;
-        /* If buffers can't be merged, at this point we
-         * must have consumed the complete packet.
-         * Otherwise, drop it. */
-        if (!n->mergeable_rx_bufs && offset < size) {
-#if 0
-            error_report("virtio-net truncated non-mergeable packet: "
-                         "i %zd mergeable %d offset %zd, size %zd, "
-                         "guest hdr len %zd, host hdr len %zd",
-                         i, n->mergeable_rx_bufs,
-                         offset, size, guest_hdr_len, host_hdr_len);
-#endif
-            return size;
-        }
-
-        /* signal other side */
-        virtqueue_fill(n->rx_vq, &elem, total, i++);
-    }
-
-    if (mhdr) {
-        stw_p(&mhdr->num_buffers, i);
-    }
-
-    virtqueue_flush(n->rx_vq, i);
-    virtio_notify(&n->vdev, n->rx_vq);
-
-    return size;
-}
-
-static int32_t virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq);
-
-static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)
-{
-    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
-
-    virtqueue_push(n->tx_vq, &n->async_tx.elem, n->async_tx.len);
-    virtio_notify(&n->vdev, n->tx_vq);
-
-    n->async_tx.elem.out_num = n->async_tx.len = 0;
-
-    virtio_queue_set_notification(n->tx_vq, 1);
-    virtio_net_flush_tx(n, n->tx_vq);
-}
-
-/* TX */
-static int32_t virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
-{
-    VirtQueueElement elem;
-    int32_t num_packets = 0;
-    if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-        return num_packets;
-    }
-
-    assert(n->vdev.vm_running);
-
-    if (n->async_tx.elem.out_num) {
-        virtio_queue_set_notification(n->tx_vq, 0);
-        return num_packets;
-    }
-
-    while (virtqueue_pop(vq, &elem)) {
-        ssize_t ret, len = 0;
-        unsigned int out_num = elem.out_num;
-        struct iovec *out_sg = &elem.out_sg[0];
-        unsigned hdr_len;
-
-        /* hdr_len refers to the header received from the guest */
-        hdr_len = n->mergeable_rx_bufs ?
-            sizeof(struct virtio_net_hdr_mrg_rxbuf) :
-            sizeof(struct virtio_net_hdr);
-
-        if (out_num < 1 || out_sg->iov_len != hdr_len) {
-            error_report("virtio-net header not in first element");
-            exit(1);
-        }
-
-        /* ignore the header if GSO is not supported */
-        if (!n->has_vnet_hdr) {
-            out_num--;
-            out_sg++;
-            len += hdr_len;
-        } else if (n->mergeable_rx_bufs) {
-            /* tapfd expects a struct virtio_net_hdr */
-            hdr_len -= sizeof(struct virtio_net_hdr);
-            out_sg->iov_len -= hdr_len;
-            len += hdr_len;
-        }
-
-        ret = qemu_sendv_packet_async(&n->nic->nc, out_sg, out_num,
-                                      virtio_net_tx_complete);
-        if (ret == 0) {
-            virtio_queue_set_notification(n->tx_vq, 0);
-            n->async_tx.elem = elem;
-            n->async_tx.len  = len;
-            return -EBUSY;
-        }
-
-        len += ret;
-
-        virtqueue_push(vq, &elem, len);
-        virtio_notify(&n->vdev, vq);
-
-        if (++num_packets >= n->tx_burst) {
-            break;
-        }
-    }
-    return num_packets;
-}
-
-static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    /* This happens when device was stopped but VCPU wasn't. */
-    if (!n->vdev.vm_running) {
-        n->tx_waiting = 1;
-        return;
-    }
-
-    if (n->tx_waiting) {
-        virtio_queue_set_notification(vq, 1);
-        qemu_del_timer(n->tx_timer);
-        n->tx_waiting = 0;
-        virtio_net_flush_tx(n, vq);
-    } else {
-        qemu_mod_timer(n->tx_timer,
-                       qemu_get_clock_ns(vm_clock) + n->tx_timeout);
-        n->tx_waiting = 1;
-        virtio_queue_set_notification(vq, 0);
-    }
-}
-
-static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIONet *n = to_virtio_net(vdev);
-
-    if (unlikely(n->tx_waiting)) {
-        return;
-    }
-    n->tx_waiting = 1;
-    /* This happens when device was stopped but VCPU wasn't. */
-    if (!n->vdev.vm_running) {
-        return;
-    }
-    virtio_queue_set_notification(vq, 0);
-    qemu_bh_schedule(n->tx_bh);
-}
-
-static void virtio_net_tx_timer(void *opaque)
-{
-    VirtIONet *n = opaque;
-    assert(n->vdev.vm_running);
-
-    n->tx_waiting = 0;
-
-    /* Just in case the driver is not ready on more */
-    if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
-        return;
-
-    virtio_queue_set_notification(n->tx_vq, 1);
-    virtio_net_flush_tx(n, n->tx_vq);
-}
-
-static void virtio_net_tx_bh(void *opaque)
-{
-    VirtIONet *n = opaque;
-    int32_t ret;
-
-    assert(n->vdev.vm_running);
-
-    n->tx_waiting = 0;
-
-    /* Just in case the driver is not ready on more */
-    if (unlikely(!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)))
-        return;
-
-    ret = virtio_net_flush_tx(n, n->tx_vq);
-    if (ret == -EBUSY) {
-        return; /* Notification re-enable handled by tx_complete */
-    }
-
-    /* If we flush a full burst of packets, assume there are
-     * more coming and immediately reschedule */
-    if (ret >= n->tx_burst) {
-        qemu_bh_schedule(n->tx_bh);
-        n->tx_waiting = 1;
-        return;
-    }
-
-    /* If less than a full burst, re-enable notification and flush
-     * anything that may have come in while we weren't looking.  If
-     * we find something, assume the guest is still active and reschedule */
-    virtio_queue_set_notification(n->tx_vq, 1);
-    if (virtio_net_flush_tx(n, n->tx_vq) > 0) {
-        virtio_queue_set_notification(n->tx_vq, 0);
-        qemu_bh_schedule(n->tx_bh);
-        n->tx_waiting = 1;
-    }
-}
-
-static void virtio_net_save(QEMUFile *f, void *opaque)
-{
-    VirtIONet *n = opaque;
-
-    /* At this point, backend must be stopped, otherwise
-     * it might keep writing to memory. */
-    assert(!n->vhost_started);
-    virtio_save(&n->vdev, f);
-
-    qemu_put_buffer(f, n->mac, ETH_ALEN);
-    qemu_put_be32(f, n->tx_waiting);
-    qemu_put_be32(f, n->mergeable_rx_bufs);
-    qemu_put_be16(f, n->status);
-    qemu_put_byte(f, n->promisc);
-    qemu_put_byte(f, n->allmulti);
-    qemu_put_be32(f, n->mac_table.in_use);
-    qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN);
-    qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
-    qemu_put_be32(f, n->has_vnet_hdr);
-    qemu_put_byte(f, n->mac_table.multi_overflow);
-    qemu_put_byte(f, n->mac_table.uni_overflow);
-    qemu_put_byte(f, n->alluni);
-    qemu_put_byte(f, n->nomulti);
-    qemu_put_byte(f, n->nouni);
-    qemu_put_byte(f, n->nobcast);
-    qemu_put_byte(f, n->has_ufo);
-}
-
-static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
-{
-    VirtIONet *n = opaque;
-    int i;
-    int ret;
-
-    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION)
-        return -EINVAL;
-
-    ret = virtio_load(&n->vdev, f);
-    if (ret) {
-        return ret;
-    }
-
-    qemu_get_buffer(f, n->mac, ETH_ALEN);
-    n->tx_waiting = qemu_get_be32(f);
-    n->mergeable_rx_bufs = qemu_get_be32(f);
-
-    if (version_id >= 3)
-        n->status = qemu_get_be16(f);
-
-    if (version_id >= 4) {
-        if (version_id < 8) {
-            n->promisc = qemu_get_be32(f);
-            n->allmulti = qemu_get_be32(f);
-        } else {
-            n->promisc = qemu_get_byte(f);
-            n->allmulti = qemu_get_byte(f);
-        }
-    }
-
-    if (version_id >= 5) {
-        n->mac_table.in_use = qemu_get_be32(f);
-        /* MAC_TABLE_ENTRIES may be different from the saved image */
-        if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
-            qemu_get_buffer(f, n->mac_table.macs,
-                            n->mac_table.in_use * ETH_ALEN);
-        } else if (n->mac_table.in_use) {
-            qemu_fseek(f, n->mac_table.in_use * ETH_ALEN, SEEK_CUR);
-            n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
-            n->mac_table.in_use = 0;
-        }
-    }
-    if (version_id >= 6)
-        qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
-
-    if (version_id >= 7) {
-        if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
-            error_report("virtio-net: saved image requires vnet_hdr=on");
-            return -1;
-        }
-
-        if (n->has_vnet_hdr) {
-            tap_using_vnet_hdr(n->nic->nc.peer, 1);
-            tap_set_offload(n->nic->nc.peer,
-                    (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
-                    (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
-                    (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
-                    (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
-                    (n->vdev.guest_features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
-        }
-    }
-
-    if (version_id >= 9) {
-        n->mac_table.multi_overflow = qemu_get_byte(f);
-        n->mac_table.uni_overflow = qemu_get_byte(f);
-    }
-
-    if (version_id >= 10) {
-        n->alluni = qemu_get_byte(f);
-        n->nomulti = qemu_get_byte(f);
-        n->nouni = qemu_get_byte(f);
-        n->nobcast = qemu_get_byte(f);
-    }
-
-    if (version_id >= 11) {
-        if (qemu_get_byte(f) && !peer_has_ufo(n)) {
-            error_report("virtio-net: saved image requires TUN_F_UFO support");
-            return -1;
-        }
-    }
-
-    /* Find the first multicast entry in the saved MAC filter */
-    for (i = 0; i < n->mac_table.in_use; i++) {
-        if (n->mac_table.macs[i * ETH_ALEN] & 1) {
-            break;
-        }
-    }
-    n->mac_table.first_multi = i;
-    return 0;
-}
-
-static void virtio_net_cleanup(NetClientState *nc)
-{
-    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
-
-    n->nic = NULL;
-}
-
-static NetClientInfo net_virtio_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
-    .size = sizeof(NICState),
-    .can_receive = virtio_net_can_receive,
-    .receive = virtio_net_receive,
-        .cleanup = virtio_net_cleanup,
-    .link_status_changed = virtio_net_set_link_status,
-};
-
-VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
-                              virtio_net_conf *net)
-{
-    VirtIONet *n;
-
-    n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
-                                        sizeof(struct virtio_net_config),
-                                        sizeof(VirtIONet));
-
-    n->vdev.get_config = virtio_net_get_config;
-    n->vdev.set_config = virtio_net_set_config;
-    n->vdev.get_features = virtio_net_get_features;
-    n->vdev.set_features = virtio_net_set_features;
-    n->vdev.bad_features = virtio_net_bad_features;
-    n->vdev.reset = virtio_net_reset;
-    n->vdev.set_status = virtio_net_set_status;
-    n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
-
-    if (net->tx && strcmp(net->tx, "timer") && strcmp(net->tx, "bh")) {
-        error_report("virtio-net: "
-                     "Unknown option tx=%s, valid options: \"timer\" \"bh\"",
-                     net->tx);
-        error_report("Defaulting to \"bh\"");
-    }
-
-    if (net->tx && !strcmp(net->tx, "timer")) {
-        n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx_timer);
-        n->tx_timer = qemu_new_timer_ns(vm_clock, virtio_net_tx_timer, n);
-        n->tx_timeout = net->txtimer;
-    } else {
-        n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx_bh);
-        n->tx_bh = qemu_bh_new(virtio_net_tx_bh, n);
-    }
-    n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl);
-    qemu_macaddr_default_if_unset(&conf->macaddr);
-    memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
-    n->status = VIRTIO_NET_S_LINK_UP;
-
-    n->nic = qemu_new_nic(&net_virtio_info, conf, object_get_typename(OBJECT(dev)), dev->id, n);
-
-    qemu_format_nic_info_str(&n->nic->nc, conf->macaddr.a);
-
-    n->tx_waiting = 0;
-    n->tx_burst = net->txburst;
-    n->mergeable_rx_bufs = 0;
-    n->promisc = 1; /* for compatibility */
-
-    n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);
-
-    n->vlans = g_malloc0(MAX_VLAN >> 3);
-
-    n->qdev = dev;
-    register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
-                    virtio_net_save, virtio_net_load, n);
-
-    add_boot_device_path(conf->bootindex, dev, "/ethernet-phy@0");
-
-    return &n->vdev;
-}
-
-void virtio_net_exit(VirtIODevice *vdev)
-{
-    VirtIONet *n = DO_UPCAST(VirtIONet, vdev, vdev);
-
-    /* This will stop vhost backend if appropriate. */
-    virtio_net_set_status(vdev, 0);
-
-    qemu_purge_queued_packets(&n->nic->nc);
-
-    unregister_savevm(n->qdev, "virtio-net", n);
-
-    g_free(n->mac_table.macs);
-    g_free(n->vlans);
-
-    if (n->tx_timer) {
-        qemu_del_timer(n->tx_timer);
-        qemu_free_timer(n->tx_timer);
-    } else {
-        qemu_bh_delete(n->tx_bh);
-    }
-
-    qemu_del_net_client(&n->nic->nc);
-    virtio_cleanup(&n->vdev);
-}
-
-/******************** VirtIONet Device **********************/
-
-static int virtio_netdev_init(DeviceState *dev)
-{
-    VirtIODevice *vdev;
-    VirtIONetState *s = VIRTIO_NET_FROM_QDEV(dev);
-
-    assert(s->trl != NULL);
-
-    vdev = virtio_net_init(dev, &s->nic, &s->net);
-
-    /* Pass default host_features to transport */
-    s->trl->host_features = s->host_features;
-
-    if (virtio_call_backend_init_cb(dev, s->trl, vdev) != 0) {
-        return -1;
-    }
-
-    /* Binding should be ready here, let's get final features */
-    if (vdev->binding->get_features) {
-       s->host_features = vdev->binding->get_features(vdev->binding_opaque);
-    }
-    return 0;
-}
-
-static Property virtio_net_properties[] = {
-    DEFINE_VIRTIO_NET_FEATURES(VirtIONetState, host_features),
-    DEFINE_NIC_PROPERTIES(VirtIONetState, nic),
-    DEFINE_PROP_UINT32("x-txtimer", VirtIONetState, net.txtimer,
-            TX_TIMER_INTERVAL),
-    DEFINE_PROP_INT32("x-txburst", VirtIONetState, net.txburst, TX_BURST),
-    DEFINE_PROP_STRING("tx", VirtIONetState, net.tx),
-    DEFINE_PROP_TRANSPORT("transport", VirtIONetState, trl),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_net_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->init = virtio_netdev_init;
-    dc->props = virtio_net_properties;
-}
-
-static TypeInfo virtio_net_info = {
-    .name = "virtio-net",
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(VirtIONetState),
-    .class_init = virtio_net_class_init,
-};
-
-static void virtio_net_register_types(void)
-{
-    type_register_static(&virtio_net_info);
-}
-
-type_init(virtio_net_register_types)
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
deleted file mode 100644 (file)
index 8dd49d3..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Virtio Network Device
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef _QEMU_VIRTIO_NET_H
-#define _QEMU_VIRTIO_NET_H
-
-#include "sysbus.h"
-#include "virtio.h"
-#include "virtio-transport.h"
-#include "net.h"
-#include "pci.h"
-
-#define ETH_ALEN    6
-
-/* from Linux's virtio_net.h */
-
-/* The ID for virtio_net */
-#define VIRTIO_ID_NET   1
-
-/* The feature bitmap for virtio net */
-#define VIRTIO_NET_F_CSUM       0       /* Host handles pkts w/ partial csum */
-#define VIRTIO_NET_F_GUEST_CSUM 1       /* Guest handles pkts w/ partial csum */
-#define VIRTIO_NET_F_MAC        5       /* Host has given MAC address. */
-#define VIRTIO_NET_F_GSO        6       /* Host handles pkts w/ any GSO type */
-#define VIRTIO_NET_F_GUEST_TSO4 7       /* Guest can handle TSOv4 in. */
-#define VIRTIO_NET_F_GUEST_TSO6 8       /* Guest can handle TSOv6 in. */
-#define VIRTIO_NET_F_GUEST_ECN  9       /* Guest can handle TSO[6] w/ ECN in. */
-#define VIRTIO_NET_F_GUEST_UFO  10      /* Guest can handle UFO in. */
-#define VIRTIO_NET_F_HOST_TSO4  11      /* Host can handle TSOv4 in. */
-#define VIRTIO_NET_F_HOST_TSO6  12      /* Host can handle TSOv6 in. */
-#define VIRTIO_NET_F_HOST_ECN   13      /* Host can handle TSO[6] w/ ECN in. */
-#define VIRTIO_NET_F_HOST_UFO   14      /* Host can handle UFO in. */
-#define VIRTIO_NET_F_MRG_RXBUF  15      /* Host can merge receive buffers. */
-#define VIRTIO_NET_F_STATUS     16      /* virtio_net_config.status available */
-#define VIRTIO_NET_F_CTRL_VQ    17      /* Control channel available */
-#define VIRTIO_NET_F_CTRL_RX    18      /* Control channel RX mode support */
-#define VIRTIO_NET_F_CTRL_VLAN  19      /* Control channel VLAN filtering */
-#define VIRTIO_NET_F_CTRL_RX_EXTRA 20   /* Extra RX mode control support */
-
-#define VIRTIO_NET_S_LINK_UP    1       /* Link is up */
-
-#define TX_TIMER_INTERVAL 150000 /* 150 us */
-
-/* Limit the number of packets that can be sent via a single flush
- * of the TX queue.  This gives us a guaranteed exit condition and
- * ensures fairness in the io path.  256 conveniently matches the
- * length of the TX queue and shows a good balance of performance
- * and latency. */
-#define TX_BURST 256
-
-typedef struct virtio_net_conf
-{
-    uint32_t txtimer;
-    int32_t txburst;
-    char *tx;
-} virtio_net_conf;
-
-/* Maximum packet size we can receive from tap device: header + 64k */
-#define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
-
-struct virtio_net_config
-{
-    /* The config defining mac address ($ETH_ALEN bytes) */
-    uint8_t mac[ETH_ALEN];
-    /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
-    uint16_t status;
-} QEMU_PACKED;
-
-/* This is the first element of the scatter-gather list.  If you don't
- * specify GSO or CSUM features, you can simply ignore the header. */
-struct virtio_net_hdr
-{
-#define VIRTIO_NET_HDR_F_NEEDS_CSUM     1       // Use csum_start, csum_offset
-#define VIRTIO_NET_HDR_F_DATA_VALID    2       // Csum is valid
-    uint8_t flags;
-#define VIRTIO_NET_HDR_GSO_NONE         0       // Not a GSO frame
-#define VIRTIO_NET_HDR_GSO_TCPV4        1       // GSO frame, IPv4 TCP (TSO)
-#define VIRTIO_NET_HDR_GSO_UDP          3       // GSO frame, IPv4 UDP (UFO)
-#define VIRTIO_NET_HDR_GSO_TCPV6        4       // GSO frame, IPv6 TCP
-#define VIRTIO_NET_HDR_GSO_ECN          0x80    // TCP has ECN set
-    uint8_t gso_type;
-    uint16_t hdr_len;
-    uint16_t gso_size;
-    uint16_t csum_start;
-    uint16_t csum_offset;
-};
-
-/* This is the version of the header to use when the MRG_RXBUF
- * feature has been negotiated. */
-struct virtio_net_hdr_mrg_rxbuf
-{
-    struct virtio_net_hdr hdr;
-    uint16_t num_buffers;   /* Number of merged rx buffers */
-};
-
-/*
- * Control virtqueue data structures
- *
- * The control virtqueue expects a header in the first sg entry
- * and an ack/status response in the last entry.  Data for the
- * command goes in between.
- */
-struct virtio_net_ctrl_hdr {
-    uint8_t class;
-    uint8_t cmd;
-};
-
-typedef uint8_t virtio_net_ctrl_ack;
-
-#define VIRTIO_NET_OK     0
-#define VIRTIO_NET_ERR    1
-
-/*
- * Control the RX mode, ie. promisucous, allmulti, etc...
- * All commands require an "out" sg entry containing a 1 byte
- * state value, zero = disable, non-zero = enable.  Commands
- * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature.
- * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA.
- */
-#define VIRTIO_NET_CTRL_RX_MODE    0
- #define VIRTIO_NET_CTRL_RX_MODE_PROMISC      0
- #define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI     1
- #define VIRTIO_NET_CTRL_RX_MODE_ALLUNI       2
- #define VIRTIO_NET_CTRL_RX_MODE_NOMULTI      3
- #define VIRTIO_NET_CTRL_RX_MODE_NOUNI        4
- #define VIRTIO_NET_CTRL_RX_MODE_NOBCAST      5
-
-/*
- * Control the MAC filter table.
- *
- * The MAC filter table is managed by the hypervisor, the guest should
- * assume the size is infinite.  Filtering should be considered
- * non-perfect, ie. based on hypervisor resources, the guest may
- * received packets from sources not specified in the filter list.
- *
- * In addition to the class/cmd header, the TABLE_SET command requires
- * two out scatterlists.  Each contains a 4 byte count of entries followed
- * by a concatenated byte stream of the ETH_ALEN MAC addresses.  The
- * first sg list contains unicast addresses, the second is for multicast.
- * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature
- * is available.
- */
-struct virtio_net_ctrl_mac {
-    uint32_t entries;
-    uint8_t macs[][ETH_ALEN];
-};
-#define VIRTIO_NET_CTRL_MAC    1
- #define VIRTIO_NET_CTRL_MAC_TABLE_SET        0
-
-/*
- * Control VLAN filtering
- *
- * The VLAN filter table is controlled via a simple ADD/DEL interface.
- * VLAN IDs not added may be filterd by the hypervisor.  Del is the
- * opposite of add.  Both commands expect an out entry containing a 2
- * byte VLAN ID.  VLAN filterting is available with the
- * VIRTIO_NET_F_CTRL_VLAN feature bit.
- */
-#define VIRTIO_NET_CTRL_VLAN       2
- #define VIRTIO_NET_CTRL_VLAN_ADD             0
- #define VIRTIO_NET_CTRL_VLAN_DEL             1
-
-#define DEFINE_VIRTIO_NET_FEATURES(_state, _field) \
-        DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
-        DEFINE_PROP_BIT("csum", _state, _field, VIRTIO_NET_F_CSUM, true), \
-        DEFINE_PROP_BIT("guest_csum", _state, _field, VIRTIO_NET_F_GUEST_CSUM, true), \
-        DEFINE_PROP_BIT("gso", _state, _field, VIRTIO_NET_F_GSO, true), \
-        DEFINE_PROP_BIT("guest_tso4", _state, _field, VIRTIO_NET_F_GUEST_TSO4, true), \
-        DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
-        DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
-        DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
-        DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
-        DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
-        DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \
-        DEFINE_PROP_BIT("host_ufo", _state, _field, VIRTIO_NET_F_HOST_UFO, true), \
-        DEFINE_PROP_BIT("mrg_rxbuf", _state, _field, VIRTIO_NET_F_MRG_RXBUF, true), \
-        DEFINE_PROP_BIT("status", _state, _field, VIRTIO_NET_F_STATUS, true), \
-        DEFINE_PROP_BIT("ctrl_vq", _state, _field, VIRTIO_NET_F_CTRL_VQ, true), \
-        DEFINE_PROP_BIT("ctrl_rx", _state, _field, VIRTIO_NET_F_CTRL_RX, true), \
-        DEFINE_PROP_BIT("ctrl_vlan", _state, _field, VIRTIO_NET_F_CTRL_VLAN, true), \
-        DEFINE_PROP_BIT("ctrl_rx_extra", _state, _field, VIRTIO_NET_F_CTRL_RX_EXTRA, true)
-
-typedef struct {
-    DeviceState qdev;
-    /* virtio-net */
-    NICConf nic;
-    virtio_net_conf net;
-
-    uint32_t host_features;
-
-    VirtIOTransportLink *trl;
-} VirtIONetState;
-
-#define VIRTIO_NET_FROM_QDEV(dev) DO_UPCAST(VirtIONetState, qdev, dev)
-
-#endif
diff --git a/hw/virtio-pci-new.c b/hw/virtio-pci-new.c
deleted file mode 100644 (file)
index 04f0da4..0000000
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * Virtio PCI Bindings
- *
- * Copyright IBM, Corp. 2007
- * Copyright (c) 2009 CodeSourcery
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Paul Brook        <paul@codesourcery.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include <inttypes.h>
-
-#include "virtio.h"
-#include "virtio-transport.h"
-#include "virtio-blk.h"
-#include "virtio-net.h"
-#include "virtio-serial.h"
-#include "virtio-scsi.h"
-#include "virtio-balloon.h"
-#include "pci.h"
-#include "qemu-error.h"
-#include "msi.h"
-#include "msix.h"
-#include "net.h"
-#include "loader.h"
-#include "kvm.h"
-#include "blockdev.h"
-#include "virtio-pci.h"
-#include "range.h"
-
-/* from Linux's linux/virtio_pci.h */
-
-/* A 32-bit r/o bitmask of the features supported by the host */
-#define VIRTIO_PCI_HOST_FEATURES        0
-
-/* A 32-bit r/w bitmask of features activated by the guest */
-#define VIRTIO_PCI_GUEST_FEATURES       4
-
-/* A 32-bit r/w PFN for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_PFN            8
-
-/* A 16-bit r/o queue size for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_NUM            12
-
-/* A 16-bit r/w queue selector */
-#define VIRTIO_PCI_QUEUE_SEL            14
-
-/* A 16-bit r/w queue notifier */
-#define VIRTIO_PCI_QUEUE_NOTIFY         16
-
-/* An 8-bit device status register.  */
-#define VIRTIO_PCI_STATUS               18
-
-/* An 8-bit r/o interrupt status register.  Reading the value will return the
- * current contents of the ISR and will also clear it.  This is effectively
- * a read-and-acknowledge. */
-#define VIRTIO_PCI_ISR                  19
-
-/* MSI-X registers: only enabled if MSI-X is enabled. */
-/* A 16-bit vector for configuration changes. */
-#define VIRTIO_MSI_CONFIG_VECTOR        20
-/* A 16-bit vector for selected queue notifications. */
-#define VIRTIO_MSI_QUEUE_VECTOR         22
-
-/* Config space size */
-#define VIRTIO_PCI_CONFIG_NOMSI         20
-#define VIRTIO_PCI_CONFIG_MSI           24
-#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
-                                         VIRTIO_PCI_CONFIG_MSI : \
-                                         VIRTIO_PCI_CONFIG_NOMSI)
-
-/* The remaining space is defined by each driver as the per-driver
- * configuration space */
-#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
-                                         VIRTIO_PCI_CONFIG_MSI : \
-                                         VIRTIO_PCI_CONFIG_NOMSI)
-
-/* How many bits to shift physical queue address written to QUEUE_PFN.
- * 12 is historical, and due to x86 page size. */
-#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
-
-/* Flags track per-device state like workarounds for quirks in older guests. */
-#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
-
-/* QEMU doesn't strictly need write barriers since everything runs in
- * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
- * KVM or if kqemu gets SMP support.
- */
-#define wmb() do { } while (0)
-
-/* HACK for virtio to determine if it's running a big endian guest */
-bool virtio_is_big_endian(void);
-
-/* virtio device */
-
-static void virtio_pci_notify(void *opaque, uint16_t vector)
-{
-    VirtIOPCI *s = opaque;
-    if (msix_enabled(&s->pci_dev)) {
-        msix_notify(&s->pci_dev, vector);
-    }
-    else {
-        qemu_set_irq(s->pci_dev.irq[0], s->vdev->isr & 1);
-    }
-}
-
-static void virtio_pci_save_config(void * opaque, QEMUFile *f)
-{
-    VirtIOPCI *s = opaque;
-    pci_device_save(&s->pci_dev, f);
-    msix_save(&s->pci_dev, f);
-    if (msix_present(&s->pci_dev)) {
-        qemu_put_be16(f, s->vdev->config_vector);
-    }
-}
-
-static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
-{
-    VirtIOPCI *s = opaque;
-    if (msix_present(&s->pci_dev)) {
-        qemu_put_be16(f, virtio_queue_vector(s->vdev, n));
-    }
-}
-
-static int virtio_pci_load_config(void * opaque, QEMUFile *f)
-{
-    VirtIOPCI *s = opaque;
-    int ret;
-    ret = pci_device_load(&s->pci_dev, f);
-    if (ret) {
-        return ret;
-    }
-    msix_unuse_all_vectors(&s->pci_dev);
-    msix_load(&s->pci_dev, f);
-    if (msix_present(&s->pci_dev)) {
-        qemu_get_be16s(f, &s->vdev->config_vector);
-    } else {
-        s->vdev->config_vector = VIRTIO_NO_VECTOR;
-    }
-    if (s->vdev->config_vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&s->pci_dev, s->vdev->config_vector);
-    }
-    return 0;
-}
-
-static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
-{
-    VirtIOPCI *s = opaque;
-    uint16_t vector;
-    if (msix_present(&s->pci_dev)) {
-        qemu_get_be16s(f, &vector);
-    } else {
-        vector = VIRTIO_NO_VECTOR;
-    }
-    virtio_queue_set_vector(s->vdev, n, vector);
-    if (vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&s->pci_dev, vector);
-    }
-    return 0;
-}
-
-static int virtio_pci_set_host_notifier_internal(VirtIOPCI *s, int n,
-        bool assign, bool set_handler)
-{
-    VirtQueue *vq = virtio_get_queue(s->vdev, n);
-    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
-    int r = 0;
-
-    if (assign) {
-        r = event_notifier_init(notifier, 1);
-        if (r < 0) {
-            error_report("%s: unable to init event notifier: %d", __func__, r);
-            return r;
-        }
-        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
-        memory_region_add_eventfd(&s->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, true, n,
-                notifier);
-    } else {
-        memory_region_del_eventfd(&s->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, true, n,
-                notifier);
-        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
-        event_notifier_cleanup(notifier);
-    }
-    return r;
-}
-
-static void virtio_pci_start_ioeventfd(VirtIOPCI *s)
-{
-    int n, r;
-
-    if (!(s->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
-        s->ioeventfd_disabled ||
-        s->ioeventfd_started) {
-        return;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(s->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(s, n, true, true);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-    s->ioeventfd_started = true;
-    return;
-
-assign_error:
-    while (--n >= 0) {
-        if (!virtio_queue_get_num(s->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(s, n, false, false);
-        assert(r >= 0);
-    }
-    s->ioeventfd_started = false;
-    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
-}
-
-static void virtio_pci_stop_ioeventfd(VirtIOPCI *s)
-{
-    int r;
-    int n;
-
-    if (!s->ioeventfd_started) {
-        return;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(s->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(s, n, false, false);
-        assert(r >= 0);
-    }
-    s->ioeventfd_started = false;
-}
-
-void virtio_pci_reset_(DeviceState *d)
-{
-    VirtIOPCI *s =
-            container_of(d, VirtIOPCI, pci_dev.qdev);
-    virtio_pci_stop_ioeventfd(s);
-    if (s->vdev) {
-        virtio_reset(s->vdev);
-    }
-    msix_unuse_all_vectors(&s->pci_dev);
-    s->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-}
-
-static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCI *s = opaque;
-    VirtIODevice *vdev = s->vdev;
-    target_phys_addr_t pa;
-
-    switch (addr) {
-    case VIRTIO_PCI_GUEST_FEATURES:
-       /* Guest does not negotiate properly?  We have to assume nothing. */
-       if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
-            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
-       }
-        virtio_set_features(vdev, val);
-        break;
-    case VIRTIO_PCI_QUEUE_PFN:
-        pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
-        if (pa == 0) {
-            virtio_pci_stop_ioeventfd(s);
-            virtio_reset(s->vdev);
-            msix_unuse_all_vectors(&s->pci_dev);
-        }
-        else
-            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
-        break;
-    case VIRTIO_PCI_QUEUE_SEL:
-        if (val < VIRTIO_PCI_QUEUE_MAX)
-            vdev->queue_sel = val;
-        break;
-    case VIRTIO_PCI_QUEUE_NOTIFY:
-        if (val < VIRTIO_PCI_QUEUE_MAX) {
-            virtio_queue_notify(vdev, val);
-        }
-        break;
-    case VIRTIO_PCI_STATUS:
-        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
-            virtio_pci_stop_ioeventfd(s);
-        }
-
-        virtio_set_status(vdev, val & 0xFF);
-
-        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
-            virtio_pci_start_ioeventfd(s);
-        }
-
-        if (vdev->status == 0) {
-            virtio_reset(s->vdev);
-            msix_unuse_all_vectors(&s->pci_dev);
-        }
-
-        /* Linux before 2.6.34 sets the device as OK without enabling
-           the PCI device bus master bit. In this case we need to disable
-           some safety checks. */
-        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(s->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            s->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-        }
-        break;
-    case VIRTIO_MSI_CONFIG_VECTOR:
-        msix_vector_unuse(&s->pci_dev, vdev->config_vector);
-        /* Make it possible for guest to discover an error took place. */
-        if (msix_vector_use(&s->pci_dev, val) < 0)
-            val = VIRTIO_NO_VECTOR;
-        vdev->config_vector = val;
-        break;
-    case VIRTIO_MSI_QUEUE_VECTOR:
-        msix_vector_unuse(&s->pci_dev,
-                          virtio_queue_vector(vdev, vdev->queue_sel));
-        /* Make it possible for guest to discover an error took place. */
-        if (msix_vector_use(&s->pci_dev, val) < 0)
-            val = VIRTIO_NO_VECTOR;
-        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
-        break;
-    default:
-        error_report("%s: unexpected address 0x%x value 0x%x",
-                     __func__, addr, val);
-        break;
-    }
-}
-
-static uint32_t virtio_ioport_read(VirtIOPCI *s, uint32_t addr)
-{
-    VirtIODevice *vdev = s->vdev;
-    uint32_t ret = 0xFFFFFFFF;
-
-    switch (addr) {
-    case VIRTIO_PCI_HOST_FEATURES:
-        ret = s->host_features;
-        break;
-    case VIRTIO_PCI_GUEST_FEATURES:
-        ret = vdev->guest_features;
-        break;
-    case VIRTIO_PCI_QUEUE_PFN:
-        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
-              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
-        break;
-    case VIRTIO_PCI_QUEUE_NUM:
-        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
-        break;
-    case VIRTIO_PCI_QUEUE_SEL:
-        ret = vdev->queue_sel;
-        break;
-    case VIRTIO_PCI_STATUS:
-        ret = vdev->status;
-        break;
-    case VIRTIO_PCI_ISR:
-        /* reading from the ISR also clears it. */
-        ret = vdev->isr;
-        vdev->isr = 0;
-        qemu_set_irq(s->pci_dev.irq[0], 0);
-        break;
-    case VIRTIO_MSI_CONFIG_VECTOR:
-        ret = vdev->config_vector;
-        break;
-    case VIRTIO_MSI_QUEUE_VECTOR:
-        ret = virtio_queue_vector(vdev, vdev->queue_sel);
-        break;
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    if (addr < config)
-        return virtio_ioport_read(s, addr);
-    addr -= config;
-    return virtio_config_readb(s->vdev, addr);
-}
-
-static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    uint16_t val;
-    if (addr < config)
-        return virtio_ioport_read(s, addr);
-    addr -= config;
-    val = virtio_config_readw(s->vdev, addr);
-    if (virtio_is_big_endian()) {
-        /*
-         * virtio is odd, ioports are LE but config space is target native
-         * endian. However, in qemu, all PIO is LE, so we need to re-swap
-         * on BE targets
-         */
-        val = bswap16(val);
-    }
-    return val;
-}
-
-static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    uint32_t val;
-    if (addr < config)
-        return virtio_ioport_read(s, addr);
-    addr -= config;
-    val = virtio_config_readl(s->vdev, addr);
-    if (virtio_is_big_endian()) {
-        val = bswap32(val);
-    }
-    return val;
-}
-
-static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(s, addr, val);
-        return;
-    }
-    addr -= config;
-    virtio_config_writeb(s->vdev, addr, val);
-}
-
-static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(s, addr, val);
-        return;
-    }
-    addr -= config;
-    if (virtio_is_big_endian()) {
-        val = bswap16(val);
-    }
-    virtio_config_writew(s->vdev, addr, val);
-}
-
-static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCI *s = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&s->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(s, addr, val);
-        return;
-    }
-    addr -= config;
-    if (virtio_is_big_endian()) {
-        val = bswap32(val);
-    }
-    virtio_config_writel(s->vdev, addr, val);
-}
-
-static const MemoryRegionPortio virtio_portio[] = {
-    { 0, 0x10000, 1, .write = virtio_pci_config_writeb, },
-    { 0, 0x10000, 2, .write = virtio_pci_config_writew, },
-    { 0, 0x10000, 4, .write = virtio_pci_config_writel, },
-    { 0, 0x10000, 1, .read = virtio_pci_config_readb, },
-    { 0, 0x10000, 2, .read = virtio_pci_config_readw, },
-    { 0, 0x10000, 4, .read = virtio_pci_config_readl, },
-    PORTIO_END_OF_LIST()
-};
-
-static const MemoryRegionOps virtio_pci_config_ops = {
-    .old_portio = virtio_portio,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
-                                uint32_t val, int len)
-{
-    VirtIOPCI *s = DO_UPCAST(VirtIOPCI,
-            pci_dev, pci_dev);
-
-    pci_default_write_config(pci_dev, address, val, len);
-
-    if (range_covers_byte(address, len, PCI_COMMAND) &&
-        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
-        !(s->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
-        virtio_pci_stop_ioeventfd(s);
-        virtio_set_status(s->vdev,
-                          s->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
-    }
-}
-
-static unsigned virtio_pci_get_features(void *opaque)
-{
-    VirtIOPCI *s = opaque;
-    return s->host_features;
-}
-
-static int kvm_virtio_pci_vq_vector_use(VirtIOPCI *s,
-                                        unsigned int queue_no,
-                                        unsigned int vector,
-                                        MSIMessage msg)
-{
-    VirtQueue *vq = virtio_get_queue(s->vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    VirtIOIRQFD *irqfd = &s->vector_irqfd[vector];
-    int ret;
-
-    if (irqfd->users == 0) {
-        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
-        if (ret < 0) {
-            return ret;
-        }
-        irqfd->virq = ret;
-    }
-    irqfd->users++;
-
-    ret = kvm_irqchip_add_irq_notifier(kvm_state, n, irqfd->virq);
-    if (ret < 0) {
-        if (--irqfd->users == 0) {
-            kvm_irqchip_release_virq(kvm_state, irqfd->virq);
-        }
-        return ret;
-    }
-
-    virtio_queue_set_guest_notifier_fd_handler(vq, true, true);
-    return 0;
-}
-
-static void kvm_virtio_pci_vq_vector_release(VirtIOPCI *s,
-                                             unsigned int queue_no,
-                                             unsigned int vector)
-{
-    VirtQueue *vq = virtio_get_queue(s->vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    VirtIOIRQFD *irqfd = &s->vector_irqfd[vector];
-    int ret;
-
-    ret = kvm_irqchip_remove_irq_notifier(kvm_state, n, irqfd->virq);
-    assert(ret == 0);
-
-    if (--irqfd->users == 0) {
-        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
-    }
-
-    virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
-}
-
-static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
-                                     MSIMessage msg)
-{
-    VirtIOPCI *s = container_of(dev, VirtIOPCI, pci_dev);
-    VirtIODevice *vdev = s->vdev;
-    int ret, queue_no;
-
-    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
-        if (!virtio_queue_get_num(vdev, queue_no)) {
-            break;
-        }
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        ret = kvm_virtio_pci_vq_vector_use(s, queue_no, vector, msg);
-        if (ret < 0) {
-            goto undo;
-        }
-    }
-    return 0;
-
-undo:
-    while (--queue_no >= 0) {
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        kvm_virtio_pci_vq_vector_release(s, queue_no, vector);
-    }
-    return ret;
-}
-
-static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
-{
-    VirtIOPCI *s = container_of(dev, VirtIOPCI, pci_dev);
-    VirtIODevice *vdev = s->vdev;
-    int queue_no;
-
-    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
-        if (!virtio_queue_get_num(vdev, queue_no)) {
-            break;
-        }
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        kvm_virtio_pci_vq_vector_release(s, queue_no, vector);
-    }
-}
-
-static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
-{
-    VirtIOPCI *s = opaque;
-    VirtQueue *vq = virtio_get_queue(s->vdev, n);
-    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
-
-    if (assign) {
-        int r = event_notifier_init(notifier, 0);
-        if (r < 0) {
-            return r;
-        }
-        virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
-    } else {
-        virtio_queue_set_guest_notifier_fd_handler(vq, false, false);
-        event_notifier_cleanup(notifier);
-    }
-
-    return 0;
-}
-
-static bool virtio_pci_query_guest_notifiers(void *opaque)
-{
-    VirtIOPCI *s = opaque;
-    return msix_enabled(&s->pci_dev);
-}
-
-static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
-{
-    VirtIOPCI *s = opaque;
-    VirtIODevice *vdev = s->vdev;
-    int r, n;
-
-    /* Must unset vector notifier while guest notifier is still assigned */
-    if (kvm_msi_via_irqfd_enabled() && !assign) {
-        msix_unset_vector_notifiers(&s->pci_dev);
-        g_free(s->vector_irqfd);
-        s->vector_irqfd = NULL;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(vdev, n)) {
-            break;
-        }
-
-        r = virtio_pci_set_guest_notifier(opaque, n, assign);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-
-    /* Must set vector notifier after guest notifier has been assigned */
-    if (kvm_msi_via_irqfd_enabled() && assign) {
-        s->vector_irqfd =
-            g_malloc0(sizeof(*s->vector_irqfd) *
-                      msix_nr_vectors_allocated(&s->pci_dev));
-        r = msix_set_vector_notifiers(&s->pci_dev,
-                                      kvm_virtio_pci_vector_use,
-                                      kvm_virtio_pci_vector_release);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-
-    return 0;
-
-assign_error:
-    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
-    assert(assign);
-    while (--n >= 0) {
-        virtio_pci_set_guest_notifier(opaque, n, !assign);
-    }
-    return r;
-}
-
-static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
-{
-    VirtIOPCI *s = opaque;
-
-    /* Stop using ioeventfd for virtqueue kick if the device starts using host
-     * notifiers.  This makes it easy to avoid stepping on each others' toes.
-     */
-    s->ioeventfd_disabled = assign;
-    if (assign) {
-        virtio_pci_stop_ioeventfd(s);
-    }
-    /* We don't need to start here: it's not needed because backend
-     * currently only stops on status change away from ok,
-     * reset, vmstop and such. If we do add code to start here,
-     * need to check vmstate, device state etc. */
-    return virtio_pci_set_host_notifier_internal(s, n, assign, false);
-}
-
-static void virtio_pci_vmstate_change(void *opaque, bool running)
-{
-    VirtIOPCI *s = opaque;
-
-    if (running) {
-        /* Try to find out if the guest has bus master disabled, but is
-           in ready state. Then we have a buggy guest OS. */
-        if ((s->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(s->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            s->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-        }
-        virtio_pci_start_ioeventfd(s);
-    } else {
-        virtio_pci_stop_ioeventfd(s);
-    }
-}
-
-static const VirtIOBindings virtio_pci_bindings = {
-    .notify = virtio_pci_notify,
-    .save_config = virtio_pci_save_config,
-    .load_config = virtio_pci_load_config,
-    .save_queue = virtio_pci_save_queue,
-    .load_queue = virtio_pci_load_queue,
-    .get_features = virtio_pci_get_features,
-    .query_guest_notifiers = virtio_pci_query_guest_notifiers,
-    .set_host_notifier = virtio_pci_set_host_notifier,
-    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
-    .vmstate_change = virtio_pci_vmstate_change,
-};
-
-static void virtio_init_pci_(VirtIOPCI *s, VirtIODevice *vdev)
-{
-    uint8_t *config;
-    uint32_t size;
-
-    s->vdev = vdev;
-
-    config = s->pci_dev.config;
-
-    if (s->class_code) {
-        pci_config_set_class(config, s->class_code);
-    }
-    pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
-                 pci_get_word(config + PCI_VENDOR_ID));
-    pci_set_word(config + PCI_SUBSYSTEM_ID, vdev->device_id);
-    config[PCI_INTERRUPT_PIN] = 1;
-
-    if (vdev->nvectors &&
-        msix_init_exclusive_bar(&s->pci_dev, vdev->nvectors, 1)) {
-        vdev->nvectors = 0;
-    }
-
-    s->pci_dev.config_write = virtio_write_config;
-
-    size = VIRTIO_PCI_REGION_SIZE(&s->pci_dev) + vdev->config_len;
-    if (size & (size-1))
-        size = 1 << qemu_fls(size);
-
-    memory_region_init_io(&s->bar, &virtio_pci_config_ops, s,
-                          "virtio-pci", size);
-    pci_register_bar(&s->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                     &s->bar);
-
-    if (!kvm_has_many_ioeventfds()) {
-        s->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
-    }
-
-    virtio_bind_device(vdev, &virtio_pci_bindings, s);
-    s->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    s->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
-    s->host_features = vdev->get_features(vdev, s->host_features);
-}
-
-static void virtio_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCI *s = DO_UPCAST(VirtIOPCI, pci_dev, pci_dev);
-
-    memory_region_destroy(&s->bar);
-    msix_uninit_exclusive_bar(pci_dev);
-}
-
-static int virtio_pci_transport_cb(DeviceState *dev, VirtIODevice *vdev,
-        VirtIOTransportLink *trl)
-{
-    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, trl->tr);
-    VirtIOPCI *s = DO_UPCAST(VirtIOPCI, pci_dev, pci_dev);
-
-    virtio_plug_into_transport(dev, trl);
-
-    // TODO: Figure out if props were explicitly set before
-
-    /* Get default host_features passed from back-end */
-    s->host_features = s->trl->host_features;
-
-    switch (vdev->device_id) {
-    case VIRTIO_ID_BLOCK:
-        s->flags |= VIRTIO_PCI_FLAG_USE_IOEVENTFD;
-        s->nvectors = 2;
-
-        if (s->class_code != PCI_CLASS_STORAGE_SCSI &&
-            s->class_code != PCI_CLASS_STORAGE_OTHER) {
-            s->class_code = PCI_CLASS_STORAGE_SCSI;
-        }
-
-        vdev->nvectors = s->nvectors;
-        pci_config_set_device_id(s->pci_dev.config, PCI_DEVICE_ID_VIRTIO_BLOCK);
-        pci_config_set_class(s->pci_dev.config, PCI_CLASS_STORAGE_SCSI);
-        virtio_init_pci_(s, vdev);
-        s->nvectors = vdev->nvectors;
-        break;
-    case VIRTIO_ID_NET:
-        s->nvectors = 3;
-
-        /* load rom */
-        pci_dev->romfile = g_strdup("pxe-virtio.rom");
-        pci_add_option_rom(pci_dev, false);
-
-        vdev->nvectors = s->nvectors;
-        pci_config_set_device_id(s->pci_dev.config, PCI_DEVICE_ID_VIRTIO_NET);
-        pci_config_set_class(s->pci_dev.config, PCI_CLASS_NETWORK_ETHERNET);
-        virtio_init_pci_(s, vdev);
-        s->nvectors = vdev->nvectors;
-        break;
-    case VIRTIO_ID_BALLOON:
-        break;
-    case VIRTIO_ID_SCSI:
-        break;
-    case VIRTIO_ID_CONSOLE:
-    {
-        break;
-    }
-    default:
-        fprintf(stderr,
-                "Unknown back-end device id: 0x%" PRIx16 "\n", vdev->device_id);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int virtio_pci_device_init(PCIDevice *pci_dev)
-{
-    VirtIOPCI *s =
-            DO_UPCAST(VirtIOPCI, pci_dev, pci_dev);
-
-    virtio_init_transport(&pci_dev->qdev, &s->trl, VIRTIO_PCI,
-            virtio_pci_transport_cb);
-
-    return 0;
-}
-
-static void virtio_pci_device_exit(PCIDevice *pci_dev)
-{
-    VirtIOPCI *s =
-            DO_UPCAST(VirtIOPCI, pci_dev, pci_dev);
-
-    switch (s->vdev->device_id) {
-        case VIRTIO_ID_BLOCK:
-            virtio_pci_stop_ioeventfd(s);
-            virtio_blk_exit(s->vdev);
-            break;
-        case VIRTIO_ID_NET:
-            virtio_pci_stop_ioeventfd(s);
-            virtio_net_exit(s->vdev);
-            break;
-        case VIRTIO_ID_BALLOON:
-            virtio_pci_stop_ioeventfd(s);
-            virtio_balloon_exit(s->vdev);
-            break;
-        case VIRTIO_ID_SCSI:
-            virtio_scsi_exit(s->vdev);
-            break;
-        case VIRTIO_ID_CONSOLE:
-            virtio_pci_stop_ioeventfd(s);
-            virtio_serial_exit(s->vdev);
-            break;
-        default:
-            fprintf(stderr,
-                    "Unknown back-end device id: 0x%" PRIx16 "\n",
-                    s->vdev->device_id);
-            return;
-        }
-
-    virtio_exit_pci(pci_dev);
-
-    return;
-}
-
-/******************** VirtIOPCI Device **********************/
-
-static Property virtio_pci_properties[] = {
-    DEFINE_PROP_HEX32("class", VirtIOPCI, class_code, 0),
-    DEFINE_PROP_BIT("ioeventfd", VirtIOPCI, flags,
-            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-    DEFINE_PROP_UINT32("vectors", VirtIOPCI, nvectors, 0),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_pci_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-    k->init = virtio_pci_device_init;
-    k->exit = virtio_pci_device_exit;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset_;
-    dc->props = virtio_pci_properties;
-}
-
-static TypeInfo virtio_pci_info = {
-    .name = VIRTIO_PCI,
-    .parent = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCI),
-    .class_init = virtio_pci_class_init,
-};
-
-/************************************************************/
-
-static void virtio_pci_register_types(void)
-{
-    type_register_static(&virtio_pci_info);
-}
-
-type_init(virtio_pci_register_types)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
deleted file mode 100755 (executable)
index d087b99..0000000
+++ /dev/null
@@ -1,1356 +0,0 @@
-/*
- * Virtio PCI Bindings
- *
- * Copyright IBM, Corp. 2007
- * Copyright (c) 2009 CodeSourcery
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Paul Brook        <paul@codesourcery.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-
-#include <inttypes.h>
-
-#include "virtio.h"
-#include "virtio-blk.h"
-#include "virtio-net.h"
-#include "virtio-serial.h"
-#include "virtio-scsi.h"
-#include "pci.h"
-#include "qemu-error.h"
-#include "msi.h"
-#include "msix.h"
-#include "net.h"
-#include "loader.h"
-#include "kvm.h"
-#include "blockdev.h"
-#include "virtio-pci.h"
-#include "range.h"
-#ifdef CONFIG_MARU
-#include "../tizen/src/hw/maru_device_ids.h"
-#include "../tizen/src/hw/maru_virtio_evdi.h"
-#include "../tizen/src/mloop_event.h"
-#endif
-
-/* from Linux's linux/virtio_pci.h */
-
-/* A 32-bit r/o bitmask of the features supported by the host */
-#define VIRTIO_PCI_HOST_FEATURES        0
-
-/* A 32-bit r/w bitmask of features activated by the guest */
-#define VIRTIO_PCI_GUEST_FEATURES       4
-
-/* A 32-bit r/w PFN for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_PFN            8
-
-/* A 16-bit r/o queue size for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_NUM            12
-
-/* A 16-bit r/w queue selector */
-#define VIRTIO_PCI_QUEUE_SEL            14
-
-/* A 16-bit r/w queue notifier */
-#define VIRTIO_PCI_QUEUE_NOTIFY         16
-
-/* An 8-bit device status register.  */
-#define VIRTIO_PCI_STATUS               18
-
-/* An 8-bit r/o interrupt status register.  Reading the value will return the
- * current contents of the ISR and will also clear it.  This is effectively
- * a read-and-acknowledge. */
-#define VIRTIO_PCI_ISR                  19
-
-/* MSI-X registers: only enabled if MSI-X is enabled. */
-/* A 16-bit vector for configuration changes. */
-#define VIRTIO_MSI_CONFIG_VECTOR        20
-/* A 16-bit vector for selected queue notifications. */
-#define VIRTIO_MSI_QUEUE_VECTOR         22
-
-/* Config space size */
-#define VIRTIO_PCI_CONFIG_NOMSI         20
-#define VIRTIO_PCI_CONFIG_MSI           24
-#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
-                                         VIRTIO_PCI_CONFIG_MSI : \
-                                         VIRTIO_PCI_CONFIG_NOMSI)
-
-/* The remaining space is defined by each driver as the per-driver
- * configuration space */
-#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
-                                         VIRTIO_PCI_CONFIG_MSI : \
-                                         VIRTIO_PCI_CONFIG_NOMSI)
-
-/* How many bits to shift physical queue address written to QUEUE_PFN.
- * 12 is historical, and due to x86 page size. */
-#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
-
-/* Flags track per-device state like workarounds for quirks in older guests. */
-#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
-
-/* QEMU doesn't strictly need write barriers since everything runs in
- * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
- * KVM or if kqemu gets SMP support.
- */
-#define wmb() do { } while (0)
-
-/* HACK for virtio to determine if it's running a big endian guest */
-bool virtio_is_big_endian(void);
-
-/* virtio device */
-
-static void virtio_pci_notify(void *opaque, uint16_t vector)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    if (msix_enabled(&proxy->pci_dev))
-        msix_notify(&proxy->pci_dev, vector);
-    else
-        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
-}
-
-static void virtio_pci_save_config(void * opaque, QEMUFile *f)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    pci_device_save(&proxy->pci_dev, f);
-    msix_save(&proxy->pci_dev, f);
-    if (msix_present(&proxy->pci_dev))
-        qemu_put_be16(f, proxy->vdev->config_vector);
-}
-
-static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    if (msix_present(&proxy->pci_dev))
-        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
-}
-
-static int virtio_pci_load_config(void * opaque, QEMUFile *f)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    int ret;
-    ret = pci_device_load(&proxy->pci_dev, f);
-    if (ret) {
-        return ret;
-    }
-    msix_unuse_all_vectors(&proxy->pci_dev);
-    msix_load(&proxy->pci_dev, f);
-    if (msix_present(&proxy->pci_dev)) {
-        qemu_get_be16s(f, &proxy->vdev->config_vector);
-    } else {
-        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
-    }
-    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
-    }
-    return 0;
-}
-
-static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint16_t vector;
-    if (msix_present(&proxy->pci_dev)) {
-        qemu_get_be16s(f, &vector);
-    } else {
-        vector = VIRTIO_NO_VECTOR;
-    }
-    virtio_queue_set_vector(proxy->vdev, n, vector);
-    if (vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&proxy->pci_dev, vector);
-    }
-    return 0;
-}
-
-static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
-                                                 int n, bool assign, bool set_handler)
-{
-    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
-    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
-    int r = 0;
-
-    if (assign) {
-        r = event_notifier_init(notifier, 1);
-        if (r < 0) {
-            error_report("%s: unable to init event notifier: %d",
-                         __func__, r);
-            return r;
-        }
-        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
-        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
-                                  true, n, notifier);
-    } else {
-        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
-                                  true, n, notifier);
-        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
-        event_notifier_cleanup(notifier);
-    }
-    return r;
-}
-
-static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
-{
-    int n, r;
-
-    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
-        proxy->ioeventfd_disabled ||
-        proxy->ioeventfd_started) {
-        return;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(proxy->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-    proxy->ioeventfd_started = true;
-    return;
-
-assign_error:
-    while (--n >= 0) {
-        if (!virtio_queue_get_num(proxy->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
-        assert(r >= 0);
-    }
-    proxy->ioeventfd_started = false;
-    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
-}
-
-static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
-{
-    int r;
-    int n;
-
-    if (!proxy->ioeventfd_started) {
-        return;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(proxy->vdev, n)) {
-            continue;
-        }
-
-        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
-        assert(r >= 0);
-    }
-    proxy->ioeventfd_started = false;
-}
-
-void virtio_pci_reset(DeviceState *d)
-{
-    VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_reset(proxy->vdev);
-    msix_unuse_all_vectors(&proxy->pci_dev);
-    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-}
-
-static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    VirtIODevice *vdev = proxy->vdev;
-    target_phys_addr_t pa;
-
-    switch (addr) {
-    case VIRTIO_PCI_GUEST_FEATURES:
-    /* Guest does not negotiate properly?  We have to assume nothing. */
-    if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
-            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
-    }
-        virtio_set_features(vdev, val);
-        break;
-    case VIRTIO_PCI_QUEUE_PFN:
-        pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
-        if (pa == 0) {
-            virtio_pci_stop_ioeventfd(proxy);
-            virtio_reset(proxy->vdev);
-            msix_unuse_all_vectors(&proxy->pci_dev);
-        }
-        else
-            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
-        break;
-    case VIRTIO_PCI_QUEUE_SEL:
-        if (val < VIRTIO_PCI_QUEUE_MAX)
-            vdev->queue_sel = val;
-        break;
-    case VIRTIO_PCI_QUEUE_NOTIFY:
-        if (val < VIRTIO_PCI_QUEUE_MAX) {
-            virtio_queue_notify(vdev, val);
-        }
-        break;
-    case VIRTIO_PCI_STATUS:
-        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
-            virtio_pci_stop_ioeventfd(proxy);
-        }
-
-        virtio_set_status(vdev, val & 0xFF);
-
-        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
-            virtio_pci_start_ioeventfd(proxy);
-        }
-
-        if (vdev->status == 0) {
-            virtio_reset(proxy->vdev);
-            msix_unuse_all_vectors(&proxy->pci_dev);
-        }
-
-        /* Linux before 2.6.34 sets the device as OK without enabling
-           the PCI device bus master bit. In this case we need to disable
-           some safety checks. */
-        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-        }
-        break;
-    case VIRTIO_MSI_CONFIG_VECTOR:
-        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
-        /* Make it possible for guest to discover an error took place. */
-        if (msix_vector_use(&proxy->pci_dev, val) < 0)
-            val = VIRTIO_NO_VECTOR;
-        vdev->config_vector = val;
-        break;
-    case VIRTIO_MSI_QUEUE_VECTOR:
-        msix_vector_unuse(&proxy->pci_dev,
-                          virtio_queue_vector(vdev, vdev->queue_sel));
-        /* Make it possible for guest to discover an error took place. */
-        if (msix_vector_use(&proxy->pci_dev, val) < 0)
-            val = VIRTIO_NO_VECTOR;
-        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
-        break;
-    default:
-        error_report("%s: unexpected address 0x%x value 0x%x",
-                     __func__, addr, val);
-        break;
-    }
-}
-
-static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
-{
-    VirtIODevice *vdev = proxy->vdev;
-    uint32_t ret = 0xFFFFFFFF;
-
-    switch (addr) {
-    case VIRTIO_PCI_HOST_FEATURES:
-        ret = proxy->host_features;
-        break;
-    case VIRTIO_PCI_GUEST_FEATURES:
-        ret = vdev->guest_features;
-        break;
-    case VIRTIO_PCI_QUEUE_PFN:
-        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
-              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
-        break;
-    case VIRTIO_PCI_QUEUE_NUM:
-        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
-        break;
-    case VIRTIO_PCI_QUEUE_SEL:
-        ret = vdev->queue_sel;
-        break;
-    case VIRTIO_PCI_STATUS:
-        ret = vdev->status;
-        break;
-    case VIRTIO_PCI_ISR:
-        /* reading from the ISR also clears it. */
-        ret = vdev->isr;
-        vdev->isr = 0;
-        qemu_set_irq(proxy->pci_dev.irq[0], 0);
-        break;
-    case VIRTIO_MSI_CONFIG_VECTOR:
-        ret = vdev->config_vector;
-        break;
-    case VIRTIO_MSI_QUEUE_VECTOR:
-        ret = virtio_queue_vector(vdev, vdev->queue_sel);
-        break;
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    if (addr < config)
-        return virtio_ioport_read(proxy, addr);
-    addr -= config;
-    return virtio_config_readb(proxy->vdev, addr);
-}
-
-static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    uint16_t val;
-    if (addr < config)
-        return virtio_ioport_read(proxy, addr);
-    addr -= config;
-    val = virtio_config_readw(proxy->vdev, addr);
-    if (virtio_is_big_endian()) {
-        /*
-         * virtio is odd, ioports are LE but config space is target native
-         * endian. However, in qemu, all PIO is LE, so we need to re-swap
-         * on BE targets
-         */
-        val = bswap16(val);
-    }
-    return val;
-}
-
-static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    uint32_t val;
-    if (addr < config)
-        return virtio_ioport_read(proxy, addr);
-    addr -= config;
-    val = virtio_config_readl(proxy->vdev, addr);
-    if (virtio_is_big_endian()) {
-        val = bswap32(val);
-    }
-    return val;
-}
-
-static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(proxy, addr, val);
-        return;
-    }
-    addr -= config;
-    virtio_config_writeb(proxy->vdev, addr, val);
-}
-
-static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(proxy, addr, val);
-        return;
-    }
-    addr -= config;
-    if (virtio_is_big_endian()) {
-        val = bswap16(val);
-    }
-    virtio_config_writew(proxy->vdev, addr, val);
-}
-
-static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
-    if (addr < config) {
-        virtio_ioport_write(proxy, addr, val);
-        return;
-    }
-    addr -= config;
-    if (virtio_is_big_endian()) {
-        val = bswap32(val);
-    }
-    virtio_config_writel(proxy->vdev, addr, val);
-}
-
-static const MemoryRegionPortio virtio_portio[] = {
-    { 0, 0x10000, 1, .write = virtio_pci_config_writeb, },
-    { 0, 0x10000, 2, .write = virtio_pci_config_writew, },
-    { 0, 0x10000, 4, .write = virtio_pci_config_writel, },
-    { 0, 0x10000, 1, .read = virtio_pci_config_readb, },
-    { 0, 0x10000, 2, .read = virtio_pci_config_readw, },
-    { 0, 0x10000, 4, .read = virtio_pci_config_readl, },
-    PORTIO_END_OF_LIST()
-};
-
-static const MemoryRegionOps virtio_pci_config_ops = {
-    .old_portio = virtio_portio,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
-                                uint32_t val, int len)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    pci_default_write_config(pci_dev, address, val, len);
-
-    if (range_covers_byte(address, len, PCI_COMMAND) &&
-        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
-        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
-        virtio_pci_stop_ioeventfd(proxy);
-        virtio_set_status(proxy->vdev,
-                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
-    }
-}
-
-static unsigned virtio_pci_get_features(void *opaque)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    return proxy->host_features;
-}
-
-static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
-                                        unsigned int queue_no,
-                                        unsigned int vector,
-                                        MSIMessage msg)
-{
-    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-    int ret;
-
-    if (irqfd->users == 0) {
-        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
-        if (ret < 0) {
-            return ret;
-        }
-        irqfd->virq = ret;
-    }
-    irqfd->users++;
-
-    ret = kvm_irqchip_add_irq_notifier(kvm_state, n, irqfd->virq);
-    if (ret < 0) {
-        if (--irqfd->users == 0) {
-            kvm_irqchip_release_virq(kvm_state, irqfd->virq);
-        }
-        return ret;
-    }
-
-    virtio_queue_set_guest_notifier_fd_handler(vq, true, true);
-    return 0;
-}
-
-static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
-                                             unsigned int queue_no,
-                                             unsigned int vector)
-{
-    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
-    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
-    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
-    int ret;
-
-    ret = kvm_irqchip_remove_irq_notifier(kvm_state, n, irqfd->virq);
-    assert(ret == 0);
-
-    if (--irqfd->users == 0) {
-        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
-    }
-
-    virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
-}
-
-static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
-                                     MSIMessage msg)
-{
-    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
-    VirtIODevice *vdev = proxy->vdev;
-    int ret, queue_no;
-
-    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
-        if (!virtio_queue_get_num(vdev, queue_no)) {
-            break;
-        }
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
-        if (ret < 0) {
-            goto undo;
-        }
-    }
-    return 0;
-
-undo:
-    while (--queue_no >= 0) {
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
-    }
-    return ret;
-}
-
-static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
-{
-    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
-    VirtIODevice *vdev = proxy->vdev;
-    int queue_no;
-
-    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
-        if (!virtio_queue_get_num(vdev, queue_no)) {
-            break;
-        }
-        if (virtio_queue_vector(vdev, queue_no) != vector) {
-            continue;
-        }
-        kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
-    }
-}
-
-static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
-    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
-
-    if (assign) {
-        int r = event_notifier_init(notifier, 0);
-        if (r < 0) {
-            return r;
-        }
-        virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
-    } else {
-        virtio_queue_set_guest_notifier_fd_handler(vq, false, false);
-        event_notifier_cleanup(notifier);
-    }
-
-    return 0;
-}
-
-static bool virtio_pci_query_guest_notifiers(void *opaque)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    return msix_enabled(&proxy->pci_dev);
-}
-
-static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
-{
-    VirtIOPCIProxy *proxy = opaque;
-    VirtIODevice *vdev = proxy->vdev;
-    int r, n;
-
-    /* Must unset vector notifier while guest notifier is still assigned */
-    if (kvm_msi_via_irqfd_enabled() && !assign) {
-        msix_unset_vector_notifiers(&proxy->pci_dev);
-        g_free(proxy->vector_irqfd);
-        proxy->vector_irqfd = NULL;
-    }
-
-    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
-        if (!virtio_queue_get_num(vdev, n)) {
-            break;
-        }
-
-        r = virtio_pci_set_guest_notifier(opaque, n, assign);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-
-    /* Must set vector notifier after guest notifier has been assigned */
-    if (kvm_msi_via_irqfd_enabled() && assign) {
-        proxy->vector_irqfd =
-            g_malloc0(sizeof(*proxy->vector_irqfd) *
-                      msix_nr_vectors_allocated(&proxy->pci_dev));
-        r = msix_set_vector_notifiers(&proxy->pci_dev,
-                                      kvm_virtio_pci_vector_use,
-                                      kvm_virtio_pci_vector_release);
-        if (r < 0) {
-            goto assign_error;
-        }
-    }
-
-    return 0;
-
-assign_error:
-    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
-    assert(assign);
-    while (--n >= 0) {
-        virtio_pci_set_guest_notifier(opaque, n, !assign);
-    }
-    return r;
-}
-
-static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
-{
-    VirtIOPCIProxy *proxy = opaque;
-
-    /* Stop using ioeventfd for virtqueue kick if the device starts using host
-     * notifiers.  This makes it easy to avoid stepping on each others' toes.
-     */
-    proxy->ioeventfd_disabled = assign;
-    if (assign) {
-        virtio_pci_stop_ioeventfd(proxy);
-    }
-    /* We don't need to start here: it's not needed because backend
-     * currently only stops on status change away from ok,
-     * reset, vmstop and such. If we do add code to start here,
-     * need to check vmstate, device state etc. */
-    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
-}
-
-static void virtio_pci_vmstate_change(void *opaque, bool running)
-{
-    VirtIOPCIProxy *proxy = opaque;
-
-    if (running) {
-        /* Try to find out if the guest has bus master disabled, but is
-           in ready state. Then we have a buggy guest OS. */
-        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
-            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
-            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
-        }
-        virtio_pci_start_ioeventfd(proxy);
-    } else {
-        virtio_pci_stop_ioeventfd(proxy);
-    }
-}
-
-static const VirtIOBindings virtio_pci_bindings = {
-    .notify = virtio_pci_notify,
-    .save_config = virtio_pci_save_config,
-    .load_config = virtio_pci_load_config,
-    .save_queue = virtio_pci_save_queue,
-    .load_queue = virtio_pci_load_queue,
-    .get_features = virtio_pci_get_features,
-    .query_guest_notifiers = virtio_pci_query_guest_notifiers,
-    .set_host_notifier = virtio_pci_set_host_notifier,
-    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
-    .vmstate_change = virtio_pci_vmstate_change,
-};
-
-void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
-{
-    uint8_t *config;
-    uint32_t size;
-
-    proxy->vdev = vdev;
-
-    config = proxy->pci_dev.config;
-
-    if (proxy->class_code) {
-        pci_config_set_class(config, proxy->class_code);
-    }
-    pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
-                 pci_get_word(config + PCI_VENDOR_ID));
-    pci_set_word(config + PCI_SUBSYSTEM_ID, vdev->device_id);
-    config[PCI_INTERRUPT_PIN] = 1;
-
-    if (vdev->nvectors &&
-        msix_init_exclusive_bar(&proxy->pci_dev, vdev->nvectors, 1)) {
-        vdev->nvectors = 0;
-    }
-
-    proxy->pci_dev.config_write = virtio_write_config;
-
-    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
-    if (size & (size-1))
-        size = 1 << qemu_fls(size);
-
-    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
-                          "virtio-pci", size);
-    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
-                     &proxy->bar);
-
-    if (!kvm_has_many_ioeventfds()) {
-        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
-    }
-
-    virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
-    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
-    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
-    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
-}
-
-static int virtio_blk_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
-        proxy->class_code != PCI_CLASS_STORAGE_OTHER)
-        proxy->class_code = PCI_CLASS_STORAGE_SCSI;
-
-    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->blk);
-    if (!vdev) {
-        return -1;
-    }
-    vdev->nvectors = proxy->nvectors;
-    virtio_init_pci(proxy, vdev);
-    /* make the actual value visible */
-    proxy->nvectors = vdev->nvectors;
-    return 0;
-}
-
-static void virtio_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    memory_region_destroy(&proxy->bar);
-    msix_uninit_exclusive_bar(pci_dev);
-}
-
-static void virtio_blk_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_blk_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_serial_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
-        proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
-        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
-        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
-
-    vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
-    if (!vdev) {
-        return -1;
-    }
-    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
-                                        ? proxy->serial.max_virtserial_ports + 1
-                                        : proxy->nvectors;
-    virtio_init_pci(proxy, vdev);
-    proxy->nvectors = vdev->nvectors;
-    return 0;
-}
-
-static void virtio_serial_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_serial_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_net_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
-
-    vdev->nvectors = proxy->nvectors;
-    virtio_init_pci(proxy, vdev);
-
-    /* make the actual value visible */
-    proxy->nvectors = vdev->nvectors;
-    return 0;
-}
-
-static void virtio_net_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_net_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_balloon_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    if (proxy->class_code != PCI_CLASS_OTHERS &&
-        proxy->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
-        proxy->class_code = PCI_CLASS_OTHERS;
-    }
-
-    vdev = virtio_balloon_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void virtio_balloon_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_balloon_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-#ifdef CONFIG_GL_BACKEND
-#if defined(CONFIG_MARU) 
-static int virtio_gl_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_gl_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-#endif
-#endif
-
-#ifdef CONFIG_MARU
-static int maru_virtio_touchscreen_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = maru_virtio_touchscreen_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void maru_virtio_touchscreen_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    maru_virtio_touchscreen_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_keyboard_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_keyboard_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void virtio_keyboard_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_keyboard_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_esm_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_esm_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void virtio_esm_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_esm_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_hwkey_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = maru_virtio_hwkey_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void virtio_hwkey_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    maru_virtio_hwkey_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static int virtio_evdi_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_evdi_init(&pci_dev->qdev);
-    if (!vdev) {
-        return -1;
-    }
-    virtio_init_pci(proxy, vdev);
-    return 0;
-}
-
-static void virtio_evdi_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_pci_stop_ioeventfd(proxy);
-    virtio_evdi_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-#endif
-
-static Property virtio_blk_properties[] = {
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, blk.conf),
-    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOPCIProxy, blk.conf),
-    DEFINE_PROP_STRING("serial", VirtIOPCIProxy, blk.serial),
-#ifdef __linux__
-    DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true),
-#endif
-    DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
-    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-    DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_blk_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_blk_init_pci;
-    k->exit = virtio_blk_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_STORAGE_SCSI;
-    dc->reset = virtio_pci_reset;
-    dc->props = virtio_blk_properties;
-}
-
-static TypeInfo virtio_blk_info = {
-    .name          = "virtio-blk-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_blk_class_init,
-};
-
-static Property virtio_net_properties[] = {
-    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
-    DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
-    DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
-    DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
-    DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_net_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_net_init_pci;
-    k->exit = virtio_net_exit_pci;
-    k->romfile = "pxe-virtio.rom";
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
-    dc->reset = virtio_pci_reset;
-    dc->props = virtio_net_properties;
-}
-
-static TypeInfo virtio_net_info = {
-    .name          = "virtio-net-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_net_class_init,
-};
-
-static Property virtio_serial_properties[] = {
-    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_serial_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_serial_init_pci;
-    k->exit = virtio_serial_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
-    dc->reset = virtio_pci_reset;
-    dc->props = virtio_serial_properties;
-}
-
-static TypeInfo virtio_serial_info = {
-    .name          = "virtio-serial-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_serial_class_init,
-};
-
-static Property virtio_balloon_properties[] = {
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_balloon_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_balloon_init_pci;
-    k->exit = virtio_balloon_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-    dc->props = virtio_balloon_properties;
-}
-
-static TypeInfo virtio_balloon_info = {
-    .name          = "virtio-balloon-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_balloon_class_init,
-};
-
-static int virtio_scsi_init_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-    VirtIODevice *vdev;
-
-    vdev = virtio_scsi_init(&pci_dev->qdev, &proxy->scsi);
-    if (!vdev) {
-        return -EINVAL;
-    }
-
-    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
-                                        ? proxy->scsi.num_queues + 3
-                                        : proxy->nvectors;
-    virtio_init_pci(proxy, vdev);
-
-    /* make the actual value visible */
-    proxy->nvectors = vdev->nvectors;
-    return 0;
-}
-
-static void virtio_scsi_exit_pci(PCIDevice *pci_dev)
-{
-    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
-    virtio_scsi_exit(proxy->vdev);
-    virtio_exit_pci(pci_dev);
-}
-
-static Property virtio_scsi_properties[] = {
-    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
-    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOPCIProxy, host_features, scsi),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_scsi_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_scsi_init_pci;
-    k->exit = virtio_scsi_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
-    k->revision = 0x00;
-    k->class_id = PCI_CLASS_STORAGE_SCSI;
-    dc->reset = virtio_pci_reset;
-    dc->props = virtio_scsi_properties;
-}
-
-static TypeInfo virtio_scsi_info = {
-    .name          = "virtio-scsi-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_scsi_class_init,
-};
-
-#if defined(CONFIG_MARU)
-#ifdef CONFIG_GL_BACKEND
-static void virtio_gl_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_gl_init_pci;
-    k->exit = virtio_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_GL;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo virtio_gl_info = {
-    .name          = "virtio-gl-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_gl_class_init,
-};
-#endif
-#endif
-
-#ifdef CONFIG_MARU
-static void maru_virtio_touchscreen_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = maru_virtio_touchscreen_init_pci;
-    k->exit = maru_virtio_touchscreen_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo maru_virtio_touchscreen_info = {
-    .name          = "virtio-touchscreen-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = maru_virtio_touchscreen_class_init,
-};
-
-static void virtio_keyboard_class_init(ObjectClass *klass, void *data) {
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_keyboard_init_pci;
-    k->exit = virtio_keyboard_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_KEYBOARD;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo virtio_keyboard_info = {
-    .name          = "virtio-keyboard-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_keyboard_class_init,
-};
-
-static void virtio_esm_class_init(ObjectClass *klass, void *data) {
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_esm_init_pci;
-    k->exit = virtio_esm_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_ESM;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo virtio_esm_info = {
-    .name          = "virtio-esm-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_esm_class_init,
-};
-
-static void virtio_hwkey_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_hwkey_init_pci;
-    k->exit = virtio_hwkey_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_HWKEY;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo virtio_hwkey_info = {
-    .name          = "virtio-hwkey-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_hwkey_class_init,
-};
-
-static void virtio_evdi_class_init(ObjectClass *klass, void *data) {
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_evdi_init_pci;
-    k->exit = virtio_evdi_exit_pci;
-    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    k->device_id = PCI_DEVICE_ID_VIRTIO_EVDI;
-    k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = virtio_pci_reset;
-}
-
-static TypeInfo virtio_evdi_info = {
-    .name          = "virtio-evdi-pci",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(VirtIOPCIProxy),
-    .class_init    = virtio_evdi_class_init,
-};
-
-
-#endif /* CONFIG_MARU */
-
-static void virtio_pci_register_types(void)
-{
-    type_register_static(&virtio_blk_info);
-    type_register_static(&virtio_net_info);
-    type_register_static(&virtio_serial_info);
-    type_register_static(&virtio_balloon_info);
-    type_register_static(&virtio_scsi_info);
-#ifdef CONFIG_GL_BACKEND
-    type_register_static(&virtio_gl_info);
-#endif
-#ifdef CONFIG_MARU
-    type_register_static(&maru_virtio_touchscreen_info);
-    type_register_static(&virtio_keyboard_info);
-    type_register_static(&virtio_esm_info);
-    type_register_static(&virtio_hwkey_info);
-    type_register_static(&virtio_evdi_info);
-#endif
-}
-
-type_init(virtio_pci_register_types)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
deleted file mode 100644 (file)
index 2cddd67..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Virtio PCI Bindings
- *
- * Copyright IBM, Corp. 2007
- * Copyright (c) 2009 CodeSourcery
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Paul Brook        <paul@codesourcery.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_VIRTIO_PCI_H
-#define QEMU_VIRTIO_PCI_H
-
-#include "virtio-blk.h"
-#include "virtio-net.h"
-#include "virtio-serial.h"
-#include "virtio-scsi.h"
-
-/* Performance improves when virtqueue kick processing is decoupled from the
- * vcpu thread using ioeventfd for some devices. */
-#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
-#define VIRTIO_PCI_FLAG_USE_IOEVENTFD   (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
-
-typedef struct {
-    int virq;
-    unsigned int users;
-} VirtIOIRQFD;
-
-typedef struct {
-    PCIDevice pci_dev;
-    VirtIODevice *vdev;
-    MemoryRegion bar;
-    uint32_t flags;
-    uint32_t class_code;
-    uint32_t nvectors;
-    VirtIOBlkConf blk;
-    NICConf nic;
-    uint32_t host_features;
-#ifdef CONFIG_LINUX
-    V9fsConf fsconf;
-#endif
-    virtio_serial_conf serial;
-    virtio_net_conf net;
-    VirtIOSCSIConf scsi;
-    bool ioeventfd_disabled;
-    bool ioeventfd_started;
-    VirtIOIRQFD *vector_irqfd;
-} VirtIOPCIProxy;
-
-typedef struct {
-    PCIDevice pci_dev;
-    VirtIODevice *vdev;
-    MemoryRegion bar;
-
-    uint32_t flags;
-    uint32_t class_code;
-    uint32_t nvectors;
-    uint32_t host_features;
-
-    VirtIOTransportLink *trl;
-
-    bool ioeventfd_disabled;
-    bool ioeventfd_started;
-    VirtIOIRQFD *vector_irqfd;
-} VirtIOPCI;
-
-void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
-void virtio_pci_reset(DeviceState *d);
-void virtio_pci_reset_(DeviceState *d);
-
-/* Virtio ABI version, if we increment this, we break the guest driver. */
-#define VIRTIO_PCI_ABI_VERSION          0
-
-#endif
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
deleted file mode 100644 (file)
index 699a485..0000000
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * A bus for connecting virtio serial and console ports
- *
- * Copyright (C) 2009, 2010 Red Hat, Inc.
- *
- * Author(s):
- *  Amit Shah <amit.shah@redhat.com>
- *
- * Some earlier parts are:
- *  Copyright IBM, Corp. 2008
- * authored by
- *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "iov.h"
-#include "monitor.h"
-#include "qemu-queue.h"
-#include "sysbus.h"
-#include "trace.h"
-#include "virtio-serial.h"
-#include "virtio-transport.h"
-
-/* The virtio-serial bus on top of which the ports will ride as devices */
-struct VirtIOSerialBus {
-    BusState qbus;
-
-    /* This is the parent device that provides the bus for ports. */
-    VirtIOSerial *vser;
-
-    /* The maximum number of ports that can ride on top of this bus */
-    uint32_t max_nr_ports;
-};
-
-struct VirtIOSerial {
-    VirtIODevice vdev;
-
-    VirtQueue *c_ivq, *c_ovq;
-    /* Arrays of ivqs and ovqs: one per port */
-    VirtQueue **ivqs, **ovqs;
-
-    VirtIOSerialBus bus;
-
-    DeviceState *qdev;
-
-    QTAILQ_HEAD(, VirtIOSerialPort) ports;
-
-    /* bitmap for identifying active ports */
-    uint32_t *ports_map;
-
-    struct virtio_console_config config;
-};
-
-static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
-{
-    VirtIOSerialPort *port;
-
-    if (id == VIRTIO_CONSOLE_BAD_ID) {
-        return NULL;
-    }
-
-    QTAILQ_FOREACH(port, &vser->ports, next) {
-        if (port->id == id)
-            return port;
-    }
-    return NULL;
-}
-
-static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
-{
-    VirtIOSerialPort *port;
-
-    QTAILQ_FOREACH(port, &vser->ports, next) {
-        if (port->ivq == vq || port->ovq == vq)
-            return port;
-    }
-    return NULL;
-}
-
-static bool use_multiport(VirtIOSerial *vser)
-{
-    return vser->vdev.guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
-}
-
-static size_t write_to_port(VirtIOSerialPort *port,
-                            const uint8_t *buf, size_t size)
-{
-    VirtQueueElement elem;
-    VirtQueue *vq;
-    size_t offset;
-
-    vq = port->ivq;
-    if (!virtio_queue_ready(vq)) {
-        return 0;
-    }
-
-    offset = 0;
-    while (offset < size) {
-        size_t len;
-
-        if (!virtqueue_pop(vq, &elem)) {
-            break;
-        }
-
-        len = iov_from_buf(elem.in_sg, elem.in_num, 0,
-                           buf + offset, size - offset);
-        offset += len;
-
-        virtqueue_push(vq, &elem, len);
-    }
-
-    virtio_notify(&port->vser->vdev, vq);
-    return offset;
-}
-
-static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
-{
-    VirtQueueElement elem;
-
-    if (!virtio_queue_ready(vq)) {
-        return;
-    }
-    while (virtqueue_pop(vq, &elem)) {
-        virtqueue_push(vq, &elem, 0);
-    }
-    virtio_notify(vdev, vq);
-}
-
-static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
-                                 VirtIODevice *vdev)
-{
-    VirtIOSerialPortClass *vsc;
-
-    assert(port);
-    assert(virtio_queue_ready(vq));
-
-    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-
-    while (!port->throttled) {
-        unsigned int i;
-
-        /* Pop an elem only if we haven't left off a previous one mid-way */
-        if (!port->elem.out_num) {
-            if (!virtqueue_pop(vq, &port->elem)) {
-                break;
-            }
-            port->iov_idx = 0;
-            port->iov_offset = 0;
-        }
-
-        for (i = port->iov_idx; i < port->elem.out_num; i++) {
-            size_t buf_size;
-            ssize_t ret;
-
-            buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
-            ret = vsc->have_data(port,
-                                  port->elem.out_sg[i].iov_base
-                                  + port->iov_offset,
-                                  buf_size);
-            if (ret < 0 && ret != -EAGAIN) {
-                /* We don't handle any other type of errors here */
-                abort();
-            }
-            if (ret == -EAGAIN || (ret >= 0 && ret < buf_size)) {
-               /*
-                 * this is a temporary check until chardevs can signal to
-                 * frontends that they are writable again. This prevents
-                 * the console from going into throttled mode (forever)
-                 * if virtio-console is connected to a pty without a
-                 * listener. Otherwise the guest spins forever.
-                 * We can revert this if
-                 * 1: chardevs can notify frondends
-                 * 2: the guest driver does not spin in these cases
-                 */
-                if (!vsc->is_console) {
-                    virtio_serial_throttle_port(port, true);
-                }
-                port->iov_idx = i;
-                if (ret > 0) {
-                    port->iov_offset += ret;
-                }
-                break;
-            }
-            port->iov_offset = 0;
-        }
-        if (port->throttled) {
-            break;
-        }
-        virtqueue_push(vq, &port->elem, 0);
-        port->elem.out_num = 0;
-    }
-    virtio_notify(vdev, vq);
-}
-
-static void flush_queued_data(VirtIOSerialPort *port)
-{
-    assert(port);
-
-    if (!virtio_queue_ready(port->ovq)) {
-        return;
-    }
-    do_flush_queued_data(port, port->ovq, &port->vser->vdev);
-}
-
-static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len)
-{
-    VirtQueueElement elem;
-    VirtQueue *vq;
-    struct virtio_console_control *cpkt;
-
-    vq = port->vser->c_ivq;
-    if (!virtio_queue_ready(vq)) {
-        return 0;
-    }
-    if (!virtqueue_pop(vq, &elem)) {
-        return 0;
-    }
-
-    cpkt = (struct virtio_console_control *)buf;
-    stl_p(&cpkt->id, port->id);
-    memcpy(elem.in_sg[0].iov_base, buf, len);
-
-    virtqueue_push(vq, &elem, len);
-    virtio_notify(&port->vser->vdev, vq);
-    return len;
-}
-
-static size_t send_control_event(VirtIOSerialPort *port, uint16_t event,
-                                 uint16_t value)
-{
-    struct virtio_console_control cpkt;
-
-    stw_p(&cpkt.event, event);
-    stw_p(&cpkt.value, value);
-
-    trace_virtio_serial_send_control_event(port->id, event, value);
-    return send_control_msg(port, &cpkt, sizeof(cpkt));
-}
-
-/* Functions for use inside qemu to open and read from/write to ports */
-int virtio_serial_open(VirtIOSerialPort *port)
-{
-    /* Don't allow opening an already-open port */
-    if (port->host_connected) {
-        return 0;
-    }
-    /* Send port open notification to the guest */
-    port->host_connected = true;
-    send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
-
-    return 0;
-}
-
-int virtio_serial_close(VirtIOSerialPort *port)
-{
-    port->host_connected = false;
-    /*
-     * If there's any data the guest sent which the app didn't
-     * consume, reset the throttling flag and discard the data.
-     */
-    port->throttled = false;
-    discard_vq_data(port->ovq, &port->vser->vdev);
-
-    send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
-
-    return 0;
-}
-
-/* Individual ports/apps call this function to write to the guest. */
-ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
-                            size_t size)
-{
-    if (!port || !port->host_connected || !port->guest_connected) {
-        return 0;
-    }
-    return write_to_port(port, buf, size);
-}
-
-/*
- * Readiness of the guest to accept data on a port.
- * Returns max. data the guest can receive
- */
-size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
-{
-    VirtQueue *vq = port->ivq;
-
-    if (!virtio_queue_ready(vq) ||
-        !(port->vser->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) ||
-        virtio_queue_empty(vq)) {
-        return 0;
-    }
-    if (use_multiport(port->vser) && !port->guest_connected) {
-        return 0;
-    }
-
-    if (virtqueue_avail_bytes(vq, 4096, 0)) {
-        return 4096;
-    }
-    if (virtqueue_avail_bytes(vq, 1, 0)) {
-        return 1;
-    }
-    return 0;
-}
-
-static void flush_queued_data_bh(void *opaque)
-{
-    VirtIOSerialPort *port = opaque;
-
-    flush_queued_data(port);
-}
-
-void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
-{
-    if (!port) {
-        return;
-    }
-
-    trace_virtio_serial_throttle_port(port->id, throttle);
-    port->throttled = throttle;
-    if (throttle) {
-        return;
-    }
-    qemu_bh_schedule(port->bh);
-}
-
-/* Guest wants to notify us of some event */
-static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
-{
-    struct VirtIOSerialPort *port;
-    VirtIOSerialPortClass *vsc;
-    struct virtio_console_control cpkt, *gcpkt;
-    uint8_t *buffer;
-    size_t buffer_len;
-
-    gcpkt = buf;
-
-    if (len < sizeof(cpkt)) {
-        /* The guest sent an invalid control packet */
-        return;
-    }
-
-    cpkt.event = lduw_p(&gcpkt->event);
-    cpkt.value = lduw_p(&gcpkt->value);
-
-    trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
-
-    if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
-        if (!cpkt.value) {
-            error_report("virtio-serial-bus: Guest failure in adding device %s",
-                         vser->bus.qbus.name);
-            return;
-        }
-        /*
-         * The device is up, we can now tell the device about all the
-         * ports we have here.
-         */
-        QTAILQ_FOREACH(port, &vser->ports, next) {
-            send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
-        }
-        return;
-    }
-
-    port = find_port_by_id(vser, ldl_p(&gcpkt->id));
-    if (!port) {
-        error_report("virtio-serial-bus: Unexpected port id %u for device %s",
-                     ldl_p(&gcpkt->id), vser->bus.qbus.name);
-        return;
-    }
-
-    trace_virtio_serial_handle_control_message_port(port->id);
-
-    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-
-    switch(cpkt.event) {
-    case VIRTIO_CONSOLE_PORT_READY:
-        if (!cpkt.value) {
-            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
-                         port->id, vser->bus.qbus.name);
-            break;
-        }
-        /*
-         * Now that we know the guest asked for the port name, we're
-         * sure the guest has initialised whatever state is necessary
-         * for this port. Now's a good time to let the guest know if
-         * this port is a console port so that the guest can hook it
-         * up to hvc.
-         */
-        if (vsc->is_console) {
-            send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
-        }
-
-        if (port->name) {
-            stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);
-            stw_p(&cpkt.value, 1);
-
-            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
-            buffer = g_malloc(buffer_len);
-
-            memcpy(buffer, &cpkt, sizeof(cpkt));
-            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
-            buffer[buffer_len - 1] = 0;
-
-            send_control_msg(port, buffer, buffer_len);
-            g_free(buffer);
-        }
-
-        if (port->host_connected) {
-            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
-        }
-
-        /*
-         * When the guest has asked us for this information it means
-         * the guest is all setup and has its virtqueues
-         * initialised. If some app is interested in knowing about
-         * this event, let it know.
-         */
-        if (vsc->guest_ready) {
-            vsc->guest_ready(port);
-        }
-        break;
-
-    case VIRTIO_CONSOLE_PORT_OPEN:
-        port->guest_connected = cpkt.value;
-        if (cpkt.value && vsc->guest_open) {
-            /* Send the guest opened notification if an app is interested */
-            vsc->guest_open(port);
-        }
-
-        if (!cpkt.value && vsc->guest_close) {
-            /* Send the guest closed notification if an app is interested */
-            vsc->guest_close(port);
-        }
-        break;
-    }
-}
-
-static void control_in(VirtIODevice *vdev, VirtQueue *vq)
-{
-}
-
-static void control_out(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtQueueElement elem;
-    VirtIOSerial *vser;
-    uint8_t *buf;
-    size_t len;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-
-    len = 0;
-    buf = NULL;
-    while (virtqueue_pop(vq, &elem)) {
-        size_t cur_len;
-
-        cur_len = iov_size(elem.out_sg, elem.out_num);
-        /*
-         * Allocate a new buf only if we didn't have one previously or
-         * if the size of the buf differs
-         */
-        if (cur_len > len) {
-            g_free(buf);
-
-            buf = g_malloc(cur_len);
-            len = cur_len;
-        }
-        iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len);
-
-        handle_control_message(vser, buf, cur_len);
-        virtqueue_push(vq, &elem, 0);
-    }
-    g_free(buf);
-    virtio_notify(vdev, vq);
-}
-
-/* Guest wrote something to some port. */
-static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOSerial *vser;
-    VirtIOSerialPort *port;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-    port = find_port_by_vq(vser, vq);
-
-    if (!port || !port->host_connected) {
-        discard_vq_data(vq, vdev);
-        return;
-    }
-
-    if (!port->throttled) {
-        do_flush_queued_data(port, vq, vdev);
-        return;
-    }
-}
-
-static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
-{
-}
-
-static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
-{
-    VirtIOSerial *vser;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-
-    if (vser->bus.max_nr_ports > 1) {
-        features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
-    }
-    return features;
-}
-
-/* Guest requested config info */
-static void get_config(VirtIODevice *vdev, uint8_t *config_data)
-{
-    VirtIOSerial *vser;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-    memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
-}
-
-static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
-{
-    struct virtio_console_config config;
-
-    memcpy(&config, config_data, sizeof(config));
-}
-
-static void guest_reset(VirtIOSerial *vser)
-{
-    VirtIOSerialPort *port;
-    VirtIOSerialPortClass *vsc;
-
-    QTAILQ_FOREACH(port, &vser->ports, next) {
-        vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-        if (port->guest_connected) {
-            port->guest_connected = false;
-
-            if (vsc->guest_close)
-                vsc->guest_close(port);
-        }
-    }
-}
-
-static void set_status(VirtIODevice *vdev, uint8_t status)
-{
-    VirtIOSerial *vser;
-    VirtIOSerialPort *port;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-    port = find_port_by_id(vser, 0);
-
-    if (port && !use_multiport(port->vser)
-        && (status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-        /*
-         * Non-multiport guests won't be able to tell us guest
-         * open/close status.  Such guests can only have a port at id
-         * 0, so set guest_connected for such ports as soon as guest
-         * is up.
-         */
-        port->guest_connected = true;
-    }
-    if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
-        guest_reset(vser);
-    }
-}
-
-static void vser_reset(VirtIODevice *vdev)
-{
-    VirtIOSerial *vser;
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-    guest_reset(vser);
-}
-
-static void virtio_serial_save(QEMUFile *f, void *opaque)
-{
-    VirtIOSerial *s = opaque;
-    VirtIOSerialPort *port;
-    uint32_t nr_active_ports;
-    unsigned int i, max_nr_ports;
-
-    /* The virtio device */
-    virtio_save(&s->vdev, f);
-
-    /* The config space */
-    qemu_put_be16s(f, &s->config.cols);
-    qemu_put_be16s(f, &s->config.rows);
-
-    qemu_put_be32s(f, &s->config.max_nr_ports);
-
-    /* The ports map */
-    max_nr_ports = tswap32(s->config.max_nr_ports);
-    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_put_be32s(f, &s->ports_map[i]);
-    }
-
-    /* Ports */
-
-    nr_active_ports = 0;
-    QTAILQ_FOREACH(port, &s->ports, next) {
-        nr_active_ports++;
-    }
-
-    qemu_put_be32s(f, &nr_active_ports);
-
-    /*
-     * Items in struct VirtIOSerialPort.
-     */
-    QTAILQ_FOREACH(port, &s->ports, next) {
-        uint32_t elem_popped;
-
-        qemu_put_be32s(f, &port->id);
-        qemu_put_byte(f, port->guest_connected);
-        qemu_put_byte(f, port->host_connected);
-
-       elem_popped = 0;
-        if (port->elem.out_num) {
-            elem_popped = 1;
-        }
-        qemu_put_be32s(f, &elem_popped);
-        if (elem_popped) {
-            qemu_put_be32s(f, &port->iov_idx);
-            qemu_put_be64s(f, &port->iov_offset);
-
-            qemu_put_buffer(f, (unsigned char *)&port->elem,
-                            sizeof(port->elem));
-        }
-    }
-}
-
-static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
-{
-    VirtIOSerial *s = opaque;
-    VirtIOSerialPort *port;
-    uint32_t max_nr_ports, nr_active_ports, ports_map;
-    unsigned int i;
-    int ret;
-
-    if (version_id > 3) {
-        return -EINVAL;
-    }
-
-    /* The virtio device */
-    ret = virtio_load(&s->vdev, f);
-    if (ret) {
-        return ret;
-    }
-
-    if (version_id < 2) {
-        return 0;
-    }
-
-    /* The config space */
-    qemu_get_be16s(f, &s->config.cols);
-    qemu_get_be16s(f, &s->config.rows);
-
-    qemu_get_be32s(f, &max_nr_ports);
-    tswap32s(&max_nr_ports);
-    if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
-        /* Source could have had more ports than us. Fail migration. */
-        return -EINVAL;
-    }
-
-    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_get_be32s(f, &ports_map);
-
-        if (ports_map != s->ports_map[i]) {
-            /*
-             * Ports active on source and destination don't
-             * match. Fail migration.
-             */
-            return -EINVAL;
-        }
-    }
-
-    qemu_get_be32s(f, &nr_active_ports);
-
-    /* Items in struct VirtIOSerialPort */
-    for (i = 0; i < nr_active_ports; i++) {
-        uint32_t id;
-        bool host_connected;
-
-        id = qemu_get_be32(f);
-        port = find_port_by_id(s, id);
-        if (!port) {
-            return -EINVAL;
-        }
-
-        port->guest_connected = qemu_get_byte(f);
-        host_connected = qemu_get_byte(f);
-        if (host_connected != port->host_connected) {
-            /*
-             * We have to let the guest know of the host connection
-             * status change
-             */
-            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN,
-                               port->host_connected);
-        }
-
-        if (version_id > 2) {
-            uint32_t elem_popped;
-
-            qemu_get_be32s(f, &elem_popped);
-            if (elem_popped) {
-                qemu_get_be32s(f, &port->iov_idx);
-                qemu_get_be64s(f, &port->iov_offset);
-
-                qemu_get_buffer(f, (unsigned char *)&port->elem,
-                                sizeof(port->elem));
-                virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
-                                 port->elem.in_num, 1);
-                virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
-                                 port->elem.out_num, 1);
-
-                /*
-                 *  Port was throttled on source machine.  Let's
-                 *  unthrottle it here so data starts flowing again.
-                 */
-                virtio_serial_throttle_port(port, false);
-            }
-        }
-    }
-    return 0;
-}
-
-static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
-
-static Property virtser_props[] = {
-    DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
-    DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
-    DEFINE_PROP_END_OF_LIST()
-};
-
-#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
-#define VIRTIO_SERIAL_BUS(obj) \
-      OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
-
-static void virtser_bus_class_init(ObjectClass *klass, void *data)
-{
-    BusClass *k = BUS_CLASS(klass);
-    k->print_dev = virtser_bus_dev_print;
-}
-
-static const TypeInfo virtser_bus_info = {
-    .name = TYPE_VIRTIO_SERIAL_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(VirtIOSerialBus),
-    .class_init = virtser_bus_class_init,
-};
-
-static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
-{
-    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
-
-    monitor_printf(mon, "%*sport %d, guest %s, host %s, throttle %s\n",
-                   indent, "", port->id,
-                   port->guest_connected ? "on" : "off",
-                   port->host_connected ? "on" : "off",
-                   port->throttled ? "on" : "off");
-}
-
-/* This function is only used if a port id is not provided by the user */
-static uint32_t find_free_port_id(VirtIOSerial *vser)
-{
-    unsigned int i, max_nr_ports;
-
-    max_nr_ports = tswap32(vser->config.max_nr_ports);
-    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        uint32_t map, bit;
-
-        map = vser->ports_map[i];
-        bit = ffs(~map);
-        if (bit) {
-            return (bit - 1) + i * 32;
-        }
-    }
-    return VIRTIO_CONSOLE_BAD_ID;
-}
-
-static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
-{
-    unsigned int i;
-
-    i = port_id / 32;
-    vser->ports_map[i] |= 1U << (port_id % 32);
-}
-
-static void add_port(VirtIOSerial *vser, uint32_t port_id)
-{
-    mark_port_added(vser, port_id);
-
-    send_control_event(find_port_by_id(vser, port_id),
-                       VIRTIO_CONSOLE_PORT_ADD, 1);
-}
-
-static void remove_port(VirtIOSerial *vser, uint32_t port_id)
-{
-    VirtIOSerialPort *port;
-    unsigned int i;
-
-    i = port_id / 32;
-    vser->ports_map[i] &= ~(1U << (port_id % 32));
-
-    port = find_port_by_id(vser, port_id);
-    /* Flush out any unconsumed buffers first */
-    discard_vq_data(port->ovq, &port->vser->vdev);
-
-    send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1);
-}
-
-static int virtser_port_qdev_init(DeviceState *qdev)
-{
-    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
-    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-    VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
-    int ret, max_nr_ports;
-    bool plugging_port0;
-
-    port->vser = bus->vser;
-    port->bh = qemu_bh_new(flush_queued_data_bh, port);
-
-    assert(vsc->have_data);
-
-    /*
-     * Is the first console port we're seeing? If so, put it up at
-     * location 0. This is done for backward compatibility (old
-     * kernel, new qemu).
-     */
-    plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
-
-    if (find_port_by_id(port->vser, port->id)) {
-        error_report("virtio-serial-bus: A port already exists at id %u",
-                     port->id);
-        return -1;
-    }
-
-    if (port->id == VIRTIO_CONSOLE_BAD_ID) {
-        if (plugging_port0) {
-            port->id = 0;
-        } else {
-            port->id = find_free_port_id(port->vser);
-            if (port->id == VIRTIO_CONSOLE_BAD_ID) {
-                error_report("virtio-serial-bus: Maximum port limit for this device reached");
-                return -1;
-            }
-        }
-    }
-
-    max_nr_ports = tswap32(port->vser->config.max_nr_ports);
-    if (port->id >= max_nr_ports) {
-        error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
-                     max_nr_ports - 1);
-        return -1;
-    }
-
-    ret = vsc->init(port);
-    if (ret) {
-        return ret;
-    }
-
-    port->elem.out_num = 0;
-
-    QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
-    port->ivq = port->vser->ivqs[port->id];
-    port->ovq = port->vser->ovqs[port->id];
-
-    add_port(port->vser, port->id);
-
-    /* Send an update to the guest about this new port added */
-    virtio_notify_config(&port->vser->vdev);
-
-    return ret;
-}
-
-static int virtser_port_qdev_exit(DeviceState *qdev)
-{
-    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
-    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-    VirtIOSerial *vser = port->vser;
-
-    qemu_bh_delete(port->bh);
-    remove_port(port->vser, port->id);
-
-    QTAILQ_REMOVE(&vser->ports, port, next);
-
-    if (vsc->exit) {
-        vsc->exit(port);
-    }
-    return 0;
-}
-
-VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
-{
-    VirtIOSerial *vser;
-    VirtIODevice *vdev;
-    uint32_t i, max_supported_ports;
-
-    if (!conf->max_virtserial_ports)
-        return NULL;
-
-    /* Each port takes 2 queues, and one pair is for the control queue */
-    max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1;
-
-    if (conf->max_virtserial_ports > max_supported_ports) {
-        error_report("maximum ports supported: %u", max_supported_ports);
-        return NULL;
-    }
-
-    vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
-                              sizeof(struct virtio_console_config),
-                              sizeof(VirtIOSerial));
-
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-
-    /* Spawn a new virtio-serial bus on which the ports will ride as devices */
-    qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, dev, NULL);
-    vser->bus.qbus.allow_hotplug = 1;
-    vser->bus.vser = vser;
-    QTAILQ_INIT(&vser->ports);
-
-    vser->bus.max_nr_ports = conf->max_virtserial_ports;
-    vser->ivqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
-    vser->ovqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
-
-    /* Add a queue for host to guest transfers for port 0 (backward compat) */
-    vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
-    /* Add a queue for guest to host transfers for port 0 (backward compat) */
-    vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);
-
-    /* TODO: host to guest notifications can get dropped
-     * if the queue fills up. Implement queueing in host,
-     * this might also make it possible to reduce the control
-     * queue size: as guest preposts buffers there,
-     * this will save 4Kbyte of guest memory per entry. */
-
-    /* control queue: host to guest */
-    vser->c_ivq = virtio_add_queue(vdev, 32, control_in);
-    /* control queue: guest to host */
-    vser->c_ovq = virtio_add_queue(vdev, 32, control_out);
-
-    for (i = 1; i < vser->bus.max_nr_ports; i++) {
-        /* Add a per-port queue for host to guest transfers */
-        vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
-        /* Add a per-per queue for guest to host transfers */
-        vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
-    }
-
-    vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
-    vser->ports_map = g_malloc0(((conf->max_virtserial_ports + 31) / 32)
-        * sizeof(vser->ports_map[0]));
-    /*
-     * Reserve location 0 for a console port for backward compat
-     * (old kernel, new qemu)
-     */
-    mark_port_added(vser, 0);
-
-    vser->vdev.get_features = get_features;
-    vser->vdev.get_config = get_config;
-    vser->vdev.set_config = set_config;
-    vser->vdev.set_status = set_status;
-    vser->vdev.reset = vser_reset;
-
-    vser->qdev = dev;
-
-    /*
-     * Register for the savevm section with the virtio-console name
-     * to preserve backward compat
-     */
-    register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
-                    virtio_serial_load, vser);
-
-    return vdev;
-}
-
-void virtio_serial_exit(VirtIODevice *vdev)
-{
-    VirtIOSerial *vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
-
-    unregister_savevm(vser->qdev, "virtio-console", vser);
-
-    g_free(vser->ivqs);
-    g_free(vser->ovqs);
-    g_free(vser->ports_map);
-
-    virtio_cleanup(vdev);
-}
-
-static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *k = DEVICE_CLASS(klass);
-    k->init = virtser_port_qdev_init;
-    k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
-    k->exit = virtser_port_qdev_exit;
-    k->unplug = qdev_simple_unplug_cb;
-    k->props = virtser_props;
-}
-
-static TypeInfo virtio_serial_port_type_info = {
-    .name = TYPE_VIRTIO_SERIAL_PORT,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(VirtIOSerialPort),
-    .abstract = true,
-    .class_size = sizeof(VirtIOSerialPortClass),
-    .class_init = virtio_serial_port_class_init,
-};
-
-static void virtio_serial_register_types(void)
-{
-    type_register_static(&virtser_bus_info);
-    type_register_static(&virtio_serial_port_type_info);
-}
-
-type_init(virtio_serial_register_types)
-
-/******************** VirtIOSer Device **********************/
-
-static int virtio_serialdev_init(DeviceState *dev)
-{
-    VirtIODevice *vdev;
-    VirtIOSerState *s = VIRTIO_SERIAL_FROM_QDEV(dev);
-    vdev = virtio_serial_init(dev, &s->serial);
-    if (!vdev) {
-        return -1;
-    }
-
-    assert(s->trl != NULL);
-
-    return virtio_call_backend_init_cb(dev, s->trl, vdev);
-}
-
-static Property virtio_serial_properties[] = {
-    DEFINE_PROP_UINT32("max_ports", VirtIOSerState,
-                       serial.max_virtserial_ports, 31),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_serial_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->init = virtio_serialdev_init;
-    dc->props = virtio_serial_properties;
-}
-
-static TypeInfo virtio_serial_info = {
-    .name = "virtio-serial",
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(VirtIOSerState),
-    .class_init = virtio_serial_class_init,
-};
-
-static void virtio_ser_register_types(void)
-{
-    type_register_static(&virtio_serial_info);
-}
-
-type_init(virtio_ser_register_types)
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
deleted file mode 100644 (file)
index c6b916a..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Virtio Serial / Console Support
- *
- * Copyright IBM, Corp. 2008
- * Copyright Red Hat, Inc. 2009, 2010
- *
- * Authors:
- *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- *  Amit Shah <amit.shah@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-#ifndef _QEMU_VIRTIO_SERIAL_H
-#define _QEMU_VIRTIO_SERIAL_H
-
-#include "sysbus.h"
-#include "qdev.h"
-#include "virtio.h"
-#include "virtio-transport.h"
-
-/* == Interface shared between the guest kernel and qemu == */
-
-/* The Virtio ID for virtio console / serial ports */
-#define VIRTIO_ID_CONSOLE              3
-
-/* Features supported */
-#define VIRTIO_CONSOLE_F_MULTIPORT     1
-
-#define VIRTIO_CONSOLE_BAD_ID           (~(uint32_t)0)
-
-struct virtio_console_config {
-    /*
-     * These two fields are used by VIRTIO_CONSOLE_F_SIZE which
-     * isn't implemented here yet
-     */
-    uint16_t cols;
-    uint16_t rows;
-
-    uint32_t max_nr_ports;
-} QEMU_PACKED;
-
-struct virtio_console_control {
-    uint32_t id;               /* Port number */
-    uint16_t event;            /* The kind of control event (see below) */
-    uint16_t value;            /* Extra information for the key */
-};
-
-struct virtio_serial_conf {
-    /* Max. number of ports we can have for a virtio-serial device */
-    uint32_t max_virtserial_ports;
-};
-
-/* Some events for the internal messages (control packets) */
-#define VIRTIO_CONSOLE_DEVICE_READY    0
-#define VIRTIO_CONSOLE_PORT_ADD                1
-#define VIRTIO_CONSOLE_PORT_REMOVE     2
-#define VIRTIO_CONSOLE_PORT_READY      3
-#define VIRTIO_CONSOLE_CONSOLE_PORT    4
-#define VIRTIO_CONSOLE_RESIZE          5
-#define VIRTIO_CONSOLE_PORT_OPEN       6
-#define VIRTIO_CONSOLE_PORT_NAME       7
-
-/* == In-qemu interface == */
-
-#define TYPE_VIRTIO_SERIAL_PORT "virtio-serial-port"
-#define VIRTIO_SERIAL_PORT(obj) \
-     OBJECT_CHECK(VirtIOSerialPort, (obj), TYPE_VIRTIO_SERIAL_PORT)
-#define VIRTIO_SERIAL_PORT_CLASS(klass) \
-     OBJECT_CLASS_CHECK(VirtIOSerialPortClass, (klass), TYPE_VIRTIO_SERIAL_PORT)
-#define VIRTIO_SERIAL_PORT_GET_CLASS(obj) \
-     OBJECT_GET_CLASS(VirtIOSerialPortClass, (obj), TYPE_VIRTIO_SERIAL_PORT)
-
-typedef struct VirtIOSerial VirtIOSerial;
-typedef struct VirtIOSerialBus VirtIOSerialBus;
-typedef struct VirtIOSerialPort VirtIOSerialPort;
-
-typedef struct VirtIOSerialPortClass {
-    DeviceClass parent_class;
-
-    /* Is this a device that binds with hvc in the guest? */
-    bool is_console;
-
-    /*
-     * The per-port (or per-app) init function that's called when a
-     * new device is found on the bus.
-     */
-    int (*init)(VirtIOSerialPort *port);
-    /*
-     * Per-port exit function that's called when a port gets
-     * hot-unplugged or removed.
-     */
-    int (*exit)(VirtIOSerialPort *port);
-
-    /* Callbacks for guest events */
-        /* Guest opened device. */
-    void (*guest_open)(VirtIOSerialPort *port);
-        /* Guest closed device. */
-    void (*guest_close)(VirtIOSerialPort *port);
-
-        /* Guest is now ready to accept data (virtqueues set up). */
-    void (*guest_ready)(VirtIOSerialPort *port);
-
-    /*
-     * Guest wrote some data to the port. This data is handed over to
-     * the app via this callback.  The app can return a size less than
-     * 'len'.  In this case, throttling will be enabled for this port.
-     */
-    ssize_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf,
-                         size_t len);
-} VirtIOSerialPortClass;
-
-/*
- * This is the state that's shared between all the ports.  Some of the
- * state is configurable via command-line options. Some of it can be
- * set by individual devices in their initfn routines. Some of the
- * state is set by the generic qdev device init routine.
- */
-struct VirtIOSerialPort {
-    DeviceState dev;
-
-    QTAILQ_ENTRY(VirtIOSerialPort) next;
-
-    /*
-     * This field gives us the virtio device as well as the qdev bus
-     * that we are associated with
-     */
-    VirtIOSerial *vser;
-
-    VirtQueue *ivq, *ovq;
-
-    /*
-     * This name is sent to the guest and exported via sysfs.
-     * The guest could create symlinks based on this information.
-     * The name is in the reverse fqdn format, like org.qemu.console.0
-     */
-    char *name;
-
-    /*
-     * This id helps identify ports between the guest and the host.
-     * The guest sends a "header" with this id with each data packet
-     * that it sends and the host can then find out which associated
-     * device to send out this data to
-     */
-    uint32_t id;
-
-    /*
-     * This is the elem that we pop from the virtqueue.  A slow
-     * backend that consumes guest data (e.g. the file backend for
-     * qemu chardevs) can cause the guest to block till all the output
-     * is flushed.  This isn't desired, so we keep a note of the last
-     * element popped and continue consuming it once the backend
-     * becomes writable again.
-     */
-    VirtQueueElement elem;
-
-    /*
-     * The index and the offset into the iov buffer that was popped in
-     * elem above.
-     */
-    uint32_t iov_idx;
-    uint64_t iov_offset;
-
-    /*
-     * When unthrottling we use a bottom-half to call flush_queued_data.
-     */
-    QEMUBH *bh;
-
-    /* Is the corresponding guest device open? */
-    bool guest_connected;
-    /* Is this device open for IO on the host? */
-    bool host_connected;
-    /* Do apps not want to receive data? */
-    bool throttled;
-};
-
-typedef struct {
-    DeviceState qdev;
-    /* virtio-serial */
-    virtio_serial_conf serial;
-    VirtIOTransportLink *trl;
-} VirtIOSerState;
-
-#define VIRTIO_SERIAL_FROM_QDEV(dev) DO_UPCAST(VirtIOSerState, qdev, dev)
-
-/* Interface to the virtio-serial bus */
-
-/*
- * Open a connection to the port
- *   Returns 0 on success (always).
- */
-int virtio_serial_open(VirtIOSerialPort *port);
-
-/*
- * Close the connection to the port
- *   Returns 0 on success (always).
- */
-int virtio_serial_close(VirtIOSerialPort *port);
-
-/*
- * Send data to Guest
- */
-ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
-                            size_t size);
-
-/*
- * Query whether a guest is ready to receive data.
- */
-size_t virtio_serial_guest_ready(VirtIOSerialPort *port);
-
-/*
- * Flow control: Ports can signal to the virtio-serial core to stop
- * sending data or re-start sending data, depending on the 'throttle'
- * value here.
- */
-void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle);
-
-#endif
diff --git a/hw/virtio-transport.c b/hw/virtio-transport.c
deleted file mode 100644 (file)
index 76360ba..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Virtio transport bindings
- *
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
- *
- * Author:
- *  Evgeny Voevodin <e.voevodin@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "virtio-transport.h"
-
-#define VIRTIO_TRANSPORT_BUS "virtio-transport"
-
-static QTAILQ_HEAD(, VirtIOTransportLink) transport_links =
-        QTAILQ_HEAD_INITIALIZER(transport_links);
-
-/*
- * Find transport device by its ID.
- */
-VirtIOTransportLink* virtio_find_transport(const char *name)
-{
-    VirtIOTransportLink *trl;
-
-    assert(name != NULL);
-
-    QTAILQ_FOREACH(trl, &transport_links, sibling) {
-        if (trl->tr->id != NULL) {
-            if (!strcmp(name, trl->tr->id)) {
-                return trl;
-            }
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Count transport devices by ID.
- */
-uint32_t virtio_count_transports(const char *name)
-{
-    VirtIOTransportLink *trl;
-    uint32_t i = 0;
-
-    QTAILQ_FOREACH(trl, &transport_links, sibling) {
-        if (name == NULL) {
-            i++;
-            continue;
-        }
-
-        if (trl->tr->id != NULL) {
-            if (!strncmp(name, trl->tr->id,strlen(name))) {
-                i++;
-            }
-        }
-    }
-    return i;
-}
-
-/*
- * Initialize new transport device
- */
-char* virtio_init_transport(DeviceState *dev, VirtIOTransportLink **trl,
-        const char* name, virtio_backend_init_cb cb)
-{
-    VirtIOTransportLink *link = g_malloc0(sizeof(VirtIOTransportLink));
-    char *buf;
-    size_t len;
-    uint32_t i;
-
-    assert(dev != NULL);
-    assert(name != NULL);
-    assert(trl != NULL);
-
-    i = virtio_count_transports(name);
-    len = strlen(name) + 16;
-    buf = g_malloc(len);
-    snprintf(buf, len, "%s.%d", name, i);
-    qbus_create(TYPE_VIRTIO_BUS, dev, buf);
-
-    /* Add new transport */
-    QTAILQ_INSERT_TAIL(&transport_links, link, sibling);
-    link->tr = dev;
-    link->cb = cb;
-    // TODO: Add a link property
-    *trl = link;
-    return buf;
-}
-
-/*
- * Unplug back-end from system bus and plug it into transport bus.
- */
-void virtio_plug_into_transport(DeviceState *dev, VirtIOTransportLink *trl)
-{
-    BusChild *kid;
-
-    /* Unplug back-end from system bus */
-    QTAILQ_FOREACH(kid, &qdev_get_parent_bus(dev)->children, sibling) {
-        if (kid->child == dev) {
-            QTAILQ_REMOVE(&qdev_get_parent_bus(dev)->children, kid, sibling);
-            break;
-        }
-    }
-
-    /* Plug back-end into transport's bus */
-    qdev_set_parent_bus(dev, QLIST_FIRST(&trl->tr->child_bus));
-
-}
-
-/*
- * Execute call-back on back-end initialization.
- * Performs initialization of MMIO or PCI transport.
- */
-int virtio_call_backend_init_cb(DeviceState *dev, VirtIOTransportLink *trl,
-        VirtIODevice *vdev)
-{
-    if (trl->cb) {
-        return trl->cb(dev, vdev, trl);
-    }
-
-    return 0;
-}
-
-static const TypeInfo virtio_bus_info = {
-    .name = TYPE_VIRTIO_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(BusState),
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_bus_info);
-}
-
-type_init(virtio_register_types)
diff --git a/hw/virtio-transport.h b/hw/virtio-transport.h
deleted file mode 100644 (file)
index 43200dc..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Virtio transport header
- *
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
- *
- * Author:
- *  Evgeny Voevodin <e.voevodin@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef VIRTIO_TRANSPORT_H_
-#define VIRTIO_TRANSPORT_H_
-
-#include "qdev.h"
-#include "qemu-common.h"
-
-#define VIRTIO_MMIO "virtio-mmio"
-#define VIRTIO_PCI "virtio-pci"
-
-#define TYPE_VIRTIO_BUS "virtio-bus"
-#define VIRTIO_BUS(obj) OBJECT_CHECK(virtio_bus, (obj), TYPE_VIRTIO_BUS)
-
-struct VirtIOTransportLink;
-
-typedef int (*virtio_backend_init_cb)(DeviceState *dev, VirtIODevice *vdev,
-             struct VirtIOTransportLink *trl);
-
-typedef struct VirtIOTransportLink {
-    DeviceState *tr;
-    virtio_backend_init_cb cb;
-    uint32_t host_features;
-    QTAILQ_ENTRY(VirtIOTransportLink) sibling;
-} VirtIOTransportLink;
-
-/*
- * Find transport device by its ID.
- */
-VirtIOTransportLink* virtio_find_transport(const char *name);
-
-/*
- * Count transport devices by ID.
- */
-uint32_t virtio_count_transports(const char *name);
-
-/*
- * Initialize new transport device
- */
-char* virtio_init_transport(DeviceState *dev, VirtIOTransportLink **trl,
-        const char* name, virtio_backend_init_cb cb);
-
-/*
- * Unplug back-end from system bus and plug it into transport bus.
- */
-void virtio_plug_into_transport(DeviceState *dev, VirtIOTransportLink *trl);
-
-/*
- * Execute call-back on back-end initialization.
- * Performs initialization of MMIO or PCI transport.
- */
-int virtio_call_backend_init_cb(DeviceState *dev, VirtIOTransportLink *trl,
-        VirtIODevice *vdev);
-
-#endif /* VIRTIO_TRANSPORT_H_ */
diff --git a/hw/virtio.c b/hw/virtio.c
deleted file mode 100644 (file)
index 4f47d4e..0000000
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
- * Virtio Support
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include <inttypes.h>
-
-#include "trace.h"
-#include "qemu-error.h"
-#include "virtio.h"
-#include "qemu-barrier.h"
-
-/* The alignment to use between consumer and producer parts of vring.
- * x86 pagesize again. This is the default, used by transports like PCI
- * which don't provide a means for the guest to tell the host the alignment.
- */
-#define VIRTIO_PCI_VRING_ALIGN         4096
-
-typedef struct VRingDesc
-{
-    uint64_t addr;
-    uint32_t len;
-    uint16_t flags;
-    uint16_t next;
-} VRingDesc;
-
-typedef struct VRingAvail
-{
-    uint16_t flags;
-    uint16_t idx;
-    uint16_t ring[0];
-} VRingAvail;
-
-typedef struct VRingUsedElem
-{
-    uint32_t id;
-    uint32_t len;
-} VRingUsedElem;
-
-typedef struct VRingUsed
-{
-    uint16_t flags;
-    uint16_t idx;
-    VRingUsedElem ring[0];
-} VRingUsed;
-
-typedef struct VRing
-{
-    unsigned int num;
-    unsigned int align;
-    target_phys_addr_t desc;
-    target_phys_addr_t avail;
-    target_phys_addr_t used;
-} VRing;
-
-struct VirtQueue
-{
-    VRing vring;
-    target_phys_addr_t pa;
-    uint16_t last_avail_idx;
-    /* Last used index value we have signalled on */
-    uint16_t signalled_used;
-
-    /* Last used index value we have signalled on */
-    bool signalled_used_valid;
-
-    /* Notification enabled? */
-    bool notification;
-
-    int inuse;
-
-    uint16_t vector;
-    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
-    VirtIODevice *vdev;
-    EventNotifier guest_notifier;
-    EventNotifier host_notifier;
-};
-
-/* virt queue functions */
-static void virtqueue_init(VirtQueue *vq)
-{
-    target_phys_addr_t pa = vq->pa;
-
-    vq->vring.desc = pa;
-    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
-    vq->vring.used = vring_align(vq->vring.avail +
-                                 offsetof(VRingAvail, ring[vq->vring.num]),
-                                 vq->vring.align);
-}
-
-static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
-{
-    target_phys_addr_t pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
-    return ldq_phys(pa);
-}
-
-static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
-{
-    target_phys_addr_t pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
-    return ldl_phys(pa);
-}
-
-static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
-{
-    target_phys_addr_t pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
-    return lduw_phys(pa);
-}
-
-static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
-{
-    target_phys_addr_t pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
-    return lduw_phys(pa);
-}
-
-static inline uint16_t vring_avail_flags(VirtQueue *vq)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.avail + offsetof(VRingAvail, flags);
-    return lduw_phys(pa);
-}
-
-static inline uint16_t vring_avail_idx(VirtQueue *vq)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.avail + offsetof(VRingAvail, idx);
-    return lduw_phys(pa);
-}
-
-static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.avail + offsetof(VRingAvail, ring[i]);
-    return lduw_phys(pa);
-}
-
-static inline uint16_t vring_used_event(VirtQueue *vq)
-{
-    return vring_avail_ring(vq, vq->vring.num);
-}
-
-static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
-    stl_phys(pa, val);
-}
-
-static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
-    stl_phys(pa, val);
-}
-
-static uint16_t vring_used_idx(VirtQueue *vq)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, idx);
-    return lduw_phys(pa);
-}
-
-static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, idx);
-    stw_phys(pa, val);
-}
-
-static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, flags);
-    stw_phys(pa, lduw_phys(pa) | mask);
-}
-
-static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
-{
-    target_phys_addr_t pa;
-    pa = vq->vring.used + offsetof(VRingUsed, flags);
-    stw_phys(pa, lduw_phys(pa) & ~mask);
-}
-
-static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
-{
-    target_phys_addr_t pa;
-    if (!vq->notification) {
-        return;
-    }
-    pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]);
-    stw_phys(pa, val);
-}
-
-void virtio_queue_set_notification(VirtQueue *vq, int enable)
-{
-    vq->notification = enable;
-    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
-        vring_avail_event(vq, vring_avail_idx(vq));
-    } else if (enable) {
-        vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
-    } else {
-        vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY);
-    }
-    if (enable) {
-        /* Expose avail event/used flags before caller checks the avail idx. */
-        smp_mb();
-    }
-}
-
-int virtio_queue_ready(VirtQueue *vq)
-{
-    return vq->vring.avail != 0;
-}
-
-int virtio_queue_empty(VirtQueue *vq)
-{
-    return vring_avail_idx(vq) == vq->last_avail_idx;
-}
-
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len, unsigned int idx)
-{
-    unsigned int offset;
-    int i;
-
-    trace_virtqueue_fill(vq, elem, len, idx);
-
-    offset = 0;
-    for (i = 0; i < elem->in_num; i++) {
-        size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
-
-        cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
-                                  elem->in_sg[i].iov_len,
-                                  1, size);
-
-        offset += elem->in_sg[i].iov_len;
-    }
-
-    for (i = 0; i < elem->out_num; i++)
-        cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
-                                  elem->out_sg[i].iov_len,
-                                  0, elem->out_sg[i].iov_len);
-
-    idx = (idx + vring_used_idx(vq)) % vq->vring.num;
-
-    /* Get a pointer to the next entry in the used ring. */
-    vring_used_ring_id(vq, idx, elem->index);
-    vring_used_ring_len(vq, idx, len);
-}
-
-void virtqueue_flush(VirtQueue *vq, unsigned int count)
-{
-    uint16_t old, new;
-    /* Make sure buffer is written before we update index. */
-    smp_wmb();
-    trace_virtqueue_flush(vq, count);
-    old = vring_used_idx(vq);
-    new = old + count;
-    vring_used_idx_set(vq, new);
-    vq->inuse -= count;
-    if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old)))
-        vq->signalled_used_valid = false;
-}
-
-void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len)
-{
-    virtqueue_fill(vq, elem, len, 0);
-    virtqueue_flush(vq, 1);
-}
-
-static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
-{
-    uint16_t num_heads = vring_avail_idx(vq) - idx;
-
-    /* Check it isn't doing very strange things with descriptor numbers. */
-    if (num_heads > vq->vring.num) {
-        error_report("Guest moved used index from %u to %u",
-                     idx, vring_avail_idx(vq));
-        exit(1);
-    }
-    /* On success, callers read a descriptor at vq->last_avail_idx.
-     * Make sure descriptor read does not bypass avail index read. */
-    if (num_heads) {
-        smp_rmb();
-    }
-
-    return num_heads;
-}
-
-static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
-{
-    unsigned int head;
-
-    /* Grab the next descriptor number they're advertising, and increment
-     * the index we've seen. */
-    head = vring_avail_ring(vq, idx % vq->vring.num);
-
-    /* If their number is silly, that's a fatal mistake. */
-    if (head >= vq->vring.num) {
-        error_report("Guest says index %u is available", head);
-        exit(1);
-    }
-
-    return head;
-}
-
-static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
-                                    unsigned int i, unsigned int max)
-{
-    unsigned int next;
-
-    /* If this descriptor says it doesn't chain, we're done. */
-    if (!(vring_desc_flags(desc_pa, i) & VRING_DESC_F_NEXT))
-        return max;
-
-    /* Check they're not leading us off end of descriptors. */
-    next = vring_desc_next(desc_pa, i);
-    /* Make sure compiler knows to grab that: we don't want it changing! */
-    smp_wmb();
-
-    if (next >= max) {
-        error_report("Desc next is %u", next);
-        exit(1);
-    }
-
-    return next;
-}
-
-int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
-{
-    unsigned int idx;
-    int total_bufs, in_total, out_total;
-
-    idx = vq->last_avail_idx;
-
-    total_bufs = in_total = out_total = 0;
-    while (virtqueue_num_heads(vq, idx)) {
-        unsigned int max, num_bufs, indirect = 0;
-        target_phys_addr_t desc_pa;
-        int i;
-
-        max = vq->vring.num;
-        num_bufs = total_bufs;
-        i = virtqueue_get_head(vq, idx++);
-        desc_pa = vq->vring.desc;
-
-        if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
-            if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
-                error_report("Invalid size for indirect buffer table");
-                exit(1);
-            }
-
-            /* If we've got too many, that implies a descriptor loop. */
-            if (num_bufs >= max) {
-                error_report("Looped descriptor");
-                exit(1);
-            }
-
-            /* loop over the indirect descriptor table */
-            indirect = 1;
-            max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
-            num_bufs = i = 0;
-            desc_pa = vring_desc_addr(desc_pa, i);
-        }
-
-        do {
-            /* If we've got too many, that implies a descriptor loop. */
-            if (++num_bufs > max) {
-                error_report("Looped descriptor");
-                exit(1);
-            }
-
-            if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
-                if (in_bytes > 0 &&
-                    (in_total += vring_desc_len(desc_pa, i)) >= in_bytes)
-                    return 1;
-            } else {
-                if (out_bytes > 0 &&
-                    (out_total += vring_desc_len(desc_pa, i)) >= out_bytes)
-                    return 1;
-            }
-        } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
-
-        if (!indirect)
-            total_bufs = num_bufs;
-        else
-            total_bufs++;
-    }
-
-    return 0;
-}
-
-void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
-    size_t num_sg, int is_write)
-{
-    unsigned int i;
-    target_phys_addr_t len;
-
-    for (i = 0; i < num_sg; i++) {
-        len = sg[i].iov_len;
-        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
-        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
-            error_report("virtio: trying to map MMIO memory");
-            exit(1);
-        }
-    }
-}
-
-int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
-{
-    unsigned int i, head, max;
-    target_phys_addr_t desc_pa = vq->vring.desc;
-
-    if (!virtqueue_num_heads(vq, vq->last_avail_idx))
-        return 0;
-
-    /* When we start there are none of either input nor output. */
-    elem->out_num = elem->in_num = 0;
-
-    max = vq->vring.num;
-
-    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
-    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
-        vring_avail_event(vq, vring_avail_idx(vq));
-    }
-
-    if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
-        if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
-            error_report("Invalid size for indirect buffer table");
-            exit(1);
-        }
-
-        /* loop over the indirect descriptor table */
-        max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
-        desc_pa = vring_desc_addr(desc_pa, i);
-        i = 0;
-    }
-
-    /* Collect all the descriptors */
-    do {
-        struct iovec *sg;
-
-        if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
-            if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
-                error_report("Too many write descriptors in indirect table");
-                exit(1);
-            }
-            elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
-            sg = &elem->in_sg[elem->in_num++];
-        } else {
-            if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
-                error_report("Too many read descriptors in indirect table");
-                exit(1);
-            }
-            elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
-            sg = &elem->out_sg[elem->out_num++];
-        }
-
-        sg->iov_len = vring_desc_len(desc_pa, i);
-
-        /* If we've got too many, that implies a descriptor loop. */
-        if ((elem->in_num + elem->out_num) > max) {
-            error_report("Looped descriptor");
-            exit(1);
-        }
-    } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
-
-    /* Now map what we have collected */
-    virtqueue_map_sg(elem->in_sg, elem->in_addr, elem->in_num, 1);
-    virtqueue_map_sg(elem->out_sg, elem->out_addr, elem->out_num, 0);
-
-    elem->index = head;
-
-    vq->inuse++;
-
-    trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
-    return elem->in_num + elem->out_num;
-}
-
-/* virtio device */
-static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
-{
-    if (vdev->binding->notify) {
-        vdev->binding->notify(vdev->binding_opaque, vector);
-    }
-}
-
-void virtio_update_irq(VirtIODevice *vdev)
-{
-    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
-}
-
-void virtio_set_status(VirtIODevice *vdev, uint8_t val)
-{
-    trace_virtio_set_status(vdev, val);
-
-    if (vdev->set_status) {
-        vdev->set_status(vdev, val);
-    }
-    vdev->status = val;
-}
-
-void virtio_reset(void *opaque)
-{
-    VirtIODevice *vdev = opaque;
-    int i;
-
-    virtio_set_status(vdev, 0);
-
-    if (vdev->reset)
-        vdev->reset(vdev);
-
-    vdev->guest_features = 0;
-    vdev->queue_sel = 0;
-    vdev->status = 0;
-    vdev->isr = 0;
-    vdev->config_vector = VIRTIO_NO_VECTOR;
-    virtio_notify_vector(vdev, vdev->config_vector);
-
-    for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        vdev->vq[i].vring.desc = 0;
-        vdev->vq[i].vring.avail = 0;
-        vdev->vq[i].vring.used = 0;
-        vdev->vq[i].last_avail_idx = 0;
-        vdev->vq[i].pa = 0;
-        vdev->vq[i].vector = VIRTIO_NO_VECTOR;
-        vdev->vq[i].signalled_used = 0;
-        vdev->vq[i].signalled_used_valid = false;
-        vdev->vq[i].notification = true;
-    }
-}
-
-uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
-{
-    uint8_t val;
-
-    vdev->get_config(vdev, vdev->config);
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return (uint32_t)-1;
-
-    val = ldub_p(vdev->config + addr);
-    return val;
-}
-
-uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
-{
-    uint16_t val;
-
-    vdev->get_config(vdev, vdev->config);
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return (uint32_t)-1;
-
-    val = lduw_p(vdev->config + addr);
-    return val;
-}
-
-uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
-{
-    uint32_t val;
-
-    vdev->get_config(vdev, vdev->config);
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return (uint32_t)-1;
-
-    val = ldl_p(vdev->config + addr);
-    return val;
-}
-
-void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
-{
-    uint8_t val = data;
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return;
-
-    stb_p(vdev->config + addr, val);
-
-    if (vdev->set_config)
-        vdev->set_config(vdev, vdev->config);
-}
-
-void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
-{
-    uint16_t val = data;
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return;
-
-    stw_p(vdev->config + addr, val);
-
-    if (vdev->set_config)
-        vdev->set_config(vdev, vdev->config);
-}
-
-void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
-{
-    uint32_t val = data;
-
-    if (addr > (vdev->config_len - sizeof(val)))
-        return;
-
-    stl_p(vdev->config + addr, val);
-
-    if (vdev->set_config)
-        vdev->set_config(vdev, vdev->config);
-}
-
-void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
-{
-    vdev->vq[n].pa = addr;
-    virtqueue_init(&vdev->vq[n]);
-}
-
-target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].pa;
-}
-
-void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
-{
-    vdev->vq[n].vring.num = num;
-    virtqueue_init(&vdev->vq[n]);
-}
-
-int virtio_queue_get_num(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.num;
-}
-
-int virtio_queue_get_id(VirtQueue *vq)
-{
-    VirtIODevice *vdev = vq->vdev;
-    assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_PCI_QUEUE_MAX]);
-    return vq - &vdev->vq[0];
-}
-
-void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
-{
-    vdev->vq[n].vring.align = align;
-    virtqueue_init(&vdev->vq[n]);
-}
-
-void virtio_queue_notify_vq(VirtQueue *vq)
-{
-    if (vq->vring.desc) {
-        VirtIODevice *vdev = vq->vdev;
-        trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
-        vq->handle_output(vdev, vq);
-    }
-}
-
-void virtio_queue_notify(VirtIODevice *vdev, int n)
-{
-    virtio_queue_notify_vq(&vdev->vq[n]);
-}
-
-uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
-{
-    return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
-        VIRTIO_NO_VECTOR;
-}
-
-void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
-{
-    if (n < VIRTIO_PCI_QUEUE_MAX)
-        vdev->vq[n].vector = vector;
-}
-
-VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
-                            void (*handle_output)(VirtIODevice *, VirtQueue *))
-{
-    int i;
-
-    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        if (vdev->vq[i].vring.num == 0)
-            break;
-    }
-
-    if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
-        abort();
-
-    vdev->vq[i].vring.num = queue_size;
-    vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
-    vdev->vq[i].handle_output = handle_output;
-
-    return &vdev->vq[i];
-}
-
-void virtio_irq(VirtQueue *vq)
-{
-    trace_virtio_irq(vq);
-    vq->vdev->isr |= 0x01;
-    virtio_notify_vector(vq->vdev, vq->vector);
-}
-
-/* Assuming a given event_idx value from the other size, if
- * we have just incremented index from old to new_idx,
- * should we trigger an event? */
-static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old)
-{
-       /* Note: Xen has similar logic for notification hold-off
-        * in include/xen/interface/io/ring.h with req_event and req_prod
-        * corresponding to event_idx + 1 and new respectively.
-        * Note also that req_event and req_prod in Xen start at 1,
-        * event indexes in virtio start at 0. */
-       return (uint16_t)(new - event - 1) < (uint16_t)(new - old);
-}
-
-static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
-{
-    uint16_t old, new;
-    bool v;
-    /* We need to expose used array entries before checking used event. */
-    smp_mb();
-    /* Always notify when queue is empty (when feature acknowledge) */
-    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
-         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
-        return true;
-    }
-
-    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
-        return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
-    }
-
-    v = vq->signalled_used_valid;
-    vq->signalled_used_valid = true;
-    old = vq->signalled_used;
-    new = vq->signalled_used = vring_used_idx(vq);
-    return !v || vring_need_event(vring_used_event(vq), new, old);
-}
-
-void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
-{
-    if (!vring_notify(vdev, vq)) {
-        return;
-    }
-
-    trace_virtio_notify(vdev, vq);
-    vdev->isr |= 0x01;
-    virtio_notify_vector(vdev, vq->vector);
-}
-
-void virtio_notify_config(VirtIODevice *vdev)
-{
-    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
-        return;
-
-    vdev->isr |= 0x03;
-    virtio_notify_vector(vdev, vdev->config_vector);
-}
-
-void virtio_save(VirtIODevice *vdev, QEMUFile *f)
-{
-    int i;
-
-    if (vdev->binding->save_config)
-        vdev->binding->save_config(vdev->binding_opaque, f);
-
-    qemu_put_8s(f, &vdev->status);
-    qemu_put_8s(f, &vdev->isr);
-    qemu_put_be16s(f, &vdev->queue_sel);
-    qemu_put_be32s(f, &vdev->guest_features);
-    qemu_put_be32(f, vdev->config_len);
-    qemu_put_buffer(f, vdev->config, vdev->config_len);
-
-    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        if (vdev->vq[i].vring.num == 0)
-            break;
-    }
-
-    qemu_put_be32(f, i);
-
-    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        if (vdev->vq[i].vring.num == 0)
-            break;
-
-        qemu_put_be32(f, vdev->vq[i].vring.num);
-        qemu_put_be64(f, vdev->vq[i].pa);
-        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
-        if (vdev->binding->save_queue)
-            vdev->binding->save_queue(vdev->binding_opaque, i, f);
-    }
-}
-
-int virtio_set_features(VirtIODevice *vdev, uint32_t val)
-{
-    uint32_t supported_features =
-        vdev->binding->get_features(vdev->binding_opaque);
-    bool bad = (val & ~supported_features) != 0;
-
-    val &= supported_features;
-    if (vdev->set_features) {
-        vdev->set_features(vdev, val);
-    }
-    vdev->guest_features = val;
-    return bad ? -1 : 0;
-}
-
-int virtio_load(VirtIODevice *vdev, QEMUFile *f)
-{
-    int num, i, ret;
-    uint32_t features;
-    uint32_t supported_features;
-
-    if (vdev->binding->load_config) {
-        ret = vdev->binding->load_config(vdev->binding_opaque, f);
-        if (ret)
-            return ret;
-    }
-
-    qemu_get_8s(f, &vdev->status);
-    qemu_get_8s(f, &vdev->isr);
-    qemu_get_be16s(f, &vdev->queue_sel);
-    qemu_get_be32s(f, &features);
-
-    if (virtio_set_features(vdev, features) < 0) {
-        supported_features = vdev->binding->get_features(vdev->binding_opaque);
-        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
-                     features, supported_features);
-        return -1;
-    }
-    vdev->config_len = qemu_get_be32(f);
-    qemu_get_buffer(f, vdev->config, vdev->config_len);
-
-    num = qemu_get_be32(f);
-
-    for (i = 0; i < num; i++) {
-        vdev->vq[i].vring.num = qemu_get_be32(f);
-        vdev->vq[i].pa = qemu_get_be64(f);
-        qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
-        vdev->vq[i].signalled_used_valid = false;
-        vdev->vq[i].notification = true;
-
-        if (vdev->vq[i].pa) {
-            uint16_t nheads;
-            virtqueue_init(&vdev->vq[i]);
-            nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
-            /* Check it isn't doing very strange things with descriptor numbers. */
-            if (nheads > vdev->vq[i].vring.num) {
-                error_report("VQ %d size 0x%x Guest index 0x%x "
-                             "inconsistent with Host index 0x%x: delta 0x%x",
-                             i, vdev->vq[i].vring.num,
-                             vring_avail_idx(&vdev->vq[i]),
-                             vdev->vq[i].last_avail_idx, nheads);
-                return -1;
-            }
-        } else if (vdev->vq[i].last_avail_idx) {
-            error_report("VQ %d address 0x0 "
-                         "inconsistent with Host index 0x%x",
-                         i, vdev->vq[i].last_avail_idx);
-                return -1;
-       }
-        if (vdev->binding->load_queue) {
-            ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
-            if (ret)
-                return ret;
-        }
-    }
-
-    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
-    return 0;
-}
-
-void virtio_cleanup(VirtIODevice *vdev)
-{
-    qemu_del_vm_change_state_handler(vdev->vmstate);
-    g_free(vdev->config);
-    g_free(vdev->vq);
-    g_free(vdev);
-}
-
-static void virtio_vmstate_change(void *opaque, int running, RunState state)
-{
-    VirtIODevice *vdev = opaque;
-    bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
-    vdev->vm_running = running;
-
-    if (backend_run) {
-        virtio_set_status(vdev, vdev->status);
-    }
-
-    if (vdev->binding->vmstate_change) {
-        vdev->binding->vmstate_change(vdev->binding_opaque, backend_run);
-    }
-
-    if (!backend_run) {
-        virtio_set_status(vdev, vdev->status);
-    }
-}
-
-VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
-                                 size_t config_size, size_t struct_size)
-{
-    VirtIODevice *vdev;
-    int i;
-
-    vdev = g_malloc0(struct_size);
-
-    vdev->device_id = device_id;
-    vdev->status = 0;
-    vdev->isr = 0;
-    vdev->queue_sel = 0;
-    vdev->config_vector = VIRTIO_NO_VECTOR;
-    vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
-    vdev->vm_running = runstate_is_running();
-    for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        vdev->vq[i].vector = VIRTIO_NO_VECTOR;
-        vdev->vq[i].vdev = vdev;
-    }
-
-    vdev->name = name;
-    vdev->config_len = config_size;
-    if (vdev->config_len)
-        vdev->config = g_malloc0(config_size);
-    else
-        vdev->config = NULL;
-
-    vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
-
-    return vdev;
-}
-
-void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
-                        void *opaque)
-{
-    vdev->binding = binding;
-    vdev->binding_opaque = opaque;
-}
-
-target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.desc;
-}
-
-target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.avail;
-}
-
-target_phys_addr_t virtio_queue_get_used_addr(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.used;
-}
-
-target_phys_addr_t virtio_queue_get_ring_addr(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.desc;
-}
-
-target_phys_addr_t virtio_queue_get_desc_size(VirtIODevice *vdev, int n)
-{
-    return sizeof(VRingDesc) * vdev->vq[n].vring.num;
-}
-
-target_phys_addr_t virtio_queue_get_avail_size(VirtIODevice *vdev, int n)
-{
-    return offsetof(VRingAvail, ring) +
-        sizeof(uint64_t) * vdev->vq[n].vring.num;
-}
-
-target_phys_addr_t virtio_queue_get_used_size(VirtIODevice *vdev, int n)
-{
-    return offsetof(VRingUsed, ring) +
-        sizeof(VRingUsedElem) * vdev->vq[n].vring.num;
-}
-
-target_phys_addr_t virtio_queue_get_ring_size(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].vring.used - vdev->vq[n].vring.desc +
-           virtio_queue_get_used_size(vdev, n);
-}
-
-uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
-{
-    return vdev->vq[n].last_avail_idx;
-}
-
-void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
-{
-    vdev->vq[n].last_avail_idx = idx;
-}
-
-VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
-{
-    return vdev->vq + n;
-}
-
-static void virtio_queue_guest_notifier_read(EventNotifier *n)
-{
-    VirtQueue *vq = container_of(n, VirtQueue, guest_notifier);
-    if (event_notifier_test_and_clear(n)) {
-        virtio_irq(vq);
-    }
-}
-
-void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
-                                                bool with_irqfd)
-{
-    if (assign && !with_irqfd) {
-        event_notifier_set_handler(&vq->guest_notifier,
-                                   virtio_queue_guest_notifier_read);
-    } else {
-        event_notifier_set_handler(&vq->guest_notifier, NULL);
-    }
-    if (!assign) {
-        /* Test and clear notifier before closing it,
-         * in case poll callback didn't have time to run. */
-        virtio_queue_guest_notifier_read(&vq->guest_notifier);
-    }
-}
-
-EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
-{
-    return &vq->guest_notifier;
-}
-
-static void virtio_queue_host_notifier_read(EventNotifier *n)
-{
-    VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
-    if (event_notifier_test_and_clear(n)) {
-        virtio_queue_notify_vq(vq);
-    }
-}
-
-void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
-                                               bool set_handler)
-{
-    if (assign && set_handler) {
-        event_notifier_set_handler(&vq->host_notifier,
-                                   virtio_queue_host_notifier_read);
-    } else {
-        event_notifier_set_handler(&vq->host_notifier, NULL);
-    }
-    if (!assign) {
-        /* Test and clear notifier before after disabling event,
-         * in case poll callback didn't have time to run. */
-        virtio_queue_host_notifier_read(&vq->host_notifier);
-    }
-}
-
-EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
-{
-    return &vq->host_notifier;
-}
diff --git a/hw/virtio.h b/hw/virtio.h
deleted file mode 100755 (executable)
index 0b03561..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Virtio Support
- *
- * Copyright IBM, Corp. 2007
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef _QEMU_VIRTIO_H
-#define _QEMU_VIRTIO_H
-
-#include "hw.h"
-#include "net.h"
-#include "qdev.h"
-#include "sysemu.h"
-#include "event_notifier.h"
-#ifdef CONFIG_LINUX
-#include "9p.h"
-#endif
-#define VIRTIO_ID_GL 6
-
-/* from Linux's linux/virtio_config.h */
-
-/* Status byte for guest to report progress, and synchronize features. */
-/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
-#define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
-/* We have found a driver for the device. */
-#define VIRTIO_CONFIG_S_DRIVER          2
-/* Driver has used its parts of the config, and is happy */
-#define VIRTIO_CONFIG_S_DRIVER_OK       4
-/* We've given up on this device. */
-#define VIRTIO_CONFIG_S_FAILED          0x80
-
-/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
- * transport being used (eg. virtio_ring), the rest are per-device feature bits. */
-#define VIRTIO_TRANSPORT_F_START        28
-#define VIRTIO_TRANSPORT_F_END          32
-
-/* We notify when the ring is completely used, even if the guest is suppressing
- * callbacks */
-#define VIRTIO_F_NOTIFY_ON_EMPTY        24
-/* We support indirect buffer descriptors */
-#define VIRTIO_RING_F_INDIRECT_DESC     28
-/* The Guest publishes the used index for which it expects an interrupt
- * at the end of the avail ring. Host should ignore the avail->flags field. */
-/* The Host publishes the avail index for which it expects a kick
- * at the end of the used ring. Guest should ignore the used->flags field. */
-#define VIRTIO_RING_F_EVENT_IDX         29
-/* A guest should never accept this.  It implies negotiation is broken. */
-#define VIRTIO_F_BAD_FEATURE           30
-
-/* from Linux's linux/virtio_ring.h */
-
-/* This marks a buffer as continuing via the next field. */
-#define VRING_DESC_F_NEXT       1
-/* This marks a buffer as write-only (otherwise read-only). */
-#define VRING_DESC_F_WRITE      2
-/* This means the buffer contains a list of buffer descriptors. */
-#define VRING_DESC_F_INDIRECT  4
-
-/* This means don't notify other side when buffer added. */
-#define VRING_USED_F_NO_NOTIFY  1
-/* This means don't interrupt guest when buffer consumed. */
-#define VRING_AVAIL_F_NO_INTERRUPT      1
-
-struct VirtQueue;
-
-static inline target_phys_addr_t vring_align(target_phys_addr_t addr,
-                                             unsigned long align)
-{
-    return (addr + align - 1) & ~(align - 1);
-}
-
-typedef struct VirtQueue VirtQueue;
-
-#define VIRTQUEUE_MAX_SIZE 1024
-
-typedef struct VirtQueueElement
-{
-    unsigned int index;
-    unsigned int out_num;
-    unsigned int in_num;
-    target_phys_addr_t in_addr[VIRTQUEUE_MAX_SIZE];
-    target_phys_addr_t out_addr[VIRTQUEUE_MAX_SIZE];
-    struct iovec in_sg[VIRTQUEUE_MAX_SIZE];
-    struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
-} VirtQueueElement;
-
-typedef struct {
-    void (*notify)(void * opaque, uint16_t vector);
-    void (*save_config)(void * opaque, QEMUFile *f);
-    void (*save_queue)(void * opaque, int n, QEMUFile *f);
-    int (*load_config)(void * opaque, QEMUFile *f);
-    int (*load_queue)(void * opaque, int n, QEMUFile *f);
-    int (*load_done)(void * opaque, QEMUFile *f);
-    unsigned (*get_features)(void * opaque);
-    bool (*query_guest_notifiers)(void * opaque);
-    int (*set_guest_notifiers)(void * opaque, bool assigned);
-    int (*set_host_notifier)(void * opaque, int n, bool assigned);
-    void (*vmstate_change)(void * opaque, bool running);
-} VirtIOBindings;
-
-#define VIRTIO_PCI_QUEUE_MAX 64
-
-#define VIRTIO_NO_VECTOR 0xffff
-
-struct VirtIODevice
-{
-    const char *name;
-    uint8_t status;
-    uint8_t isr;
-    uint16_t queue_sel;
-    uint32_t guest_features;
-    size_t config_len;
-    void *config;
-    uint16_t config_vector;
-    int nvectors;
-    uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
-    uint32_t (*bad_features)(VirtIODevice *vdev);
-    void (*set_features)(VirtIODevice *vdev, uint32_t val);
-    void (*get_config)(VirtIODevice *vdev, uint8_t *config);
-    void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
-    void (*reset)(VirtIODevice *vdev);
-    void (*set_status)(VirtIODevice *vdev, uint8_t val);
-    VirtQueue *vq;
-    const VirtIOBindings *binding;
-    void *binding_opaque;
-    uint16_t device_id;
-    bool vm_running;
-    VMChangeStateEntry *vmstate;
-};
-
-VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
-                            void (*handle_output)(VirtIODevice *,
-                                                  VirtQueue *));
-
-void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len);
-void virtqueue_flush(VirtQueue *vq, unsigned int count);
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len, unsigned int idx);
-
-void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
-    size_t num_sg, int is_write);
-int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
-int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
-
-void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
-
-void virtio_save(VirtIODevice *vdev, QEMUFile *f);
-
-int virtio_load(VirtIODevice *vdev, QEMUFile *f);
-
-void virtio_cleanup(VirtIODevice *vdev);
-
-void virtio_notify_config(VirtIODevice *vdev);
-
-void virtio_queue_set_notification(VirtQueue *vq, int enable);
-
-int virtio_queue_ready(VirtQueue *vq);
-
-int virtio_queue_empty(VirtQueue *vq);
-
-/* Host binding interface.  */
-
-VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
-                                 size_t config_size, size_t struct_size);
-uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
-uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
-uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);
-void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data);
-void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data);
-void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data);
-void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr);
-target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n);
-void virtio_queue_set_num(VirtIODevice *vdev, int n, int num);
-int virtio_queue_get_num(VirtIODevice *vdev, int n);
-void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
-void virtio_queue_notify(VirtIODevice *vdev, int n);
-uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
-void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
-void virtio_set_status(VirtIODevice *vdev, uint8_t val);
-void virtio_reset(void *opaque);
-void virtio_update_irq(VirtIODevice *vdev);
-int virtio_set_features(VirtIODevice *vdev, uint32_t val);
-
-void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
-                        void *opaque);
-
-/* Base devices.  */
-typedef struct VirtIOBlkConf VirtIOBlkConf;
-VirtIODevice *virtio_blk_init(DeviceState *dev, VirtIOBlkConf *blk);
-struct virtio_net_conf;
-VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
-                              struct virtio_net_conf *net);
-typedef struct virtio_serial_conf virtio_serial_conf;
-VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
-VirtIODevice *virtio_balloon_init(DeviceState *dev);
-typedef struct VirtIOSCSIConf VirtIOSCSIConf;
-VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *conf);
-#ifdef CONFIG_LINUX
-VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
-#endif
-#ifdef CONFIG_GL_BACKEND
-VirtIODevice *virtio_gl_init(DeviceState *dev);
-#endif
-
-void virtio_net_exit(VirtIODevice *vdev);
-void virtio_blk_exit(VirtIODevice *vdev);
-void virtio_serial_exit(VirtIODevice *vdev);
-void virtio_balloon_exit(VirtIODevice *vdev);
-void virtio_scsi_exit(VirtIODevice *vdev);
-
-/* Maru devices */
-#ifdef CONFIG_MARU
-#include "tizen/src/hw/maru_virtio_touchscreen.h"
-#include "tizen/src/hw/maru_virtio_keyboard.h"
-#include "tizen/src/hw/maru_virtio_esm.h"
-#include "tizen/src/hw/maru_virtio_hwkey.h"
-#endif
-
-
-#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
-       DEFINE_PROP_BIT("indirect_desc", _state, _field, \
-                       VIRTIO_RING_F_INDIRECT_DESC, true), \
-       DEFINE_PROP_BIT("event_idx", _state, _field, \
-                       VIRTIO_RING_F_EVENT_IDX, true)
-
-target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_used_addr(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_ring_addr(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_desc_size(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_used_size(VirtIODevice *vdev, int n);
-target_phys_addr_t virtio_queue_get_ring_size(VirtIODevice *vdev, int n);
-uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
-void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
-VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
-int virtio_queue_get_id(VirtQueue *vq);
-EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
-void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
-                                                bool with_irqfd);
-EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
-void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
-                                               bool set_handler);
-void virtio_queue_notify_vq(VirtQueue *vq);
-void virtio_irq(VirtQueue *vq);
-#endif
similarity index 100%
rename from hw/virtio-mmio.c
rename to hw/virtio/virtio-mmio.c