WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] pvscsi: Enable REPORT_LUN command emu

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] pvscsi: Enable REPORT_LUN command emulation.
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 05 Jun 2008 05:40:20 -0700
Delivery-date: Thu, 05 Jun 2008 05:40:56 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1212658854 -3600
# Node ID 3b045d92c4c0e1e91c717f7810ba7d44a9f46b13
# Parent  ee72fd7d22c86326ff5a6880ac744b0a9e9785cc
pvscsi: Enable REPORT_LUN command emulation.

Signed-off-by: Tomonari Horikoshi <t.horikoshi@xxxxxxxxxxxxxx>
Signed-off-by: Jun Kamada <kama@xxxxxxxxxxxxxx>
---
 drivers/xen/scsiback/common.h   |   11 +-
 drivers/xen/scsiback/emulate.c  |  194 +++++++++++++++++++++++++---------------
 drivers/xen/scsiback/scsiback.c |   18 +--
 3 files changed, 139 insertions(+), 84 deletions(-)

diff -r ee72fd7d22c8 -r 3b045d92c4c0 drivers/xen/scsiback/common.h
--- a/drivers/xen/scsiback/common.h     Thu Jun 05 10:40:33 2008 +0100
+++ b/drivers/xen/scsiback/common.h     Thu Jun 05 10:40:54 2008 +0100
@@ -60,7 +60,6 @@
 #include <xen/interface/io/ring.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/vscsiif.h>
-
 
 
 #define DPRINTK(_f, _a...)                     \
@@ -171,11 +170,13 @@ void scsiback_release_translation_entry(
 
 
 void scsiback_cmd_exec(pending_req_t *pending_req);
+void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
+                               pending_req_t *pending_req);
+void scsiback_fast_flush_area(pending_req_t *req);
 
-#if 0 /*SAMPLE CODING(tentative)*//*emulation*/
-void scsiback_dispatch_emulation_cmdexec(vscsiif_request_t *ring_req,
-                               pending_req_t *pending_req);
-#endif
+void scsiback_rsp_emulation(pending_req_t *pending_req);
+void scsiback_req_emulation_or_cmdexec(pending_req_t *pending_req);
+void scsiback_emulation_init(void);
 
 
 #endif /* __SCSIIF__BACKEND__COMMON_H__ */
diff -r ee72fd7d22c8 -r 3b045d92c4c0 drivers/xen/scsiback/emulate.c
--- a/drivers/xen/scsiback/emulate.c    Thu Jun 05 10:40:33 2008 +0100
+++ b/drivers/xen/scsiback/emulate.c    Thu Jun 05 10:40:54 2008 +0100
@@ -31,7 +31,7 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
-#include "comback.h"
+#include "common.h"
 
 /* Following SCSI commands are not defined in scsi/scsi.h */
 #define EXTENDED_COPY          0x83    /* EXTENDED COPY command        */
@@ -76,12 +76,29 @@ static unsigned char bitmap[VSCSI_MAX_SC
 /*
   Emulation routines for each SCSI op_code.
 */
-static void (*pre_function[MAX_SCSI_OP_CODE])(pending_request_t *, void *);
-static void (*post_function[MAX_SCSI_OP_CODE])(pending_request_t *, void *);
+static void (*pre_function[VSCSI_MAX_SCSI_OP_CODE])(pending_req_t *, void *);
+static void (*post_function[VSCSI_MAX_SCSI_OP_CODE])(pending_req_t *, void *);
 
 
 static const int check_condition_result =
                (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+
+static void scsiback_mk_sense_buffer(uint8_t *data, uint8_t key,
+                       uint8_t asc, uint8_t asq)
+{
+       data[0] = 0x70;  /* fixed, current */
+       data[2] = key;
+       data[7] = 0xa;    /* implies 18 byte sense buffer */
+       data[12] = asc;
+       data[13] = asq;
+}
+
+static void resp_not_supported_cmd(pending_req_t *pending_req)
+{
+       scsiback_mk_sense_buffer(pending_req->sense_buffer, ILLEGAL_REQUEST,
+               INVALID_OPCODE, 0);
+       pending_req->rslt = check_condition_result;
+}
 
 
 static int __copy_to_sg(struct scatterlist *sg, unsigned int nr_sg,
@@ -91,20 +108,22 @@ static int __copy_to_sg(struct scatterli
        void *to;
        unsigned int from_rest = buflen;
        unsigned int to_capa;
-       unsigned int copy_size;
+       unsigned int copy_size = 0;
        unsigned int i;
+       unsigned long pfn;
 
        for (i = 0; i < nr_sg; i++) {
                if (sg->page == NULL) {
-                       printk(KERN_WARN "%s: inconsistent length field in "
+                       printk(KERN_WARNING "%s: inconsistent length field in "
                               "scatterlist\n", __FUNCTION__);
-                       return -1;
+                       return -ENOMEM;
                }
 
                to_capa  = sg->length;
-               copy_size = min_t(to_capa, from_rest);
-
-               to = page_to_virt(sg->page) + (sg->offset);
+               copy_size = min_t(unsigned int, to_capa, from_rest);
+
+               pfn = page_to_pfn(sg->page);
+               to = pfn_to_kaddr(pfn) + (sg->offset);
                memcpy(to, from, copy_size);
 
                from_rest  -= copy_size;
@@ -116,9 +135,9 @@ static int __copy_to_sg(struct scatterli
                from += copy_size;
        }
 
-       printk(KERN_WARN "%s: no space in scatterlist\n",
+       printk(KERN_WARNING "%s: no space in scatterlist\n",
               __FUNCTION__);
-       return -1;
+       return -ENOMEM;
 }
 
 static int __copy_from_sg(struct scatterlist *sg, unsigned int nr_sg,
@@ -130,24 +149,26 @@ static int __copy_from_sg(struct scatter
        unsigned int to_capa = buflen;
        unsigned int copy_size;
        unsigned int i;
+       unsigned long pfn;
 
        for (i = 0; i < nr_sg; i++) {
                if (sg->page == NULL) {
-                       printk(KERN_WARN "%s: inconsistent length field in "
+                       printk(KERN_WARNING "%s: inconsistent length field in "
                               "scatterlist\n", __FUNCTION__);
-                       return -1;
+                       return -ENOMEM;
                }
 
                from_rest = sg->length;
                if ((from_rest > 0) && (to_capa < from_rest)) {
-                       printk(KERN_WARN
+                       printk(KERN_WARNING
                               "%s: no space in destination buffer\n",
                               __FUNCTION__);
-                       return -1;
+                       return -ENOMEM;
                }
                copy_size = from_rest;
 
-               from = page_to_virt(sg->page) + (sg->offset);
+               pfn = page_to_pfn(sg->page);
+               from = pfn_to_kaddr(pfn) + (sg->offset);
                memcpy(to, from, copy_size);
 
                to_capa  -= copy_size;
@@ -160,34 +181,20 @@ static int __copy_from_sg(struct scatter
 }
 
 
-static void scsiback_mk_sense_buffer(uint8_t *date, uint8_t key, uint8_t asc,
-                               utint_8 asq)
-{
-       data[0] = 0x70;  /* fixed, current */
-       data[2] = key;
-       data[7] = 0xa;    /* implies 18 byte sense buffer */
-       data[12] = asc;
-       data[13] = asq;
-}
-
-
-
-/* tuning point*/
-#define VSCSIIF_RLUN_ARR_SZ            2048
-
 /* quoted scsi_debug.c/resp_report_luns() */
-static void __report_luns(pending_request_t *pending_req, void *data)
+static void __report_luns(pending_req_t *pending_req, void *data)
 {
        struct vscsibk_info *info   = pending_req->info;
        unsigned int        channel = pending_req->sdev->channel;
        unsigned int        target  = pending_req->sdev->id;
+       unsigned int        nr_seg  = pending_req->nr_segments;
        unsigned char *cmd = (unsigned char *)pending_req->cmnd;
        
-       unsigned char rq_buff[VSCSIIF_RLUN_ARR_SZ];
-       unsigned char *sense_buf = pending_req->sense_buffer;
+       unsigned char *rq_buff = NULL;
        unsigned char alloc_len;
+       unsigned int buff_len = 0;
        int select_report = (int)cmd[2];
-       int lun_cnt = 0;
+       int i, lun_cnt = 0, lun, upper, err = 0;
        
        struct v2p_entry *entry;
        struct list_head *head = &(info->v2p_entry_lists);
@@ -196,27 +203,24 @@ static void __report_luns(pending_reques
        struct scsi_lun *one_lun;
 
        alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
-       if ((alloc_len < 4) || (select_report != 0)) {
-               scsiback_mk_sense_buffer(pending_req->sense_buffer, 
ILLEGAL_REQUEST,
-                       INVALID_FIELD_IN_CDB, 0);
-               pending_req->rslt = check_condition_result;
-               return;
-       }
-
-       memset(rq_buff, 0, VSCSIIF_RLUN_ARR_SZ);
-       __copy_from_sg(pending_req->sgl, pending_req->nr_segments,
-               rq_buff, VSCSIIF_RLUN_ARR_SZ);
-
-
-       rq_buff[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff;
-       rq_buff[3] = (sizeof(struct scsi_lun) * num) & 0xff;
-
+       if ((alloc_len < 4) || (select_report != 0))
+               goto fail;
+       
+       for (i = 0; i < nr_seg; i++)
+               buff_len += pending_req->sgl[i].length;
+
+       if ((rq_buff = kmalloc(buff_len, GFP_KERNEL)) == NULL) {
+               printk(KERN_ERR "scsiback:%s kmalloc err\n", __FUNCTION__);
+               goto fail;
+       }
+
+       memset(rq_buff, 0, buff_len);
 
        one_lun = (struct scsi_lun *) &rq_buff[8];
        spin_lock_irqsave(&info->v2p_lock, flags);
        list_for_each_entry(entry, head, l) {
                if ((entry->v.chn == channel) &&
-                   (entry->v.tgt == target) {
+                   (entry->v.tgt == target)) {
                        lun = entry->v.lun;
                        upper = (lun >> 8) & 0x3f;
                        if (upper)
@@ -225,18 +229,34 @@ static void __report_luns(pending_reques
                        lun_cnt++;
                }
        }
+
        spin_unlock_irqrestore(&info->v2p_lock, flags);
 
-
-       lun_alloc = (unsigned char *)(one_lun + lun_cnt) - rq_buff;
-       
-       return fill_from_dev_buffer(scp, rq_buff,
-                                   min((int)alloc_len, lun_alloc));
-}
-
-
-
-int __pre_do_emulation(pending_request_t *pending_req, void *data)
+       rq_buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
+       rq_buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
+
+       err = __copy_to_sg(pending_req->sgl, nr_seg, rq_buff, buff_len);
+       if (err)
+               goto fail;
+
+       memset(pending_req->sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE);
+       pending_req->rslt = 0x00;
+
+       kfree(rq_buff);
+       return;
+
+fail:
+       scsiback_mk_sense_buffer(pending_req->sense_buffer, ILLEGAL_REQUEST,
+               INVALID_FIELD_IN_CDB, 0);
+       pending_req->rslt = check_condition_result;
+       if (rq_buff)
+               kfree(rq_buff);
+       return;
+}
+
+
+
+int __pre_do_emulation(pending_req_t *pending_req, void *data)
 {
        uint8_t op_code = pending_req->cmnd[0];
 
@@ -253,9 +273,9 @@ int __pre_do_emulation(pending_request_t
        return (bitmap[op_code] & VSCSIIF_NEED_CMD_EXEC);
 }
 
-void scsiback_rsp_emulation(pending_request_t *pending_req)
-{
-       uint8_t op_code = pending_req->cdb[0];
+void scsiback_rsp_emulation(pending_req_t *pending_req)
+{
+       uint8_t op_code = pending_req->cmnd[0];
 
        if ((bitmap[op_code] & VSCSIIF_NEED_EMULATE_RSPBUF) &&
            post_function[op_code] != NULL) {
@@ -268,8 +288,46 @@ void scsiback_rsp_emulation(pending_requ
 
 void scsiback_req_emulation_or_cmdexec(pending_req_t *pending_req)
 {
-       if (__pre_do_emulation(pending_req, NULL))
+       if (__pre_do_emulation(pending_req, NULL)) {
                scsiback_cmd_exec(pending_req);
-       else 
-               scsiback_do_resp_with_sense(pending_req);
-}
+       }
+       else {
+               scsiback_fast_flush_area(pending_req);
+               scsiback_do_resp_with_sense(pending_req->sense_buffer,
+                       pending_req->rslt, pending_req);
+       }
+}
+
+
+/*
+  Following are not customizable functions.
+*/
+void scsiback_emulation_init(void)
+{
+       int i;
+
+       /* Initialize to default state */
+       for (i = 0; i < VSCSI_MAX_SCSI_OP_CODE; i++) {
+               bitmap[i]        = VSCSIIF_NEED_CMD_EXEC;
+               pre_function[i]  = NULL;
+               post_function[i] = NULL;
+               /* means,
+                  - no need for pre-emulation
+                  - no need for post-emulation
+                  - call native driver
+
+                  (Current setting is black-list bases, white-list
+                  bases may be appropriate for security.)
+               */
+       }
+
+       /*
+         Register appropriate functions below as you need.
+         (See scsi/scsi.h for definition of SCSI op_code.)
+       */
+       pre_function[REPORT_LUNS] = __report_luns;
+       bitmap[REPORT_LUNS] = (VSCSIIF_NEED_EMULATE_REQBUF | 
+                                       VSCSIIF_NEED_EMULATE_RSPBUF);
+
+       return;
+}
diff -r ee72fd7d22c8 -r 3b045d92c4c0 drivers/xen/scsiback/scsiback.c
--- a/drivers/xen/scsiback/scsiback.c   Thu Jun 05 10:40:33 2008 +0100
+++ b/drivers/xen/scsiback/scsiback.c   Thu Jun 05 10:40:54 2008 +0100
@@ -78,7 +78,7 @@ static unsigned long vaddr(pending_req_t
        (pending_grant_handles[vaddr_pagenr(_req, _seg)])
 
 
-static void fast_flush_area(pending_req_t *req)
+void scsiback_fast_flush_area(pending_req_t *req)
 {
        struct gnttab_unmap_grant_ref unmap[VSCSIIF_SG_TABLESIZE];
        unsigned int i, invcount = 0;
@@ -141,7 +141,7 @@ static void scsiback_notify_work(struct 
        wake_up(&info->wq);
 }
 
-static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
+void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
                                pending_req_t *pending_req)
 {
        vscsiif_response_t *ring_res;
@@ -223,10 +223,8 @@ static void scsiback_cmd_done(void *data
                        __scsi_print_sense("scsiback", sense_buffer, 
SCSI_SENSE_BUFFERSIZE);
        }
 
-#if 0 /*SAMPLE CODING(tentative)*//*emulation*/
        scsiback_rsp_emulation(pending_req);
-#endif
-       fast_flush_area(pending_req);
+       scsiback_fast_flush_area(pending_req);
        scsiback_do_resp_with_sense(sense_buffer, errors, pending_req);
 
 
@@ -303,7 +301,7 @@ static int scsiback_gnttab_data_map(vscs
        return 0;
        
 fail_flush:
-       fast_flush_area(pending_req);
+       scsiback_fast_flush_area(pending_req);
        return -ENOMEM;
 }
 
@@ -622,11 +620,7 @@ static int scsiback_do_cmd_fn(struct vsc
                }
 
                if (pending_req->act == VSCSIIF_ACT_SCSI_CDB) {
-#if 0 /*SAMPLE CODING(tentative)*//*emulation*/
-                       scsiback_req_emulation_or_through(pending_req);
-#else
-                       scsiback_cmd_exec(pending_req);
-#endif
+                       scsiback_req_emulation_or_cmdexec(pending_req);
                } else if (pending_req->act == VSCSIIF_ACT_SCSI_RESET) {
                        scsiback_device_reset_exec(pending_req);
                } else {
@@ -707,6 +701,8 @@ static int __init scsiback_init(void)
        if (scsiback_xenbus_init())
                goto out_of_memory;
 
+       scsiback_emulation_init();
+
        return 0;
 
 out_of_memory:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] pvscsi: Enable REPORT_LUN command emulation., Xen patchbot-linux-2.6.18-xen <=