From f8d5f5d36e4d7cbfde05e5846216d08a4dfe6a52 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 22 Feb 2012 14:11:42 +0100
Subject: [PATCH 026/109] usb-storage: fill status in complete callback.

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1329919979-20948-26-git-send-email-pbonzini@redhat.com>
Patchwork-id: 37504
O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 025/102] usb-storage: fill status in complete callback.
Bugzilla: 782029
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>

From: Gerd Hoffmann <kraxel@redhat.com>

Put status word into device state, fill it in command_complete, have
usb_msd_send_status just send it out.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from 92a114f6f8487b8b256340cac5a5a10498e220c1)

Conflicts:
	hw/usb-msd.c due to lack of 4f4321c1
---
 hw/usb-msd.c |   37 +++++++++++++++++++++----------------
 1 files changed, 21 insertions(+), 16 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 hw/usb-msd.c |   37 +++++++++++++++++++++----------------
 1 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index ff4fd5f..f9470fe 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -38,6 +38,13 @@ enum USBMSDMode {
     USB_MSDM_CSW /* Command Status.  */
 };
 
+struct usb_msd_csw {
+    uint32_t sig;
+    uint32_t tag;
+    uint32_t residue;
+    uint8_t status;
+};
+
 typedef struct {
     USBDevice dev;
     enum USBMSDMode mode;
@@ -48,6 +55,7 @@ typedef struct {
     uint32_t data_len;
     uint32_t residue;
     uint32_t tag;
+    struct usb_msd_csw csw;
     SCSIRequest *req;
     SCSIBus bus;
     BlockConf conf;
@@ -69,13 +77,6 @@ struct usb_msd_cbw {
     uint8_t cmd[16];
 };
 
-struct usb_msd_csw {
-    uint32_t sig;
-    uint32_t tag;
-    uint32_t residue;
-    uint8_t status;
-};
-
 enum {
     STR_MANUFACTURER = 1,
     STR_PRODUCT,
@@ -199,18 +200,15 @@ static void usb_msd_copy_data(MSDState *s)
 
 static void usb_msd_send_status(MSDState *s, USBPacket *p)
 {
-    struct usb_msd_csw csw;
     int len;
 
     DPRINTF("Command status %d tag 0x%x, len %zd\n",
-            s->result, s->tag, p->len);
-    csw.sig = cpu_to_le32(0x53425355);
-    csw.tag = cpu_to_le32(s->tag);
-    csw.residue = s->residue;
-    csw.status = s->result;
-
-    len = MIN(sizeof(csw), p->len);
-    memcpy(p->data, &csw, len);
+            s->csw.status, s->csw.tag, p->len);
+
+    assert(s->csw.sig == 0x53425355);
+    len = MIN(sizeof(s->csw), p->len);
+    memcpy(p->data, &s->csw, len);
+    memset(&s->csw, 0, sizeof(s->csw));
 }
 
 static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
@@ -242,6 +240,12 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
     DPRINTF("Command complete %d\n", status);
     s->residue = s->data_len;
     s->result = status != 0;
+
+    s->csw.sig = cpu_to_le32(0x53425355);
+    s->csw.tag = cpu_to_le32(s->tag);
+    s->csw.residue = s->residue;
+    s->csw.status = s->result;
+
     if (s->packet) {
         if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
             /* A deferred packet with no write data remaining must be
@@ -265,6 +269,7 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
     } else if (s->data_len == 0) {
         s->mode = USB_MSDM_CSW;
     }
+
     scsi_req_unref(req);
     s->req = NULL;
 }
-- 
1.7.7.6

