qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 14/51] scsi-disk: fix VERIFY emulation


From: Michael Roth
Subject: [Qemu-devel] [PATCH 14/51] scsi-disk: fix VERIFY emulation
Date: Fri, 21 Feb 2014 02:16:50 -0600

From: Paolo Bonzini <address@hidden>

VERIFY emulation was completely botched (and remained botched through
all the refactorings).  The command must be emulated both in check-medium
mode (BYTCHK=00, which we implement by doing nothing) and in check-bytes
mode (which we do not implement yet).  Unlike WRITE AND VERIFY (which we
treat simply as WRITE with FUA bit set), VERIFY cannot be handled like
READ.  In fact the device is _receiving_ data for VERIFY, not _sending_
it like READ.

Cc: address@hidden
Tested-by: Hervé Poussineau <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
(cherry picked from commit d97e7730816094a71cd1f19a56d7a73f77cdbf96)

Conflicts:

        hw/scsi/scsi-disk.c

*fixed up WRITE_SAME_* conflicts due to 84f94a9a not being in 1.7.0

Signed-off-by: Michael Roth <address@hidden>
---
 hw/scsi/scsi-disk.c |   26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 74e6a14..1fd1c26 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1597,6 +1597,14 @@ static void scsi_disk_emulate_write_data(SCSIRequest 
*req)
         scsi_disk_emulate_unmap(r, r->iov.iov_base);
         break;
 
+    case VERIFY_10:
+    case VERIFY_12:
+    case VERIFY_16:
+        if (r->req.status == -1) {
+            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
+        }
+        break;
+
     default:
         abort();
     }
@@ -1837,6 +1845,14 @@ static int32_t scsi_disk_emulate_command(SCSIRequest 
*req, uint8_t *buf)
     case UNMAP:
         DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
         break;
+    case VERIFY_10:
+    case VERIFY_12:
+    case VERIFY_16:
+        DPRINTF("Verify (bytchk %lu)\n", (r->req.buf[1] >> 1) & 3);
+        if (req->cmd.buf[1] & 6) {
+            goto illegal_request;
+        }
+        break;
     case WRITE_SAME_10:
     case WRITE_SAME_16:
         nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);
@@ -1936,10 +1952,6 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, 
uint8_t *buf)
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
             return 0;
         }
-        /* fallthrough */
-    case VERIFY_10:
-    case VERIFY_12:
-    case VERIFY_16:
         DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",
                 (command & 0xe) == 0xe ? "And Verify " : "",
                 r->req.cmd.lba, len);
@@ -2207,14 +2219,14 @@ static const SCSIReqOps *const 
scsi_disk_reqops_dispatch[256] = {
     [UNMAP]                           = &scsi_disk_emulate_reqops,
     [WRITE_SAME_10]                   = &scsi_disk_emulate_reqops,
     [WRITE_SAME_16]                   = &scsi_disk_emulate_reqops,
+    [VERIFY_10]                       = &scsi_disk_emulate_reqops,
+    [VERIFY_12]                       = &scsi_disk_emulate_reqops,
+    [VERIFY_16]                       = &scsi_disk_emulate_reqops,
 
     [READ_6]                          = &scsi_disk_dma_reqops,
     [READ_10]                         = &scsi_disk_dma_reqops,
     [READ_12]                         = &scsi_disk_dma_reqops,
     [READ_16]                         = &scsi_disk_dma_reqops,
-    [VERIFY_10]                       = &scsi_disk_dma_reqops,
-    [VERIFY_12]                       = &scsi_disk_dma_reqops,
-    [VERIFY_16]                       = &scsi_disk_dma_reqops,
     [WRITE_6]                         = &scsi_disk_dma_reqops,
     [WRITE_10]                        = &scsi_disk_dma_reqops,
     [WRITE_12]                        = &scsi_disk_dma_reqops,
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]