Blame 0105-scsi-disk-fix-VERIFY-emulation.patch

c40251
From ddc0dda3d6352e4c28e0bd11cce1d90734dce0db Mon Sep 17 00:00:00 2001
c40251
From: Paolo Bonzini <pbonzini@redhat.com>
c40251
Date: Thu, 28 Nov 2013 11:18:56 +0100
c40251
Subject: [PATCH] scsi-disk: fix VERIFY emulation
c40251
MIME-Version: 1.0
c40251
Content-Type: text/plain; charset=UTF-8
c40251
Content-Transfer-Encoding: 8bit
c40251
c40251
VERIFY emulation was completely botched (and remained botched through
c40251
all the refactorings).  The command must be emulated both in check-medium
c40251
mode (BYTCHK=00, which we implement by doing nothing) and in check-bytes
c40251
mode (which we do not implement yet).  Unlike WRITE AND VERIFY (which we
c40251
treat simply as WRITE with FUA bit set), VERIFY cannot be handled like
c40251
READ.  In fact the device is _receiving_ data for VERIFY, not _sending_
c40251
it like READ.
c40251
c40251
Cc: qemu-stable@nongnu.org
c40251
Tested-by: Hervé Poussineau <hpoussin@reactos.org>
c40251
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
c40251
(cherry picked from commit d97e7730816094a71cd1f19a56d7a73f77cdbf96)
c40251
c40251
Conflicts:
c40251
	hw/scsi/scsi-disk.c
c40251
---
c40251
 hw/scsi/scsi-disk.c | 26 +++++++++++++++++++-------
c40251
 1 file changed, 19 insertions(+), 7 deletions(-)
c40251
c40251
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
c40251
index 74e6a14..1fd1c26 100644
c40251
--- a/hw/scsi/scsi-disk.c
c40251
+++ b/hw/scsi/scsi-disk.c
c40251
@@ -1597,6 +1597,14 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req)
c40251
         scsi_disk_emulate_unmap(r, r->iov.iov_base);
c40251
         break;
c40251
 
c40251
+    case VERIFY_10:
c40251
+    case VERIFY_12:
c40251
+    case VERIFY_16:
c40251
+        if (r->req.status == -1) {
c40251
+            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
c40251
+        }
c40251
+        break;
c40251
+
c40251
     default:
c40251
         abort();
c40251
     }
c40251
@@ -1837,6 +1845,14 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
c40251
     case UNMAP:
c40251
         DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
c40251
         break;
c40251
+    case VERIFY_10:
c40251
+    case VERIFY_12:
c40251
+    case VERIFY_16:
c40251
+        DPRINTF("Verify (bytchk %lu)\n", (r->req.buf[1] >> 1) & 3);
c40251
+        if (req->cmd.buf[1] & 6) {
c40251
+            goto illegal_request;
c40251
+        }
c40251
+        break;
c40251
     case WRITE_SAME_10:
c40251
     case WRITE_SAME_16:
c40251
         nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);
c40251
@@ -1936,10 +1952,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
c40251
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
c40251
             return 0;
c40251
         }
c40251
-        /* fallthrough */
c40251
-    case VERIFY_10:
c40251
-    case VERIFY_12:
c40251
-    case VERIFY_16:
c40251
         DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",
c40251
                 (command & 0xe) == 0xe ? "And Verify " : "",
c40251
                 r->req.cmd.lba, len);
c40251
@@ -2207,14 +2219,14 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = {
c40251
     [UNMAP]                           = &scsi_disk_emulate_reqops,
c40251
     [WRITE_SAME_10]                   = &scsi_disk_emulate_reqops,
c40251
     [WRITE_SAME_16]                   = &scsi_disk_emulate_reqops,
c40251
+    [VERIFY_10]                       = &scsi_disk_emulate_reqops,
c40251
+    [VERIFY_12]                       = &scsi_disk_emulate_reqops,
c40251
+    [VERIFY_16]                       = &scsi_disk_emulate_reqops,
c40251
 
c40251
     [READ_6]                          = &scsi_disk_dma_reqops,
c40251
     [READ_10]                         = &scsi_disk_dma_reqops,
c40251
     [READ_12]                         = &scsi_disk_dma_reqops,
c40251
     [READ_16]                         = &scsi_disk_dma_reqops,
c40251
-    [VERIFY_10]                       = &scsi_disk_dma_reqops,
c40251
-    [VERIFY_12]                       = &scsi_disk_dma_reqops,
c40251
-    [VERIFY_16]                       = &scsi_disk_dma_reqops,
c40251
     [WRITE_6]                         = &scsi_disk_dma_reqops,
c40251
     [WRITE_10]                        = &scsi_disk_dma_reqops,
c40251
     [WRITE_12]                        = &scsi_disk_dma_reqops,