qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 11/15] scsi: add xfer mode


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 11/15] scsi: add xfer mode
Date: Tue, 17 Nov 2009 11:17:47 +0100

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 hw/scsi-bus.c     |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/scsi-generic.c |   40 ++++++----------------------------------
 hw/scsi.h         |    7 +++++++
 3 files changed, 59 insertions(+), 34 deletions(-)

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;
-- 
1.6.2.5





reply via email to

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