0a122b
From e110f0eee587fbfc75409e0980f25275dd8551de Mon Sep 17 00:00:00 2001
0a122b
From: Paolo Bonzini <pbonzini@redhat.com>
0a122b
Date: Mon, 20 Jan 2014 12:49:45 +0100
0a122b
Subject: [PATCH 29/34] scsi-disk: fix VERIFY emulation
0a122b
MIME-Version: 1.0
0a122b
Content-Type: text/plain; charset=UTF-8
0a122b
Content-Transfer-Encoding: 8bit
0a122b
0a122b
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
0a122b
Message-id: <1390222185-24969-3-git-send-email-pbonzini@redhat.com>
0a122b
Patchwork-id: 56834
0a122b
O-Subject: [RHEL 7.0 qemu-kvm PATCH 2/2] scsi-disk: fix VERIFY emulation
0a122b
Bugzilla: 1035644
0a122b
RH-Acked-by: Fam Zheng <famz@redhat.com>
0a122b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
0a122b
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
0a122b
0a122b
VERIFY emulation was completely botched (and remained botched through
0a122b
all the refactorings).  The command must be emulated both in check-medium
0a122b
mode (BYTCHK=00, which we implement by doing nothing) and in check-bytes
0a122b
mode (which we do not implement yet).  Unlike WRITE AND VERIFY (which we
0a122b
treat simply as WRITE with FUA bit set), VERIFY cannot be handled like
0a122b
READ.  In fact the device is _receiving_ data for VERIFY, not _sending_
0a122b
it like READ.
0a122b
0a122b
Cc: qemu-stable@nongnu.org
0a122b
Tested-by: Hervé Poussineau <hpoussin@reactos.org>
0a122b
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
(cherry picked from commit d97e7730816094a71cd1f19a56d7a73f77cdbf96)
0a122b
---
0a122b
 hw/scsi/scsi-disk.c | 27 ++++++++++++++++++++-------
0a122b
 1 file changed, 20 insertions(+), 7 deletions(-)
0a122b
0a122b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
0a122b
---
0a122b
 hw/scsi/scsi-disk.c |   27 ++++++++++++++++++++-------
0a122b
 1 files changed, 20 insertions(+), 7 deletions(-)
0a122b
0a122b
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
0a122b
index c44f159..7653411 100644
0a122b
--- a/hw/scsi/scsi-disk.c
0a122b
+++ b/hw/scsi/scsi-disk.c
0a122b
@@ -1720,10 +1720,19 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req)
0a122b
         scsi_disk_emulate_unmap(r, r->iov.iov_base);
0a122b
         break;
0a122b
 
0a122b
+    case VERIFY_10:
0a122b
+    case VERIFY_12:
0a122b
+    case VERIFY_16:
0a122b
+        if (r->req.status == -1) {
0a122b
+            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
0a122b
+        }
0a122b
+        break;
0a122b
+
0a122b
     case WRITE_SAME_10:
0a122b
     case WRITE_SAME_16:
0a122b
         scsi_disk_emulate_write_same(r, r->iov.iov_base);
0a122b
         break;
0a122b
+
0a122b
     default:
0a122b
         abort();
0a122b
     }
0a122b
@@ -1964,6 +1973,14 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
0a122b
     case UNMAP:
0a122b
         DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
0a122b
         break;
0a122b
+    case VERIFY_10:
0a122b
+    case VERIFY_12:
0a122b
+    case VERIFY_16:
0a122b
+        DPRINTF("Verify (bytchk %lu)\n", (r->req.buf[1] >> 1) & 3);
0a122b
+        if (req->cmd.buf[1] & 6) {
0a122b
+            goto illegal_request;
0a122b
+        }
0a122b
+        break;
0a122b
     case WRITE_SAME_10:
0a122b
     case WRITE_SAME_16:
0a122b
         DPRINTF("WRITE SAME %d (len %lu)\n",
0a122b
@@ -2044,10 +2061,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
0a122b
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
0a122b
             return 0;
0a122b
         }
0a122b
-        /* fallthrough */
0a122b
-    case VERIFY_10:
0a122b
-    case VERIFY_12:
0a122b
-    case VERIFY_16:
0a122b
         DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",
0a122b
                 (command & 0xe) == 0xe ? "And Verify " : "",
0a122b
                 r->req.cmd.lba, len);
0a122b
@@ -2315,14 +2328,14 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = {
0a122b
     [UNMAP]                           = &scsi_disk_emulate_reqops,
0a122b
     [WRITE_SAME_10]                   = &scsi_disk_emulate_reqops,
0a122b
     [WRITE_SAME_16]                   = &scsi_disk_emulate_reqops,
0a122b
+    [VERIFY_10]                       = &scsi_disk_emulate_reqops,
0a122b
+    [VERIFY_12]                       = &scsi_disk_emulate_reqops,
0a122b
+    [VERIFY_16]                       = &scsi_disk_emulate_reqops,
0a122b
 
0a122b
     [READ_6]                          = &scsi_disk_dma_reqops,
0a122b
     [READ_10]                         = &scsi_disk_dma_reqops,
0a122b
     [READ_12]                         = &scsi_disk_dma_reqops,
0a122b
     [READ_16]                         = &scsi_disk_dma_reqops,
0a122b
-    [VERIFY_10]                       = &scsi_disk_dma_reqops,
0a122b
-    [VERIFY_12]                       = &scsi_disk_dma_reqops,
0a122b
-    [VERIFY_16]                       = &scsi_disk_dma_reqops,
0a122b
     [WRITE_6]                         = &scsi_disk_dma_reqops,
0a122b
     [WRITE_10]                        = &scsi_disk_dma_reqops,
0a122b
     [WRITE_12]                        = &scsi_disk_dma_reqops,
0a122b
-- 
0a122b
1.7.1
0a122b