From patchwork Fri May 25 09:44:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 161267 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 510D9B6EF3 for ; Fri, 25 May 2012 19:49:07 +1000 (EST) Received: from localhost ([::1]:51775 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXr55-0002S2-9n for incoming@patchwork.ozlabs.org; Fri, 25 May 2012 05:45:11 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47586) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXr4U-00011i-2r for qemu-devel@nongnu.org; Fri, 25 May 2012 05:44:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SXr4O-0000cl-Dr for qemu-devel@nongnu.org; Fri, 25 May 2012 05:44:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:14708) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXr4O-0000by-6i for qemu-devel@nongnu.org; Fri, 25 May 2012 05:44:28 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q4P9iQ2K025854 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 25 May 2012 05:44:26 -0400 Received: from rincewind.home.kraxel.org (ovpn-116-44.ams2.redhat.com [10.36.116.44]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q4P9iPY6023655; Fri, 25 May 2012 05:44:26 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id AFC5942575; Fri, 25 May 2012 11:44:22 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 25 May 2012 11:44:17 +0200 Message-Id: <1337939061-13629-7-git-send-email-kraxel@redhat.com> In-Reply-To: <1337939061-13629-1-git-send-email-kraxel@redhat.com> References: <1337939061-13629-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Paolo Bonzini , Gerd Hoffmann Subject: [Qemu-devel] [PATCH 06/10] scsi: prepare migration code for usb-storage support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Signed-off-by: Gerd Hoffmann Acked-by: Paolo Bonzini --- hw/scsi-bus.c | 8 ++++---- hw/scsi-disk.c | 13 +++++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 8ab9bcd..92b8176 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..4fd39ff 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -132,8 +132,13 @@ 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) { + qemu_put_be64s(f, &r->iov.iov_len); + qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len); + } } } @@ -148,6 +153,10 @@ 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) { + qemu_get_be64s(f, &r->iov.iov_len); + assert(r->iov.iov_len <= r->buflen); + qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len); } }