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