|
|
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,
|