qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 10/32] scsi-disk: move all non-DMA commands to scsi_disk_emulate_command
Date: Fri, 27 Jul 2012 17:02:37 +0200	[thread overview]
Message-ID: <1343401379-19495-11-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1343401379-19495-1-git-send-email-pbonzini@redhat.com>

We want to use separate SCSIReqOps for emulated commands needing an
allocated buffer vs. those that are zerocopy when the HBA supports
S/G lists.  Ensure that all of the former are in scsi_disk_emulate_command.

Commands that do not have any parameters are more similar to emulated
commands, so also move them, even if they do I/O.

Finally, MODE SELECT and MODE SELECT(10) are broken because we do not
yet support passing parameter data _to_ emulated commands, so disable
them.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi-disk.c |  152 ++++++++++++++++++++++++--------------------------------
 1 file changed, 66 insertions(+), 86 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index f8e9dc1..9f7258d 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1448,10 +1448,65 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
         }
         DPRINTF("Unsupported Service Action In\n");
         goto illegal_request;
+    case SYNCHRONIZE_CACHE:
+        /* The request is used as the AIO opaque value, so add a ref.  */
+        scsi_req_ref(&r->req);
+        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
+        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
+        return 0;
+    case SEEK_10:
+        DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba);
+        if (r->req.cmd.lba > s->qdev.max_lba) {
+            goto illegal_lba;
+        }
+        break;
+#if 0
+    case MODE_SELECT:
+        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
+        /* We don't support mode parameter changes.
+           Allow the mode parameter header + block descriptors only. */
+        if (r->req.cmd.xfer > 12) {
+            goto illegal_request;
+        }
+        break;
+    case MODE_SELECT_10:
+        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
+        /* We don't support mode parameter changes.
+           Allow the mode parameter header + block descriptors only. */
+        if (r->req.cmd.xfer > 16) {
+            goto illegal_request;
+        }
+        break;
+#endif
+    case WRITE_SAME_10:
+        nb_sectors = lduw_be_p(&req->cmd.buf[7]);
+        goto write_same;
+    case WRITE_SAME_16:
+        nb_sectors = ldl_be_p(&req->cmd.buf[10]) & 0xffffffffULL;
+    write_same:
+        if (r->req.cmd.lba > s->qdev.max_lba) {
+            goto illegal_lba;
+        }
+
+        /*
+         * We only support WRITE SAME with the unmap bit set for now.
+         */
+        if (!(req->cmd.buf[1] & 0x8)) {
+            goto illegal_request;
+        }
+
+        /* The request is used as the AIO opaque value, so add a ref.  */
+        scsi_req_ref(&r->req);
+        r->req.aiocb = bdrv_aio_discard(s->qdev.conf.bs,
+                                        r->req.cmd.lba * (s->qdev.blocksize / 512),
+                                        nb_sectors * (s->qdev.blocksize / 512),
+                                        scsi_aio_complete, r);
+        return 0;
     default:
         scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
         return -1;
     }
+    assert(r->sector_count == 0);
     buflen = MIN(buflen, req->cmd.xfer);
     return buflen;
 
@@ -1460,6 +1515,10 @@ illegal_request:
         scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
     }
     return -1;
+
+illegal_lba:
+    scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
+    return 0;
 }
 
 /* Execute a scsi command.  Returns the length of the data expected by the
@@ -1513,38 +1572,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     }
 
     switch (command) {
-    case TEST_UNIT_READY:
-    case INQUIRY:
-    case MODE_SENSE:
-    case MODE_SENSE_10:
-    case RESERVE:
-    case RESERVE_10:
-    case RELEASE:
-    case RELEASE_10:
-    case START_STOP:
-    case ALLOW_MEDIUM_REMOVAL:
-    case READ_CAPACITY_10:
-    case READ_TOC:
-    case READ_DISC_INFORMATION:
-    case READ_DVD_STRUCTURE:
-    case GET_CONFIGURATION:
-    case GET_EVENT_STATUS_NOTIFICATION:
-    case MECHANISM_STATUS:
-    case SERVICE_ACTION_IN_16:
-    case REQUEST_SENSE:
-        rc = scsi_disk_emulate_command(r);
-        if (rc < 0) {
-            return 0;
-        }
-
-        r->iov.iov_len = rc;
-        break;
-    case SYNCHRONIZE_CACHE:
-        /* The request is used as the AIO opaque value, so add a ref.  */
-        scsi_req_ref(&r->req);
-        bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
-        r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
-        return 0;
     case READ_6:
     case READ_10:
     case READ_12:
@@ -1577,63 +1604,16 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
         r->sector_count = len * (s->qdev.blocksize / 512);
         break;
-    case MODE_SELECT:
-        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
-        /* We don't support mode parameter changes.
-           Allow the mode parameter header + block descriptors only. */
-        if (r->req.cmd.xfer > 12) {
-            goto fail;
-        }
-        break;
-    case MODE_SELECT_10:
-        DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
-        /* We don't support mode parameter changes.
-           Allow the mode parameter header + block descriptors only. */
-        if (r->req.cmd.xfer > 16) {
-            goto fail;
+    default:
+        rc = scsi_disk_emulate_command(r);
+        if (rc < 0) {
+            return 0;
         }
-        break;
-    case SEEK_10:
-        DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba);
-        if (r->req.cmd.lba > s->qdev.max_lba) {
-            goto illegal_lba;
+        if (r->req.aiocb) {
+            return 0;
         }
+        r->iov.iov_len = rc;
         break;
-    case WRITE_SAME_10:
-        len = lduw_be_p(&buf[7]);
-        goto write_same;
-    case WRITE_SAME_16:
-        len = ldl_be_p(&buf[10]) & 0xffffffffULL;
-    write_same:
-
-        DPRINTF("WRITE SAME() (sector %" PRId64 ", count %d)\n",
-                r->req.cmd.lba, len);
-
-        if (r->req.cmd.lba > s->qdev.max_lba) {
-            goto illegal_lba;
-        }
-
-        /*
-         * We only support WRITE SAME with the unmap bit set for now.
-         */
-        if (!(buf[1] & 0x8)) {
-            goto fail;
-        }
-
-        /* The request is used as the AIO opaque value, so add a ref.  */
-        scsi_req_ref(&r->req);
-        r->req.aiocb = bdrv_aio_discard(s->qdev.conf.bs,
-                                        r->req.cmd.lba * (s->qdev.blocksize / 512),
-                                        len * (s->qdev.blocksize / 512),
-                                        scsi_aio_complete, r);
-        return 0;
-    default:
-        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
-        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
-        return 0;
-    fail:
-        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
-        return 0;
     illegal_lba:
         scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
-- 
1.7.10.4

  parent reply	other threads:[~2012-07-27 15:03 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-27 15:02 [Qemu-devel] [PULL 00/32] SCSI patches for 2012-08-27 Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 01/32] megasas: Replace trace_megasas_dcmd_dump_frame() Paolo Bonzini
2012-07-30  9:40   ` Stefan Hajnoczi
2012-07-27 15:02 ` [Qemu-devel] [PATCH 02/32] megasas: fix misuse of scsi_req_abort Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 03/32] lsi: use qdev_reset_all Paolo Bonzini
2013-04-23  8:47   ` Jan Kiszka
2013-04-23 16:13     ` Paolo Bonzini
2013-04-23 16:43       ` Paolo Bonzini
2013-04-23 16:54         ` Jan Kiszka
2012-07-27 15:02 ` [Qemu-devel] [PATCH 04/32] lsi: introduce lsi_request_free Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 05/32] lsi: avoid redundant tests of s->current != NULL Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 06/32] scsi-block: remove properties that are not relevant for passthrough Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 07/32] cutils: add strpadcpy() Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 08/32] scsi-disk: let the user customize vendor and product name Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 09/32] scsi-disk: make discard asynchronous Paolo Bonzini
2012-07-27 15:02 ` Paolo Bonzini [this message]
2012-07-27 15:02 ` [Qemu-devel] [PATCH 11/32] scsi-disk: split scsi-disk reqops Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 12/32] scsi-disk: separate read_data/write_data implementation for emulate_reqops Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 13/32] scsi-disk: support emulated TO_DEV requests Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 14/32] scsi-disk: adjust offsets in MODE SENSE by 2 Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 15/32] scsi-disk: fix changeable values for MODE_PAGE_R_W_ERROR Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 16/32] scsi-disk: parse MODE SELECT commands and parameters Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 17/32] scsi-disk: support toggling the write cache Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 18/32] scsi-disk: rd/wr/vr-protect !=0 is an error Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 19/32] scsi-disk: improve the lba-out-of-range tests for read/write/verify Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 20/32] scsi-disk: Fail medium writes with proper sense for readonly LUNs Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 21/32] scsi-disk: removable hard disks support load/eject Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 22/32] scsi: add tracepoint for scsi_req_cancel Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 23/32] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 24/32] scsi: establish precedence levels for unit attention Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 25/32] scsi-disk: report resized disk via sense codes Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 26/32] scsi: report parameter changes to HBA drivers Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 27/32] virtio-scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 28/32] virtio-scsi: Report missed events Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 29/32] virtio-scsi: do not report dropped events after reset Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 30/32] virtio-scsi: report parameter change events Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 31/32] virtio-scsi: add ioeventfd support Paolo Bonzini
2012-07-27 15:02 ` [Qemu-devel] [PATCH 32/32] virtio-scsi: enable MSI-X support Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1343401379-19495-11-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).