Patchwork [11/15] scsi: add xfer mode

login
register
mail settings
Submitter Gerd Hoffmann
Date Nov. 17, 2009, 10:17 a.m.
Message ID <1258453071-3496-12-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/38620/
State New
Headers show

Comments

Gerd Hoffmann - Nov. 17, 2009, 10:17 a.m.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/scsi-bus.c     |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/scsi-generic.c |   40 ++++++----------------------------------
 hw/scsi.h         |    7 +++++++
 3 files changed, 59 insertions(+), 34 deletions(-)
Christoph Hellwig - Nov. 17, 2009, 11:53 a.m.
On Tue, Nov 17, 2009 at 11:17:47AM +0100, Gerd Hoffmann wrote:
> +static void scsi_req_xfer_mode(SCSIRequest *req)
> +{
> +    switch (req->cmd.buf[0]) {

Having this as a void seem a bit odd to me.  I'd make it return the
mode, and maybe just pass the cmd to it to make it more clear.

> +static int is_write(SCSIGenericReq *r)
>  {
> +    switch (r->req.cmd.mode) {
> +    case SCSI_XFER_TO_DEV:
>          return 1;
> +    default:
> +        return 0;
>      }
>  }

Does this helper relaly buy anything over a simple

    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {

check?
Paul Brook - Nov. 17, 2009, 11:58 a.m.
> add xfer mode

This should also be used by scsi-disc.c

Paul

Patch

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0b31924..77409de 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -237,6 +237,51 @@  static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd)
     return 0;
 }
 
+static void scsi_req_xfer_mode(SCSIRequest *req)
+{
+    switch (req->cmd.buf[0]) {
+    case WRITE_6:
+    case WRITE_10:
+    case WRITE_VERIFY:
+    case WRITE_12:
+    case WRITE_VERIFY_12:
+    case COPY:
+    case COPY_VERIFY:
+    case COMPARE:
+    case CHANGE_DEFINITION:
+    case LOG_SELECT:
+    case MODE_SELECT:
+    case MODE_SELECT_10:
+    case SEND_DIAGNOSTIC:
+    case WRITE_BUFFER:
+    case FORMAT_UNIT:
+    case REASSIGN_BLOCKS:
+    case RESERVE:
+    case SEARCH_EQUAL:
+    case SEARCH_HIGH:
+    case SEARCH_LOW:
+    case UPDATE_BLOCK:
+    case WRITE_LONG:
+    case WRITE_SAME:
+    case SEARCH_HIGH_12:
+    case SEARCH_EQUAL_12:
+    case SEARCH_LOW_12:
+    case SET_WINDOW:
+    case MEDIUM_SCAN:
+    case SEND_VOLUME_TAG:
+    case WRITE_LONG_2:
+        req->cmd.mode = SCSI_XFER_TO_DEV;
+        break;
+    default:
+        if (req->cmd.xfer)
+            req->cmd.mode = SCSI_XFER_FROM_DEV;
+        else {
+            req->cmd.mode = SCSI_XFER_NONE;
+        }
+        break;
+    }
+}
+
 static uint64_t scsi_req_lba(SCSIRequest *req)
 {
     uint8_t *buf = req->cmd.buf;
@@ -282,6 +327,7 @@  int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
         return rc;
 
     memcpy(req->cmd.buf, buf, req->cmd.len);
+    scsi_req_xfer_mode(req);
     req->cmd.lba = scsi_req_lba(req);
     return 0;
 }
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 3f4fbbb..d9f08b6 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -329,42 +329,14 @@  static void scsi_req_fixup(SCSIRequest *req)
     }
 }
 
-static int is_write(int command)
+static int is_write(SCSIGenericReq *r)
 {
-    switch (command) {
-    case COPY:
-    case COPY_VERIFY:
-    case COMPARE:
-    case CHANGE_DEFINITION:
-    case LOG_SELECT:
-    case MODE_SELECT:
-    case MODE_SELECT_10:
-    case SEND_DIAGNOSTIC:
-    case WRITE_BUFFER:
-    case FORMAT_UNIT:
-    case REASSIGN_BLOCKS:
-    case RESERVE:
-    case SEARCH_EQUAL:
-    case SEARCH_HIGH:
-    case SEARCH_LOW:
-    case WRITE_6:
-    case WRITE_10:
-    case WRITE_VERIFY:
-    case UPDATE_BLOCK:
-    case WRITE_LONG:
-    case WRITE_SAME:
-    case SEARCH_HIGH_12:
-    case SEARCH_EQUAL_12:
-    case SEARCH_LOW_12:
-    case WRITE_12:
-    case WRITE_VERIFY_12:
-    case SET_WINDOW:
-    case MEDIUM_SCAN:
-    case SEND_VOLUME_TAG:
-    case WRITE_LONG_2:
+    switch (r->req.cmd.mode) {
+    case SCSI_XFER_TO_DEV:
         return 1;
+    default:
+        return 0;
     }
-    return 0;
 }
 
 /* Execute a scsi command.  Returns the length of the data expected by the
@@ -437,7 +409,7 @@  static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
 
     memset(r->buf, 0, r->buflen);
     r->len = r->req.cmd.xfer;
-    if (is_write(cmd[0])) {
+    if (is_write(r)) {
         r->len = 0;
         return -r->req.cmd.xfer;
     }
diff --git a/hw/scsi.h b/hw/scsi.h
index 8eec616..f2d033f 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -18,6 +18,12 @@  typedef struct SCSIDeviceInfo SCSIDeviceInfo;
 typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag,
                                   uint32_t arg);
 
+enum SCSIXferMode {
+    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
+    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
+    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
+};
+
 typedef struct SCSIRequest {
     SCSIBus           *bus;
     SCSIDevice        *dev;
@@ -28,6 +34,7 @@  typedef struct SCSIRequest {
         int len;
         size_t xfer;
         uint64_t lba;
+        enum SCSIXferMode mode;
     } cmd;
     BlockDriverAIOCB  *aiocb;
     QTAILQ_ENTRY(SCSIRequest) next;