[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 07/37] scsi: prepare migration code for usb-storage
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 07/37] scsi: prepare migration code for usb-storage support |
Date: |
Thu, 7 Jun 2012 11:30:56 +0200 |
usb-storage can't handle requests in one go as the data transfer can be
splitted into lots of usb packets. Because of that there can be
normal in-flight requests at savevm time and we need to handle that.
With other scsi hba's this happens only in case i/o is stopped due to
errors and there are pending requests which need to be restarted
(req->retry = true).
So, first we need to save req->retry and then handle the req->retry =
false case. Write requests are handled fine already. For read requests
we have to save the buffer as we will not restart the request (and thus
not refill the buffer) on the target host.
Cc: Paolo Bonzini <address@hidden>
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/scsi-bus.c | 8 ++++----
hw/scsi-disk.c | 16 ++++++++++++++--
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index f10f3ec..4a79821 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1507,10 +1507,9 @@ static void put_scsi_requests(QEMUFile *f, void *pv,
size_t size)
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_sbyte(f, req->retry ? 1 : 2);
qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf));
qemu_put_be32s(f, &req->tag);
qemu_put_be32s(f, &req->lun);
@@ -1528,8 +1527,9 @@ 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);
+ int8_t sbyte;
- while (qemu_get_sbyte(f)) {
+ while ((sbyte = qemu_get_sbyte(f)) > 0) {
uint8_t buf[SCSI_CMD_BUF_SIZE];
uint32_t tag;
uint32_t lun;
@@ -1539,6 +1539,7 @@ static int get_scsi_requests(QEMUFile *f, void *pv,
size_t size)
qemu_get_be32s(f, &tag);
qemu_get_be32s(f, &lun);
req = scsi_req_new(s, tag, lun, buf, NULL);
+ req->retry = (sbyte == 1);
if (bus->info->load_request) {
req->hba_private = bus->info->load_request(f, req);
}
@@ -1547,7 +1548,6 @@ static int get_scsi_requests(QEMUFile *f, void *pv,
size_t size)
}
/* Just restart it later. */
- req->retry = true;
scsi_req_enqueue_internal(req);
/* At this point, the request will be kept alive by the reference
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 045c764..1691491 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -132,8 +132,14 @@ static void scsi_disk_save_request(QEMUFile *f,
SCSIRequest *req)
qemu_put_be64s(f, &r->sector);
qemu_put_be32s(f, &r->sector_count);
qemu_put_be32s(f, &r->buflen);
- if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
- qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
+ if (r->buflen) {
+ if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
+ qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
+ } else if (!req->retry) {
+ uint32_t len = r->iov.iov_len;
+ qemu_put_be32s(f, &len);
+ qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
+ }
}
}
@@ -148,6 +154,12 @@ static void scsi_disk_load_request(QEMUFile *f,
SCSIRequest *req)
scsi_init_iovec(r, r->buflen);
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
+ } else if (!r->req.retry) {
+ uint32_t len;
+ qemu_get_be32s(f, &len);
+ r->iov.iov_len = len;
+ assert(r->iov.iov_len <= r->buflen);
+ qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
}
}
--
1.7.1
- [Qemu-devel] [PATCH 27/37] ehci: move async schedule to bottom half, (continued)
- [Qemu-devel] [PATCH 27/37] ehci: move async schedule to bottom half, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 01/37] uhci: fix bandwidth management, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 22/37] ehci: cache USBDevice in EHCIQueue, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 10/37] usb-storage: add scsi_off, remove scsi_buf, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 06/37] uhci: fix irq routing, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 18/37] xhci: trace: transfers, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 26/37] ehci: add async field to EHCIQueue, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 12/37] xhci: Clean up reset function, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 21/37] ehci: make ehci_execute work on EHCIPacket instead of EHCIQueue, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 11/37] usb-storage: migration support, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 07/37] scsi: prepare migration code for usb-storage support,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH 16/37] xhci: trace: ring fetch, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 36/37] ehci: adaptive wakeup rate., Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 31/37] ehci: add ehci_*_enabled() helpers, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 34/37] ehci: remove unused attach_poll_counter, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 15/37] xhci: trace: irq + events, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 37/37] ehci: rework frame skipping, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 33/37] ehci: fix halt status handling, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 24/37] ehci: add queuing support, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 35/37] ehci: create ehci_update_frindex, Gerd Hoffmann, 2012/06/07
- [Qemu-devel] [PATCH 19/37] xhci: trace: slots, Gerd Hoffmann, 2012/06/07