Re: [PATCH v2] scsi: NCR5380: use msecs_to_jiffies for conversions

2015-02-01 Thread Nicholas Mc Guire
On Mon, 02 Feb 2015, Michael Schmitz wrote:

> Hi Nicholas,
> 
> >> The values for USLEEP_* are taken to be in units jiffies, according to
> >> comments in NCR5380.c. Replacing them by the msecs_to_jiffies conversion
> >> is in fact wrong.
> >>
> >> Please drop the changes to g_NCR5380.c for that reason.
> >>
> >
> > right the comment indicates it should be jiffies - my interpretation
> > of that was that in NCR5380.c
> > were  jiffies + (250 * HZ / 1000); constructs would be correctly
> > converted to e.g. jiffies + msecs_to_jiffies(250)
> 
> No objection there.
> 
> > And defines like USLEEP_POLL are noted to be in jiffies:
> > * USLEEP_SLEEP - amount of time, in jiffies, to sleep
> >
> > and then defined correctly as HZ indepenedent values:
> > #define USLEEP_SLEEP (20*HZ/1000
> >
> > and thus should be the same as msecs_to_jiffies(20)
> 
> None here either.
> 
> >
> > now g_NCR5380.c defines
> > #define USLEEP_POLL 1
> > #define USLEEP_SLEEP20
> > #define USLEEP_WAITLONG 500
> >
> > for the DTC3181E card - but without the conversion to ms
> > from the use in the code though (e.g NCR5380_set_timer) it
> > seemed to me that it actually should be jiffeis equivalent ms and
> 
> We can't know that - it's a fair guess, but the way it is currently
> defined will see these constants used as jiffies, not ms.
> 
> 'git blame' is of little help here ...
> 
> ^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  59) /*
> settings for DTC3181E card with only Mustek scanner attached */
> ^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  60) #define
> USLEEP_POLL 1
> ^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  61) #define
> USLEEP_SLEEP20
> ^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  62) #define
> USLEEP_WAITLONG 500
> 
> The DTC3181E part dates back to '97. Let's see whether Ronald stilll 
> remembers.
> 
> HZ used to be set to 100 in those days, so USLEEP_POLL=1 equates to
> 10ms, not 1ms
>

ok - thats my ignorance - did not think that far - but it makes sense
to me now why the values would be correct without conversion. looking
at linux-2.0.31 (1998) your assumption looks correct

 #ifndef USLEEP_SLEEP
 /* 20 ms (reasonable hard disk speed) */
 #define USLEEP_SLEEP 2
 #endif
 /* 300 RPM (floppy speed) */
 #ifndef USLEEP_POLL
 #define USLEEP_POLL 20
 #endif 
 

in linux-2.2.16 this becomes

 #ifndef USLEEP_SLEEP
 /* 20 ms (reasonable hard disk speed) */
 #define USLEEP_SLEEP (20*HZ/1000)
 #endif
 /* 300 RPM (floppy speed) */
 #ifndef USLEEP_POLL
 #define USLEEP_POLL (200*HZ/1000)
 #endif

but no update for the DTC case that stays

 /* settings for DTC3181E card with only Mustek scanner attached */
 #define USLEEP 
 #define USLEEP_POLL 1
 #define USLEEP_SLEEP20
 #define USLEEP_WAITLONG 500

so the original timing unit does seem to be 100HZ based and your 
conversion below seems to be the right one.

> > the intent was only to change the USLEEP_POLL and USLEEP_WAITLONG
> > settings for the specific device but not the unit and thus it
> > shuld have been converted by msecs_to_jiffies(1) resp.
> > msecs_to_jiffies(500). The problem with this if it is left in its
> > current form is that the timeouts would actually depend on the HZ
> > setting of the system which is probably not the intent.
> 
> I think it's safe to assume the code in question predates the option
> to configure the scheduling tick frequency, so yes, probably not
> intended.
> 
> The problem with your replacing jiffies by ms is that this will change
> the timing for this particular combination of hardware by an order of
> magnitude. That large a change in timing would need to be backed up by
> testing on the actual hardware.
> 
> Much safer to use
> 
> #define USLEEP_POLLmsecs_to_jiffies(10)
> #define USLEEP_SLEEP   msecs_to_jiffies(200)
> #define USLEEP_WAITLONGmsecs_to_jiffies(5000)
> 
> and make sure no change in timing is incurred at all.
>

well your solution definitely is the safer and from looking at
2.0.31 -> 2.2.16 likely the right one and it achieves the goal 
of HZ independent timing.

thanks - will clean it up accordingly

thx!
hofrat 
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] am53c974: remove left-over debugging code

2015-02-01 Thread Hannes Reinecke
A shost_printk() statement was left over from debugging.
It can safely be removed; the same information is displayed
in the debugging message some lines further down.

Cc: Ondrej Zary 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/am53c974.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/scsi/am53c974.c b/drivers/scsi/am53c974.c
index aa3e2c7..a6f5ee8 100644
--- a/drivers/scsi/am53c974.c
+++ b/drivers/scsi/am53c974.c
@@ -178,12 +178,6 @@ static void pci_esp_dma_drain(struct esp *esp)
break;
cpu_relax();
}
-   if (resid > 1) {
-   /* FIFO not cleared */
-   shost_printk(KERN_INFO, esp->host,
-"FIFO not cleared, %d bytes left\n",
-resid);
-   }
 
/*
 * When there is a residual BCMPLT will never be set
-- 
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/10] qla2xxx: Fix various warnings reported by static source code analysis tools

2015-02-01 Thread Saurav Kashyap
Hi Bart,
Thanks for the patches. We will run regression with these changes and ack
if everything goes through fine.

Thanks,
~Saurav


>This patch series addresses several warnings reported by static source
>code analysis tools for the qla2xxx driver (gcc (W=1), sparse (C=2) and
>smatch (C=2 CHECK="smatch -p=kernel")). The patches in this series are:
>
>0001-qla2xxx-Report-both-rsp_info-and-rsp_info_len.patch
>0002-qla2xxx-Declare-local-functions-static.patch
>0003-qla2xxx-Remove-set-but-not-used-variables.patch
>0004-qla2xxx-Replace-two-macros-with-an-inline-function.patch
>0005-qla2xxx-Remove-__constant_-prefix.patch
>0006-qla2xxx-Avoid-that-sparse-complains-about-duplicate-.patch
>0007-qla2xxx-Fix-sparse-annotations.patch
>0008-qla2xxx-Remove-a-superfluous-test.patch
>0009-qla2xxx-Remove-dead-code.patch
>0010-qla2xxx-Comment-out-dead-code.patch

<>

Re: [PATCH-v2 01/11] lib/iovec: Add memcpy_fromiovec_out library function

2015-02-01 Thread Al Viro
On Mon, Feb 02, 2015 at 04:44:12AM +, Al Viro wrote:
> On Mon, Feb 02, 2015 at 04:06:24AM +, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger 
> > 
> > This patch adds a new memcpy_fromiovec_out() library function which modifies
> > the passed *iov following memcpy_fromiovec(), but also returns the next 
> > current
> > iovec pointer via **iov_out.
> > 
> > This is useful for vhost ANY_LAYOUT support when guests are allowed to 
> > generate
> > incoming virtio request headers combined with subsequent SGL payloads into a
> > single iovec.
> 
> Please, don't.  Just use copy_from_iter(); you are open-coding an uglier
> variant of such.

PS: see vfs.git#for-davem (or postings on netdev with the same stuff).
I really hope to bury memcpy_...iovec...() crap for good; please, don't
reintroduce more of it.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH-v2 01/11] lib/iovec: Add memcpy_fromiovec_out library function

2015-02-01 Thread Al Viro
On Mon, Feb 02, 2015 at 04:06:24AM +, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger 
> 
> This patch adds a new memcpy_fromiovec_out() library function which modifies
> the passed *iov following memcpy_fromiovec(), but also returns the next 
> current
> iovec pointer via **iov_out.
> 
> This is useful for vhost ANY_LAYOUT support when guests are allowed to 
> generate
> incoming virtio request headers combined with subsequent SGL payloads into a
> single iovec.

Please, don't.  Just use copy_from_iter(); you are open-coding an uglier
variant of such.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 08/11] vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Signal support of VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits
required for virtio-scsi 1.0 spec layout requirements.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index a20a5fd..25a07a9 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -171,7 +171,9 @@ enum {
 /* Note: can't set VIRTIO_F_VERSION_1 yet, since that implies ANY_LAYOUT. */
 enum {
VHOST_SCSI_FEATURES = VHOST_FEATURES | (1ULL << VIRTIO_SCSI_F_HOTPLUG) |
-  (1ULL << VIRTIO_SCSI_F_T10_PI)
+  (1ULL << VIRTIO_SCSI_F_T10_PI) |
+  (1ULL << VIRTIO_F_ANY_LAYOUT) |
+  (1ULL << VIRTIO_F_VERSION_1)
 };
 
 #define VHOST_SCSI_MAX_TARGET  256
@@ -1693,7 +1695,10 @@ static void vhost_scsi_handle_kick(struct vhost_work 
*work)
poll.work);
struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
 
-   vhost_scsi_handle_vq(vs, vq);
+   if (vhost_has_feature(vq, VIRTIO_F_ANY_LAYOUT))
+   vhost_scsi_handle_vqal(vs, vq);
+   else
+   vhost_scsi_handle_vq(vs, vq);
 }
 
 static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 03/11] vhost/scsi: Fix incorrect early vhost_scsi_handle_vq failures

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch fixes vhost_scsi_handle_vq() failure cases that result in BUG_ON()
getting triggered when vhost_scsi_free_cmd() is called, and ->tvc_se_cmd has
not been initialized by target_submit_cmd_map_sgls().

It changes tcm_vhost_release_cmd() to use tcm_vhost_cmd->tvc_nexus for obtaining
se_session pointer reference.  Also, avoid calling put_page() on NULL sg->page
entries in vhost_scsi_map_to_sgl() failure path.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 52 +---
 1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index a03ac41..9c5ac23 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -460,7 +460,7 @@ static void tcm_vhost_release_cmd(struct se_cmd *se_cmd)
 {
struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
struct tcm_vhost_cmd, tvc_se_cmd);
-   struct se_session *se_sess = se_cmd->se_sess;
+   struct se_session *se_sess = tv_cmd->tvc_nexus->tvn_se_sess;
int i;
 
if (tv_cmd->tvc_sgl_count) {
@@ -859,9 +859,11 @@ vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *cmd,
ret = vhost_scsi_map_to_sgl(cmd, sg, sgl_count, &iov[i],
cmd->tvc_upages, write);
if (ret < 0) {
-   for (i = 0; i < cmd->tvc_sgl_count; i++)
-   put_page(sg_page(&cmd->tvc_sgl[i]));
-
+   for (i = 0; i < cmd->tvc_sgl_count; i++) {
+   struct page *page = sg_page(&cmd->tvc_sgl[i]);
+   if (page)
+   put_page(page);
+   }
cmd->tvc_sgl_count = 0;
return ret;
}
@@ -900,9 +902,11 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
ret = vhost_scsi_map_to_sgl(cmd, prot_sg, prot_sgl_count, 
&iov[i],
cmd->tvc_upages, write);
if (ret < 0) {
-   for (i = 0; i < cmd->tvc_prot_sgl_count; i++)
-   put_page(sg_page(&cmd->tvc_prot_sgl[i]));
-
+   for (i = 0; i < cmd->tvc_prot_sgl_count; i++) {
+   struct page *page = 
sg_page(&cmd->tvc_prot_sgl[i]);
+   if (page)
+   put_page(page);
+   }
cmd->tvc_prot_sgl_count = 0;
return ret;
}
@@ -1060,12 +1064,14 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
if (unlikely(vq->iov[0].iov_len < req_size)) {
pr_err("Expecting virtio-scsi header: %zu, got %zu\n",
   req_size, vq->iov[0].iov_len);
-   break;
+   vhost_scsi_send_bad_target(vs, vq, head, out);
+   continue;
}
ret = memcpy_fromiovecend(req, &vq->iov[0], 0, req_size);
if (unlikely(ret)) {
vq_err(vq, "Faulted on virtio_scsi_cmd_req\n");
-   break;
+   vhost_scsi_send_bad_target(vs, vq, head, out);
+   continue;
}
 
/* virtio-scsi spec requires byte 0 of the lun to be 1 */
@@ -1096,14 +1102,16 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
if (data_direction != DMA_TO_DEVICE) {
vq_err(vq, "Received non zero 
do_pi_niov"
", but wrong data_direction\n");
-   goto err_cmd;
+   vhost_scsi_send_bad_target(vs, vq, 
head, out);
+   continue;
}
prot_bytes = vhost32_to_cpu(vq, 
v_req_pi.pi_bytesout);
} else if (v_req_pi.pi_bytesin) {
if (data_direction != DMA_FROM_DEVICE) {
vq_err(vq, "Received non zero 
di_pi_niov"
", but wrong data_direction\n");
-   goto err_cmd;
+   vhost_scsi_send_bad_target(vs, vq, 
head, out);
+   continue;
}
prot_bytes = vhost32_to_cpu(vq, 
v_req_pi.pi_bytesin);
}
@@ -1143,7 +1151,8 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
  

[PATCH-v2 10/11] vhost/scsi: Drop left-over scsi_tcq.h include

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

With the recent removal of MSG_*_TAG defines in commit 68d81f40,
vhost-scsi is now using TCM_*_TAG and doesn't depend upon host
side scsi_tcq.h definitions anymore.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index b17b5a0..6a785d8 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -38,7 +38,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 09/11] vhost/scsi: Drop legacy pre virtio v1.0 !ANY_LAYOUT logic

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

With the new ANY_LAYOUT logic in place for vhost_scsi_handle_vqal(),
there is no longer a reason to keep around the legacy code with
!ANY_LAYOUT assumptions.

Go ahead and drop the pre virtio 1.0 logic in vhost_scsi_handle_vq()
and associated helpers.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 339 +--
 1 file changed, 1 insertion(+), 338 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 25a07a9..b17b5a0 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -825,93 +825,6 @@ out:
 }
 
 static int
-vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *cmd,
- struct iovec *iov,
- int niov,
- bool write)
-{
-   struct scatterlist *sg = cmd->tvc_sgl;
-   unsigned int sgl_count = 0;
-   int ret, i;
-
-   for (i = 0; i < niov; i++)
-   sgl_count += iov_num_pages(iov[i].iov_base, iov[i].iov_len);
-
-   if (sgl_count > TCM_VHOST_PREALLOC_SGLS) {
-   pr_err("vhost_scsi_map_iov_to_sgl() sgl_count: %u greater than"
-   " preallocated TCM_VHOST_PREALLOC_SGLS: %u\n",
-   sgl_count, TCM_VHOST_PREALLOC_SGLS);
-   return -ENOBUFS;
-   }
-
-   pr_debug("%s sg %p sgl_count %u\n", __func__, sg, sgl_count);
-   sg_init_table(sg, sgl_count);
-   cmd->tvc_sgl_count = sgl_count;
-
-   pr_debug("Mapping iovec %p for %u pages\n", &iov[0], sgl_count);
-
-   for (i = 0; i < niov; i++) {
-   ret = vhost_scsi_map_to_sgl(cmd, iov[i].iov_base, 
iov[i].iov_len,
-   sg, write);
-   if (ret < 0) {
-   for (i = 0; i < cmd->tvc_sgl_count; i++) {
-   struct page *page = sg_page(&cmd->tvc_sgl[i]);
-   if (page)
-   put_page(page);
-   }
-   cmd->tvc_sgl_count = 0;
-   return ret;
-   }
-   sg += ret;
-   sgl_count -= ret;
-   }
-   return 0;
-}
-
-static int
-vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
-  struct iovec *iov,
-  int niov,
-  bool write)
-{
-   struct scatterlist *prot_sg = cmd->tvc_prot_sgl;
-   unsigned int prot_sgl_count = 0;
-   int ret, i;
-
-   for (i = 0; i < niov; i++)
-   prot_sgl_count += iov_num_pages(iov[i].iov_base, 
iov[i].iov_len);
-
-   if (prot_sgl_count > TCM_VHOST_PREALLOC_PROT_SGLS) {
-   pr_err("vhost_scsi_map_iov_to_prot() sgl_count: %u greater than"
-   " preallocated TCM_VHOST_PREALLOC_PROT_SGLS: %u\n",
-   prot_sgl_count, TCM_VHOST_PREALLOC_PROT_SGLS);
-   return -ENOBUFS;
-   }
-
-   pr_debug("%s prot_sg %p prot_sgl_count %u\n", __func__,
-prot_sg, prot_sgl_count);
-   sg_init_table(prot_sg, prot_sgl_count);
-   cmd->tvc_prot_sgl_count = prot_sgl_count;
-
-   for (i = 0; i < niov; i++) {
-   ret = vhost_scsi_map_to_sgl(cmd, iov[i].iov_base, 
iov[i].iov_len,
-   prot_sg, write);
-   if (ret < 0) {
-   for (i = 0; i < cmd->tvc_prot_sgl_count; i++) {
-   struct page *page = 
sg_page(&cmd->tvc_prot_sgl[i]);
-   if (page)
-   put_page(page);
-   }
-   cmd->tvc_prot_sgl_count = 0;
-   return ret;
-   }
-   prot_sg += ret;
-   prot_sgl_count -= ret;
-   }
-   return 0;
-}
-
-static int
 vhost_scsi_calc_sgls(struct iovec *iov, size_t off, size_t bytes,
 int *niov, int max_niov, int max_sgls)
 {
@@ -1391,253 +1304,6 @@ out:
mutex_unlock(&vq->mutex);
 }
 
-static void
-vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
-{
-   struct tcm_vhost_tpg **vs_tpg;
-   struct virtio_scsi_cmd_req v_req;
-   struct virtio_scsi_cmd_req_pi v_req_pi;
-   struct tcm_vhost_tpg *tpg;
-   struct tcm_vhost_cmd *cmd;
-   u64 tag;
-   u32 exp_data_len, data_first, data_num, data_direction, prot_first;
-   unsigned out, in, i;
-   int head, ret, data_niov, prot_niov, prot_bytes;
-   size_t req_size;
-   u16 lun;
-   u8 *target, *lunp, task_attr;
-   bool hdr_pi;
-   void *req, *cdb;
-
-   mutex_lock(&vq->mutex);
-   /*
-* We can handle the vq only after the endpoint is setup by calling the
-* VHOST_SCSI_SET_ENDPOINT ioctl.
-*/
-   vs_tpg = vq->private_data;
-   if (!vs_tpg)
- 

[PATCH-v2 11/11] vhost/scsi: Global tcm_vhost -> vhost_scsi rename

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

There is a large amount of code that still references the original
'tcm_vhost' naming conventions, instead of modern 'vhost_scsi'.

Go ahead and do a global rename to make the usage consistent.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 658 +--
 1 file changed, 329 insertions(+), 329 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 6a785d8..57a6f0a 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -51,13 +51,13 @@
 
 #include "vhost.h"
 
-#define TCM_VHOST_VERSION  "v0.1"
-#define TCM_VHOST_NAMELEN 256
-#define TCM_VHOST_MAX_CDB_SIZE 32
-#define TCM_VHOST_DEFAULT_TAGS 256
-#define TCM_VHOST_PREALLOC_SGLS 2048
-#define TCM_VHOST_PREALLOC_UPAGES 2048
-#define TCM_VHOST_PREALLOC_PROT_SGLS 512
+#define VHOST_SCSI_VERSION  "v0.1"
+#define VHOST_SCSI_NAMELEN 256
+#define VHOST_SCSI_MAX_CDB_SIZE 32
+#define VHOST_SCSI_DEFAULT_TAGS 256
+#define VHOST_SCSI_PREALLOC_SGLS 2048
+#define VHOST_SCSI_PREALLOC_UPAGES 2048
+#define VHOST_SCSI_PREALLOC_PROT_SGLS 512
 
 struct vhost_scsi_inflight {
/* Wait for the flush operation to finish */
@@ -66,7 +66,7 @@ struct vhost_scsi_inflight {
struct kref kref;
 };
 
-struct tcm_vhost_cmd {
+struct vhost_scsi_cmd {
/* Descriptor from vhost_get_vq_desc() for virt_queue segment */
int tvc_vq_desc;
/* virtio-scsi initiator task attribute */
@@ -80,7 +80,7 @@ struct tcm_vhost_cmd {
/* The number of scatterlists associated with this cmd */
u32 tvc_sgl_count;
u32 tvc_prot_sgl_count;
-   /* Saved unpacked SCSI LUN for tcm_vhost_submission_work() */
+   /* Saved unpacked SCSI LUN for vhost_scsi_submission_work() */
u32 tvc_lun;
/* Pointer to the SGL formatted memory from virtio-scsi */
struct scatterlist *tvc_sgl;
@@ -93,13 +93,13 @@ struct tcm_vhost_cmd {
/* Pointer to vhost_virtqueue for the cmd */
struct vhost_virtqueue *tvc_vq;
/* Pointer to vhost nexus memory */
-   struct tcm_vhost_nexus *tvc_nexus;
+   struct vhost_scsi_nexus *tvc_nexus;
/* The TCM I/O descriptor that is accessed via container_of() */
struct se_cmd tvc_se_cmd;
-   /* work item used for cmwq dispatch to tcm_vhost_submission_work() */
+   /* work item used for cmwq dispatch to vhost_scsi_submission_work() */
struct work_struct work;
/* Copy of the incoming SCSI command descriptor block (CDB) */
-   unsigned char tvc_cdb[TCM_VHOST_MAX_CDB_SIZE];
+   unsigned char tvc_cdb[VHOST_SCSI_MAX_CDB_SIZE];
/* Sense buffer that will be mapped into outgoing status */
unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER];
/* Completed commands list, serviced from vhost worker thread */
@@ -108,53 +108,53 @@ struct tcm_vhost_cmd {
struct vhost_scsi_inflight *inflight;
 };
 
-struct tcm_vhost_nexus {
+struct vhost_scsi_nexus {
/* Pointer to TCM session for I_T Nexus */
struct se_session *tvn_se_sess;
 };
 
-struct tcm_vhost_nacl {
+struct vhost_scsi_nacl {
/* Binary World Wide unique Port Name for Vhost Initiator port */
u64 iport_wwpn;
/* ASCII formatted WWPN for Sas Initiator port */
-   char iport_name[TCM_VHOST_NAMELEN];
-   /* Returned by tcm_vhost_make_nodeacl() */
+   char iport_name[VHOST_SCSI_NAMELEN];
+   /* Returned by vhost_scsi_make_nodeacl() */
struct se_node_acl se_node_acl;
 };
 
-struct tcm_vhost_tpg {
+struct vhost_scsi_tpg {
/* Vhost port target portal group tag for TCM */
u16 tport_tpgt;
/* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus 
shutdown */
int tv_tpg_port_count;
/* Used for vhost_scsi device reference to tpg_nexus, protected by 
tv_tpg_mutex */
int tv_tpg_vhost_count;
-   /* list for tcm_vhost_list */
+   /* list for vhost_scsi_list */
struct list_head tv_tpg_list;
/* Used to protect access for tpg_nexus */
struct mutex tv_tpg_mutex;
/* Pointer to the TCM VHost I_T Nexus for this TPG endpoint */
-   struct tcm_vhost_nexus *tpg_nexus;
-   /* Pointer back to tcm_vhost_tport */
-   struct tcm_vhost_tport *tport;
-   /* Returned by tcm_vhost_make_tpg() */
+   struct vhost_scsi_nexus *tpg_nexus;
+   /* Pointer back to vhost_scsi_tport */
+   struct vhost_scsi_tport *tport;
+   /* Returned by vhost_scsi_make_tpg() */
struct se_portal_group se_tpg;
/* Pointer back to vhost_scsi, protected by tv_tpg_mutex */
struct vhost_scsi *vhost_scsi;
 };
 
-struct tcm_vhost_tport {
+struct vhost_scsi_tport {
/* SCSI protocol the tport is providing */
u8 tport_proto_id;
/* Binary World Wide unique Port Name for Vhost Target port */
u64 tport_wwpn;
/* ASCII formatted WWPN for Vhos

[PATCH-v2 04/11] vhost/scsi: Change vhost_scsi_map_to_sgl to accept iov ptr + len

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch changes vhost_scsi_map_to_sgl() parameters to accept virtio
iovec ptr + len when determing pages_nr.

This is currently done with iov_num_pages() -> PAGE_ALIGN, so allow
the same parameters as well.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 37 +++--
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 9c5ac23..049e603 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -220,10 +220,10 @@ static struct workqueue_struct *tcm_vhost_workqueue;
 static DEFINE_MUTEX(tcm_vhost_mutex);
 static LIST_HEAD(tcm_vhost_list);
 
-static int iov_num_pages(struct iovec *iov)
+static int iov_num_pages(void __user *iov_base, size_t iov_len)
 {
-   return (PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) -
-  ((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT;
+   return (PAGE_ALIGN((unsigned long)iov_base + iov_len) -
+  ((unsigned long)iov_base & PAGE_MASK)) >> PAGE_SHIFT;
 }
 
 static void tcm_vhost_done_inflight(struct kref *kref)
@@ -777,25 +777,18 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, struct 
tcm_vhost_tpg *tpg,
  * Returns the number of scatterlist entries used or -errno on error.
  */
 static int
-vhost_scsi_map_to_sgl(struct tcm_vhost_cmd *tv_cmd,
+vhost_scsi_map_to_sgl(struct tcm_vhost_cmd *cmd,
+ void __user *ptr,
+ size_t len,
  struct scatterlist *sgl,
- unsigned int sgl_count,
- struct iovec *iov,
- struct page **pages,
  bool write)
 {
-   unsigned int npages = 0, pages_nr, offset, nbytes;
+   unsigned int npages = 0, offset, nbytes;
+   unsigned int pages_nr = iov_num_pages(ptr, len);
struct scatterlist *sg = sgl;
-   void __user *ptr = iov->iov_base;
-   size_t len = iov->iov_len;
+   struct page **pages = cmd->tvc_upages;
int ret, i;
 
-   pages_nr = iov_num_pages(iov);
-   if (pages_nr > sgl_count) {
-   pr_err("vhost_scsi_map_to_sgl() pages_nr: %u greater than"
-  " sgl_count: %u\n", pages_nr, sgl_count);
-   return -ENOBUFS;
-   }
if (pages_nr > TCM_VHOST_PREALLOC_UPAGES) {
pr_err("vhost_scsi_map_to_sgl() pages_nr: %u greater than"
   " preallocated TCM_VHOST_PREALLOC_UPAGES: %u\n",
@@ -840,7 +833,7 @@ vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *cmd,
int ret, i;
 
for (i = 0; i < niov; i++)
-   sgl_count += iov_num_pages(&iov[i]);
+   sgl_count += iov_num_pages(iov[i].iov_base, iov[i].iov_len);
 
if (sgl_count > TCM_VHOST_PREALLOC_SGLS) {
pr_err("vhost_scsi_map_iov_to_sgl() sgl_count: %u greater than"
@@ -856,8 +849,8 @@ vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *cmd,
pr_debug("Mapping iovec %p for %u pages\n", &iov[0], sgl_count);
 
for (i = 0; i < niov; i++) {
-   ret = vhost_scsi_map_to_sgl(cmd, sg, sgl_count, &iov[i],
-   cmd->tvc_upages, write);
+   ret = vhost_scsi_map_to_sgl(cmd, iov[i].iov_base, 
iov[i].iov_len,
+   sg, write);
if (ret < 0) {
for (i = 0; i < cmd->tvc_sgl_count; i++) {
struct page *page = sg_page(&cmd->tvc_sgl[i]);
@@ -884,7 +877,7 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
int ret, i;
 
for (i = 0; i < niov; i++)
-   prot_sgl_count += iov_num_pages(&iov[i]);
+   prot_sgl_count += iov_num_pages(iov[i].iov_base, 
iov[i].iov_len);
 
if (prot_sgl_count > TCM_VHOST_PREALLOC_PROT_SGLS) {
pr_err("vhost_scsi_map_iov_to_prot() sgl_count: %u greater than"
@@ -899,8 +892,8 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
cmd->tvc_prot_sgl_count = prot_sgl_count;
 
for (i = 0; i < niov; i++) {
-   ret = vhost_scsi_map_to_sgl(cmd, prot_sg, prot_sgl_count, 
&iov[i],
-   cmd->tvc_upages, write);
+   ret = vhost_scsi_map_to_sgl(cmd, iov[i].iov_base, 
iov[i].iov_len,
+   prot_sg, write);
if (ret < 0) {
for (i = 0; i < cmd->tvc_prot_sgl_count; i++) {
struct page *page = 
sg_page(&cmd->tvc_prot_sgl[i]);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 06/11] vhost/scsi: Add ANY_LAYOUT vhost_skip_iovec_bytes helper

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch adds a vhost_skip_iovec_bytes() helper for skipping ahead
a number of bytes into the passed *iov_in + off_in, saving the current
**iov_out + off_out so it may be used by the caller.

This is useful for virtio-scsi READs when needing to skip ahead of
the starting response header bytes, and when T10_PI is enabled to
skip ahead of any preceeding protection payload to the start of
data payload.

It also checks max_niov to ensure the passed number of bytes does
not exceed what vhost_get_vq_desc() reports as the total number of
iovecs into vhost_virtqueue->iov[] for a individual request.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index ecbd567..d888bd9 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1078,6 +1078,46 @@ vhost_scsi_send_bad_target(struct vhost_scsi *vs,
pr_err("Faulted on virtio_scsi_cmd_resp\n");
 }
 
+int vhost_skip_iovec_bytes(size_t bytes, int max_niov,
+  struct iovec *iov_in, size_t off_in,
+  struct iovec **iov_out, size_t *off_out)
+{
+   int i = 0;
+
+   *off_out = 0;
+
+   if (!bytes)
+   return 0;
+
+   while (bytes) {
+   size_t iov_len = iov_in[i].iov_len - off_in;
+   size_t len = min(iov_len, bytes);
+
+   if (bytes -= len) {
+   if (++i == max_niov) {
+   pr_err("%s exceeded max_niov: %d\n",
+  __func__, max_niov);
+   return -EINVAL;
+   }
+   off_in = 0;
+   continue;
+   }
+   if (iov_len > len) {
+   *iov_out = &iov_in[i];
+   *off_out = len;
+   } else if (iov_len == len) {
+   if (++i == max_niov) {
+   pr_err("%s exceeded max_niov: %d\n",
+   __func__, max_niov);
+   return -EINVAL;
+   }
+   *iov_out = &iov_in[i];
+   *off_out = 0;
+   }
+   }
+   return i;
+}
+
 static void
 vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 07/11] vhost/scsi: Add ANY_LAYOUT vhost_virtqueue callback

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch adds ANY_LAYOUT support with a new vqs[].vq.handle_kick()
callback in vhost_scsi_handle_vqal().

It calculates data_direction + exp_data_len for the new tcm_vhost_cmd
descriptor by walking both outgoing + incoming iovecs, assuming the
layout of outgoing request header + T10_PI + Data payload comes first.

It also uses memcpy_fromiovec_out() to copy leading virtio-scsi
request header that may or may not include SCSI CDB, that returns a
re-calculated iovec to start of T10_PI or Data SGL memory.

v2 changes:
  - Fix up vhost_scsi_handle_vqal comments
  - Minor vhost_scsi_handle_vqal simplifications
  - Add missing minimum virtio-scsi response buffer size check
  - Fix pi_bytes* error message typo
  - Convert to use vhost_skip_iovec_bytes() common code
  - Add max_niov sanity checks vs. out + in offset into vq

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 271 +++
 1 file changed, 271 insertions(+)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d888bd9..a20a5fd 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1119,6 +1119,277 @@ int vhost_skip_iovec_bytes(size_t bytes, int max_niov,
 }
 
 static void
+vhost_scsi_handle_vqal(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
+{
+   struct tcm_vhost_tpg **vs_tpg, *tpg;
+   struct virtio_scsi_cmd_req v_req;
+   struct virtio_scsi_cmd_req_pi v_req_pi;
+   struct tcm_vhost_cmd *cmd;
+   struct iovec *iov_out, *prot_iov, *data_iov;
+   u64 tag;
+   u32 exp_data_len, data_direction;
+   unsigned out, in, i;
+   int head, ret, prot_bytes, max_niov;
+   size_t req_size, rsp_size = sizeof(struct virtio_scsi_cmd_resp);
+   size_t out_size, in_size, data_off, prot_off;
+   u16 lun;
+   u8 *target, *lunp, task_attr;
+   bool t10_pi = vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI);
+   void *req, *cdb;
+
+   mutex_lock(&vq->mutex);
+   /*
+* We can handle the vq only after the endpoint is setup by calling the
+* VHOST_SCSI_SET_ENDPOINT ioctl.
+*/
+   vs_tpg = vq->private_data;
+   if (!vs_tpg)
+   goto out;
+
+   vhost_disable_notify(&vs->dev, vq);
+
+   for (;;) {
+   head = vhost_get_vq_desc(vq, vq->iov,
+ARRAY_SIZE(vq->iov), &out, &in,
+NULL, NULL);
+   pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n",
+head, out, in);
+   /* On error, stop handling until the next kick. */
+   if (unlikely(head < 0))
+   break;
+   /* Nothing new?  Wait for eventfd to tell us they refilled. */
+   if (head == vq->num) {
+   if (unlikely(vhost_enable_notify(&vs->dev, vq))) {
+   vhost_disable_notify(&vs->dev, vq);
+   continue;
+   }
+   break;
+   }
+   /*
+* Check for a sane response buffer so we can report early
+* errors back to the guest.
+*/
+   if (unlikely(vq->iov[out].iov_len < rsp_size)) {
+   vq_err(vq, "Expecting at least virtio_scsi_cmd_resp"
+   " size, got %zu bytes\n", vq->iov[out].iov_len);
+   break;
+   }
+   /*
+* Setup pointers and values based upon different virtio-scsi
+* request header if T10_PI is enabled in KVM guest.
+*/
+   if (t10_pi) {
+   req = &v_req_pi;
+   req_size = sizeof(v_req_pi);
+   lunp = &v_req_pi.lun[0];
+   target = &v_req_pi.lun[1];
+   } else {
+   req = &v_req;
+   req_size = sizeof(v_req);
+   lunp = &v_req.lun[0];
+   target = &v_req.lun[1];
+   }
+   /*
+* Determine data_direction for ANY_LAYOUT by calculating the
+* total outgoing iovec sizes / incoming iovec sizes vs.
+* virtio-scsi request / response headers respectively.
+*
+* FIXME: Not correct for BIDI operation
+*/
+   out_size = in_size = 0;
+   for (i = 0; i < out; i++)
+   out_size += vq->iov[i].iov_len;
+   for (i = out; i < out + in; i++)
+   in_size += vq->iov[i].iov_len;
+   /*
+* Any associated T10_PI bytes for the outgoing / incoming
+* payloads are included in calculation of exp_data_len here.
+*/
+   if (

[PATCH-v2 02/11] vhost/scsi: Convert completion path to use memcpy_toiovecend

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Required for ANY_LAYOUT support when the incoming virtio-scsi response
header + fixed size sense buffer payload may span more than a single
iovec entry.

This changes existing code to save cmd->tvc_resp_iod instead of the
first single iovec base pointer from &vq->iov[out].

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 01c01cb..a03ac41 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -87,8 +87,8 @@ struct tcm_vhost_cmd {
struct scatterlist *tvc_sgl;
struct scatterlist *tvc_prot_sgl;
struct page **tvc_upages;
-   /* Pointer to response */
-   struct virtio_scsi_cmd_resp __user *tvc_resp;
+   /* Pointer to response header iovec */
+   struct iovec *tvc_resp_iov;
/* Pointer to vhost_scsi for our device */
struct vhost_scsi *tvc_vhost;
/* Pointer to vhost_virtqueue for the cmd */
@@ -703,7 +703,8 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work 
*work)
 se_cmd->scsi_sense_length);
memcpy(v_rsp.sense, cmd->tvc_sense_buf,
   se_cmd->scsi_sense_length);
-   ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
+   ret = memcpy_toiovecend(cmd->tvc_resp_iov, (unsigned char 
*)&v_rsp,
+   0, sizeof(v_rsp));
if (likely(ret == 0)) {
struct vhost_scsi_virtqueue *q;
vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0);
@@ -1159,7 +1160,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct 
vhost_virtqueue *vq)
 
cmd->tvc_vhost = vs;
cmd->tvc_vq = vq;
-   cmd->tvc_resp = vq->iov[out].iov_base;
+   cmd->tvc_resp_iov = &vq->iov[out];
 
pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
cmd->tvc_cdb[0], cmd->tvc_lun);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 00/11] vhost/scsi: Add ANY_LAYOUT + VERSION_1 support

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

Hi MST, Paolo, & Co,

This -v2 series adds vhost/scsi ANY_LAYOUT + VERSION_1 host feature bit
support.

It adds a new vhost_virtqueue ->handle_kick() callback to determine the
start of protection and data payloads iovecs past starting virtio-scsi
request and response headers, based upon data_direction.

It assumes request/CDB and response/sense_buffer headers may span more
than a single iovec using lib/iovec.c logic, and adds a new addition of
memcpy_fromiovec_out() to return the current re-calcuated **iov_out.

It also allows virtio-scsi headers + T10_PI + Data SGL payloads to span
the same iovec when pinning user-space memory via get_user_pages_fast()
code.  (Not tested yet)

It's currently functioning against v3.19-rc1 virtio-scsi LLD in T10_PI
mode with ANY_LAYOUT -> VERSION_1 guest feature bits enabled, using the
layout following existing convention with protection/data SGL payloads
residing within seperate iovecs.

Here's how the changelog is looking:

v2 changes:
  - Update memcpy_fromiovec_out usage comment
  - Clear ->tvc_sgl_count for vhost_scsi_mapal failure
  - Make vhost_scsi_mapal + vhost_scsi_calc_sgls accept max_niov
  - Update vhost_scsi_handle_vqal comments
  - Minor vhost_scsi_handle_vqal simplifications
  - Add missing minimum virtio-scsi response buffer size check
  - Fix pi_bytes* error message typo
  - Convert to use vhost_skip_iovec_bytes() common code
  - Add max_niov sanity checks vs. out + in offset into vq
  - Drop legacy pre virtio v1.0 !ANY_LAYOUT code

Also included in patch #11 is an over-due change to rename code in scsi.c
to line up with modern vhost_scsi naming convention.

Please review.

Thank you,

--nab

Nicholas Bellinger (11):
  lib/iovec: Add memcpy_fromiovec_out library function
  vhost/scsi: Convert completion path to use memcpy_toiovecend
  vhost/scsi: Fix incorrect early vhost_scsi_handle_vq failures
  vhost/scsi: Change vhost_scsi_map_to_sgl to accept iov ptr + len
  vhost/scsi: Add ANY_LAYOUT iov -> sgl mapping prerequisites
  vhost/scsi: Add ANY_LAYOUT vhost_skip_iovec_bytes helper
  vhost/scsi: Add ANY_LAYOUT vhost_virtqueue callback
  vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits
  vhost/scsi: Drop legacy pre virtio v1.0 !ANY_LAYOUT logic
  vhost/scsi: Drop left-over scsi_tcq.h include
  vhost/scsi: Global tcm_vhost -> vhost_scsi rename

 drivers/vhost/scsi.c | 1125 +++---
 include/linux/uio.h  |2 +
 lib/iovec.c  |   35 ++
 3 files changed, 646 insertions(+), 516 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 01/11] lib/iovec: Add memcpy_fromiovec_out library function

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch adds a new memcpy_fromiovec_out() library function which modifies
the passed *iov following memcpy_fromiovec(), but also returns the next current
iovec pointer via **iov_out.

This is useful for vhost ANY_LAYOUT support when guests are allowed to generate
incoming virtio request headers combined with subsequent SGL payloads into a
single iovec.

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 include/linux/uio.h |  2 ++
 lib/iovec.c | 35 +++
 2 files changed, 37 insertions(+)

diff --git a/include/linux/uio.h b/include/linux/uio.h
index 1c5e453..3e4473d 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -136,6 +136,8 @@ size_t csum_and_copy_to_iter(void *addr, size_t bytes, 
__wsum *csum, struct iov_
 size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct 
iov_iter *i);
 
 int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
+int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov,
+struct iovec **iov_out, int len);
 int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
int offset, int len);
 int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
diff --git a/lib/iovec.c b/lib/iovec.c
index 2d99cb4..24c8148 100644
--- a/lib/iovec.c
+++ b/lib/iovec.c
@@ -28,6 +28,41 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec 
*iov, int len)
 EXPORT_SYMBOL(memcpy_fromiovec);
 
 /*
+ * Copy iovec to kernel, modifying the passed *iov entries.
+ *
+ * Save **iov_out for the caller to use upon return, that may either
+ * contain the current entry with a re-calculated iov_base + iov_len
+ * or next unmodified entry.
+ *
+ * Also note that any iovec entries preceeding the final *iov_out are
+ * zeroed by copy_from_user().
+ *
+ * Returns -EFAULT on error.
+ */
+
+int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov,
+struct iovec **iov_out, int len)
+{
+   while (len > 0) {
+   if (iov->iov_len) {
+   int copy = min_t(unsigned int, len, iov->iov_len);
+   if (copy_from_user(kdata, iov->iov_base, copy))
+   return -EFAULT;
+   len -= copy;
+   kdata += copy;
+   iov->iov_base += copy;
+   iov->iov_len -= copy;
+   }
+   if (!iov->iov_len)
+   iov++;
+   }
+   *iov_out = iov;
+
+   return 0;
+}
+EXPORT_SYMBOL(memcpy_fromiovec_out);
+
+/*
  * Copy kernel to iovec. Returns -EFAULT on error.
  */
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH-v2 05/11] vhost/scsi: Add ANY_LAYOUT iov -> sgl mapping prerequisites

2015-02-01 Thread Nicholas A. Bellinger
From: Nicholas Bellinger 

This patch adds ANY_LAYOUT prerequisites logic for accepting a set of
protection + data payloads via iovec + offset.  Also includes helpers
for calcuating SGLs + invoking vhost_scsi_map_to_sgl() with a known
number of iovecs.

Required by ANY_LAYOUT processing when struct iovec may be offset into
the first outgoing virtio-scsi request header.

v2 changes:
  - Clear ->tvc_sgl_count for vhost_scsi_mapal failure
  - Make vhost_scsi_mapal + vhost_scsi_calc_sgls accept max_niov
  - Minor cleanups

Cc: Michael S. Tsirkin 
Cc: Paolo Bonzini 
Signed-off-by: Nicholas Bellinger 
---
 drivers/vhost/scsi.c | 115 +++
 1 file changed, 115 insertions(+)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 049e603..ecbd567 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -909,6 +909,121 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
return 0;
 }
 
+static int
+vhost_scsi_calc_sgls(struct iovec *iov, size_t off, size_t bytes,
+int *niov, int max_niov, int max_sgls)
+{
+   size_t tmp = 0;
+   int sgl_count = 0;
+
+   *niov = 0;
+
+   while (tmp < bytes) {
+   void __user *base = iov[*niov].iov_base + off;
+   size_t len = iov[(*niov)++].iov_len - off;
+
+   if (*niov > max_niov) {
+   pr_err("%s: current *niov %d exceeds max_niov: %d\n",
+  __func__, *niov, max_niov);
+   return -EINVAL;
+   }
+   sgl_count += iov_num_pages(base, len);
+   tmp += min(len, bytes);
+   off = 0;
+   }
+   if (sgl_count > max_sgls) {
+   pr_err("%s: requested sgl_count: %d exceeds pre-allocated"
+  " max_sgls: %d\n", __func__, sgl_count, max_sgls);
+   return -ENOBUFS;
+   }
+   return sgl_count;
+}
+
+static int
+vhost_scsi_iov_to_sgl(struct tcm_vhost_cmd *cmd, bool write,
+ struct iovec *iov, size_t iov_off, int niov,
+ struct scatterlist *sg, int sg_count)
+{
+   int i, ret;
+
+   for (i = 0; i < niov; i++) {
+   void __user *base = iov[i].iov_base + iov_off;
+   size_t len = iov[i].iov_len - iov_off;
+
+   ret = vhost_scsi_map_to_sgl(cmd, base, len, sg, write);
+   if (ret < 0) {
+   for (i = 0; i < sg_count; i++) {
+   struct page *page = sg_page(&sg[i]);
+   if (page)
+   put_page(page);
+   }
+   return ret;
+   }
+   sg += ret;
+   iov_off = 0;
+   }
+   return 0;
+}
+
+static int
+vhost_scsi_mapal(struct tcm_vhost_cmd *cmd, int max_niov,
+size_t prot_bytes, struct iovec *prot_iov, size_t prot_off,
+size_t data_bytes, struct iovec *data_iov, size_t data_off)
+{
+   int sgl_count = 0, niov, ret;
+   bool write = (cmd->tvc_data_direction == DMA_FROM_DEVICE);
+
+   if (prot_bytes) {
+   if (!prot_iov) {
+   pr_err("%s: prot_iov is NULL, but prot_bytes: %zu"
+  "present\n", __func__, prot_bytes);
+   return -EINVAL;
+   }
+   sgl_count = vhost_scsi_calc_sgls(prot_iov, prot_off, prot_bytes,
+&niov, max_niov,
+TCM_VHOST_PREALLOC_PROT_SGLS);
+   if (sgl_count < 0)
+   return sgl_count;
+
+   sg_init_table(cmd->tvc_prot_sgl, sgl_count);
+   cmd->tvc_prot_sgl_count = sgl_count;
+   pr_debug("%s prot_sg %p prot_sgl_count %u\n", __func__,
+cmd->tvc_prot_sgl, cmd->tvc_prot_sgl_count);
+
+   ret = vhost_scsi_iov_to_sgl(cmd, write, prot_iov, prot_off,
+   niov, cmd->tvc_prot_sgl,
+   cmd->tvc_prot_sgl_count);
+   if (ret < 0) {
+   cmd->tvc_prot_sgl_count = 0;
+   return ret;
+   }
+   max_niov -= niov;
+   }
+   if (!data_iov) {
+   pr_err("%s: data_iov is NULL, but data_bytes: %zu present\n",
+  __func__, data_bytes);
+   return -EINVAL;
+   }
+   sgl_count = vhost_scsi_calc_sgls(data_iov, data_off, data_bytes,
+&niov, max_niov,
+TCM_VHOST_PREALLOC_SGLS);
+   if (sgl_count < 0)
+   return sgl_count;
+
+   sg_init_table(cmd->tvc_sgl, sgl_count);
+   cmd->tvc_sgl_count = sgl_count;
+   pr_debug("%s data_sg %p data_sgl_count %u\n", __func__,
+   

Re: [PATCH v2] scsi: NCR5380: use msecs_to_jiffies for conversions

2015-02-01 Thread Michael Schmitz
Hi Nicholas,

>> The values for USLEEP_* are taken to be in units jiffies, according to
>> comments in NCR5380.c. Replacing them by the msecs_to_jiffies conversion
>> is in fact wrong.
>>
>> Please drop the changes to g_NCR5380.c for that reason.
>>
>
> right the comment indicates it should be jiffies - my interpretation
> of that was that in NCR5380.c
> were  jiffies + (250 * HZ / 1000); constructs would be correctly
> converted to e.g. jiffies + msecs_to_jiffies(250)

No objection there.

> And defines like USLEEP_POLL are noted to be in jiffies:
> * USLEEP_SLEEP - amount of time, in jiffies, to sleep
>
> and then defined correctly as HZ indepenedent values:
> #define USLEEP_SLEEP (20*HZ/1000
>
> and thus should be the same as msecs_to_jiffies(20)

None here either.

>
> now g_NCR5380.c defines
> #define USLEEP_POLL 1
> #define USLEEP_SLEEP20
> #define USLEEP_WAITLONG 500
>
> for the DTC3181E card - but without the conversion to ms
> from the use in the code though (e.g NCR5380_set_timer) it
> seemed to me that it actually should be jiffeis equivalent ms and

We can't know that - it's a fair guess, but the way it is currently
defined will see these constants used as jiffies, not ms.

'git blame' is of little help here ...

^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  59) /*
settings for DTC3181E card with only Mustek scanner attached */
^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  60) #define
USLEEP_POLL 1
^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  61) #define
USLEEP_SLEEP20
^1da177e (Linus Torvalds 2005-04-16 15:20:36 -0700  62) #define
USLEEP_WAITLONG 500

The DTC3181E part dates back to '97. Let's see whether Ronald stilll remembers.

HZ used to be set to 100 in those days, so USLEEP_POLL=1 equates to
10ms, not 1ms

> the intent was only to change the USLEEP_POLL and USLEEP_WAITLONG
> settings for the specific device but not the unit and thus it
> shuld have been converted by msecs_to_jiffies(1) resp.
> msecs_to_jiffies(500). The problem with this if it is left in its
> current form is that the timeouts would actually depend on the HZ
> setting of the system which is probably not the intent.

I think it's safe to assume the code in question predates the option
to configure the scheduling tick frequency, so yes, probably not
intended.

The problem with your replacing jiffies by ms is that this will change
the timing for this particular combination of hardware by an order of
magnitude. That large a change in timing would need to be backed up by
testing on the actual hardware.

Much safer to use

#define USLEEP_POLLmsecs_to_jiffies(10)
#define USLEEP_SLEEP   msecs_to_jiffies(200)
#define USLEEP_WAITLONGmsecs_to_jiffies(5000)

and make sure no change in timing is incurred at all.

Cheers,

  Michael


>
> Pleas do give this one more look if the argument above is
> not sound I appologize for the noise.
>
> thx!
> hofrat
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


New am53c974 driver spamming syslog

2015-02-01 Thread Ondrej Zary
Hello,
just got a Dawicontrol DC-2964 card (AM53C9AKC chip) and tested the new
am53c974 driver. It seems to work but it's spamming the log with
"FIFO not cleared, 15 bytes left" messages:

[8.787282] am53c974 :00:0b.0: No valid Tekram EEprom found
[8.787958] am53c974 :00:0b.0: esp0: regs[1e800:1e800] irq[11]
[8.788225] am53c974 :00:0b.0: esp0: is a AM53C974, 40 MHz (ccf=0), SCSI 
ID 7
[   11.792268] scsi host2: esp
[   11.804706] scsi 2:0:0:0: Direct-Access IBM  DORS-32160   WA0A 
PQ: 0 ANSI: 2
[   11.804944] scsi target2:0:0: Beginning Domain Validation
[   11.821786] scsi target2:0:0: FAST-10 SCSI 10.0 MB/s ST (100 ns, offset 15)
[   11.833829] scsi target2:0:0: Domain Validation skipping write tests
[   11.833962] scsi target2:0:0: Ending Domain Validation
[   13.279133] sd 2:0:0:0: [sdb] 4226725 512-byte logical blocks: (2.16 GB/2.01 
GiB)
[   13.310822] sd 2:0:0:0: [sdb] Write Protect is off
[   13.310956] sd 2:0:0:0: [sdb] Mode Sense: b3 00 00 08
[   13.331969] sd 2:0:0:0: [sdb] Write cache: enabled, read cache: enabled, 
doesn't support DPO or FUA
[   13.447963] scsi host2: FIFO not cleared, 15 bytes left
[   13.450064] scsi host2: FIFO not cleared, 15 bytes left
[   13.451915] scsi host2: FIFO not cleared, 15 bytes left
[   13.453692] scsi host2: FIFO not cleared, 15 bytes left
[   13.455496] scsi host2: FIFO not cleared, 15 bytes left
[   13.457330] scsi host2: FIFO not cleared, 15 bytes left
[   13.459059] scsi host2: FIFO not cleared, 15 bytes left
[   13.460842] scsi host2: FIFO not cleared, 15 bytes left
[   13.462264]  sdb: sdb1
[   13.566346] sd 2:0:0:0: [sdb] Attached SCSI disk
[   13.705929] sd 2:0:0:0: Attached scsi generic sg1 type 0
[   13.844777] scsi host2: FIFO not cleared, 15 bytes left
...

Also got this error once but was unable to reproduce it. No SCSI devices were
detected (the reset probably didn't happen). rmmod and modprobe fixed it.
[8.728312] am53c974 :00:0b.0: No valid Tekram EEprom found
[8.728987] am53c974 :00:0b.0: esp0: regs[1e800:1e800] irq[11]
[8.729098] am53c974 :00:0b.0: esp0: is a AM53C974, 40 MHz (ccf=0), SCSI 
ID 7
[   11.732390] scsi host2: esp
[   11.739919] scsi host2: data done, DMA error, resetting


-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


HL-DT-ST DVDRAM GSA-T20N-(P) not recognized after installation

2015-02-01 Thread Wolfgang Hahnl

[1.]
summary: - HL-DT-ST DVDRAM GSA-T20N-(P)
+ HL-DT-ST DVDRAM GSA-T20N-(P) not recognized after installation

[2.]

I installed Ubuntu 14.04 via DVD-iso in the DVD drive. During 
installation procedure the DVD drive worked properly. After installation 
I got no connection to the device. If I insert a video DVD the drive 
starts and stops again. If I execute at a terminal:


sudo lshw -C disk

I got only information about the hard drive and no information about DVDRAM.

As per the BIOS:
IDE Slave
HL-DT-ST DVDRAM GSA-T20N-(P)
Transfer Mode: 8FPIO4/DMA2]
Ultra DMA Mode: Mode 2

kernel-bug-exists-upstream
kernel-bug-exists-upstream-3.19-rc6

[3]
Keywords: DVDRAM, kernel, bios

[4]
cat /proc/version
Linux version 3.19.0-031900rc6-generic (kernel@gomeisa) (gcc version 
4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #201501261152 SMP Mon Jan 26 
17:14:44 UTC 2015


[7]
sudo lsb_release -rd
[sudo] password for lilly:
Description:Ubuntu 14.04.1 LTS
Release:14.04


[7.1]

lilly@lilly-ECO4511IW:/usr/src/linux-headers-3.19.0-031900rc6-generic/scripts$ 
sh ver_linux

If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.

Linux lilly-ECO4511IW 3.19.0-031900rc6-generic #201501261152 SMP Mon Jan 
26 17:14:44 UTC 2015 i686 i686 i686 GNU/Linux


Gnu C  ver_linux:
Gnu make   3.81
binutils   2.24
util-linux 2.20.1
mount  support
module-init-tools  15
e2fsprogs  1.42.9
pcmciautils018
PPP 2.4.5
Linux C Library 2.19
Dynamic linker (ldd) 2.19
Procps 3.3.9
Net-tools 1.60
Kbd1.15.5
Sh-utils   8.21
wireless-tools 30
Modules Loaded arc4 rfcomm bnep snd_hda_codec_realtek 
snd_hda_codec_generic snd_hda_codec_si3054 snd_hda_intel 
snd_hda_controller iwl4965 iwlegacy snd_hda_codec mac80211 snd_hwdep 
snd_pcm coretemp snd_seq_midi snd_seq_midi_event kvm_intel snd_rawmidi 
binfmt_misc kvm cfg80211 joydev snd_seq serio_raw snd_seq_device 
snd_timer snd soundcore parport_pc ppdev lp btusb bluetooth lpc_ich 
mac_hid parport hid_generic usbhid hid i915 psmouse ahci libahci r8169 
i2c_algo_bit drm_kms_helper video mii drm


[7.2]
cat /proc/cpuinfo
processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model   : 15
model name  : Intel(R) Core(TM)2 Duo CPU T7100  @ 1.80GHz
stepping: 13
microcode   : 0xa1
cpu MHz : 800.000
cache size  : 2048 KB
physical id : 0
siblings: 2
core id : 0
cpu cores   : 2
apicid  : 0
initial apicid  : 0
fdiv_bug: no
f00f_bug: no
coma_bug: no
fpu : yes
fpu_exception   : yes
cpuid level : 10
wp  : yes
flags   : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge 
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm 
constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl 
vmx est tm2 ssse3 cx16 xtpr pdcm lahf_lm ida dtherm tpr_shadow vnmi 
flexpriority

bugs:
bogomips: 3591.11
clflush size: 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor   : 1
vendor_id   : GenuineIntel
cpu family  : 6
model   : 15
model name  : Intel(R) Core(TM)2 Duo CPU T7100  @ 1.80GHz
stepping: 13
microcode   : 0xa1
cpu MHz : 800.000
cache size  : 2048 KB
physical id : 0
siblings: 2
core id : 1
cpu cores   : 2
apicid  : 1
initial apicid  : 1
fdiv_bug: no
f00f_bug: no
coma_bug: no
fpu : yes
fpu_exception   : yes
cpuid level : 10
wp  : yes
flags   : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge 
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm 
constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl 
vmx est tm2 ssse3 cx16 xtpr pdcm lahf_lm ida dtherm tpr_shadow vnmi 
flexpriority

bugs:
bogomips: 3591.11
clflush size: 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:




[7.3]
cat /proc/modules
arc4 12509 2 - Live 0x
rfcomm 59314 12 - Live 0x
bnep 19107 2 - Live 0x
snd_hda_codec_realtek 68841 1 - Live 0x
snd_hda_codec_generic 63667 1 snd_hda_codec_realtek, Live 0x
snd_hda_codec_si3054 12928 1 - Live 0x
snd_hda_intel 29576 3 - Live 0x
snd_hda_controller 30930 1 snd_hda_intel, Live 0x
iwl4965 112529 0 - Live 0x
iwlegacy 88297 1 iwl4965, Live 0x
snd_hda_codec 121018 5 
snd_hda_codec_realtek,snd_hda_codec_generic,snd_hda_codec_si3054,snd_hda_intel,snd_hda_controller, 
Live 0x

mac80211 643092 2 iwl4965,iwlegacy, Live 0x
snd_hwdep 13276 1 snd_hda_codec, Live 0x
snd_pcm 89214 6 
snd_hda_codec_si3054,snd_hd