From c2f7c38d7334ea4ef3f99a1d1cbeb968cc29c749 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 22 Feb 2012 14:11:45 +0100
Subject: [PATCH 029/109] usb-storage: don't try to send the status early.

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1329919979-20948-29-git-send-email-pbonzini@redhat.com>
Patchwork-id: 37514
O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 028/102] usb-storage: don't try to send the status early.
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>

Until recently all scsi commands sent to scsi-disk did either transfer
data or finished instantly.  The correct implementation of
SYNCRONIZE_CACHE changed the picture though, and usb-storage needs
a fix to handle that case correctly.

(cherry picked from 59310659073d85745854f2f10c4292555c5a1c51)
---
 hw/usb-msd.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

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

diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 977d809..43013f0 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -401,9 +401,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
             s->scsi_len = 0;
             s->req = scsi_req_new(s->scsi_dev, tag, 0, cbw.cmd, NULL);
             scsi_req_enqueue(s->req);
-            /* ??? Should check that USB and SCSI data transfer
-               directions match.  */
-            if (s->mode != USB_MSDM_CSW && s->residue == 0) {
+            if (s->req && s->req->cmd.xfer != SCSI_XFER_NONE) {
                 scsi_req_continue(s->req);
             }
             ret = len;
@@ -457,9 +455,15 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
             if (len < 13)
                 goto fail;
 
-            usb_msd_send_status(s, p);
-            s->mode = USB_MSDM_CBW;
-            ret = 13;
+            if (s->req) {
+                /* still in flight */
+                s->packet = p;
+                ret = USB_RET_ASYNC;
+            } else {
+                usb_msd_send_status(s, p);
+                s->mode = USB_MSDM_CBW;
+                ret = 13;
+            }
             break;
 
         case USB_MSDM_DATAIN:
-- 
1.7.7.6

