packages: qemu-kvm/enable_architectural_PMU_cpuid_leaf.patch (NEW), qemu-kv...

baggins baggins at pld-linux.org
Wed Feb 15 22:47:50 CET 2012


Author: baggins                      Date: Wed Feb 15 21:47:50 2012 GMT
Module: packages                      Tag: HEAD
---- Log message:
- features for 1.1

---- Files affected:
packages/qemu-kvm:
   enable_architectural_PMU_cpuid_leaf.patch (NONE -> 1.1)  (NEW), qemu_virtio-scsi_support.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/qemu-kvm/enable_architectural_PMU_cpuid_leaf.patch
diff -u /dev/null packages/qemu-kvm/enable_architectural_PMU_cpuid_leaf.patch:1.1
--- /dev/null	Wed Feb 15 22:47:50 2012
+++ packages/qemu-kvm/enable_architectural_PMU_cpuid_leaf.patch	Wed Feb 15 22:47:45 2012
@@ -0,0 +1,37 @@
+commit a0fa82085e175bf8ce6d69a3f83695f81af2a649
+Author: Gleb Natapov <gleb at redhat.com>
+Date:   Thu Dec 15 12:44:05 2011 +0200
+
+    enable architectural PMU cpuid leaf for kvm
+    
+    Signed-off-by: Gleb Natapov <gleb at redhat.com>
+    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+
+diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
+index 0b3af90..91a104b 100644
+--- a/target-i386/cpuid.c
++++ b/target-i386/cpuid.c
+@@ -1180,10 +1180,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+         break;
+     case 0xA:
+         /* Architectural Performance Monitoring Leaf */
+-        *eax = 0;
+-        *ebx = 0;
+-        *ecx = 0;
+-        *edx = 0;
++        if (kvm_enabled()) {
++            KVMState *s = env->kvm_state;
++
++            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
++            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
++            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
++            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
++        } else {
++            *eax = 0;
++            *ebx = 0;
++            *ecx = 0;
++            *edx = 0;
++        }
+         break;
+     case 0xD:
+         /* Processor Extended State */

================================================================
Index: packages/qemu-kvm/qemu_virtio-scsi_support.patch
diff -u /dev/null packages/qemu-kvm/qemu_virtio-scsi_support.patch:1.1
--- /dev/null	Wed Feb 15 22:47:50 2012
+++ packages/qemu-kvm/qemu_virtio-scsi_support.patch	Wed Feb 15 22:47:45 2012
@@ -0,0 +1,1652 @@
+diff -ruNp qemu-kvm-1.0/default-configs/pci.mak qemu-kvm-1.0.virtio-scsi/default-configs/pci.mak
+--- qemu-kvm-1.0/default-configs/pci.mak	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/default-configs/pci.mak	2012-02-07 14:44:53.424905251 -0600
+@@ -1,5 +1,6 @@
+ CONFIG_PCI=y
+ CONFIG_VIRTIO_PCI=y
++CONFIG_VIRTIO_SCSI=y
+ CONFIG_VIRTIO=y
+ CONFIG_USB_UHCI=y
+ CONFIG_USB_OHCI=y
+diff -ruNp qemu-kvm-1.0/default-configs/s390x-softmmu.mak qemu-kvm-1.0.virtio-scsi/default-configs/s390x-softmmu.mak
+--- qemu-kvm-1.0/default-configs/s390x-softmmu.mak	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/default-configs/s390x-softmmu.mak	2012-02-07 14:44:53.424905251 -0600
+@@ -1 +1,2 @@
+ CONFIG_VIRTIO=y
++CONFIG_VIRTIO_SCSI=y
+diff -ruNp qemu-kvm-1.0/dma.h qemu-kvm-1.0.virtio-scsi/dma.h
+--- qemu-kvm-1.0/dma.h	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/dma.h	2012-02-07 14:44:53.425905267 -0600
+@@ -17,6 +17,13 @@
+ 
+ typedef struct ScatterGatherEntry ScatterGatherEntry;
+ 
++struct QEMUSGList {
++    ScatterGatherEntry *sg;
++    int nsg;
++    int nalloc;
++    size_t size;
++};
++
+ #if defined(TARGET_PHYS_ADDR_BITS)
+ typedef target_phys_addr_t dma_addr_t;
+ 
+@@ -32,13 +39,6 @@ struct ScatterGatherEntry {
+     dma_addr_t len;
+ };
+ 
+-struct QEMUSGList {
+-    ScatterGatherEntry *sg;
+-    int nsg;
+-    int nalloc;
+-    dma_addr_t size;
+-};
+-
+ void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
+ void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
+ void qemu_sglist_destroy(QEMUSGList *qsg);
+@@ -58,4 +58,10 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDri
+ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
+                                  QEMUSGList *sg, uint64_t sector,
+                                  BlockDriverCompletionFunc *cb, void *opaque);
++uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
++uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
++
++void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
++                    QEMUSGList *sg, enum BlockAcctType type);
++
+ #endif
+diff -ruNp qemu-kvm-1.0/dma-helpers.c qemu-kvm-1.0.virtio-scsi/dma-helpers.c
+--- qemu-kvm-1.0/dma-helpers.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/dma-helpers.c	2012-02-07 14:44:53.424905251 -0600
+@@ -196,3 +196,39 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDr
+ {
+     return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
+ }
++
++
++static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, bool to_dev)
++{
++    uint64_t resid;
++    int sg_cur_index;
++
++    resid = sg->size;
++    sg_cur_index = 0;
++    len = MIN(len, resid);
++    while (len > 0) {
++        ScatterGatherEntry entry = sg->sg[sg_cur_index++];
++        cpu_physical_memory_rw(entry.base, ptr, MIN(len, entry.len), !to_dev);
++        ptr += entry.len;
++        len -= entry.len;
++        resid -= entry.len;
++    }
++
++    return resid;
++}
++
++uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg)
++{
++    return dma_buf_rw(ptr, len, sg, 0);
++}
++
++uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
++{
++    return dma_buf_rw(ptr, len, sg, 1);
++}
++
++void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
++                    QEMUSGList *sg, enum BlockAcctType type)
++{
++    bdrv_acct_start(bs, cookie, sg->size, type);
++}
+diff -ruNp qemu-kvm-1.0/hw/esp.c qemu-kvm-1.0.virtio-scsi/hw/esp.c
+--- qemu-kvm-1.0/hw/esp.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/esp.c	2012-02-07 14:44:53.425905267 -0600
+@@ -389,7 +389,8 @@ static void esp_do_dma(ESPState *s)
+     esp_dma_done(s);
+ }
+ 
+-static void esp_command_complete(SCSIRequest *req, uint32_t status)
++static void esp_command_complete(SCSIRequest *req, uint32_t status,
++                                 int32_t resid)
+ {
+     ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
+ 
+diff -ruNp qemu-kvm-1.0/hw/ide/ahci.c qemu-kvm-1.0.virtio-scsi/hw/ide/ahci.c
+--- qemu-kvm-1.0/hw/ide/ahci.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/ide/ahci.c	2012-02-07 14:44:53.426905283 -0600
+@@ -425,55 +425,6 @@ static void ahci_reg_init(AHCIState *s)
+     }
+ }
+ 
+-static uint32_t read_from_sglist(uint8_t *buffer, uint32_t len,
+-                                 QEMUSGList *sglist)
+-{
+-    uint32_t i = 0;
+-    uint32_t total = 0, once;
+-    ScatterGatherEntry *cur_prd;
+-    uint32_t sgcount;
+-
+-    cur_prd = sglist->sg;
+-    sgcount = sglist->nsg;
+-    for (i = 0; len && sgcount; i++) {
+-        once = MIN(cur_prd->len, len);
+-        cpu_physical_memory_read(cur_prd->base, buffer, once);
+-        cur_prd++;
+-        sgcount--;
+-        len -= once;
+-        buffer += once;
+-        total += once;
+-    }
+-
+-    return total;
+-}
+-
+-static uint32_t write_to_sglist(uint8_t *buffer, uint32_t len,
+-                                QEMUSGList *sglist)
+-{
+-    uint32_t i = 0;
+-    uint32_t total = 0, once;
+-    ScatterGatherEntry *cur_prd;
+-    uint32_t sgcount;
+-
+-    DPRINTF(-1, "total: 0x%x bytes\n", len);
+-
+-    cur_prd = sglist->sg;
+-    sgcount = sglist->nsg;
+-    for (i = 0; len && sgcount; i++) {
+-        once = MIN(cur_prd->len, len);
+-        DPRINTF(-1, "write 0x%x bytes to 0x%lx\n", once, (long)cur_prd->base);
+-        cpu_physical_memory_write(cur_prd->base, buffer, once);
+-        cur_prd++;
+-        sgcount--;
+-        len -= once;
+-        buffer += once;
+-        total += once;
+-    }
+-
+-    return total;
+-}
+-
+ static void check_cmd(AHCIState *s, int port)
+ {
+     AHCIPortRegs *pr = &s->dev[port].port_regs;
+@@ -794,9 +745,8 @@ static void process_ncq_command(AHCIStat
+             DPRINTF(port, "tag %d aio read %"PRId64"\n",
+                     ncq_tfs->tag, ncq_tfs->lba);
+ 
+-            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+-                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+-                            BDRV_ACCT_READ);
++            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
++                           &ncq_tfs->sglist, BDRV_ACCT_READ);
+             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
+                                            &ncq_tfs->sglist, ncq_tfs->lba,
+                                            ncq_cb, ncq_tfs);
+@@ -808,9 +758,8 @@ static void process_ncq_command(AHCIStat
+             DPRINTF(port, "tag %d aio write %"PRId64"\n",
+                     ncq_tfs->tag, ncq_tfs->lba);
+ 
+-            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+-                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+-                            BDRV_ACCT_WRITE);
++            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
++                           &ncq_tfs->sglist, BDRV_ACCT_WRITE);
+             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
+                                             &ncq_tfs->sglist, ncq_tfs->lba,
+                                             ncq_cb, ncq_tfs);
+@@ -1015,12 +964,12 @@ static int ahci_start_transfer(IDEDMA *d
+             is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
+             has_sglist ? "" : "o");
+ 
+-    if (is_write && has_sglist && (s->data_ptr < s->data_end)) {
+-        read_from_sglist(s->data_ptr, size, &s->sg);
+-    }
+-
+-    if (!is_write && has_sglist && (s->data_ptr < s->data_end)) {
+-        write_to_sglist(s->data_ptr, size, &s->sg);
++    if (has_sglist && size) {
++        if (is_write) {
++            dma_buf_write(s->data_ptr, size, &s->sg);
++        } else {
++            dma_buf_read(s->data_ptr, size, &s->sg);
++        }
+     }
+ 
+     /* update number of transferred bytes */
+@@ -1059,14 +1008,9 @@ static int ahci_dma_prepare_buf(IDEDMA *
+ {
+     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
+     IDEState *s = &ad->port.ifs[0];
+-    int i;
+ 
+     ahci_populate_sglist(ad, &s->sg);
+-
+-    s->io_buffer_size = 0;
+-    for (i = 0; i < s->sg.nsg; i++) {
+-        s->io_buffer_size += s->sg.sg[i].len;
+-    }
++    s->io_buffer_size = s->sg.size;
+ 
+     DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
+     return s->io_buffer_size != 0;
+@@ -1084,9 +1028,9 @@ static int ahci_dma_rw_buf(IDEDMA *dma,
+     }
+ 
+     if (is_write) {
+-        write_to_sglist(p, l, &s->sg);
++        dma_buf_read(p, l, &s->sg);
+     } else {
+-        read_from_sglist(p, l, &s->sg);
++        dma_buf_write(p, l, &s->sg);
+     }
+ 
+     /* update number of transferred bytes */
+diff -ruNp qemu-kvm-1.0/hw/lsi53c895a.c qemu-kvm-1.0.virtio-scsi/hw/lsi53c895a.c
+--- qemu-kvm-1.0/hw/lsi53c895a.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/lsi53c895a.c	2012-02-07 14:44:53.427905299 -0600
+@@ -699,7 +699,7 @@ static int lsi_queue_req(LSIState *s, SC
+ }
+ 
+  /* Callback to indicate that the SCSI layer has completed a command.  */
+-static void lsi_command_complete(SCSIRequest *req, uint32_t status)
++static void lsi_command_complete(SCSIRequest *req, uint32_t status, int32_t resid)
+ {
+     LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+     int out;
+diff -ruNp qemu-kvm-1.0/hw/pci.h qemu-kvm-1.0.virtio-scsi/hw/pci.h
+--- qemu-kvm-1.0/hw/pci.h	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/pci.h	2012-02-07 14:44:53.427905299 -0600
+@@ -76,6 +76,7 @@
+ #define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
+ #define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
+ #define PCI_DEVICE_ID_VIRTIO_CONSOLE     0x1003
++#define PCI_DEVICE_ID_VIRTIO_SCSI        0x1004
+ 
+ #define FMT_PCIBUS                      PRIx64
+ 
+diff -ruNp qemu-kvm-1.0/hw/s390-virtio-bus.c qemu-kvm-1.0.virtio-scsi/hw/s390-virtio-bus.c
+--- qemu-kvm-1.0/hw/s390-virtio-bus.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/s390-virtio-bus.c	2012-02-07 14:44:53.428905315 -0600
+@@ -158,6 +158,18 @@ static int s390_virtio_serial_init(VirtI
+     return r;
+ }
+ 
++static int s390_virtio_scsi_init(VirtIOS390Device *dev)
++{
++    VirtIODevice *vdev;
++
++    vdev = virtio_scsi_init((DeviceState *)dev, &dev->scsi);
++    if (!vdev) {
++        return -1;
++    }
++
++    return s390_virtio_device_init(dev, vdev);
++}
++
+ static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
+ {
+     ram_addr_t token_off;
+@@ -370,6 +382,17 @@ static VirtIOS390DeviceInfo s390_virtio_
+     },
+ };
+ 
++static VirtIOS390DeviceInfo s390_virtio_scsi = {
++    .init = s390_virtio_scsi_init,
++    .qdev.name = "virtio-scsi-s390",
++    .qdev.alias = "virtio-scsi",
++    .qdev.size = sizeof(VirtIOS390Device),
++    .qdev.props = (Property[]) {
++        DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOS390Device, host_features, scsi),
++        DEFINE_PROP_END_OF_LIST(),
++    },
++};
++
+ static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
+ {
+     VirtIOS390DeviceInfo *_info = (VirtIOS390DeviceInfo *)info;
+@@ -392,6 +415,7 @@ static void s390_virtio_register(void)
+     s390_virtio_bus_register_withprop(&s390_virtio_serial);
+     s390_virtio_bus_register_withprop(&s390_virtio_blk);
+     s390_virtio_bus_register_withprop(&s390_virtio_net);
++    s390_virtio_bus_register_withprop(&s390_virtio_scsi);
+ }
+ device_init(s390_virtio_register);
+ 
+diff -ruNp qemu-kvm-1.0/hw/s390-virtio-bus.h qemu-kvm-1.0.virtio-scsi/hw/s390-virtio-bus.h
+--- qemu-kvm-1.0/hw/s390-virtio-bus.h	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/s390-virtio-bus.h	2012-02-07 14:44:53.428905315 -0600
+@@ -19,6 +19,7 @@
+ 
+ #include "virtio-net.h"
+ #include "virtio-serial.h"
++#include "virtio-scsi.h"
+ 
+ #define VIRTIO_DEV_OFFS_TYPE		0	/* 8 bits */
+ #define VIRTIO_DEV_OFFS_NUM_VQ		1	/* 8 bits */
+@@ -47,6 +48,7 @@ typedef struct VirtIOS390Device {
+     uint32_t host_features;
+     virtio_serial_conf serial;
+     virtio_net_conf net;
++    VirtIOSCSIConf scsi;
+ } VirtIOS390Device;
+ 
+ typedef struct VirtIOS390Bus {
+diff -ruNp qemu-kvm-1.0/hw/scsi-bus.c qemu-kvm-1.0.virtio-scsi/hw/scsi-bus.c
+--- qemu-kvm-1.0/hw/scsi-bus.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/scsi-bus.c	2012-02-07 14:44:53.428905315 -0600
+@@ -5,6 +5,7 @@
+ #include "qdev.h"
+ #include "blockdev.h"
+ #include "trace.h"
++#include "dma.h"
+ 
+ static char *scsibus_get_fw_dev_path(DeviceState *dev);
+ static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
+@@ -50,6 +51,7 @@ static void scsi_dma_restart_bh(void *op
+                 scsi_req_continue(req);
+                 break;
+             case SCSI_XFER_NONE:
++                assert(!req->sg);
+                 scsi_req_dequeue(req);
+                 scsi_req_enqueue(req);
+                 break;
+@@ -512,6 +514,8 @@ SCSIRequest *scsi_req_new(SCSIDevice *d,
+     }
+ 
+     req->cmd = cmd;
++    req->resid = req->cmd.xfer;
++
+     switch (buf[0]) {
+     case INQUIRY:
+         trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]);
+@@ -624,15 +628,25 @@ void scsi_req_build_sense(SCSIRequest *r
+     req->sense_len = 18;
+ }
+ 
+-int32_t scsi_req_enqueue(SCSIRequest *req)
++static void scsi_req_enqueue_internal(SCSIRequest *req)
+ {
+-    int32_t rc;
+-
+     assert(!req->enqueued);
+     scsi_req_ref(req);
++    if (req->bus->info->get_sg_list) {
++        req->sg = req->bus->info->get_sg_list(req);
++    } else {
++        req->sg = NULL;
++    }
+     req->enqueued = true;
+     QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
++}
++
++int32_t scsi_req_enqueue(SCSIRequest *req)
++{
++    int32_t rc;
+ 
++    assert (!req->retry);
++    scsi_req_enqueue_internal(req);
+     scsi_req_ref(req);
+     rc = req->ops->send_command(req, req->cmd.buf);
+     scsi_req_unref(req);
+@@ -1254,12 +1268,32 @@ void scsi_req_continue(SCSIRequest *req)
+    Once it completes, calling scsi_req_continue will restart I/O.  */
+ void scsi_req_data(SCSIRequest *req, int len)
+ {
++    uint8_t *buf;
+     if (req->io_canceled) {
+         trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len);
+-    } else {
+-        trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
++        return;
++    }
++    trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
++    assert(req->cmd.mode != SCSI_XFER_NONE);
++    if (!req->sg) {
++        req->resid -= len;
+         req->bus->info->transfer_data(req, len);
++        return;
++    }
++
++    /* If the device calls scsi_req_data and the HBA specified a
++     * scatter/gather list, the transfer has to happen in a single
++     * step.  */
++    assert(!req->dma_started);
++    req->dma_started = true;
++
++    buf = scsi_req_get_buf(req);
++    if (req->cmd.mode == SCSI_XFER_FROM_DEV) {
++        req->resid = dma_buf_read(buf, len, req->sg);
++    } else {
++        req->resid = dma_buf_write(buf, len, req->sg);
+     }
++    scsi_req_continue(req);
+ }
+ 
+ void scsi_req_print(SCSIRequest *req)
+@@ -1318,7 +1352,7 @@ void scsi_req_complete(SCSIRequest *req,
+ 
+     scsi_req_ref(req);
+     scsi_req_dequeue(req);
+-    req->bus->info->complete(req, req->status);
++    req->bus->info->complete(req, req->status, req->resid);
+     scsi_req_unref(req);
+ }
+ 
+@@ -1393,3 +1427,100 @@ SCSIDevice *scsi_device_find(SCSIBus *bu
+     }
+     return target_dev;
+ }
++
++
++/* SCSI request list.  For simplicity, pv points to the whole device */
++
++static void put_scsi_requests(QEMUFile *f, void *pv, size_t size)
++{
++    SCSIDevice *s = pv;
++    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
++    SCSIRequest *req;
++
++    QTAILQ_FOREACH(req, &s->requests, next) {
++        assert(!req->io_canceled);
++        assert(req->status == -1);
++        assert(req->retry);
++        assert(req->enqueued);
++
++        qemu_put_sbyte(f, 1);
++        qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf));
++        qemu_put_be32s(f, &req->tag);
++        qemu_put_be32s(f, &req->lun);
++        if (bus->info->save_request) {
++            bus->info->save_request(f, req);
++        }
++        if (req->ops->save_request) {
++            req->ops->save_request(f, req);
++        }
++    }
++    qemu_put_sbyte(f, 0);
++}
++
++static int get_scsi_requests(QEMUFile *f, void *pv, size_t size)
++{
++    SCSIDevice *s = pv;
++    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
++
++    while (qemu_get_sbyte(f)) {
++        uint8_t buf[SCSI_CMD_BUF_SIZE];
++        uint32_t tag;
++        uint32_t lun;
++        SCSIRequest *req;
++
++        qemu_get_buffer(f, buf, sizeof(buf));
++        qemu_get_be32s(f, &tag);
++        qemu_get_be32s(f, &lun);
++        req = scsi_req_new(s, tag, lun, buf, NULL);
++        if (bus->info->load_request) {
++            req->hba_private = bus->info->load_request(f, req);
++        }
++        if (req->ops->load_request) {
++            req->ops->load_request(f, req);
++        }
++
++        /* Just restart it later.  */
++        req->retry = true;
++        scsi_req_enqueue_internal(req);
++
++        /* At this point, the request will be kept alive by the reference
++         * added by scsi_req_enqueue_internal, so we can release our reference.
++         * The HBA of course will add its own reference in the load_request
++         * callback if it needs to hold on the SCSIRequest.
++         */
++        scsi_req_unref(req);
++    }
++
++    return 0;
++}
++
++const VMStateInfo vmstate_info_scsi_requests = {
++    .name = "scsi-requests",
++    .get  = get_scsi_requests,
++    .put  = put_scsi_requests,
++};
++
++const VMStateDescription vmstate_scsi_device = {
++    .name = "SCSIDevice",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .minimum_version_id_old = 1,
++    .fields = (VMStateField[]) {
++        VMSTATE_UINT8(unit_attention.key, SCSIDevice),
++        VMSTATE_UINT8(unit_attention.asc, SCSIDevice),
++        VMSTATE_UINT8(unit_attention.ascq, SCSIDevice),
++        VMSTATE_BOOL(sense_is_ua, SCSIDevice),
++        VMSTATE_UINT8_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE),
++        VMSTATE_UINT32(sense_len, SCSIDevice),
++        {
++            .name         = "requests",
++            .version_id   = 0,
++            .field_exists = NULL,
++            .size         = 0,   /* ouch */
++            .info         = &vmstate_info_scsi_requests,
++            .flags        = VMS_SINGLE,
++            .offset       = 0,
++        },
++        VMSTATE_END_OF_LIST()
++    }
++};
+diff -ruNp qemu-kvm-1.0/hw/scsi-disk.c qemu-kvm-1.0.virtio-scsi/hw/scsi-disk.c
+--- qemu-kvm-1.0/hw/scsi-disk.c	2011-12-04 04:38:06.000000000 -0600
++++ qemu-kvm-1.0.virtio-scsi/hw/scsi-disk.c	2012-02-07 14:44:53.429905331 -0600
+@@ -38,6 +38,7 @@ do { fprintf(stderr, "scsi-disk: " fmt ,
+ #include "sysemu.h"
+ #include "blockdev.h"
+ #include "block_int.h"
++#include "dma.h"
+ 
+ #ifdef __linux
+ #include <scsi/sg.h>
+@@ -110,12 +111,12 @@ static void scsi_cancel_io(SCSIRequest *
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list