[PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

2016-03-12 Thread K. Y. Srinivasan
The default user scan function associated with FC (fc_user_scan)
is not suitable for FC hosts on Hyper-V since we don't have
an rport associated with FC host on Hyper-V . Set it to NULL so we can
support manual scan of FC targets on Hyper-V.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Tested-by: Long Li <lon...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 132b168..8aec590 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1776,6 +1776,12 @@ static int __init storvsc_drv_init(void)
 * Install Hyper-V specific timeout handler.
 */
fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
+   /*
+* The default user scan function associated with FC (fc_user_scan)
+* is not suitable for FC hosts on Hyper-V. Set it to NULL so we can
+* support manual scan of FC targets on Hyper-V.
+*/
+   fc_transport_template->user_scan = NULL;
 #endif
 
ret = vmbus_driver_register(_drv);
-- 
1.7.4.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 v4 1/1] scsi: storvsc: Fix a build issue reported by kbuild test robot

2016-02-26 Thread K. Y. Srinivasan
tree:   
https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgit.kernel.org%2fpub%2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git=01%7c01%7ckys%40microsoft.com%7ce2e0622715844b79ad7108d32796ec3c%7c72f988bf86f141af91ab2d7cd011db47%7c1=ubr4GbBaNS%2ftOz%2buJBk0CL9N0UNG9x2TidLgy6Yovg4%3d
 master
head:   03c21cb775a313f1ff19be59c5d02df3e3526471
commit: dac582417bc449b1f7f572d3f1dd9d23eec15cc9 storvsc: Properly support 
Fibre Channel devices
date:   3 weeks ago
config: x86_64-randconfig-s3-01281016 (attached as .config)
reproduce:
git checkout dac582417bc449b1f7f572d3f1dd9d23eec15cc9
# save the attached .config to linux build tree
make ARCH=x86_64

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `storvsc_remove':
>> storvsc_drv.c:(.text+0x213af7): undefined reference to `fc_remove_host'
   drivers/built-in.o: In function `storvsc_drv_init':
>> storvsc_drv.c:(.init.text+0xcbcc): undefined reference to 
>> `fc_attach_transport'
>> storvsc_drv.c:(.init.text+0xcc06): undefined reference to 
>> `fc_release_transport'
   drivers/built-in.o: In function `storvsc_drv_exit':
>> storvsc_drv.c:(.exit.text+0x123c): undefined reference to 
>> `fc_release_transport'

With this commit, the storvsc driver depends on FC atttributes. Make this
dependency explicit.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reported-by: Fengguang Wu <fengguang...@intel.com>
---
v1 - v4: Incorporated suggestions from James Bottomley 
<james.bottom...@hansenpartnership.com>

 drivers/scsi/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 64eed87..166de0c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -594,6 +594,7 @@ config XEN_SCSI_FRONTEND
 config HYPERV_STORAGE
tristate "Microsoft Hyper-V virtual storage driver"
depends on SCSI && HYPERV
+   depends on m || SCSI_FC_ATTRS != m
default HYPERV
help
  Select this option to enable the Hyper-V virtual storage driver.
-- 
1.7.4.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 1/1] scsi: storvsc: Fix a build issue reported by kbuild test robot

2016-02-26 Thread K. Y. Srinivasan
tree:   
https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgit.kernel.org%2fpub%2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git=01%7c01%7ckys%40microsoft.com%7ce2e0622715844b79ad7108d32796ec3c%7c72f988bf86f141af91ab2d7cd011db47%7c1=ubr4GbBaNS%2ftOz%2buJBk0CL9N0UNG9x2TidLgy6Yovg4%3d
 master
head:   03c21cb775a313f1ff19be59c5d02df3e3526471
commit: dac582417bc449b1f7f572d3f1dd9d23eec15cc9 storvsc: Properly support 
Fibre Channel devices
date:   3 weeks ago
config: x86_64-randconfig-s3-01281016 (attached as .config)
reproduce:
git checkout dac582417bc449b1f7f572d3f1dd9d23eec15cc9
# save the attached .config to linux build tree
make ARCH=x86_64

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `storvsc_remove':
>> storvsc_drv.c:(.text+0x213af7): undefined reference to `fc_remove_host'
   drivers/built-in.o: In function `storvsc_drv_init':
>> storvsc_drv.c:(.init.text+0xcbcc): undefined reference to 
>> `fc_attach_transport'
>> storvsc_drv.c:(.init.text+0xcc06): undefined reference to 
>> `fc_release_transport'
   drivers/built-in.o: In function `storvsc_drv_exit':
>> storvsc_drv.c:(.exit.text+0x123c): undefined reference to 
>> `fc_release_transport'

With this commit, the storvsc driver depends on FC atttributes. Make this
dependency explicit.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reported-by: Fengguang Wu <fengguang...@intel.com>
---
 drivers/scsi/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 64eed87..24365c3 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -594,6 +594,7 @@ config XEN_SCSI_FRONTEND
 config HYPERV_STORAGE
tristate "Microsoft Hyper-V virtual storage driver"
depends on SCSI && HYPERV
+   depends on SCSI_FC_ATTRS
default HYPERV
help
  Select this option to enable the Hyper-V virtual storage driver.
-- 
1.7.4.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 1/1] scsi: storvsc: Fix a build issue reported by kbuild test robot

2016-01-29 Thread K. Y. Srinivasan
tree:   
https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgit.kernel.org%2fpub%2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git=01%7c01%7ckys%40microsoft.com%7ce2e0622715844b79ad7108d32796ec3c%7c72f988bf86f141af91ab2d7cd011db47%7c1=ubr4GbBaNS%2ftOz%2buJBk0CL9N0UNG9x2TidLgy6Yovg4%3d
 master
head:   03c21cb775a313f1ff19be59c5d02df3e3526471
commit: dac582417bc449b1f7f572d3f1dd9d23eec15cc9 storvsc: Properly support 
Fibre Channel devices
date:   3 weeks ago
config: x86_64-randconfig-s3-01281016 (attached as .config)
reproduce:
git checkout dac582417bc449b1f7f572d3f1dd9d23eec15cc9
# save the attached .config to linux build tree
make ARCH=x86_64

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `storvsc_remove':
>> storvsc_drv.c:(.text+0x213af7): undefined reference to `fc_remove_host'
   drivers/built-in.o: In function `storvsc_drv_init':
>> storvsc_drv.c:(.init.text+0xcbcc): undefined reference to 
>> `fc_attach_transport'
>> storvsc_drv.c:(.init.text+0xcc06): undefined reference to 
>> `fc_release_transport'
   drivers/built-in.o: In function `storvsc_drv_exit':
>> storvsc_drv.c:(.exit.text+0x123c): undefined reference to 
>> `fc_release_transport'

With this commit, the storvsc driver depends on FC atttributes. Make this
dependency explicit.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reported-by: Fengguang Wu <fengguang...@intel.com>
---
V2: Fixed the dependency based on suggestion by James Bottomley 
<james.bottom...@hansenpartnership.com>

 drivers/scsi/Kconfig |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 64eed87..ce0d07b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -594,6 +594,7 @@ config XEN_SCSI_FRONTEND
 config HYPERV_STORAGE
tristate "Microsoft Hyper-V virtual storage driver"
depends on SCSI && HYPERV
+   depends on SCSI_FC_ATTRS || SCSI_FC_ATTRS !=m
default HYPERV
help
  Select this option to enable the Hyper-V virtual storage driver.
-- 
1.7.4.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 2/2] scsi: storvsc: Use the specified target ID in device lookup

2016-01-27 Thread K. Y. Srinivasan
The current code assumes that there is only one target in device lookup.
Fix this bug. This will alow us to correctly handle hot reomoval of LUNs.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Alex Ng <ale...@microsoft.com>
Tested-by: Vivek Yadav <vya...@microsoft.com>
---
V2: Made lun and target_id unsigned 8 bit entities - Hannes Reinecke 
<h...@suse.de>

 drivers/scsi/storvsc_drv.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 622f64a..132b168 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -478,19 +478,18 @@ struct hv_host_device {
 struct storvsc_scan_work {
struct work_struct work;
struct Scsi_Host *host;
-   uint lun;
+   u8 lun;
+   u8 tgt_id;
 };
 
 static void storvsc_device_scan(struct work_struct *work)
 {
struct storvsc_scan_work *wrk;
-   uint lun;
struct scsi_device *sdev;
 
wrk = container_of(work, struct storvsc_scan_work, work);
-   lun = wrk->lun;
 
-   sdev = scsi_device_lookup(wrk->host, 0, 0, lun);
+   sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
if (!sdev)
goto done;
scsi_rescan_device(>sdev_gendev);
@@ -541,7 +540,7 @@ static void storvsc_remove_lun(struct work_struct *work)
if (!scsi_host_get(wrk->host))
goto done;
 
-   sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
+   sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
 
if (sdev) {
scsi_remove_device(sdev);
@@ -941,6 +940,7 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
 
wrk->host = host;
wrk->lun = vm_srb->lun;
+   wrk->tgt_id = vm_srb->target_id;
INIT_WORK(>work, process_err_fn);
schedule_work(>work);
 }
-- 
1.7.4.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 1/2] scsi: storvsc: Install the storvsc specific timeout handler for FC devices

2016-01-27 Thread K. Y. Srinivasan
The default timeout routine used for FC transport is not
suitable for FC devices managed by storvsc since FC devices
managed by storvsc driver do not have an rport associated
with them. Use the time out handler used for SCSI devices
for FC devices as well.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Alex Ng <ale...@microsoft.com>
Tested-by: Vivek Yadav <vya...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 41c115c..622f64a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -1770,6 +1771,11 @@ static int __init storvsc_drv_init(void)
fc_transport_template = fc_attach_transport(_transport_functions);
if (!fc_transport_template)
return -ENODEV;
+
+   /*
+* Install Hyper-V specific timeout handler.
+*/
+   fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
 #endif
 
ret = vmbus_driver_register(_drv);
-- 
1.7.4.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 0/2] scsi: storvsc: Miscellaneous fixes

2016-01-27 Thread K. Y. Srinivasan
Some miscellaneous fixes.

V2: addressed comments from Hannes Reinecke <h...@suse.de>

K. Y. Srinivasan (2):
  scsi: storvsc: Install the storvsc specific timeout handler for FC
devices
  scsi: storvsc: Use the specified target ID in device lookup

 drivers/scsi/storvsc_drv.c |   16 +++-
 1 files changed, 11 insertions(+), 5 deletions(-)

-- 
1.7.4.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 V4 4/4] scsi: storvsc: Tighten up the interrupt path

2015-12-23 Thread K. Y. Srinivasan
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. While the compiler does inline
get_in_stor_device() (and other static functions) in the call chain
in the interrupt path, the compiler is repeatedly inlining
the call to get_in_stor_device() each time it is invoked.
The return value of get_in_stor_device() can be cached in the
interrupt path since there is higher level serialization in
place to ensure correct handling when the module unload races
with the processing of an incoming message from the host.
Optimize this code path by caching the pointer to storvsc_device
and passing it as an argument.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
Added Reviewed-by: Hannes Reinecke <h...@suse.com>
Added additional details to the commit log - James Bottomley 
<james.bottom...@hansenpartnership.com>
 
 drivers/scsi/storvsc_drv.c |   23 ---
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 811f276..41c115c 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -945,19 +945,16 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+  struct storvsc_device *stor_dev)
 {
struct scsi_cmnd *scmnd = cmd_request->cmd;
-   struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
struct Scsi_Host *host;
-   struct storvsc_device *stor_dev;
-   struct hv_device *dev = host_dev->dev;
u32 payload_sz = cmd_request->payload_sz;
void *payload = cmd_request->payload;
 
-   stor_dev = get_in_stor_device(dev);
host = stor_dev->host;
 
vm_srb = _request->vstor_packet.vm_srb;
@@ -987,14 +984,13 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
  struct vstor_packet *vstor_packet,
  struct storvsc_cmd_request *request)
 {
-   struct storvsc_device *stor_device;
struct vstor_packet *stor_pkt;
+   struct hv_device *device = stor_device->device;
 
-   stor_device = hv_get_drvdata(device);
stor_pkt = >vstor_packet;
 
/*
@@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
stor_pkt->vm_srb.data_transfer_length =
vstor_packet->vm_srb.data_transfer_length;
 
-   storvsc_command_completion(request);
+   storvsc_command_completion(request, stor_device);
 
if (atomic_dec_and_test(_device->num_outstanding_req) &&
stor_device->drain_notify)
@@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 struct vstor_packet *vstor_packet,
 struct storvsc_cmd_request *request)
 {
struct storvsc_scan_work *work;
-   struct storvsc_device *stor_device;
 
switch (vstor_packet->operation) {
case VSTOR_OPERATION_COMPLETE_IO:
-   storvsc_on_io_completion(device, vstor_packet, request);
+   storvsc_on_io_completion(stor_device, vstor_packet, request);
break;
 
case VSTOR_OPERATION_REMOVE_DEVICE:
case VSTOR_OPERATION_ENUMERATE_BUS:
-   stor_device = get_in_stor_device(device);
work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
if (!work)
return;
@@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device *device,
break;
 
case VSTOR_OPERATION_FCHBA_DATA:
-   stor_device = get_in_stor_device(device);
cache_wwn(stor_device, vstor_packet);
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
fc_host_node_name(stor_device->host) = stor_device->node_name;
@@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void *context)
vmscsi_size_delta));
complete(>wait_event);
} else {
-

[PATCH V4 2/4] scsi: storvsc: Properly support Fibre Channel devices

2015-12-23 Thread K. Y. Srinivasan
For FC devices managed by this driver, atttach the appropriate transport
template. This will allow us to create the appropriate sysfs files for
these devices. With this we can publish the wwn for both the port and the node.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>
V3: Fixed build issues reported by kbuild test robot <l...@intel.com>
V4: Handle configuration of SCSI_FC_ATTRS correctly (both module and 
built in)

 drivers/scsi/storvsc_drv.c |  181 ---
 1 files changed, 134 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 00bb4bd..cfbb289 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -397,6 +398,9 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+static struct scsi_transport_template *fc_transport_template;
+#endif
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -456,6 +460,11 @@ struct storvsc_device {
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
+   /*
+* Currently active port and node names for FC devices.
+*/
+   u64 node_name;
+   u64 port_name;
 };
 
 struct hv_host_device {
@@ -695,7 +704,26 @@ static void  handle_multichannel_storage(struct hv_device 
*device, int max_chns)
vmbus_are_subchannels_present(device->channel);
 }
 
-static int storvsc_channel_init(struct hv_device *device)
+static void cache_wwn(struct storvsc_device *stor_device,
+ struct vstor_packet *vstor_packet)
+{
+   /*
+* Cache the currently active port and node ww names.
+*/
+   if (vstor_packet->wwn_packet.primary_active) {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
+   } else {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
+   }
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
 {
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
@@ -727,19 +755,15 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   vstor_packet->status != 0)
+   return -EINVAL;
 
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
@@ -764,18 +788,14 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
-   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
+   return -EINVAL;
 
if (vstor_packet->status == 0) {
vmstor_proto_version =
@@ -791,10 +811,8 @@ static int storvsc_channel_init(struct hv_device *device)
}
}
 
-   if (vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->s

[PATCH V4 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init()

2015-12-23 Thread K. Y. Srinivasan
The function storvsc_channel_init() repeatedly interacts with the host to
extract various channel properties. Refactor this code to eliminate code
repetition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>
V4: Added Reviewed-by: Hannes Reinecke <h...@suse.com>

 drivers/scsi/storvsc_drv.c |  126 
 1 files changed, 46 insertions(+), 80 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index cfbb289..811f276 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device,
}
 }
 
-static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+
+static int storvsc_execute_vstor_op(struct hv_device *device,
+   struct storvsc_cmd_request *request,
+   bool status_check)
 {
-   struct storvsc_device *stor_device;
-   struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t, i;
-   int max_chns;
-   bool process_sub_channels = false;
-
-   stor_device = get_out_stor_device(device);
-   if (!stor_device)
-   return -ENODEV;
+   int ret, t;
 
-   request = _device->init_request;
vstor_packet = >vstor_packet;
 
-   /*
-* Now, initiate the vsc/vsp initialization protocol on the open
-* channel
-*/
-   memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(>wait_event);
-   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
ret = vmbus_sendpacket(device->channel, vstor_packet,
@@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
if (t == 0)
return -ETIMEDOUT;
 
+   if (!status_check)
+   return ret;
+
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
 
+   return ret;
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+{
+   struct storvsc_device *stor_device;
+   struct storvsc_cmd_request *request;
+   struct vstor_packet *vstor_packet;
+   int ret, i;
+   int max_chns;
+   bool process_sub_channels = false;
+
+   stor_device = get_out_stor_device(device);
+   if (!stor_device)
+   return -ENODEV;
+
+   request = _device->init_request;
+   vstor_packet = >vstor_packet;
+
+   /*
+* Now, initiate the vsc/vsp initialization protocol on the open
+* channel
+*/
+   memset(request, 0, sizeof(struct storvsc_cmd_request));
+   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+   ret = storvsc_execute_vstor_op(device, request, true);
+   if (ret)
+   return ret;
+   /*
+* Query host supported protocol version.
+*/
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation =
VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
vstor_packet->version.major_minor =
vmstor_protocols[i].protocol_version;
@@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 * The revision number is only used in Windows; set it to 0.
 */
vstor_packet->version.revision = 0;
-
-   ret = vmbus_sendpacket(device->channel, vstor_packet,
-  (sizeof(struct vstor_packet) -
-   vmscsi_size_delta),
-  (unsigned long)request,
-  VM_PKT_DATA_INBAND,
-  VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+   ret = storvsc_execute_vstor_op(device, request, false);
if (ret != 0)
return ret;
 
-   t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0)
-   return -ETIMEDOUT;
-
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
return -EINVAL;
 
@@ -817,26 +828,10 @@ static int storvsc_channel_init(

[PATCH V4 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet

2015-12-23 Thread K. Y. Srinivasan
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match
the Window's definition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index c41f674..00bb4bd 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -92,9 +92,8 @@ enum vstor_packet_operation {
  */
 
 struct hv_fc_wwn_packet {
-   boolprimary_active;
-   u8  reserved1;
-   u8  reserved2;
+   u8  primary_active;
+   u8  reserved1[3];
u8  primary_port_wwn[8];
u8  primary_node_wwn[8];
u8  secondary_port_wwn[8];
-- 
1.7.4.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 V4 0/4] scsi: storvsc: Properly support FC hosts

2015-12-23 Thread K. Y. Srinivasan
Properly support FC hosts. Additional cleanup patches are also
included.

V2: Comments from Dan Carpenter <dan.carpen...@oracle.com> and
from Johannes Thumshirn <jthumsh...@suse.de> addressed.

V3: Fixed build issues reported by kbuild test robot <l...@intel.com>
V4: Addressed comments from Hannes and James.

K. Y. Srinivasan (4):
  scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet
  scsi: storvsc: Properly support Fibre Channel devices
  scsi: storvsc: Refactor the code in storvsc_channel_init()
  scsi: storvsc: Tighten up the interrupt path

 drivers/scsi/storvsc_drv.c |  275 +--
 1 files changed, 160 insertions(+), 115 deletions(-)

-- 
1.7.4.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 V3 2/4] scsi: storvsc: Properly support Fibre Channel devices

2015-12-13 Thread K. Y. Srinivasan
For FC devices managed by this driver, atttach the appropriate transport
template. This will allow us to create the appropriate sysfs files for
these devices. With this we can publish the wwn for both the port and the node.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>
V3: Fixed build issues reported by kbuild test robot <l...@intel.com>

 drivers/scsi/storvsc_drv.c |  181 ---
 1 files changed, 134 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 00bb4bd..220b794 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -397,6 +398,9 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
+#ifdef CONFIG_SCSI_FC_ATTRS
+static struct scsi_transport_template *fc_transport_template;
+#endif
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -456,6 +460,11 @@ struct storvsc_device {
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
+   /*
+* Currently active port and node names for FC devices.
+*/
+   u64 node_name;
+   u64 port_name;
 };
 
 struct hv_host_device {
@@ -695,7 +704,26 @@ static void  handle_multichannel_storage(struct hv_device 
*device, int max_chns)
vmbus_are_subchannels_present(device->channel);
 }
 
-static int storvsc_channel_init(struct hv_device *device)
+static void cache_wwn(struct storvsc_device *stor_device,
+ struct vstor_packet *vstor_packet)
+{
+   /*
+* Cache the currently active port and node ww names.
+*/
+   if (vstor_packet->wwn_packet.primary_active) {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
+   } else {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
+   }
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
 {
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
@@ -727,19 +755,15 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   vstor_packet->status != 0)
+   return -EINVAL;
 
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
@@ -764,18 +788,14 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
-   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
+   return -EINVAL;
 
if (vstor_packet->status == 0) {
vmstor_proto_version =
@@ -791,10 +811,8 @@ static int storvsc_channel_init(struct hv_device *device)
}
}
 
-   if (vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->status != 0)
+   return -EINVAL;
 
 
memset(vstor_packet, 0, sizeof(struct v

[PATCH V3 0/4] scsi: storvsc: Properly support FC hosts

2015-12-13 Thread K. Y. Srinivasan
Properly support FC hosts. Additional cleanup patches are also
included.

V2: Comments from Dan Carpenter <dan.carpen...@oracle.com> and
from Johannes Thumshirn <jthumsh...@suse.de> addressed.

V3: Fixed build issues reported by kbuild test robot <l...@intel.com>

K. Y. Srinivasan (4):
  scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet
  scsi: storvsc: Properly support Fibre Channel devices
  scsi: storvsc: Refactor the code in storvsc_channel_init()
  scsi: storvsc: Tighten up the interrupt path

 drivers/scsi/storvsc_drv.c |  275 +--
 1 files changed, 160 insertions(+), 115 deletions(-)

-- 
1.7.4.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 V3 4/4] scsi: storvsc: Tighten up the interrupt path

2015-12-13 Thread K. Y. Srinivasan
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. Fix this.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |   23 ---
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index d6ca4f2..b68aebe 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -945,19 +945,16 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+  struct storvsc_device *stor_dev)
 {
struct scsi_cmnd *scmnd = cmd_request->cmd;
-   struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
struct Scsi_Host *host;
-   struct storvsc_device *stor_dev;
-   struct hv_device *dev = host_dev->dev;
u32 payload_sz = cmd_request->payload_sz;
void *payload = cmd_request->payload;
 
-   stor_dev = get_in_stor_device(dev);
host = stor_dev->host;
 
vm_srb = _request->vstor_packet.vm_srb;
@@ -987,14 +984,13 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
  struct vstor_packet *vstor_packet,
  struct storvsc_cmd_request *request)
 {
-   struct storvsc_device *stor_device;
struct vstor_packet *stor_pkt;
+   struct hv_device *device = stor_device->device;
 
-   stor_device = hv_get_drvdata(device);
stor_pkt = >vstor_packet;
 
/*
@@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
stor_pkt->vm_srb.data_transfer_length =
vstor_packet->vm_srb.data_transfer_length;
 
-   storvsc_command_completion(request);
+   storvsc_command_completion(request, stor_device);
 
if (atomic_dec_and_test(_device->num_outstanding_req) &&
stor_device->drain_notify)
@@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 struct vstor_packet *vstor_packet,
 struct storvsc_cmd_request *request)
 {
struct storvsc_scan_work *work;
-   struct storvsc_device *stor_device;
 
switch (vstor_packet->operation) {
case VSTOR_OPERATION_COMPLETE_IO:
-   storvsc_on_io_completion(device, vstor_packet, request);
+   storvsc_on_io_completion(stor_device, vstor_packet, request);
break;
 
case VSTOR_OPERATION_REMOVE_DEVICE:
case VSTOR_OPERATION_ENUMERATE_BUS:
-   stor_device = get_in_stor_device(device);
work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
if (!work)
return;
@@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device *device,
break;
 
case VSTOR_OPERATION_FCHBA_DATA:
-   stor_device = get_in_stor_device(device);
cache_wwn(stor_device, vstor_packet);
 #ifdef CONFIG_SCSI_FC_ATTRS
fc_host_node_name(stor_device->host) = stor_device->node_name;
@@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void *context)
vmscsi_size_delta));
complete(>wait_event);
} else {
-   storvsc_on_receive(device,
+   storvsc_on_receive(stor_device,
(struct vstor_packet *)packet,
request);
}
-- 
1.7.4.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 V3 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init()

2015-12-13 Thread K. Y. Srinivasan
The function storvsc_channel_init() repeatedly interacts with the host to
extract various channel properties. Refactor this code to eliminate code
repetition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>

 drivers/scsi/storvsc_drv.c |  126 
 1 files changed, 46 insertions(+), 80 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 220b794..d6ca4f2 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -723,29 +723,17 @@ static void cache_wwn(struct storvsc_device *stor_device,
}
 }
 
-static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+
+static int storvsc_execute_vstor_op(struct hv_device *device,
+   struct storvsc_cmd_request *request,
+   bool status_check)
 {
-   struct storvsc_device *stor_device;
-   struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t, i;
-   int max_chns;
-   bool process_sub_channels = false;
-
-   stor_device = get_out_stor_device(device);
-   if (!stor_device)
-   return -ENODEV;
+   int ret, t;
 
-   request = _device->init_request;
vstor_packet = >vstor_packet;
 
-   /*
-* Now, initiate the vsc/vsp initialization protocol on the open
-* channel
-*/
-   memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(>wait_event);
-   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
ret = vmbus_sendpacket(device->channel, vstor_packet,
@@ -761,17 +749,50 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
if (t == 0)
return -ETIMEDOUT;
 
+   if (!status_check)
+   return ret;
+
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
 
+   return ret;
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+{
+   struct storvsc_device *stor_device;
+   struct storvsc_cmd_request *request;
+   struct vstor_packet *vstor_packet;
+   int ret, i;
+   int max_chns;
+   bool process_sub_channels = false;
+
+   stor_device = get_out_stor_device(device);
+   if (!stor_device)
+   return -ENODEV;
+
+   request = _device->init_request;
+   vstor_packet = >vstor_packet;
+
+   /*
+* Now, initiate the vsc/vsp initialization protocol on the open
+* channel
+*/
+   memset(request, 0, sizeof(struct storvsc_cmd_request));
+   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+   ret = storvsc_execute_vstor_op(device, request, true);
+   if (ret)
+   return ret;
+   /*
+* Query host supported protocol version.
+*/
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation =
VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
vstor_packet->version.major_minor =
vmstor_protocols[i].protocol_version;
@@ -780,20 +801,10 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 * The revision number is only used in Windows; set it to 0.
 */
vstor_packet->version.revision = 0;
-
-   ret = vmbus_sendpacket(device->channel, vstor_packet,
-  (sizeof(struct vstor_packet) -
-   vmscsi_size_delta),
-  (unsigned long)request,
-  VM_PKT_DATA_INBAND,
-  VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+   ret = storvsc_execute_vstor_op(device, request, false);
if (ret != 0)
return ret;
 
-   t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0)
-   return -ETIMEDOUT;
-
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
return -EINVAL;
 
@@ -817,26 +828,10 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation

[PATCH V3 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet

2015-12-13 Thread K. Y. Srinivasan
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match
the Window's definition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index c41f674..00bb4bd 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -92,9 +92,8 @@ enum vstor_packet_operation {
  */
 
 struct hv_fc_wwn_packet {
-   boolprimary_active;
-   u8  reserved1;
-   u8  reserved2;
+   u8  primary_active;
+   u8  reserved1[3];
u8  primary_port_wwn[8];
u8  primary_node_wwn[8];
u8  secondary_port_wwn[8];
-- 
1.7.4.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 2/4] scsi: storvsc: Properly support Fibre Channel devices

2015-12-12 Thread K. Y. Srinivasan
For FC devices managed by this driver, atttach the appropriate transport
template. This will allow us to create the appropriate sysfs files for
these devices. With this we can publish the wwn for both the port and the node.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>

 drivers/scsi/storvsc_drv.c |  162 +++-
 1 files changed, 115 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 00bb4bd..ab9828c 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -397,6 +398,7 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
+static struct scsi_transport_template *fc_transport_template;
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -456,6 +458,11 @@ struct storvsc_device {
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
+   /*
+* Currently active port and node names for FC devices.
+*/
+   u64 node_name;
+   u64 port_name;
 };
 
 struct hv_host_device {
@@ -695,7 +702,26 @@ static void  handle_multichannel_storage(struct hv_device 
*device, int max_chns)
vmbus_are_subchannels_present(device->channel);
 }
 
-static int storvsc_channel_init(struct hv_device *device)
+static void cache_wwn(struct storvsc_device *stor_device,
+ struct vstor_packet *vstor_packet)
+{
+   /*
+* Cache the currently active port and node ww names.
+*/
+   if (vstor_packet->wwn_packet.primary_active) {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
+   } else {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
+   }
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
 {
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
@@ -727,19 +753,15 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   vstor_packet->status != 0)
+   return -EINVAL;
 
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
@@ -764,18 +786,14 @@ static int storvsc_channel_init(struct hv_device *device)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   return ret;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
-   }
+   if (t == 0)
+   return -ETIMEDOUT;
 
-   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
+   return -EINVAL;
 
if (vstor_packet->status == 0) {
vmstor_proto_version =
@@ -791,10 +809,8 @@ static int storvsc_channel_init(struct hv_device *device)
}
}
 
-   if (vstor_packet->status != 0) {
-   ret = -EINVAL;
-   goto cleanup;
-   }
+   if (vstor_packet->status != 0)
+   return -EINVAL;
 
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
@@ -809,19 +825,15 @@ static int storvsc_channel_init(struct hv_device *device)
   VMB

[PATCH V2 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init()

2015-12-12 Thread K. Y. Srinivasan
The function storvsc_channel_init() repeatedly interacts with the host to
extract various channel properties. Refactor this code to eliminate code
repetition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Tested-by: Alex Ng <ale...@microsoft.com>
---
V2: Fixed error paths - Dan Carpenter <dan.carpen...@oracle.com>

 drivers/scsi/storvsc_drv.c |  126 
 1 files changed, 46 insertions(+), 80 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index ab9828c..947f812 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -721,29 +721,17 @@ static void cache_wwn(struct storvsc_device *stor_device,
}
 }
 
-static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+
+static int storvsc_execute_vstor_op(struct hv_device *device,
+   struct storvsc_cmd_request *request,
+   bool status_check)
 {
-   struct storvsc_device *stor_device;
-   struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t, i;
-   int max_chns;
-   bool process_sub_channels = false;
-
-   stor_device = get_out_stor_device(device);
-   if (!stor_device)
-   return -ENODEV;
+   int ret, t;
 
-   request = _device->init_request;
vstor_packet = >vstor_packet;
 
-   /*
-* Now, initiate the vsc/vsp initialization protocol on the open
-* channel
-*/
-   memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(>wait_event);
-   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
ret = vmbus_sendpacket(device->channel, vstor_packet,
@@ -759,17 +747,50 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
if (t == 0)
return -ETIMEDOUT;
 
+   if (!status_check)
+   return ret;
+
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return -EINVAL;
 
+   return ret;
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+{
+   struct storvsc_device *stor_device;
+   struct storvsc_cmd_request *request;
+   struct vstor_packet *vstor_packet;
+   int ret, i;
+   int max_chns;
+   bool process_sub_channels = false;
+
+   stor_device = get_out_stor_device(device);
+   if (!stor_device)
+   return -ENODEV;
+
+   request = _device->init_request;
+   vstor_packet = >vstor_packet;
+
+   /*
+* Now, initiate the vsc/vsp initialization protocol on the open
+* channel
+*/
+   memset(request, 0, sizeof(struct storvsc_cmd_request));
+   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+   ret = storvsc_execute_vstor_op(device, request, true);
+   if (ret)
+   return ret;
+   /*
+* Query host supported protocol version.
+*/
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation =
VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
vstor_packet->version.major_minor =
vmstor_protocols[i].protocol_version;
@@ -778,20 +799,10 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 * The revision number is only used in Windows; set it to 0.
 */
vstor_packet->version.revision = 0;
-
-   ret = vmbus_sendpacket(device->channel, vstor_packet,
-  (sizeof(struct vstor_packet) -
-   vmscsi_size_delta),
-  (unsigned long)request,
-  VM_PKT_DATA_INBAND,
-  VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+   ret = storvsc_execute_vstor_op(device, request, false);
if (ret != 0)
return ret;
 
-   t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0)
-   return -ETIMEDOUT;
-
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
return -EINVAL;
 
@@ -815,26 +826,10 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation

[PATCH V2 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet

2015-12-12 Thread K. Y. Srinivasan
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match
the Window's definition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index c41f674..00bb4bd 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -92,9 +92,8 @@ enum vstor_packet_operation {
  */
 
 struct hv_fc_wwn_packet {
-   boolprimary_active;
-   u8  reserved1;
-   u8  reserved2;
+   u8  primary_active;
+   u8  reserved1[3];
u8  primary_port_wwn[8];
u8  primary_node_wwn[8];
u8  secondary_port_wwn[8];
-- 
1.7.4.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 4/4] scsi: storvsc: Tighten up the interrupt path

2015-12-12 Thread K. Y. Srinivasan
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. Fix this.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |   23 ---
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 947f812..3d3d157 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -943,19 +943,16 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+  struct storvsc_device *stor_dev)
 {
struct scsi_cmnd *scmnd = cmd_request->cmd;
-   struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
struct Scsi_Host *host;
-   struct storvsc_device *stor_dev;
-   struct hv_device *dev = host_dev->dev;
u32 payload_sz = cmd_request->payload_sz;
void *payload = cmd_request->payload;
 
-   stor_dev = get_in_stor_device(dev);
host = stor_dev->host;
 
vm_srb = _request->vstor_packet.vm_srb;
@@ -985,14 +982,13 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
  struct vstor_packet *vstor_packet,
  struct storvsc_cmd_request *request)
 {
-   struct storvsc_device *stor_device;
struct vstor_packet *stor_pkt;
+   struct hv_device *device = stor_device->device;
 
-   stor_device = hv_get_drvdata(device);
stor_pkt = >vstor_packet;
 
/*
@@ -1047,7 +1043,7 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
stor_pkt->vm_srb.data_transfer_length =
vstor_packet->vm_srb.data_transfer_length;
 
-   storvsc_command_completion(request);
+   storvsc_command_completion(request, stor_device);
 
if (atomic_dec_and_test(_device->num_outstanding_req) &&
stor_device->drain_notify)
@@ -1056,21 +1052,19 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 struct vstor_packet *vstor_packet,
 struct storvsc_cmd_request *request)
 {
struct storvsc_scan_work *work;
-   struct storvsc_device *stor_device;
 
switch (vstor_packet->operation) {
case VSTOR_OPERATION_COMPLETE_IO:
-   storvsc_on_io_completion(device, vstor_packet, request);
+   storvsc_on_io_completion(stor_device, vstor_packet, request);
break;
 
case VSTOR_OPERATION_REMOVE_DEVICE:
case VSTOR_OPERATION_ENUMERATE_BUS:
-   stor_device = get_in_stor_device(device);
work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
if (!work)
return;
@@ -1081,7 +1075,6 @@ static void storvsc_on_receive(struct hv_device *device,
break;
 
case VSTOR_OPERATION_FCHBA_DATA:
-   stor_device = get_in_stor_device(device);
cache_wwn(stor_device, vstor_packet);
fc_host_node_name(stor_device->host) = stor_device->node_name;
fc_host_port_name(stor_device->host) = stor_device->port_name;
@@ -1129,7 +1122,7 @@ static void storvsc_on_channel_callback(void *context)
vmscsi_size_delta));
complete(>wait_event);
} else {
-   storvsc_on_receive(device,
+   storvsc_on_receive(stor_device,
(struct vstor_packet *)packet,
request);
}
-- 
1.7.4.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 0/4] scsi: storvsc: Properly support FC hosts

2015-12-12 Thread K. Y. Srinivasan
Properly support FC hosts. Additional cleanup patches are also
included.

In this version I have adddressed comments from
Dan Carpenter <dan.carpen...@oracle.com> and
from Johannes Thumshirn <jthumsh...@suse.de>.

K. Y. Srinivasan (4):
  scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet
  scsi: storvsc: Properly support Fibre Channel devices
  scsi: storvsc: Refactor the code in storvsc_channel_init()
  scsi: storvsc: Tighten up the interrupt path

 drivers/scsi/storvsc_drv.c |  256 
 1 files changed, 141 insertions(+), 115 deletions(-)

-- 
1.7.4.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 0/4] scsi: storvsc: Properly support FC hosts

2015-12-10 Thread K. Y. Srinivasan
Properly support FC hosts. Additional cleanup patches are also
included.

K. Y. Srinivasan (4):
  scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet
  scsi: storvsc: Properly support Fibre Channel devices
  scsi: storvsc: Refactor the code in storvsc_channel_init()
  scsi: storvsc: Tighten up the interrupt path

 drivers/scsi/storvsc_drv.c |  235 ++--
 1 files changed, 138 insertions(+), 97 deletions(-)

-- 
1.7.4.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 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet

2015-12-10 Thread K. Y. Srinivasan
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match
the Window's definition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index c41f674..00bb4bd 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -92,9 +92,8 @@ enum vstor_packet_operation {
  */
 
 struct hv_fc_wwn_packet {
-   boolprimary_active;
-   u8  reserved1;
-   u8  reserved2;
+   u8  primary_active;
+   u8  reserved1[3];
u8  primary_port_wwn[8];
u8  primary_node_wwn[8];
u8  secondary_port_wwn[8];
-- 
1.7.4.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 2/4] scsi: storvsc: Properly support Fibre Channel devices

2015-12-10 Thread K. Y. Srinivasan
For FC devices managed by this driver, atttach the appropriate transport
template. This will allow us to create the appropriate sysfs files for
these devices. With this we can publish the wwn for both the port and the node.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |  100 +--
 1 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 00bb4bd..b94d471 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -397,6 +398,7 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
+static struct scsi_transport_template *fc_transport_template;
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -456,6 +458,11 @@ struct storvsc_device {
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
+   /*
+* Currently active port and node names for FC devices.
+*/
+   u64 node_name;
+   u64 port_name;
 };
 
 struct hv_host_device {
@@ -695,7 +702,26 @@ static void  handle_multichannel_storage(struct hv_device 
*device, int max_chns)
vmbus_are_subchannels_present(device->channel);
 }
 
-static int storvsc_channel_init(struct hv_device *device)
+static void cache_wwn(struct storvsc_device *stor_device,
+ struct vstor_packet *vstor_packet)
+{
+   /*
+* Cache the currently active port and node ww names.
+*/
+   if (vstor_packet->wwn_packet.primary_active) {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
+   } else {
+   stor_device->node_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
+   stor_device->port_name =
+   wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
+   }
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
 {
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
@@ -837,6 +863,40 @@ static int storvsc_channel_init(struct hv_device *device)
stor_device->max_transfer_bytes =
vstor_packet->storage_channel_properties.max_transfer_bytes;
 
+   if (!is_fc)
+   goto done;
+
+   memset(vstor_packet, 0, sizeof(struct vstor_packet));
+   vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA;
+   vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+   ret = vmbus_sendpacket(device->channel, vstor_packet,
+  (sizeof(struct vstor_packet) -
+  vmscsi_size_delta),
+  (unsigned long)request,
+  VM_PKT_DATA_INBAND,
+  VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+   if (ret != 0)
+   goto cleanup;
+
+   t = wait_for_completion_timeout(>wait_event, 5*HZ);
+   if (t == 0) {
+   ret = -ETIMEDOUT;
+   goto cleanup;
+   }
+
+   if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+   vstor_packet->status != 0)
+   goto cleanup;
+
+   /*
+* Cache the currently active port and node ww names.
+*/
+   cache_wwn(stor_device, vstor_packet);
+
+done:
+
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
@@ -1076,6 +1136,12 @@ static void storvsc_on_receive(struct hv_device *device,
schedule_work(>work);
break;
 
+   case VSTOR_OPERATION_FCHBA_DATA:
+   stor_device = get_in_stor_device(device);
+   cache_wwn(stor_device, vstor_packet);
+   fc_host_node_name(stor_device->host) = stor_device->node_name;
+   fc_host_port_name(stor_device->host) = stor_device->port_name;
+   break;
default:
break;
}
@@ -1131,7 +1197,8 @@ static void storvsc_on_channel_callback(void *context)
return;
 }
 
-static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
+static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
+ bool is_fc)
 {
struct vmstorage_channel_prop

[PATCH 4/4] scsi: storvsc: Tighten up the interrupt path

2015-12-10 Thread K. Y. Srinivasan
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. Fix this.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |   23 ---
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6f18e94..8ba9908 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -958,19 +958,16 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+  struct storvsc_device *stor_dev)
 {
struct scsi_cmnd *scmnd = cmd_request->cmd;
-   struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
struct Scsi_Host *host;
-   struct storvsc_device *stor_dev;
-   struct hv_device *dev = host_dev->dev;
u32 payload_sz = cmd_request->payload_sz;
void *payload = cmd_request->payload;
 
-   stor_dev = get_in_stor_device(dev);
host = stor_dev->host;
 
vm_srb = _request->vstor_packet.vm_srb;
@@ -1000,14 +997,13 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
  struct vstor_packet *vstor_packet,
  struct storvsc_cmd_request *request)
 {
-   struct storvsc_device *stor_device;
struct vstor_packet *stor_pkt;
+   struct hv_device *device = stor_device->device;
 
-   stor_device = hv_get_drvdata(device);
stor_pkt = >vstor_packet;
 
/*
@@ -1062,7 +1058,7 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
stor_pkt->vm_srb.data_transfer_length =
vstor_packet->vm_srb.data_transfer_length;
 
-   storvsc_command_completion(request);
+   storvsc_command_completion(request, stor_device);
 
if (atomic_dec_and_test(_device->num_outstanding_req) &&
stor_device->drain_notify)
@@ -1071,21 +1067,19 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 struct vstor_packet *vstor_packet,
 struct storvsc_cmd_request *request)
 {
struct storvsc_scan_work *work;
-   struct storvsc_device *stor_device;
 
switch (vstor_packet->operation) {
case VSTOR_OPERATION_COMPLETE_IO:
-   storvsc_on_io_completion(device, vstor_packet, request);
+   storvsc_on_io_completion(stor_device, vstor_packet, request);
break;
 
case VSTOR_OPERATION_REMOVE_DEVICE:
case VSTOR_OPERATION_ENUMERATE_BUS:
-   stor_device = get_in_stor_device(device);
work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
if (!work)
return;
@@ -1096,7 +1090,6 @@ static void storvsc_on_receive(struct hv_device *device,
break;
 
case VSTOR_OPERATION_FCHBA_DATA:
-   stor_device = get_in_stor_device(device);
cache_wwn(stor_device, vstor_packet);
fc_host_node_name(stor_device->host) = stor_device->node_name;
fc_host_port_name(stor_device->host) = stor_device->port_name;
@@ -1144,7 +1137,7 @@ static void storvsc_on_channel_callback(void *context)
vmscsi_size_delta));
complete(>wait_event);
} else {
-   storvsc_on_receive(device,
+   storvsc_on_receive(stor_device,
(struct vstor_packet *)packet,
request);
}
-- 
1.7.4.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 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init()

2015-12-10 Thread K. Y. Srinivasan
The function storvsc_channel_init() repeatedly interacts with the host to
extract various channel properties. Refactor this code to eliminate code
repetition.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |  155 
 1 files changed, 57 insertions(+), 98 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index b94d471..6f18e94 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -721,29 +721,16 @@ static void cache_wwn(struct storvsc_device *stor_device,
}
 }
 
-static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+static int storvsc_execute_vstor_op(struct hv_device *device,
+   struct storvsc_cmd_request *request,
+   bool status_check)
 {
-   struct storvsc_device *stor_device;
-   struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t, i;
-   int max_chns;
-   bool process_sub_channels = false;
-
-   stor_device = get_out_stor_device(device);
-   if (!stor_device)
-   return -ENODEV;
+   int ret, t;
 
-   request = _device->init_request;
vstor_packet = >vstor_packet;
 
-   /*
-* Now, initiate the vsc/vsp initialization protocol on the open
-* channel
-*/
-   memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(>wait_event);
-   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
ret = vmbus_sendpacket(device->channel, vstor_packet,
@@ -753,27 +740,62 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
-   goto cleanup;
+   goto done;
 
t = wait_for_completion_timeout(>wait_event, 5*HZ);
if (t == 0) {
ret = -ETIMEDOUT;
-   goto cleanup;
+   goto done;
}
 
+   if (!status_check)
+   goto done;
+
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0) {
ret = -EINVAL;
-   goto cleanup;
+   goto done;
}
 
+done:
+   return ret;
+}
+
+static int storvsc_channel_init(struct hv_device *device, bool is_fc)
+{
+   struct storvsc_device *stor_device;
+   struct storvsc_cmd_request *request;
+   struct vstor_packet *vstor_packet;
+   int ret, i;
+   int max_chns;
+   bool process_sub_channels = false;
+
+   stor_device = get_out_stor_device(device);
+   if (!stor_device)
+   return -ENODEV;
+
+   request = _device->init_request;
+   vstor_packet = >vstor_packet;
+
+   /*
+* Now, initiate the vsc/vsp initialization protocol on the open
+* channel
+*/
+   memset(request, 0, sizeof(struct storvsc_cmd_request));
+   vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+   ret = storvsc_execute_vstor_op(device, request, true);
+   if (ret)
+   goto cleanup;
+
+   /*
+* Query host supported protocol version.
+*/
 
for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation =
VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
vstor_packet->version.major_minor =
vmstor_protocols[i].protocol_version;
@@ -783,20 +805,9 @@ static int storvsc_channel_init(struct hv_device *device, 
bool is_fc)
 */
vstor_packet->version.revision = 0;
 
-   ret = vmbus_sendpacket(device->channel, vstor_packet,
-  (sizeof(struct vstor_packet) -
-   vmscsi_size_delta),
-  (unsigned long)request,
-  VM_PKT_DATA_INBAND,
-  VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-   if (ret != 0)
-   goto cleanup;
-
-   t = wait_for_completion_timeout(>wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
+   ret = storvsc_execute_vstor_op(device, request, false);
+   if (ret)
goto cleanup;
-   }
 
if (vstor_pack

[PATCH 1/1] scsi: storvsc: Fix a bug in the handling of SRB status flags

2015-10-06 Thread K. Y. Srinivasan
SRB status can have additional information. Mask these out before processing 
SRB status.

This patch was sent as part of a collection of patches more than a year ago.
While the rest of the patches in the set were comitted, this patch was not.
I woulod like to thank Olaf for noticing that this patch was not committed
upstream.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 072c11e..face2e6 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -349,11 +349,14 @@ enum storvsc_request_type {
  */
 
 #define SRB_STATUS_AUTOSENSE_VALID 0x80
+#define SRB_STATUS_QUEUE_FROZEN0x40
 #define SRB_STATUS_INVALID_LUN 0x20
 #define SRB_STATUS_SUCCESS 0x01
 #define SRB_STATUS_ABORTED 0x02
 #define SRB_STATUS_ERROR   0x04
 
+#define SRB_STATUS(status) \
+   (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
 /*
  * This is the end of Protocol specific defines.
  */
@@ -858,7 +861,7 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
void (*process_err_fn)(struct work_struct *work);
bool do_work = false;
 
-   switch (vm_srb->srb_status) {
+   switch (SRB_STATUS(vm_srb->srb_status)) {
case SRB_STATUS_ERROR:
/*
 * If there is an error; offline the device since all
-- 
1.7.4.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 1/1] storvsc: get rid of bounce buffer

2015-10-01 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuzn...@redhat.com>

Storvsc driver needs to ensure there are no 'holes' in the presented
sg list (all segments in the middle of the list need to be of PAGE_SIZE).
When a hole is detected storvsc driver creates a 'bounce sgl' without
holes and copies data over with copy_{to,from}_bounce_buffer() functions.
Setting virt_boundary_mask to PAGE_SIZE - 1 guarantees we'll never see
such holes so we can significantly simplify the driver. This is also
supposed to bring us some performance improvement for certain workloads
as we eliminate copying.

Reported-by: Radim Kr.má<rkrc...@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com>
Reviewed-by: K. Y. Srinivasan <k...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |  286 +---
 1 files changed, 5 insertions(+), 281 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 9c8db21..072c11e 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -393,9 +393,6 @@ static void storvsc_on_channel_callback(void *context);
 struct storvsc_cmd_request {
struct scsi_cmnd *cmd;
 
-   unsigned int bounce_sgl_count;
-   struct scatterlist *bounce_sgl;
-
struct hv_device *device;
 
/* Synchronize the request/response if needed */
@@ -586,241 +583,6 @@ get_in_err:
 
 }
 
-static void destroy_bounce_buffer(struct scatterlist *sgl,
- unsigned int sg_count)
-{
-   int i;
-   struct page *page_buf;
-
-   for (i = 0; i < sg_count; i++) {
-   page_buf = sg_page(([i]));
-   if (page_buf != NULL)
-   __free_page(page_buf);
-   }
-
-   kfree(sgl);
-}
-
-static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
-{
-   int i;
-
-   /* No need to check */
-   if (sg_count < 2)
-   return -1;
-
-   /* We have at least 2 sg entries */
-   for (i = 0; i < sg_count; i++) {
-   if (i == 0) {
-   /* make sure 1st one does not have hole */
-   if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
-   return i;
-   } else if (i == sg_count - 1) {
-   /* make sure last one does not have hole */
-   if (sgl[i].offset != 0)
-   return i;
-   } else {
-   /* make sure no hole in the middle */
-   if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
-   return i;
-   }
-   }
-   return -1;
-}
-
-static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
-   unsigned int sg_count,
-   unsigned int len,
-   int write)
-{
-   int i;
-   int num_pages;
-   struct scatterlist *bounce_sgl;
-   struct page *page_buf;
-   unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
-
-   num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
-
-   bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
-   if (!bounce_sgl)
-   return NULL;
-
-   sg_init_table(bounce_sgl, num_pages);
-   for (i = 0; i < num_pages; i++) {
-   page_buf = alloc_page(GFP_ATOMIC);
-   if (!page_buf)
-   goto cleanup;
-   sg_set_page(_sgl[i], page_buf, buf_len, 0);
-   }
-
-   return bounce_sgl;
-
-cleanup:
-   destroy_bounce_buffer(bounce_sgl, num_pages);
-   return NULL;
-}
-
-/* Assume the original sgl has enough room */
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-   struct scatterlist *bounce_sgl,
-   unsigned int orig_sgl_count,
-   unsigned int bounce_sgl_count)
-{
-   int i;
-   int j = 0;
-   unsigned long src, dest;
-   unsigned int srclen, destlen, copylen;
-   unsigned int total_copied = 0;
-   unsigned long bounce_addr = 0;
-   unsigned long dest_addr = 0;
-   unsigned long flags;
-   struct scatterlist *cur_dest_sgl;
-   struct scatterlist *cur_src_sgl;
-
-   local_irq_save(flags);
-   cur_dest_sgl = orig_sgl;
-   cur_src_sgl = bounce_sgl;
-   for (i = 0; i < orig_sgl_count; i++) {
-   dest_addr = (unsigned long)
-   kmap_atomic(sg_page(cur_dest_sgl)) +
-   cur_dest_sgl->offset;
-   dest = dest_addr;
-   destlen = 

[PATCH 2/3] scsi: introduce short_inquiry flag for broken host adapters

2015-09-17 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuzn...@redhat.com>

Some host adapters (e.g. Hyper-V storvsc) are known for not respecting the
SPC-2/3/4 requirement for 'INQUIRY data (see table ...) shall contain at
least 36 bytes'. As a result we get tons on 'scsi 0:7:1:1: scsi scan:
INQUIRY result too short (5), using 36' messages on console. This can be
problematic for slow consoles. Introduce short_inquiry host template flag
to avoid printing error messages for such adapters.

Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com>
Reviewed-by: K. Y. Srinivasan <k...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
---
 drivers/scsi/scsi_scan.c   |7 ---
 drivers/scsi/storvsc_drv.c |1 +
 include/scsi/scsi_host.h   |6 ++
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 01ad016..5e325ce 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -701,9 +701,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, 
unsigned char *inq_result,
 * strings.
 */
if (sdev->inquiry_len < 36) {
-   sdev_printk(KERN_INFO, sdev,
-   "scsi scan: INQUIRY result too short (%d),"
-   " using 36\n", sdev->inquiry_len);
+   if (!sdev->host->hostt->short_inquiry)
+   sdev_printk(KERN_INFO, sdev,
+   "scsi scan: INQUIRY result too short (%d),"
+   " using 36\n", sdev->inquiry_len);
sdev->inquiry_len = 36;
}
 
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 40c43ae..bce131b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1781,6 +1781,7 @@ static struct scsi_host_template scsi_driver = {
/* Make sure we dont get a sg segment crosses a page boundary */
.dma_boundary = PAGE_SIZE-1,
.no_write_same =1,
+   .short_inquiry =1,
 };
 
 enum {
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index e113c75..7b022af 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -454,6 +454,12 @@ struct scsi_host_template {
unsigned no_async_abort:1;
 
/*
+* True if this host adapter returns short (<36 bytes) responses to
+* some INQUIRY requests.
+*/
+   unsigned short_inquiry:1;
+
+   /*
 * Countdown for host blocking with no commands outstanding.
 */
unsigned int max_host_blocked;
-- 
1.7.4.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 1/3] scsi_scan: don't dump trace when scsi_prep_async_scan() is called twice

2015-09-17 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov <vkuzn...@redhat.com>

The only user of scsi_prep_async_scan() is scsi_scan_host() and it handles
the situation correctly. Move 'called twice' reporting to debug level as
well.

The issue is observed on Hyper-V: on any device add/remove event storvsc
driver calls scsi_scan_host() and in case previous scan is still running
we get the message and stack dump on console.

Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com>
Reviewed-by: K. Y. Srinivasan <k...@microsoft.com>
Tested-by: Alex Ng <ale...@microsoft.com>
Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
---
 drivers/scsi/scsi_scan.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index f9f3f82..01ad016 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1712,8 +1712,7 @@ static struct async_scan_data 
*scsi_prep_async_scan(struct Scsi_Host *shost)
return NULL;
 
if (shost->async_scan) {
-   shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
-   dump_stack();
+   shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
return NULL;
}
 
-- 
1.7.4.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 0/3] scsi: Some miscellaneous fixes

2015-09-17 Thread K. Y. Srinivasan
Some miscellaneous fixes.

K. Y. Srinivasan (1):
  storvsc: Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag

Vitaly Kuznetsov (2):
  scsi_scan: don't dump trace when scsi_prep_async_scan() is called
twice
  scsi: introduce short_inquiry flag for broken host adapters

 drivers/scsi/scsi_scan.c   |   10 +-
 drivers/scsi/storvsc_drv.c |4 ++--
 include/scsi/scsi_host.h   |6 ++
 3 files changed, 13 insertions(+), 7 deletions(-)

-- 
1.7.4.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 RESEND 3/3] storvsc: Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag

2015-09-17 Thread K. Y. Srinivasan
Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag since we are not specifying
tags. Qlogic driver does not work correctly if the SRB_FLAGS_QUEUE_ACTION_ENABLE
is set and no action tag is specified.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Tested-by: Vivek Yadav <vya...@microsoft.com>
Reviewed-by: Long Li <lon...@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index bce131b..9c8db21 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1647,8 +1647,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
vm_srb->win8_extension.time_out_value = 60;
 
vm_srb->win8_extension.srb_flags |=
-   (SRB_FLAGS_QUEUE_ACTION_ENABLE |
-   SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
+   SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
 
/* Build the SRB */
switch (scmnd->sc_data_direction) {
-- 
1.7.4.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 1/1] storvsc: Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag

2015-08-31 Thread K. Y. Srinivasan
Don't set the SRB_FLAGS_QUEUE_ACTION_ENABLE flag since we are not specifying
tags.

Signed-off-by: K. Y. Srinivasan <k...@microsoft.com>
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 40c43ae..ad8c4bc 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1647,8 +1647,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
vm_srb->win8_extension.time_out_value = 60;
 
vm_srb->win8_extension.srb_flags |=
-   (SRB_FLAGS_QUEUE_ACTION_ENABLE |
-   SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
+   SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
 
/* Build the SRB */
switch (scmnd->sc_data_direction) {
-- 
1.7.4.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 1/1] scsi: storvsc: Use ARRAY_SIZE() to compute the elements in the protocol array

2015-08-14 Thread K. Y. Srinivasan
Rather than hard coding the number of elements in the array, use the 
ARRAY_SIZE()
macro to compute the number of elements in the array. This would minimize the
changes needed when we have to extend the protocols supported.

This was suggested by Johannes Thumshirn jthumsh...@suse.de.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 64fa305..4dffc3b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -226,9 +226,8 @@ struct vmstor_protocol {
int vmscsi_size_delta;
 };
 
-#define VMSTOR_NUM_PROTOCOLS5
 
-const struct vmstor_protocol vmstor_protocols[VMSTOR_NUM_PROTOCOLS] = {
+const struct vmstor_protocol vmstor_protocols[] = {
{
VMSTOR_PROTO_VERSION_WIN10,
POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
@@ -959,7 +958,7 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
 
-   for (i = 0; i  VMSTOR_NUM_PROTOCOLS; i++) {
+   for (i = 0; i  ARRAY_SIZE(vmstor_protocols); i++) {
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet-operation =
-- 
1.7.4.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 RESEND V2 7/7] scsi: storvsc: Set the error code correctly in failure conditions

2015-08-13 Thread K. Y. Srinivasan
In the function storvsc_channel_init(), error code was not getting
set correctly in some of the failure cases. Fix this issue.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reported-by: Dan Carpenter dan.carpen...@oracle.com
---
 drivers/scsi/storvsc_drv.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 021cbdf..aac8297 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -960,8 +960,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
 
for (i = 0; i  VMSTOR_NUM_PROTOCOLS; i++) {
@@ -1040,8 +1042,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
/*
 * Check to see if multi-channel support is there.
@@ -1078,8 +1082,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
if (process_sub_channels)
handle_multichannel_storage(device, max_chns);
-- 
1.7.4.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 RESEND V2 1/7] scsi: storvsc: Rather than look for sets of specific protocol versions, make decisions based on ranges.

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Rather than look for sets of specific protocol versions,
make decisions based on ranges. This will be safer and require fewer changes
going forward as we add more storage protocol versions.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   11 +++
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3c6584f..582f3b5 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -988,8 +988,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if ((vmbus_proto_version != VERSION_WIN7) 
-  (vmbus_proto_version != VERSION_WS2008))  {
+   if (vmbus_proto_version = VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1758,9 +1757,7 @@ static int storvsc_probe(struct hv_device *device,
 * set state to properly communicate with the host.
 */
 
-   switch (vmbus_proto_version) {
-   case VERSION_WS2008:
-   case VERSION_WIN7:
+   if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
vmstor_current_major = VMSTOR_WIN7_MAJOR;
@@ -1768,8 +1765,7 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
-   break;
-   default:
+   } else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
vmstor_current_major = VMSTOR_WIN8_MAJOR;
@@ -1783,7 +1779,6 @@ static int storvsc_probe(struct hv_device *device,
 * VCPUs in the guest.
 */
max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
-   break;
}
 
scsi_driver.can_queue = (max_outstanding_req_per_channel *
-- 
1.7.4.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 RESEND V2 6/7] scsi: storvsc: Allow write_same when host is windows 10

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Allow WRITE_SAME for Windows10 and above hosts.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 58fa47a..021cbdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1488,7 +1488,8 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 
/*
 * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
-* if the device is a MSFT virtual device.
+* if the device is a MSFT virtual device.  If the host is
+* WIN10 or newer, allow write_same.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
switch (vmstor_proto_version) {
@@ -1497,6 +1498,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
sdevice-scsi_level = SCSI_SPC_3;
break;
}
+
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN10)
+   sdevice-no_write_same = 0;
}
 
return 0;
-- 
1.7.4.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 RESEND V2 4/7] scsi: storvsc: use correct defaults for values determined by protocol negotiation

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use correct defaults for values determined by protocol negotiation,
instead of resetting them with every scsi controller.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   33 +++--
 1 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f29871e..6f38cdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -151,19 +151,17 @@ struct hv_fc_wwn_packet {
 
 /*
  * Sense buffer size changed in win8; have a run-time
- * variable to track the size we should use.
+ * variable to track the size we should use.  This value will
+ * likely change during protocol negotiation but it is valid
+ * to start by assuming pre-Win8.
  */
-static int sense_buffer_size;
+static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
 
 /*
- * The size of the vmscsi_request has changed in win8. The
- * additional size is because of new elements added to the
- * structure. These elements are valid only when we are talking
- * to a win8 host.
- * Track the correction to size we need to apply.
- */
-
-static int vmscsi_size_delta;
+ * The storage protocol version is determined during the
+ * initial exchange with the host.  It will indicate which
+ * storage functionality is available in the host.
+*/
 static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
@@ -209,6 +207,17 @@ struct vmscsi_request {
 
 
 /*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is because of new elements added to the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correction to size we need to apply. This value
+ * will likely change during protocol negotiation but it is
+ * valid to start by assuming pre-Win8.
+ */
+static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
+
+/*
  * The list of storage protocols in order of preference.
  */
 struct vmstor_protocol {
@@ -1810,14 +1819,10 @@ static int storvsc_probe(struct hv_device *device,
 */
 
if (vmbus_proto_version  VERSION_WIN8) {
-   sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
-   sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = 0;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 RESEND V2 2/7] scsi: storvsc: Use a single value to track protocol versions

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use a single value to track protocol versions to simplify
comparisons and to be consistent with vmbus version tracking.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   35 +--
 1 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 582f3b5..5f9d133 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -58,12 +58,11 @@
  * Win8: 5.1
  */
 
+#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)   MAJOR_)  0xff)  8) | \
+   (((MINOR_)  0xff)))
 
-#define VMSTOR_WIN7_MAJOR 4
-#define VMSTOR_WIN7_MINOR 2
-
-#define VMSTOR_WIN8_MAJOR 5
-#define VMSTOR_WIN8_MINOR 1
+#define VMSTOR_PROTO_VERSION_WIN7  VMSTOR_PROTO_VERSION(4, 2)
+#define VMSTOR_PROTO_VERSION_WIN8  VMSTOR_PROTO_VERSION(5, 1)
 
 
 /*  Packet structure describing virtual storage requests. */
@@ -161,8 +160,7 @@ static int sense_buffer_size;
  */
 
 static int vmscsi_size_delta;
-static int vmstor_current_major;
-static int vmstor_current_minor;
+static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
/*
@@ -481,18 +479,6 @@ done:
kfree(wrk);
 }
 
-/*
- * Major/minor macros.  Minor version is in LSB, meaning that earlier flat
- * version numbers will be interpreted as 0.x (i.e., 1 becomes 0.1).
- */
-
-static inline u16 storvsc_get_version(u8 major, u8 minor)
-{
-   u16 version;
-
-   version = ((major  8) | minor);
-   return version;
-}
 
 /*
  * We can get incoming messages from the host that are not in response to
@@ -930,8 +916,7 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet-operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
vstor_packet-flags = REQUEST_COMPLETION_FLAG;
 
-   vstor_packet-version.major_minor =
-   storvsc_get_version(vmstor_current_major, vmstor_current_minor);
+   vstor_packet-version.major_minor = vmstor_proto_version;
 
/*
 * The revision number is only used in Windows; set it to 0.
@@ -1562,7 +1547,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
u32 payload_sz;
u32 length;
 
-   if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
/*
 * On legacy hosts filter unimplemented commands.
 * Future hosts are expected to correctly handle
@@ -1760,16 +1745,14 @@ static int storvsc_probe(struct hv_device *device,
if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
-   vmstor_current_major = VMSTOR_WIN7_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN7_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN7;
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
-   vmstor_current_major = VMSTOR_WIN8_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN8_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 RESEND V2 0/7] scsi: storvsc: Some miscellaneous cleanup

2015-08-13 Thread K. Y. Srinivasan
Cleanup version handling as well as base feature detection on storage
version as opposed to host version.

In this version, I have addressed comments from Dan Carpenter.

K. Y. Srinivasan (1):
  scsi: storvsc: Set the error code correctly in failure conditions

Keith Mange (6):
  scsi: storvsc: Rather than look for sets of specific protocol
versions, make decisions based on ranges.
  scsi: storvsc: Use a single value to track protocol versions
  scsi: storvsc: Untangle the storage protocol negotiation from the
vmbus protocol negotiation.
  scsi: storvsc: use correct defaults for values determined by protocol
negotiation
  scsi: storvsc: use storage protocol version to determine storage
capabilities
  scsi: storvsc: Allow write_same when host is windows 10

 drivers/scsi/storvsc_drv.c |  206 
 1 files changed, 132 insertions(+), 74 deletions(-)

-- 
1.7.4.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 RESEND V2 3/7] scsi: storvsc: Untangle the storage protocol negotiation from the vmbus protocol negotiation.

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Currently we are making decisions based on vmbus protocol versions
that have been negotiated; use storage potocol versions instead.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |  109 +++-
 1 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5f9d133..f29871e 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -56,14 +56,18 @@
  * V1 RC  2008/1/31:  2.0
  * Win7: 4.2
  * Win8: 5.1
+ * Win8.1: 6.0
+ * Win10: 6.2
  */
 
 #define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)   MAJOR_)  0xff)  8) | \
(((MINOR_)  0xff)))
 
+#define VMSTOR_PROTO_VERSION_WIN6  VMSTOR_PROTO_VERSION(2, 0)
 #define VMSTOR_PROTO_VERSION_WIN7  VMSTOR_PROTO_VERSION(4, 2)
 #define VMSTOR_PROTO_VERSION_WIN8  VMSTOR_PROTO_VERSION(5, 1)
-
+#define VMSTOR_PROTO_VERSION_WIN8_1VMSTOR_PROTO_VERSION(6, 0)
+#define VMSTOR_PROTO_VERSION_WIN10 VMSTOR_PROTO_VERSION(6, 2)
 
 /*  Packet structure describing virtual storage requests. */
 enum vstor_packet_operation {
@@ -205,6 +209,46 @@ struct vmscsi_request {
 
 
 /*
+ * The list of storage protocols in order of preference.
+ */
+struct vmstor_protocol {
+   int protocol_version;
+   int sense_buffer_size;
+   int vmscsi_size_delta;
+};
+
+#define VMSTOR_NUM_PROTOCOLS5
+
+const struct vmstor_protocol vmstor_protocols[VMSTOR_NUM_PROTOCOLS] = {
+   {
+   VMSTOR_PROTO_VERSION_WIN10,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN8_1,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN8,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN7,
+   PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
+   sizeof(struct vmscsi_win8_extension),
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN6,
+   PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
+   sizeof(struct vmscsi_win8_extension),
+   }
+};
+
+
+/*
  * This structure is sent during the intialization phase to get the different
  * properties of the channel.
  */
@@ -871,7 +915,7 @@ static int storvsc_channel_init(struct hv_device *device)
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t;
+   int ret, t, i;
int max_chns;
bool process_sub_channels = false;
 
@@ -911,36 +955,59 @@ static int storvsc_channel_init(struct hv_device *device)
goto cleanup;
 
 
-   /* reuse the packet for version range supported */
-   memset(vstor_packet, 0, sizeof(struct vstor_packet));
-   vstor_packet-operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet-flags = REQUEST_COMPLETION_FLAG;
+   for (i = 0; i  VMSTOR_NUM_PROTOCOLS; i++) {
+   /* reuse the packet for version range supported */
+   memset(vstor_packet, 0, sizeof(struct vstor_packet));
+   vstor_packet-operation =
+   VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
+   vstor_packet-flags = REQUEST_COMPLETION_FLAG;
 
-   vstor_packet-version.major_minor = vmstor_proto_version;
+   vstor_packet-version.major_minor =
+   vmstor_protocols[i].protocol_version;
 
-   /*
-* The revision number is only used in Windows; set it to 0.
-*/
-   vstor_packet-version.revision = 0;
+   /*
+* The revision number is only used in Windows; set it to 0.
+*/
+   vstor_packet-version.revision = 0;
 
-   ret = vmbus_sendpacket(device-channel, vstor_packet,
+   ret = vmbus_sendpacket(device-channel, vstor_packet,
   (sizeof(struct vstor_packet) -
vmscsi_size_delta),
   (unsigned long)request,
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-   if (ret != 0)
-   goto cleanup;
+   if (ret != 0)
+   goto cleanup;
 
-   t = wait_for_completion_timeout(request-wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
+   t = wait_for_completion_timeout(request-wait_event, 5*HZ);
+   if (t == 0) {
+   ret = -ETIMEDOUT;
+   goto cleanup

[PATCH RESEND V2 5/7] scsi: storvsc: use storage protocol version to determine storage capabilities

2015-08-13 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use storage protocol version instead of vmbus protocol
version when determining storage capabilities.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6f38cdf..58fa47a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1049,7 +1049,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if (vmbus_proto_version = VERSION_WIN8) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1491,9 +1491,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 * if the device is a MSFT virtual device.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
-   switch (vmbus_proto_version) {
-   case VERSION_WIN8:
-   case VERSION_WIN8_1:
+   switch (vmstor_proto_version) {
+   case VMSTOR_PROTO_VERSION_WIN8:
+   case VMSTOR_PROTO_VERSION_WIN8_1:
sdevice-scsi_level = SCSI_SPC_3;
break;
}
-- 
1.7.4.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 1/1] Drivers: hv: vmbus: fix init_vp_index() for reloading hv_netvsc

2015-08-13 Thread K. Y. Srinivasan
From: Dexuan Cui de...@microsoft.com

This fixes the recent commit 3b71107d73b16074afa7658f3f0fcf837aabfe24:
Drivers: hv: vmbus: Further improve CPU affiliation logic

Without the fix, reloading hv_netvsc hangs the guest.

Signed-off-by: Dexuan Cui de...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/hv/channel_mgmt.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 3ab4753..8a4105c 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -204,6 +204,8 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel, u32 relid)
spin_lock_irqsave(vmbus_connection.channel_lock, flags);
list_del(channel-listentry);
spin_unlock_irqrestore(vmbus_connection.channel_lock, flags);
+
+   primary_channel = channel;
} else {
primary_channel = channel-primary_channel;
spin_lock_irqsave(primary_channel-lock, flags);
@@ -211,6 +213,14 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel, u32 relid)
primary_channel-num_sc--;
spin_unlock_irqrestore(primary_channel-lock, flags);
}
+
+   /*
+* We need to free the bit for init_vp_index() to work in the case
+* of sub-channel, when we reload drivers like hv_netvsc.
+*/
+   cpumask_clear_cpu(channel-target_cpu,
+ primary_channel-alloced_cpus_in_node);
+
free_channel(channel);
 }
 
@@ -457,6 +467,13 @@ static void init_vp_index(struct vmbus_channel *channel, 
const uuid_le *type_gui
continue;
}
 
+   /*
+* NOTE: in the case of sub-channel, we clear the sub-channel
+* related bit(s) in primary-alloced_cpus_in_node in
+* hv_process_channel_removal(), so when we reload drivers
+* like hv_netvsc in SMP guest, here we're able to re-allocate
+* bit from primary-alloced_cpus_in_node.
+*/
if (!cpumask_test_cpu(cur_cpu,
primary-alloced_cpus_in_node)) {
cpumask_set_cpu(cur_cpu,
-- 
1.7.4.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 0/7] scsi: storvsc: Some miscellaneous cleanup

2015-06-03 Thread K. Y. Srinivasan
Cleanup version handling as well as base feature detection on storage
version as opposed to host version.

In this version, I have addressed comments from Dan Carpenter.

K. Y. Srinivasan (1):
  scsi: storvsc: Set the error code correctly in failure conditions

Keith Mange (6):
  scsi: storvsc: Rather than look for sets of specific protocol
versions, make decisions based on ranges.
  scsi: storvsc: Use a single value to track protocol versions
  scsi: storvsc: Untangle the storage protocol negotiation from the
vmbus protocol negotiation.
  scsi: storvsc: use correct defaults for values determined by protocol
negotiation
  scsi: storvsc: use storage protocol version to determine storage
capabilities
  scsi: storvsc: Allow write_same when host is windows 10

 drivers/scsi/storvsc_drv.c |  206 
 1 files changed, 132 insertions(+), 74 deletions(-)

-- 
1.7.4.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 1/7] scsi: storvsc: Rather than look for sets of specific protocol versions, make decisions based on ranges.

2015-06-03 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Rather than look for sets of specific protocol versions,
make decisions based on ranges. This will be safer and require fewer changes
going forward as we add more storage protocol versions.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   11 +++
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3c6584f..582f3b5 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -988,8 +988,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if ((vmbus_proto_version != VERSION_WIN7) 
-  (vmbus_proto_version != VERSION_WS2008))  {
+   if (vmbus_proto_version = VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1758,9 +1757,7 @@ static int storvsc_probe(struct hv_device *device,
 * set state to properly communicate with the host.
 */
 
-   switch (vmbus_proto_version) {
-   case VERSION_WS2008:
-   case VERSION_WIN7:
+   if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
vmstor_current_major = VMSTOR_WIN7_MAJOR;
@@ -1768,8 +1765,7 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
-   break;
-   default:
+   } else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
vmstor_current_major = VMSTOR_WIN8_MAJOR;
@@ -1783,7 +1779,6 @@ static int storvsc_probe(struct hv_device *device,
 * VCPUs in the guest.
 */
max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
-   break;
}
 
scsi_driver.can_queue = (max_outstanding_req_per_channel *
-- 
1.7.4.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 5/7] scsi: storvsc: use storage protocol version to determine storage capabilities

2015-06-03 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use storage protocol version instead of vmbus protocol
version when determining storage capabilities.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6f38cdf..58fa47a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1049,7 +1049,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if (vmbus_proto_version = VERSION_WIN8) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1491,9 +1491,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 * if the device is a MSFT virtual device.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
-   switch (vmbus_proto_version) {
-   case VERSION_WIN8:
-   case VERSION_WIN8_1:
+   switch (vmstor_proto_version) {
+   case VMSTOR_PROTO_VERSION_WIN8:
+   case VMSTOR_PROTO_VERSION_WIN8_1:
sdevice-scsi_level = SCSI_SPC_3;
break;
}
-- 
1.7.4.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 4/7] scsi: storvsc: use correct defaults for values determined by protocol negotiation

2015-06-03 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use correct defaults for values determined by protocol negotiation,
instead of resetting them with every scsi controller.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   33 +++--
 1 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f29871e..6f38cdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -151,19 +151,17 @@ struct hv_fc_wwn_packet {
 
 /*
  * Sense buffer size changed in win8; have a run-time
- * variable to track the size we should use.
+ * variable to track the size we should use.  This value will
+ * likely change during protocol negotiation but it is valid
+ * to start by assuming pre-Win8.
  */
-static int sense_buffer_size;
+static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
 
 /*
- * The size of the vmscsi_request has changed in win8. The
- * additional size is because of new elements added to the
- * structure. These elements are valid only when we are talking
- * to a win8 host.
- * Track the correction to size we need to apply.
- */
-
-static int vmscsi_size_delta;
+ * The storage protocol version is determined during the
+ * initial exchange with the host.  It will indicate which
+ * storage functionality is available in the host.
+*/
 static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
@@ -209,6 +207,17 @@ struct vmscsi_request {
 
 
 /*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is because of new elements added to the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correction to size we need to apply. This value
+ * will likely change during protocol negotiation but it is
+ * valid to start by assuming pre-Win8.
+ */
+static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
+
+/*
  * The list of storage protocols in order of preference.
  */
 struct vmstor_protocol {
@@ -1810,14 +1819,10 @@ static int storvsc_probe(struct hv_device *device,
 */
 
if (vmbus_proto_version  VERSION_WIN8) {
-   sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
-   sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = 0;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 2/7] scsi: storvsc: Use a single value to track protocol versions

2015-06-03 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Use a single value to track protocol versions to simplify
comparisons and to be consistent with vmbus version tracking.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   35 +--
 1 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 582f3b5..5f9d133 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -58,12 +58,11 @@
  * Win8: 5.1
  */
 
+#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)   MAJOR_)  0xff)  8) | \
+   (((MINOR_)  0xff)))
 
-#define VMSTOR_WIN7_MAJOR 4
-#define VMSTOR_WIN7_MINOR 2
-
-#define VMSTOR_WIN8_MAJOR 5
-#define VMSTOR_WIN8_MINOR 1
+#define VMSTOR_PROTO_VERSION_WIN7  VMSTOR_PROTO_VERSION(4, 2)
+#define VMSTOR_PROTO_VERSION_WIN8  VMSTOR_PROTO_VERSION(5, 1)
 
 
 /*  Packet structure describing virtual storage requests. */
@@ -161,8 +160,7 @@ static int sense_buffer_size;
  */
 
 static int vmscsi_size_delta;
-static int vmstor_current_major;
-static int vmstor_current_minor;
+static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
/*
@@ -481,18 +479,6 @@ done:
kfree(wrk);
 }
 
-/*
- * Major/minor macros.  Minor version is in LSB, meaning that earlier flat
- * version numbers will be interpreted as 0.x (i.e., 1 becomes 0.1).
- */
-
-static inline u16 storvsc_get_version(u8 major, u8 minor)
-{
-   u16 version;
-
-   version = ((major  8) | minor);
-   return version;
-}
 
 /*
  * We can get incoming messages from the host that are not in response to
@@ -930,8 +916,7 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet-operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
vstor_packet-flags = REQUEST_COMPLETION_FLAG;
 
-   vstor_packet-version.major_minor =
-   storvsc_get_version(vmstor_current_major, vmstor_current_minor);
+   vstor_packet-version.major_minor = vmstor_proto_version;
 
/*
 * The revision number is only used in Windows; set it to 0.
@@ -1562,7 +1547,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
u32 payload_sz;
u32 length;
 
-   if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
/*
 * On legacy hosts filter unimplemented commands.
 * Future hosts are expected to correctly handle
@@ -1760,16 +1745,14 @@ static int storvsc_probe(struct hv_device *device,
if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
-   vmstor_current_major = VMSTOR_WIN7_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN7_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN7;
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
-   vmstor_current_major = VMSTOR_WIN8_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN8_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 6/7] scsi: storvsc: Allow write_same when host is windows 10

2015-06-03 Thread K. Y. Srinivasan
From: Keith Mange keith.ma...@microsoft.com

Allow WRITE_SAME for Windows10 and above hosts.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 58fa47a..021cbdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1488,7 +1488,8 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 
/*
 * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
-* if the device is a MSFT virtual device.
+* if the device is a MSFT virtual device.  If the host is
+* WIN10 or newer, allow write_same.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
switch (vmstor_proto_version) {
@@ -1497,6 +1498,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
sdevice-scsi_level = SCSI_SPC_3;
break;
}
+
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN10)
+   sdevice-no_write_same = 0;
}
 
return 0;
-- 
1.7.4.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 7/7] scsi: storvsc: Set the error code correctly in failure conditions

2015-06-03 Thread K. Y. Srinivasan
In the function storvsc_channel_init(), error code was not getting
set correctly in some of the failure cases. Fix this issue.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reported-by: Dan Carpenter dan.carpen...@oracle.com
---
 drivers/scsi/storvsc_drv.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 021cbdf..aac8297 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -960,8 +960,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
 
for (i = 0; i  VMSTOR_NUM_PROTOCOLS; i++) {
@@ -1040,8 +1042,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
/*
 * Check to see if multi-channel support is there.
@@ -1078,8 +1082,10 @@ static int storvsc_channel_init(struct hv_device *device)
}
 
if (vstor_packet-operation != VSTOR_OPERATION_COMPLETE_IO ||
-   vstor_packet-status != 0)
+   vstor_packet-status != 0) {
+   ret = -EINVAL;
goto cleanup;
+   }
 
if (process_sub_channels)
handle_multichannel_storage(device, max_chns);
-- 
1.7.4.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 2/6] scsi: storvsc: Use a single value to track protocol versions

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Use a single value to track protocol versions to simplify
comparisons and to be consistent with vmbus version tracking.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   35 +--
 1 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 582f3b5..5f9d133 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -58,12 +58,11 @@
  * Win8: 5.1
  */
 
+#define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)   MAJOR_)  0xff)  8) | \
+   (((MINOR_)  0xff)))
 
-#define VMSTOR_WIN7_MAJOR 4
-#define VMSTOR_WIN7_MINOR 2
-
-#define VMSTOR_WIN8_MAJOR 5
-#define VMSTOR_WIN8_MINOR 1
+#define VMSTOR_PROTO_VERSION_WIN7  VMSTOR_PROTO_VERSION(4, 2)
+#define VMSTOR_PROTO_VERSION_WIN8  VMSTOR_PROTO_VERSION(5, 1)
 
 
 /*  Packet structure describing virtual storage requests. */
@@ -161,8 +160,7 @@ static int sense_buffer_size;
  */
 
 static int vmscsi_size_delta;
-static int vmstor_current_major;
-static int vmstor_current_minor;
+static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
/*
@@ -481,18 +479,6 @@ done:
kfree(wrk);
 }
 
-/*
- * Major/minor macros.  Minor version is in LSB, meaning that earlier flat
- * version numbers will be interpreted as 0.x (i.e., 1 becomes 0.1).
- */
-
-static inline u16 storvsc_get_version(u8 major, u8 minor)
-{
-   u16 version;
-
-   version = ((major  8) | minor);
-   return version;
-}
 
 /*
  * We can get incoming messages from the host that are not in response to
@@ -930,8 +916,7 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet-operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
vstor_packet-flags = REQUEST_COMPLETION_FLAG;
 
-   vstor_packet-version.major_minor =
-   storvsc_get_version(vmstor_current_major, vmstor_current_minor);
+   vstor_packet-version.major_minor = vmstor_proto_version;
 
/*
 * The revision number is only used in Windows; set it to 0.
@@ -1562,7 +1547,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
u32 payload_sz;
u32 length;
 
-   if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
/*
 * On legacy hosts filter unimplemented commands.
 * Future hosts are expected to correctly handle
@@ -1760,16 +1745,14 @@ static int storvsc_probe(struct hv_device *device,
if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
-   vmstor_current_major = VMSTOR_WIN7_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN7_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN7;
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
-   vmstor_current_major = VMSTOR_WIN8_MAJOR;
-   vmstor_current_minor = VMSTOR_WIN8_MINOR;
+   vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 4/6] scsi: storvsc: use correct defaults for values determined by protocol negotiation

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Use correct defaults for values determined by protocol negotiation,
instead of resetting them with every scsi controller.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   33 +++--
 1 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f29871e..6f38cdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -151,19 +151,17 @@ struct hv_fc_wwn_packet {
 
 /*
  * Sense buffer size changed in win8; have a run-time
- * variable to track the size we should use.
+ * variable to track the size we should use.  This value will
+ * likely change during protocol negotiation but it is valid
+ * to start by assuming pre-Win8.
  */
-static int sense_buffer_size;
+static int sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
 
 /*
- * The size of the vmscsi_request has changed in win8. The
- * additional size is because of new elements added to the
- * structure. These elements are valid only when we are talking
- * to a win8 host.
- * Track the correction to size we need to apply.
- */
-
-static int vmscsi_size_delta;
+ * The storage protocol version is determined during the
+ * initial exchange with the host.  It will indicate which
+ * storage functionality is available in the host.
+*/
 static int vmstor_proto_version;
 
 struct vmscsi_win8_extension {
@@ -209,6 +207,17 @@ struct vmscsi_request {
 
 
 /*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is because of new elements added to the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correction to size we need to apply. This value
+ * will likely change during protocol negotiation but it is
+ * valid to start by assuming pre-Win8.
+ */
+static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
+
+/*
  * The list of storage protocols in order of preference.
  */
 struct vmstor_protocol {
@@ -1810,14 +1819,10 @@ static int storvsc_probe(struct hv_device *device,
 */
 
if (vmbus_proto_version  VERSION_WIN8) {
-   sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
} else {
-   sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
-   vmscsi_size_delta = 0;
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
-- 
1.7.4.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 5/6] scsi: storvsc: use storage protocol version to determine storage capabilities

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Use storage protocol version instead of vmbus protocol
version when determining storage capabilities.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6f38cdf..58fa47a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1049,7 +1049,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if (vmbus_proto_version = VERSION_WIN8) {
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1491,9 +1491,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 * if the device is a MSFT virtual device.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
-   switch (vmbus_proto_version) {
-   case VERSION_WIN8:
-   case VERSION_WIN8_1:
+   switch (vmstor_proto_version) {
+   case VMSTOR_PROTO_VERSION_WIN8:
+   case VMSTOR_PROTO_VERSION_WIN8_1:
sdevice-scsi_level = SCSI_SPC_3;
break;
}
-- 
1.7.4.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 3/6] hv:scsi:Untangle the storage protocol negotiation from the vmbus protocol negotiation.

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Currently we are making decisions based on vmbus protocol versions
that have been negotiated; use storage potocol versions instead.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |  109 +++-
 1 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5f9d133..f29871e 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -56,14 +56,18 @@
  * V1 RC  2008/1/31:  2.0
  * Win7: 4.2
  * Win8: 5.1
+ * Win8.1: 6.0
+ * Win10: 6.2
  */
 
 #define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)   MAJOR_)  0xff)  8) | \
(((MINOR_)  0xff)))
 
+#define VMSTOR_PROTO_VERSION_WIN6  VMSTOR_PROTO_VERSION(2, 0)
 #define VMSTOR_PROTO_VERSION_WIN7  VMSTOR_PROTO_VERSION(4, 2)
 #define VMSTOR_PROTO_VERSION_WIN8  VMSTOR_PROTO_VERSION(5, 1)
-
+#define VMSTOR_PROTO_VERSION_WIN8_1VMSTOR_PROTO_VERSION(6, 0)
+#define VMSTOR_PROTO_VERSION_WIN10 VMSTOR_PROTO_VERSION(6, 2)
 
 /*  Packet structure describing virtual storage requests. */
 enum vstor_packet_operation {
@@ -205,6 +209,46 @@ struct vmscsi_request {
 
 
 /*
+ * The list of storage protocols in order of preference.
+ */
+struct vmstor_protocol {
+   int protocol_version;
+   int sense_buffer_size;
+   int vmscsi_size_delta;
+};
+
+#define VMSTOR_NUM_PROTOCOLS5
+
+const struct vmstor_protocol vmstor_protocols[VMSTOR_NUM_PROTOCOLS] = {
+   {
+   VMSTOR_PROTO_VERSION_WIN10,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN8_1,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN8,
+   POST_WIN7_STORVSC_SENSE_BUFFER_SIZE,
+   0
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN7,
+   PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
+   sizeof(struct vmscsi_win8_extension),
+   },
+   {
+   VMSTOR_PROTO_VERSION_WIN6,
+   PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE,
+   sizeof(struct vmscsi_win8_extension),
+   }
+};
+
+
+/*
  * This structure is sent during the intialization phase to get the different
  * properties of the channel.
  */
@@ -871,7 +915,7 @@ static int storvsc_channel_init(struct hv_device *device)
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
-   int ret, t;
+   int ret, t, i;
int max_chns;
bool process_sub_channels = false;
 
@@ -911,36 +955,59 @@ static int storvsc_channel_init(struct hv_device *device)
goto cleanup;
 
 
-   /* reuse the packet for version range supported */
-   memset(vstor_packet, 0, sizeof(struct vstor_packet));
-   vstor_packet-operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-   vstor_packet-flags = REQUEST_COMPLETION_FLAG;
+   for (i = 0; i  VMSTOR_NUM_PROTOCOLS; i++) {
+   /* reuse the packet for version range supported */
+   memset(vstor_packet, 0, sizeof(struct vstor_packet));
+   vstor_packet-operation =
+   VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
+   vstor_packet-flags = REQUEST_COMPLETION_FLAG;
 
-   vstor_packet-version.major_minor = vmstor_proto_version;
+   vstor_packet-version.major_minor =
+   vmstor_protocols[i].protocol_version;
 
-   /*
-* The revision number is only used in Windows; set it to 0.
-*/
-   vstor_packet-version.revision = 0;
+   /*
+* The revision number is only used in Windows; set it to 0.
+*/
+   vstor_packet-version.revision = 0;
 
-   ret = vmbus_sendpacket(device-channel, vstor_packet,
+   ret = vmbus_sendpacket(device-channel, vstor_packet,
   (sizeof(struct vstor_packet) -
vmscsi_size_delta),
   (unsigned long)request,
   VM_PKT_DATA_INBAND,
   VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-   if (ret != 0)
-   goto cleanup;
+   if (ret != 0)
+   goto cleanup;
 
-   t = wait_for_completion_timeout(request-wait_event, 5*HZ);
-   if (t == 0) {
-   ret = -ETIMEDOUT;
-   goto cleanup;
+   t = wait_for_completion_timeout(request-wait_event, 5*HZ);
+   if (t == 0) {
+   ret = -ETIMEDOUT;
+   goto cleanup

[PATCH 1/6] scsi: storvsc: Rather than look for sets of specific protocol versions, make decisions based on ranges.

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Rather than look for sets of specific protocol versions,
make decisions based on ranges. This will be safer and require fewer changes
going forward as we add more storage protocol versions.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   11 +++
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3c6584f..582f3b5 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -988,8 +988,7 @@ static int storvsc_channel_init(struct hv_device *device)
 * support multi-channel.
 */
max_chns = vstor_packet-storage_channel_properties.max_channel_cnt;
-   if ((vmbus_proto_version != VERSION_WIN7) 
-  (vmbus_proto_version != VERSION_WS2008))  {
+   if (vmbus_proto_version = VERSION_WIN8) {
if (vstor_packet-storage_channel_properties.flags 
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
@@ -1758,9 +1757,7 @@ static int storvsc_probe(struct hv_device *device,
 * set state to properly communicate with the host.
 */
 
-   switch (vmbus_proto_version) {
-   case VERSION_WS2008:
-   case VERSION_WIN7:
+   if (vmbus_proto_version  VERSION_WIN8) {
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
vmstor_current_major = VMSTOR_WIN7_MAJOR;
@@ -1768,8 +1765,7 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_IDE_MAX_TARGETS;
max_channels = STORVSC_IDE_MAX_CHANNELS;
-   break;
-   default:
+   } else {
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
vmstor_current_major = VMSTOR_WIN8_MAJOR;
@@ -1783,7 +1779,6 @@ static int storvsc_probe(struct hv_device *device,
 * VCPUs in the guest.
 */
max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
-   break;
}
 
scsi_driver.can_queue = (max_outstanding_req_per_channel *
-- 
1.7.4.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 0/6] scsi: storvsc: Some miscellaneous cleanup

2015-05-29 Thread K. Y. Srinivasan
Cleanup version handling as well as base feature detection on storage
version as opposed to host version.

keith.ma...@microsoft.com (6):
  scsi: storvsc: Rather than look for sets of specific protocol
versions, make decisions based on ranges.
  scsi: storvsc: Use a single value to track protocol versions
  hv:scsi:Untangle the storage protocol negotiation from the vmbus
protocol negotiation.
  scsi: storvsc: use correct defaults for values determined by protocol
negotiation
  scsi: storvsc: use storage protocol version to determine storage
capabilities
  scsi: storvsc: Allow write_same when host is windows 10

 drivers/scsi/storvsc_drv.c |  194 
 1 files changed, 123 insertions(+), 71 deletions(-)

-- 
1.7.4.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 6/6] scsi: storvsc: Allow write_same when host is windows 10

2015-05-29 Thread K. Y. Srinivasan
From: keith.ma...@microsoft.com keith.ma...@microsoft.com

Allow WRITE_SAME for Windows10 and above hosts.

Tested-by: Alex Ng ale...@microsoft.com
Signed-off-by: Keith Mange keith.ma...@microsoft.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 58fa47a..021cbdf 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1488,7 +1488,8 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 
/*
 * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
-* if the device is a MSFT virtual device.
+* if the device is a MSFT virtual device.  If the host is
+* WIN10 or newer, allow write_same.
 */
if (!strncmp(sdevice-vendor, Msft, 4)) {
switch (vmstor_proto_version) {
@@ -1497,6 +1498,9 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
sdevice-scsi_level = SCSI_SPC_3;
break;
}
+
+   if (vmstor_proto_version = VMSTOR_PROTO_VERSION_WIN10)
+   sdevice-no_write_same = 0;
}
 
return 0;
-- 
1.7.4.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 1/1] scsi: storvsc: Set the SRB flags correctly when no data transfer is needed

2015-04-24 Thread K. Y. Srinivasan
Set the SRB flags correctly when there is no data transfer.

Cc: sta...@vger.kernel.org
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index d9dad90..3c6584f 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1600,8 +1600,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
break;
default:
vm_srb-data_in = UNKNOWN_TYPE;
-   vm_srb-win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN |
-SRB_FLAGS_DATA_OUT);
+   vm_srb-win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER;
break;
}
 
-- 
1.7.4.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 1/1] scsi: storvsc: Set the SRB flags correctly when no data transfer is needed

2015-04-24 Thread K. Y. Srinivasan
Set the SRB flags correctly when there is no data transfer.

Cc: sta...@vger.kernel.org
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index d9dad90..3c6584f 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1600,8 +1600,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
break;
default:
vm_srb-data_in = UNKNOWN_TYPE;
-   vm_srb-win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN |
-SRB_FLAGS_DATA_OUT);
+   vm_srb-win8_extension.srb_flags |= SRB_FLAGS_NO_DATA_TRANSFER;
break;
}
 
-- 
1.7.4.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 1/7] scsi: storvsc: Increase the ring buffer size

2015-03-27 Thread K. Y. Srinivasan
Increase the default ring buffer size as this can significantly
improve performance especially on high latency storage back-ends.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..27fe850 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -308,7 +308,7 @@ enum storvsc_request_type {
  * This is the end of Protocol specific defines.
  */
 
-static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
-- 
1.7.4.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 6/7] scsi: storvsc: Don't assume that the scatterlist is not chained

2015-03-27 Thread K. Y. Srinivasan
The current code assumes that the scatterlists presented are not chained.
Fix the code to not make this assumption.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
V2: Got rid of double assignment. Olaf Hering o...@aepfle.de
 drivers/scsi/storvsc_drv.c |   99 +--
 1 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f8e4dd9..4156e29 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -626,19 +626,6 @@ cleanup:
return NULL;
 }
 
-/* Disgusting wrapper functions */
-static inline unsigned long sg_kmap_atomic(struct scatterlist *sgl, int idx)
-{
-   void *addr = kmap_atomic(sg_page(sgl + idx));
-   return (unsigned long)addr;
-}
-
-static inline void sg_kunmap_atomic(unsigned long addr)
-{
-   kunmap_atomic((void *)addr);
-}
-
-
 /* Assume the original sgl has enough room */
 static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
struct scatterlist *bounce_sgl,
@@ -653,32 +640,38 @@ static unsigned int copy_from_bounce_buffer(struct 
scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long dest_addr = 0;
unsigned long flags;
+   struct scatterlist *cur_dest_sgl;
+   struct scatterlist *cur_src_sgl;
 
local_irq_save(flags);
-
+   cur_dest_sgl = orig_sgl;
+   cur_src_sgl = bounce_sgl;
for (i = 0; i  orig_sgl_count; i++) {
-   dest_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+   dest_addr = (unsigned long)
+   kmap_atomic(sg_page(cur_dest_sgl)) +
+   cur_dest_sgl-offset;
dest = dest_addr;
-   destlen = orig_sgl[i].length;
+   destlen = cur_dest_sgl-length;
 
if (bounce_addr == 0)
-   bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+   bounce_addr = (unsigned long)kmap_atomic(
+   sg_page(cur_src_sgl));
 
while (destlen) {
-   src = bounce_addr + bounce_sgl[j].offset;
-   srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+   src = bounce_addr + cur_src_sgl-offset;
+   srclen = cur_src_sgl-length - cur_src_sgl-offset;
 
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
 
total_copied += copylen;
-   bounce_sgl[j].offset += copylen;
+   cur_src_sgl-offset += copylen;
destlen -= copylen;
dest += copylen;
 
-   if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+   if (cur_src_sgl-offset == cur_src_sgl-length) {
/* full */
-   sg_kunmap_atomic(bounce_addr);
+   kunmap_atomic((void *)bounce_addr);
j++;
 
/*
@@ -692,21 +685,27 @@ static unsigned int copy_from_bounce_buffer(struct 
scatterlist *orig_sgl,
/*
 * We are done; cleanup and return.
 */
-   sg_kunmap_atomic(dest_addr - 
orig_sgl[i].offset);
+   kunmap_atomic((void *)(dest_addr -
+   cur_dest_sgl-offset));
local_irq_restore(flags);
return total_copied;
}
 
/* if we need to use another bounce buffer */
-   if (destlen || i != orig_sgl_count - 1)
-   bounce_addr = 
sg_kmap_atomic(bounce_sgl,j);
+   if (destlen || i != orig_sgl_count - 1) {
+   cur_src_sgl = sg_next(cur_src_sgl);
+   bounce_addr = (unsigned long)
+   kmap_atomic(
+   sg_page(cur_src_sgl));
+   }
} else if (destlen == 0  i == orig_sgl_count - 1) {
/* unmap the last bounce that is  PAGE_SIZE */
-   sg_kunmap_atomic(bounce_addr);
+   kunmap_atomic((void *)bounce_addr);
}
}
 
-   sg_kunmap_atomic(dest_addr - orig_sgl[i].offset

[PATCH V2 3/7] scsi: storvsc: Always send on the selected outgoing channel

2015-03-27 Thread K. Y. Srinivasan
The current code always sent packets without data on the primary channel.
Properly distribute sending of packets with no data amongst all available
channels. I would like to thank Long Li for noticing this problem.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 7f569f9..0ba7f2c 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1362,7 +1362,7 @@ static int storvsc_do_io(struct hv_device *device,
vmscsi_size_delta),
(unsigned long)request);
} else {
-   ret = vmbus_sendpacket(device-channel, vstor_packet,
+   ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
   (sizeof(struct vstor_packet) -
vmscsi_size_delta),
   (unsigned long)request,
-- 
1.7.4.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 5/7] scsi: storvsc: Fix a bug in copy_from_bounce_buffer()

2015-03-27 Thread K. Y. Srinivasan
We may exit this function without properly freeing up the maapings
we may have acquired. Fix the bug.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |   15 ---
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index cdf048b..f8e4dd9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -754,21 +754,22 @@ static unsigned int copy_to_bounce_buffer(struct 
scatterlist *orig_sgl,
if (bounce_sgl[j].length == PAGE_SIZE) {
/* full..move to next entry */
sg_kunmap_atomic(bounce_addr);
+   bounce_addr = 0;
j++;
+   }
 
-   /* if we need to use another bounce buffer */
-   if (srclen || i != orig_sgl_count - 1)
-   bounce_addr = 
sg_kmap_atomic(bounce_sgl,j);
+   /* if we need to use another bounce buffer */
+   if (srclen  bounce_addr == 0)
+   bounce_addr = sg_kmap_atomic(bounce_sgl, j);
 
-   } else if (srclen == 0  i == orig_sgl_count - 1) {
-   /* unmap the last bounce that is  PAGE_SIZE */
-   sg_kunmap_atomic(bounce_addr);
-   }
}
 
sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
}
 
+   if (bounce_addr)
+   sg_kunmap_atomic(bounce_addr);
+
local_irq_restore(flags);
 
return total_copied;
-- 
1.7.4.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 7/7] scsi: storvsc: Set the tablesize based on the information given by the host

2015-03-27 Thread K. Y. Srinivasan
Set the tablesize based on the information given by the host.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
Tested-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   89 +++
 1 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 4156e29..d9dad90 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
/* Synchronize the request/response if needed */
struct completion wait_event;
 
-   struct hv_multipage_buffer data_buffer;
+   struct vmbus_channel_packet_multipage_buffer mpb;
+   struct vmbus_packet_mpb_array *payload;
+   u32 payload_sz;
+
struct vstor_packet vstor_packet;
 };
 
@@ -1103,6 +1106,8 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
struct Scsi_Host *host;
struct storvsc_device *stor_dev;
struct hv_device *dev = host_dev-dev;
+   u32 payload_sz = cmd_request-payload_sz;
+   void *payload = cmd_request-payload;
 
stor_dev = get_in_stor_device(dev);
host = stor_dev-host;
@@ -1132,10 +1137,14 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
 sense_hdr.ascq);
 
scsi_set_resid(scmnd,
-   cmd_request-data_buffer.len -
+   cmd_request-payload-range.len -
vm_srb-data_transfer_length);
 
scmnd-scsi_done(scmnd);
+
+   if (payload_sz 
+   sizeof(struct vmbus_channel_packet_multipage_buffer))
+   kfree(payload);
 }
 
 static void storvsc_on_io_completion(struct hv_device *device,
@@ -1337,7 +1346,7 @@ static int storvsc_dev_remove(struct hv_device *device)
 }
 
 static int storvsc_do_io(struct hv_device *device,
- struct storvsc_cmd_request *request)
+struct storvsc_cmd_request *request)
 {
struct storvsc_device *stor_device;
struct vstor_packet *vstor_packet;
@@ -1369,13 +1378,14 @@ static int storvsc_do_io(struct hv_device *device,
 
 
vstor_packet-vm_srb.data_transfer_length =
-   request-data_buffer.len;
+   request-payload-range.len;
 
vstor_packet-operation = VSTOR_OPERATION_EXECUTE_SRB;
 
-   if (request-data_buffer.len) {
-   ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
-   request-data_buffer,
+   if (request-payload-range.len) {
+
+   ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
+   request-payload, request-payload_sz,
vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
@@ -1549,6 +1559,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
struct scatterlist *cur_sgl;
+   struct vmbus_packet_mpb_array  *payload;
+   u32 payload_sz;
+   u32 length;
 
if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
/*
@@ -1602,48 +1615,71 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
 
memcpy(vm_srb-cdb, scmnd-cmnd, vm_srb-cdb_length);
 
-   cmd_request-data_buffer.len = scsi_bufflen(scmnd);
-   if (scsi_sg_count(scmnd)) {
-   sgl = (struct scatterlist *)scsi_sglist(scmnd);
-   sg_count = scsi_sg_count(scmnd);
+   sgl = (struct scatterlist *)scsi_sglist(scmnd);
+   sg_count = scsi_sg_count(scmnd);
 
+   length = scsi_bufflen(scmnd);
+   payload = (struct vmbus_packet_mpb_array *)cmd_request-mpb;
+   payload_sz = sizeof(cmd_request-mpb);
+
+   if (sg_count) {
/* check if we need to bounce the sgl */
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
cmd_request-bounce_sgl =
-   create_bounce_buffer(sgl, scsi_sg_count(scmnd),
-scsi_bufflen(scmnd),
+   create_bounce_buffer(sgl, sg_count,
+length,
 vm_srb-data_in);
if (!cmd_request-bounce_sgl)
return SCSI_MLQUEUE_HOST_BUSY;
 
cmd_request-bounce_sgl_count =
-   ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) 
-   PAGE_SHIFT;
+   ALIGN(length, PAGE_SIZE)  PAGE_SHIFT;
 
if (vm_srb-data_in == WRITE_TYPE

[PATCH V2 4/7] scsi: storvsc: Retrieve information about the capability of the target

2015-03-27 Thread K. Y. Srinivasan
The storage protocol informs the guest of the I/O capabilities of the storage
stack. Retrieve this information and use it in the guest.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 0ba7f2c..cdf048b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -377,6 +377,10 @@ struct storvsc_device {
unsigned char path_id;
unsigned char target_id;
 
+   /*
+* Max I/O, the device can support.
+*/
+   u32   max_transfer_bytes;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -974,6 +978,8 @@ static int storvsc_channel_init(struct hv_device *device)
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
+   stor_device-max_transfer_bytes =
+   vstor_packet-storage_channel_properties.max_transfer_bytes;
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet-operation = VSTOR_OPERATION_END_INITIALIZATION;
-- 
1.7.4.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 2/7] scsi: storvsc: Size the queue depth based on the ringbuffer size

2015-03-27 Thread K. Y. Srinivasan
Size the queue depth based on the ringbuffer size. Also accomodate for the
fact that we could have multiple channels (ringbuffers) per adaptor.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
v2: Fixed a bug in computing queue depth: Venkatesh Srinivas 
venkate...@google.com
 drivers/scsi/storvsc_drv.c |   27 ---
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 27fe850..7f569f9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -309,10 +309,15 @@ enum storvsc_request_type {
  */
 
 static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
+static u32 max_outstanding_req_per_channel;
+
+static int storvsc_vcpus_per_sub_channel = 4;
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
 
+module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
+MODULE_PARM_DESC(vcpus_per_sub_channel, Ratio of VCPUs to subchannels);
 /*
  * Timeout in seconds for all devices managed by this driver.
  */
@@ -320,7 +325,6 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
-#define STORVSC_MAX_IO_REQUESTS200
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -1376,7 +1380,6 @@ static int storvsc_do_io(struct hv_device *device,
 
 static int storvsc_device_configure(struct scsi_device *sdevice)
 {
-   scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS);
 
blk_queue_max_segment_size(sdevice-request_queue, PAGE_SIZE);
 
@@ -1646,7 +1649,6 @@ static struct scsi_host_template scsi_driver = {
.eh_timed_out = storvsc_eh_timed_out,
.slave_configure =  storvsc_device_configure,
.cmd_per_lun =  255,
-   .can_queue =STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id =  -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
/* currently 32 */
@@ -1686,6 +1688,7 @@ static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
 {
int ret;
+   int num_cpus = num_online_cpus();
struct Scsi_Host *host;
struct hv_host_device *host_dev;
bool dev_is_ide = ((dev_id-driver_data == IDE_GUID) ? true : false);
@@ -1694,6 +1697,7 @@ static int storvsc_probe(struct hv_device *device,
int max_luns_per_target;
int max_targets;
int max_channels;
+   int max_sub_channels = 0;
 
/*
 * Based on the windows host we are running on,
@@ -1719,12 +1723,18 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
+   /*
+* On Windows8 and above, we support sub-channels for storage.
+* The number of sub-channels offerred is based on the number of
+* VCPUs in the guest.
+*/
+   max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
break;
}
 
-   if (dev_id-driver_data == SFC_GUID)
-   scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
-STORVSC_FC_MAX_TARGETS);
+   scsi_driver.can_queue = (max_outstanding_req_per_channel *
+(max_sub_channels + 1));
+
host = scsi_host_alloc(scsi_driver,
   sizeof(struct hv_host_device));
if (!host)
@@ -1837,7 +1847,6 @@ static struct hv_driver storvsc_drv = {
 
 static int __init storvsc_drv_init(void)
 {
-   u32 max_outstanding_req_per_channel;
 
/*
 * Divide the ring buffer data size (which is 1 page less
@@ -1852,10 +1861,6 @@ static int __init storvsc_drv_init(void)
vmscsi_size_delta,
sizeof(u64)));
 
-   if (max_outstanding_req_per_channel 
-   STORVSC_MAX_IO_REQUESTS)
-   return -EINVAL;
-
return vmbus_driver_register(storvsc_drv);
 }
 
-- 
1.7.4.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 0/7] scsi: storvsc: Miscellaneous enhancements and fixes

2015-03-27 Thread K. Y. Srinivasan
This patch-set addresses perf issues discovered on the Azure storage stack.
These patches also fix a couple of bugs.

As in the first version of this patch-set, some of the patches are simply a 
resend.
I have bumped up the version number of all patches though. In this version, I 
have
addressed issues raised by Olaf Hering o...@aepfle.de,
Long Li lon...@microsoft.com and Venkatesh Srinivas venkate...@google.com

K. Y. Srinivasan (7):
  scsi: storvsc: Increase the ring buffer size
  scsi: storvsc: Size the queue depth based on the ringbuffer size
  scsi: storvsc: Always send on the selected outgoing channel
  scsi: storvsc: Retrieve information about the capability of the
target
  scsi: storvsc: Fix a bug in copy_from_bounce_buffer()
  scsi: storvsc: Don't assume that the scatterlist is not chained
  scsi: storvsc: Set the tablesize based on the information given by
the host

 drivers/scsi/storvsc_drv.c |  232 
 1 files changed, 149 insertions(+), 83 deletions(-)

-- 
1.7.4.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 5/7] scsi: storvsc: Fix a bug in copy_from_bounce_buffer()

2015-03-23 Thread K. Y. Srinivasan
We may exit this function without properly freeing up the maapings
we may have acquired. Fix the bug.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |   15 ---
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5c13eec..88f5d79 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -754,21 +754,22 @@ static unsigned int copy_to_bounce_buffer(struct 
scatterlist *orig_sgl,
if (bounce_sgl[j].length == PAGE_SIZE) {
/* full..move to next entry */
sg_kunmap_atomic(bounce_addr);
+   bounce_addr = 0;
j++;
+   }
 
-   /* if we need to use another bounce buffer */
-   if (srclen || i != orig_sgl_count - 1)
-   bounce_addr = 
sg_kmap_atomic(bounce_sgl,j);
+   /* if we need to use another bounce buffer */
+   if (srclen  bounce_addr == 0)
+   bounce_addr = sg_kmap_atomic(bounce_sgl, j);
 
-   } else if (srclen == 0  i == orig_sgl_count - 1) {
-   /* unmap the last bounce that is  PAGE_SIZE */
-   sg_kunmap_atomic(bounce_addr);
-   }
}
 
sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
}
 
+   if (bounce_addr)
+   sg_kunmap_atomic(bounce_addr);
+
local_irq_restore(flags);
 
return total_copied;
-- 
1.7.4.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 RESEND 1/7] scsi: storvsc: Increase the ring buffer size

2015-03-23 Thread K. Y. Srinivasan
Increase the default ring buffer size as this can significantly
improve performance especially on high latency storage back-ends.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..27fe850 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -308,7 +308,7 @@ enum storvsc_request_type {
  * This is the end of Protocol specific defines.
  */
 
-static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
-- 
1.7.4.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 RESEND 4/7] scsi: storvsc: Retrieve information about the capability of the target

2015-03-23 Thread K. Y. Srinivasan
The storage protocol informs the guest of the I/O capabilities of the storage
stack. Retrieve this information and use it in the guest.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index be8f12e..5c13eec 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -377,6 +377,10 @@ struct storvsc_device {
unsigned char path_id;
unsigned char target_id;
 
+   /*
+* Max I/O, the device can support.
+*/
+   u32   max_transfer_bytes;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -974,6 +978,8 @@ static int storvsc_channel_init(struct hv_device *device)
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
+   stor_device-max_transfer_bytes =
+   vstor_packet-storage_channel_properties.max_transfer_bytes;
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet-operation = VSTOR_OPERATION_END_INITIALIZATION;
-- 
1.7.4.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 0/7] scsi: storvsc: Miscellaneous enhancements and fixes

2015-03-23 Thread K. Y. Srinivasan
This patch-set addresses perf issues discovered on the Azure storage stack.
These patches also fix a couple of bugs.

K. Y. Srinivasan (7):
  scsi: storvsc: Increase the ring buffer size
  scsi: storvsc: Size the queue depth based on the ringbuffer size
  scsi: storvsc: Always send on the selected outgoing channel
  scsi: storvsc: Retrieve information about the capability of the
target
  scsi: storvsc: Fix a bug in copy_from_bounce_buffer()
  scsi: storvsc: Don't assume that the scatterlist is not chained
  scsi: storvsc: Set the tablesize based on the information given by
the host

 drivers/scsi/storvsc_drv.c |  231 
 1 files changed, 149 insertions(+), 82 deletions(-)

-- 
1.7.4.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 6/7] scsi: storvsc: Don't assume that the scatterlist is not chained

2015-03-23 Thread K. Y. Srinivasan
The current code assumes that the scatterlists presented are not chained.
Fix the code to not make this assumption.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   98 +--
 1 files changed, 57 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 88f5d79..a599677 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -626,19 +626,6 @@ cleanup:
return NULL;
 }
 
-/* Disgusting wrapper functions */
-static inline unsigned long sg_kmap_atomic(struct scatterlist *sgl, int idx)
-{
-   void *addr = kmap_atomic(sg_page(sgl + idx));
-   return (unsigned long)addr;
-}
-
-static inline void sg_kunmap_atomic(unsigned long addr)
-{
-   kunmap_atomic((void *)addr);
-}
-
-
 /* Assume the original sgl has enough room */
 static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
struct scatterlist *bounce_sgl,
@@ -653,32 +640,39 @@ static unsigned int copy_from_bounce_buffer(struct 
scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long dest_addr = 0;
unsigned long flags;
+   struct scatterlist *cur_dest_sgl;
+   struct scatterlist *cur_src_sgl;
 
local_irq_save(flags);
-
+   cur_dest_sgl = orig_sgl;
+   cur_src_sgl = bounce_sgl;
for (i = 0; i  orig_sgl_count; i++) {
-   dest_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+   dest_addr = (unsigned long)
+   kmap_atomic(sg_page(cur_dest_sgl)) +
+   cur_dest_sgl-offset;
dest = dest_addr;
destlen = orig_sgl[i].length;
+   destlen = cur_dest_sgl-length;
 
if (bounce_addr == 0)
-   bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+   bounce_addr = (unsigned long)kmap_atomic(
+   sg_page(cur_src_sgl));
 
while (destlen) {
-   src = bounce_addr + bounce_sgl[j].offset;
-   srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+   src = bounce_addr + cur_src_sgl-offset;
+   srclen = cur_src_sgl-length - cur_src_sgl-offset;
 
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
 
total_copied += copylen;
-   bounce_sgl[j].offset += copylen;
+   cur_src_sgl-offset += copylen;
destlen -= copylen;
dest += copylen;
 
-   if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+   if (cur_src_sgl-offset == cur_src_sgl-length) {
/* full */
-   sg_kunmap_atomic(bounce_addr);
+   kunmap_atomic((void *)bounce_addr);
j++;
 
/*
@@ -692,21 +686,27 @@ static unsigned int copy_from_bounce_buffer(struct 
scatterlist *orig_sgl,
/*
 * We are done; cleanup and return.
 */
-   sg_kunmap_atomic(dest_addr - 
orig_sgl[i].offset);
+   kunmap_atomic((void *)(dest_addr -
+   cur_dest_sgl-offset));
local_irq_restore(flags);
return total_copied;
}
 
/* if we need to use another bounce buffer */
-   if (destlen || i != orig_sgl_count - 1)
-   bounce_addr = 
sg_kmap_atomic(bounce_sgl,j);
+   if (destlen || i != orig_sgl_count - 1) {
+   cur_src_sgl = sg_next(cur_src_sgl);
+   bounce_addr = (unsigned long)
+   kmap_atomic(
+   sg_page(cur_src_sgl));
+   }
} else if (destlen == 0  i == orig_sgl_count - 1) {
/* unmap the last bounce that is  PAGE_SIZE */
-   sg_kunmap_atomic(bounce_addr);
+   kunmap_atomic((void *)bounce_addr);
}
}
 
-   sg_kunmap_atomic(dest_addr - orig_sgl[i].offset);
+   kunmap_atomic((void *)(dest_addr - cur_dest_sgl-offset));
+   cur_dest_sgl = sg_next

[PATCH RESEND 2/7] scsi: storvsc: Size the queue depth based on the ringbuffer size

2015-03-23 Thread K. Y. Srinivasan
Size the queue depth based on the ringbuffer size. Also accomodate for the
fact that we could have multiple channels (ringbuffers) per adaptor.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   27 ---
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 27fe850..5a12897 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -309,10 +309,15 @@ enum storvsc_request_type {
  */
 
 static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
+static u32 max_outstanding_req_per_channel;
+
+static int storvsc_vcpus_per_sub_channel = 4;
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
 
+module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
+MODULE_PARM_DESC(vcpus_per_sub_channel, Ratio of VCPUs to subchannels);
 /*
  * Timeout in seconds for all devices managed by this driver.
  */
@@ -320,7 +325,6 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
-#define STORVSC_MAX_IO_REQUESTS200
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -1376,7 +1380,6 @@ static int storvsc_do_io(struct hv_device *device,
 
 static int storvsc_device_configure(struct scsi_device *sdevice)
 {
-   scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS);
 
blk_queue_max_segment_size(sdevice-request_queue, PAGE_SIZE);
 
@@ -1646,7 +1649,6 @@ static struct scsi_host_template scsi_driver = {
.eh_timed_out = storvsc_eh_timed_out,
.slave_configure =  storvsc_device_configure,
.cmd_per_lun =  255,
-   .can_queue =STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id =  -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
/* currently 32 */
@@ -1686,6 +1688,7 @@ static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
 {
int ret;
+   int num_cpus = num_online_cpus();
struct Scsi_Host *host;
struct hv_host_device *host_dev;
bool dev_is_ide = ((dev_id-driver_data == IDE_GUID) ? true : false);
@@ -1694,6 +1697,7 @@ static int storvsc_probe(struct hv_device *device,
int max_luns_per_target;
int max_targets;
int max_channels;
+   int max_sub_channels = 0;
 
/*
 * Based on the windows host we are running on,
@@ -1719,12 +1723,18 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
+   /*
+* On Windows8 and above, we support sub-channels for storage.
+* The number of sub-channels offerred is based on the number of
+* VCPUs in the guest.
+*/
+   max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
break;
}
 
-   if (dev_id-driver_data == SFC_GUID)
-   scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
-STORVSC_FC_MAX_TARGETS);
+   scsi_driver.can_queue = (max_outstanding_req_per_channel *
+max_sub_channels + 1);
+
host = scsi_host_alloc(scsi_driver,
   sizeof(struct hv_host_device));
if (!host)
@@ -1837,7 +1847,6 @@ static struct hv_driver storvsc_drv = {
 
 static int __init storvsc_drv_init(void)
 {
-   u32 max_outstanding_req_per_channel;
 
/*
 * Divide the ring buffer data size (which is 1 page less
@@ -1852,10 +1861,6 @@ static int __init storvsc_drv_init(void)
vmscsi_size_delta,
sizeof(u64)));
 
-   if (max_outstanding_req_per_channel 
-   STORVSC_MAX_IO_REQUESTS)
-   return -EINVAL;
-
return vmbus_driver_register(storvsc_drv);
 }
 
-- 
1.7.4.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 7/7] scsi: storvsc: Set the tablesize based on the information given by the host

2015-03-23 Thread K. Y. Srinivasan
Set the tablesize based on the information given by the host.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
v2: Rebase the code and enable clustering

 drivers/scsi/storvsc_drv.c |   89 +++
 1 files changed, 64 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index a599677..71871f2 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
/* Synchronize the request/response if needed */
struct completion wait_event;
 
-   struct hv_multipage_buffer data_buffer;
+   struct vmbus_channel_packet_multipage_buffer mpb;
+   struct vmbus_packet_mpb_array *payload;
+   u32 payload_sz;
+
struct vstor_packet vstor_packet;
 };
 
@@ -1133,10 +1136,14 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
 sense_hdr.ascq);
 
scsi_set_resid(scmnd,
-   cmd_request-data_buffer.len -
+   cmd_request-payload-range.len -
vm_srb-data_transfer_length);
 
scmnd-scsi_done(scmnd);
+
+   if (cmd_request-payload_sz 
+   sizeof(struct vmbus_channel_packet_multipage_buffer))
+   kfree(cmd_request-payload);
 }
 
 static void storvsc_on_io_completion(struct hv_device *device,
@@ -1338,7 +1345,7 @@ static int storvsc_dev_remove(struct hv_device *device)
 }
 
 static int storvsc_do_io(struct hv_device *device,
- struct storvsc_cmd_request *request)
+struct storvsc_cmd_request *request)
 {
struct storvsc_device *stor_device;
struct vstor_packet *vstor_packet;
@@ -1370,13 +1377,14 @@ static int storvsc_do_io(struct hv_device *device,
 
 
vstor_packet-vm_srb.data_transfer_length =
-   request-data_buffer.len;
+   request-payload-range.len;
 
vstor_packet-operation = VSTOR_OPERATION_EXECUTE_SRB;
 
-   if (request-data_buffer.len) {
-   ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
-   request-data_buffer,
+   if (request-payload-range.len) {
+
+   ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
+   request-payload, request-payload_sz,
vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
@@ -1550,6 +1558,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
struct scatterlist *cur_sgl;
+   struct vmbus_packet_mpb_array  *payload;
+   u32 payload_sz;
+   u32 pfn_cnt;
+   u32 length;
 
if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
/*
@@ -1603,48 +1615,72 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
 
memcpy(vm_srb-cdb, scmnd-cmnd, vm_srb-cdb_length);
 
-   cmd_request-data_buffer.len = scsi_bufflen(scmnd);
-   if (scsi_sg_count(scmnd)) {
-   sgl = (struct scatterlist *)scsi_sglist(scmnd);
-   sg_count = scsi_sg_count(scmnd);
+   sgl = (struct scatterlist *)scsi_sglist(scmnd);
+   sg_count = scsi_sg_count(scmnd);
 
+   length = scsi_bufflen(scmnd);
+   payload = (struct vmbus_packet_mpb_array *)cmd_request-mpb;
+   payload_sz = sizeof(cmd_request-mpb);
+
+   if (sg_count) {
/* check if we need to bounce the sgl */
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
cmd_request-bounce_sgl =
-   create_bounce_buffer(sgl, scsi_sg_count(scmnd),
-scsi_bufflen(scmnd),
+   create_bounce_buffer(sgl, sg_count,
+length,
 vm_srb-data_in);
if (!cmd_request-bounce_sgl)
return SCSI_MLQUEUE_HOST_BUSY;
 
cmd_request-bounce_sgl_count =
-   ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) 
-   PAGE_SHIFT;
+   ALIGN(length, PAGE_SIZE)  PAGE_SHIFT;
 
if (vm_srb-data_in == WRITE_TYPE)
copy_to_bounce_buffer(sgl,
-   cmd_request-bounce_sgl,
-   scsi_sg_count(scmnd));
+   cmd_request-bounce_sgl, sg_count);
 
sgl = cmd_request-bounce_sgl;
sg_count = cmd_request-bounce_sgl_count

[PATCH RESEND 3/7] scsi: storvsc: Always send on the selected outgoing channel

2015-03-23 Thread K. Y. Srinivasan
The current code always sent packets without data on the primary channel.
Properly distribute sending of packets with no data amongst all available
channels. I would like to thank Long Li for noticing this problem.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5a12897..be8f12e 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1362,7 +1362,7 @@ static int storvsc_do_io(struct hv_device *device,
vmscsi_size_delta),
(unsigned long)request);
} else {
-   ret = vmbus_sendpacket(device-channel, vstor_packet,
+   ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
   (sizeof(struct vstor_packet) -
vmscsi_size_delta),
   (unsigned long)request,
-- 
1.7.4.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 1/3] scsi: storvsc: Retrieve information about the capability of the target

2015-03-09 Thread K. Y. Srinivasan
The storage protocol informs the guest of the I/O capabilities of the storage
stack. Retrieve this information and use it in the guest.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index be8f12e..5c13eec 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -377,6 +377,10 @@ struct storvsc_device {
unsigned char path_id;
unsigned char target_id;
 
+   /*
+* Max I/O, the device can support.
+*/
+   u32   max_transfer_bytes;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -974,6 +978,8 @@ static int storvsc_channel_init(struct hv_device *device)
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
+   stor_device-max_transfer_bytes =
+   vstor_packet-storage_channel_properties.max_transfer_bytes;
 
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet-operation = VSTOR_OPERATION_END_INITIALIZATION;
-- 
1.7.4.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 3/3] scsi: storvsc: Enable clustering

2015-03-09 Thread K. Y. Srinivasan
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index a36c232..d7ebf00 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1693,7 +1693,7 @@ static struct scsi_host_template scsi_driver = {
.slave_configure =  storvsc_device_configure,
.cmd_per_lun =  255,
.this_id =  -1,
-   .use_clustering =   DISABLE_CLUSTERING,
+   .use_clustering =   ENABLE_CLUSTERING,
/* Make sure we dont get a sg segment crosses a page boundary */
.dma_boundary = PAGE_SIZE-1,
.no_write_same =1,
-- 
1.7.4.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 0/3] scsi: storvsc: Increase the tablesize based on host's capabilities

2015-03-09 Thread K. Y. Srinivasan
Presently, storvsc limits the I/O size arbitrarily. Make this configurable
based on what the host advertises.

K. Y. Srinivasan (3):
  scsi: storvsc: Retrieve information about the capability of the
target
  scsi: storvsc: Set the tablesize based on the information given by
the host
  scsi: storvsc: Enable clustering

 drivers/scsi/storvsc_drv.c |   78 +++-
 1 files changed, 62 insertions(+), 16 deletions(-)

-- 
1.7.4.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 2/3] scsi: storvsc: Set the tablesize based on the information given by the host

2015-03-09 Thread K. Y. Srinivasan
Set the tablesize based on what the host has informed us.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   70 ++-
 1 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5c13eec..a36c232 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
/* Synchronize the request/response if needed */
struct completion wait_event;
 
-   struct hv_multipage_buffer data_buffer;
+   struct vmbus_channel_packet_multipage_buffer mpb;
+   struct vmbus_packet_mpb_array *payload;
+   u32 payload_sz;
+
struct vstor_packet vstor_packet;
 };
 
@@ -1119,10 +1122,14 @@ static void storvsc_command_completion(struct 
storvsc_cmd_request *cmd_request)
 sense_hdr.ascq);
 
scsi_set_resid(scmnd,
-   cmd_request-data_buffer.len -
+   cmd_request-payload-range.len -
vm_srb-data_transfer_length);
 
scmnd-scsi_done(scmnd);
+
+   if (cmd_request-payload_sz 
+   sizeof(struct vmbus_channel_packet_multipage_buffer))
+   kfree(cmd_request-payload);
 }
 
 static void storvsc_on_io_completion(struct hv_device *device,
@@ -1324,7 +1331,7 @@ static int storvsc_dev_remove(struct hv_device *device)
 }
 
 static int storvsc_do_io(struct hv_device *device,
- struct storvsc_cmd_request *request)
+struct storvsc_cmd_request *request)
 {
struct storvsc_device *stor_device;
struct vstor_packet *vstor_packet;
@@ -1356,13 +1363,14 @@ static int storvsc_do_io(struct hv_device *device,
 
 
vstor_packet-vm_srb.data_transfer_length =
-   request-data_buffer.len;
+   request-payload-range.len;
 
vstor_packet-operation = VSTOR_OPERATION_EXECUTE_SRB;
 
-   if (request-data_buffer.len) {
-   ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
-   request-data_buffer,
+   if (request-payload-range.len) {
+
+   ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
+   request-payload, request-payload_sz,
vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
@@ -1535,6 +1543,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
struct scatterlist *sgl;
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
+   struct vmbus_packet_mpb_array  *payload;
+   u32 payload_sz;
+   u32 pfn_cnt;
+   u32 length;
 
if (vmstor_current_major = VMSTOR_WIN8_MAJOR) {
/*
@@ -1588,7 +1600,11 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
 
memcpy(vm_srb-cdb, scmnd-cmnd, vm_srb-cdb_length);
 
-   cmd_request-data_buffer.len = scsi_bufflen(scmnd);
+   sgl = (struct scatterlist *)scsi_sglist(scmnd);
+   length = scsi_bufflen(scmnd);
+   payload = (struct vmbus_packet_mpb_array *)cmd_request-mpb;
+   payload_sz = sizeof(cmd_request-mpb);
+
if (scsi_sg_count(scmnd)) {
sgl = (struct scatterlist *)scsi_sglist(scmnd);
sg_count = scsi_sg_count(scmnd);
@@ -1615,19 +1631,40 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
sg_count = cmd_request-bounce_sgl_count;
}
 
-   cmd_request-data_buffer.offset = sgl[0].offset;
+   pfn_cnt = DIV_ROUND_UP(sgl[0].offset + length, PAGE_SIZE);
+
+   if (pfn_cnt  MAX_PAGE_BUFFER_COUNT) {
+
+   payload_sz = (pfn_cnt * sizeof(void *) +
+ sizeof(struct vmbus_packet_mpb_array));
+   payload = kzalloc(payload_sz, GFP_ATOMIC);
+   if (!payload) {
+   if (cmd_request-bounce_sgl_count)
+   destroy_bounce_buffer(
+   cmd_request-bounce_sgl,
+   cmd_request-bounce_sgl_count);
+
+   return SCSI_MLQUEUE_DEVICE_BUSY;
+   }
+   }
+
+   payload-range.len = length;
+   payload-range.offset = sgl[0].offset;
 
for (i = 0; i  sg_count; i++)
-   cmd_request-data_buffer.pfn_array[i] =
+   payload-range.pfn_array[i] =
page_to_pfn(sg_page((sgl[i])));
 
} else if (scsi_sglist(scmnd)) {
-   cmd_request-data_buffer.offset =
+   payload-range.len

[PATCH 1/3] scsi: storvsc: Increase the ring buffer size

2015-02-27 Thread K. Y. Srinivasan
Increase the default ring buffer size as this can significantly
improve performance especially on high latency storage back-ends.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..27fe850 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -308,7 +308,7 @@ enum storvsc_request_type {
  * This is the end of Protocol specific defines.
  */
 
-static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
-- 
1.7.4.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 3/3] scsi: storvsc: Always send on the selected outgoing channel

2015-02-27 Thread K. Y. Srinivasan
The current code always sent packets without data on the primary channel.
Properly distribute sending of packets with no data amongst all available
channels. I would like to thank Long Li for noticing this problem.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5a12897..be8f12e 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1362,7 +1362,7 @@ static int storvsc_do_io(struct hv_device *device,
vmscsi_size_delta),
(unsigned long)request);
} else {
-   ret = vmbus_sendpacket(device-channel, vstor_packet,
+   ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
   (sizeof(struct vstor_packet) -
vmscsi_size_delta),
   (unsigned long)request,
-- 
1.7.4.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 2/3] scsi: storvsc: Size the queue depth based on the ringbuffer size

2015-02-27 Thread K. Y. Srinivasan
Size the queue depth based on the ringbuffer size. Also accomodate for the
fact that we could have multiple channels (ringbuffers) per adaptor.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Reviewed-by: Long Li lon...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   27 ---
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 27fe850..5a12897 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -309,10 +309,15 @@ enum storvsc_request_type {
  */
 
 static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
+static u32 max_outstanding_req_per_channel;
+
+static int storvsc_vcpus_per_sub_channel = 4;
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size (bytes));
 
+module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
+MODULE_PARM_DESC(vcpus_per_sub_channel, Ratio of VCPUs to subchannels);
 /*
  * Timeout in seconds for all devices managed by this driver.
  */
@@ -320,7 +325,6 @@ static int storvsc_timeout = 180;
 
 static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
 
-#define STORVSC_MAX_IO_REQUESTS200
 
 static void storvsc_on_channel_callback(void *context);
 
@@ -1376,7 +1380,6 @@ static int storvsc_do_io(struct hv_device *device,
 
 static int storvsc_device_configure(struct scsi_device *sdevice)
 {
-   scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS);
 
blk_queue_max_segment_size(sdevice-request_queue, PAGE_SIZE);
 
@@ -1646,7 +1649,6 @@ static struct scsi_host_template scsi_driver = {
.eh_timed_out = storvsc_eh_timed_out,
.slave_configure =  storvsc_device_configure,
.cmd_per_lun =  255,
-   .can_queue =STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id =  -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
/* currently 32 */
@@ -1686,6 +1688,7 @@ static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
 {
int ret;
+   int num_cpus = num_online_cpus();
struct Scsi_Host *host;
struct hv_host_device *host_dev;
bool dev_is_ide = ((dev_id-driver_data == IDE_GUID) ? true : false);
@@ -1694,6 +1697,7 @@ static int storvsc_probe(struct hv_device *device,
int max_luns_per_target;
int max_targets;
int max_channels;
+   int max_sub_channels = 0;
 
/*
 * Based on the windows host we are running on,
@@ -1719,12 +1723,18 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
+   /*
+* On Windows8 and above, we support sub-channels for storage.
+* The number of sub-channels offerred is based on the number of
+* VCPUs in the guest.
+*/
+   max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
break;
}
 
-   if (dev_id-driver_data == SFC_GUID)
-   scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
-STORVSC_FC_MAX_TARGETS);
+   scsi_driver.can_queue = (max_outstanding_req_per_channel *
+max_sub_channels + 1);
+
host = scsi_host_alloc(scsi_driver,
   sizeof(struct hv_host_device));
if (!host)
@@ -1837,7 +1847,6 @@ static struct hv_driver storvsc_drv = {
 
 static int __init storvsc_drv_init(void)
 {
-   u32 max_outstanding_req_per_channel;
 
/*
 * Divide the ring buffer data size (which is 1 page less
@@ -1852,10 +1861,6 @@ static int __init storvsc_drv_init(void)
vmscsi_size_delta,
sizeof(u64)));
 
-   if (max_outstanding_req_per_channel 
-   STORVSC_MAX_IO_REQUESTS)
-   return -EINVAL;
-
return vmbus_driver_register(storvsc_drv);
 }
 
-- 
1.7.4.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 0/3] scsi: storvsc: Some enhancements

2015-02-27 Thread K. Y. Srinivasan
While testing on some high latency storage backends, to get the advertised IOPS,
we have to increase the size of the ringbuffer. Address this issue.

K. Y. Srinivasan (3):
  scsi: storvsc: Increase the ring buffer size
  Scsi: storvsc: Size the queue depth based on the ringbuffer size
  scsi: storvsc: Always send on the selected outgoing channel

 drivers/scsi/storvsc_drv.c |   30 +-
 1 files changed, 17 insertions(+), 13 deletions(-)

-- 
1.7.4.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 4/4] Drivers: scsi: storvsc: Force SPC-3 compliance on win8 and win8 r2 hosts

2014-12-16 Thread K. Y. Srinivasan
On win8 and win8 r2 hosts force SPC-3 compliance for MSFT virtual disks.
Ubuntu has been carrying a similar patch outside the tree for a while now.
Starting with win10, the host will support SPC-3 compliance. Based on all
the testing that has been done on win8 and win8 r2 hosts, we are comfortable
claiming SPC-3 compliance on these hosts as well. This will enable TRIM
support on these hosts.

Suggested by: James Bottomley james.bottom...@hansenpartnership.com
Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index fdc5164..7487e07 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1468,6 +1468,19 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 */
sdevice-sdev_bflags |= msft_blist_flags;
 
+   /*
+* If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
+* if the device is a MSFT virtual device.
+*/
+   if (!strncmp(sdevice-vendor, Msft, 4)) {
+   switch (vmbus_proto_version) {
+   case VERSION_WIN8:
+   case VERSION_WIN8_1:
+   sdevice-scsi_level = SCSI_SPC_3;
+   break;
+   }
+   }
+
return 0;
 }
 
-- 
1.7.4.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 0/4] Drivers: scsi: storvsc: Fix miscellaneous issues

2014-12-16 Thread K. Y. Srinivasan
The first two patches in this series are a resend; these were submitted
some months ago and as far as I know, there were no outstanding issues.

Win8 and win8 r2 hosts do support SPC-3 features but claim SPC-2 compliance.
This issue is fixed here as well.

K. Y. Srinivasan (4):
  Drivers: scsi: storvsc: In responce to a scan event, scan the host
  Drivers: scsi: storvsc: Force discovery of LUNs that may have been
removed.
  Drivers: scsi: storvsc: Fix a bug in storvsc limits
  Drivers: scsi: storvsc: Force SPC-3 compliance on win8 and win8 r2
hosts

 drivers/scsi/storvsc_drv.c |   71 +++
 1 files changed, 57 insertions(+), 14 deletions(-)

-- 
1.7.4.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 2/4] Drivers: scsi: storvsc: Force discovery of LUNs that may have been removed.

2014-12-16 Thread K. Y. Srinivasan
The host asks the guest to scan when a LUN is removed or added.
The only way a guest can identify the removed LUN is when an I/O is
attempted on a removed LUN - the SRB status code indicates that the LUN
is invalid. We currently handle this SRB status and remove the device.

Rather than waiting for an I/O to remove the device, force the discovery of
LUNs that may have been removed prior to discovering LUNs that may have
been added.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   26 ++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 0a96fef..a7163c6 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -430,10 +430,36 @@ static void storvsc_host_scan(struct work_struct *work)
 {
struct storvsc_scan_work *wrk;
struct Scsi_Host *host;
+   struct scsi_device *sdev;
+   unsigned long flags;
 
wrk = container_of(work, struct storvsc_scan_work, work);
host = wrk-host;
 
+   /*
+* Before scanning the host, first check to see if any of the
+* currrently known devices have been hot removed. We issue a
+* unit ready command against all currently known devices.
+* This I/O will result in an error for devices that have been
+* removed. As part of handling the I/O error, we remove the device.
+*
+* When a LUN is added or removed, the host sends us a signal to
+* scan the host. Thus we are forced to discover the LUNs that
+* may have been removed this way.
+*/
+   mutex_lock(host-scan_mutex);
+   spin_lock_irqsave(host-host_lock, flags);
+   list_for_each_entry(sdev, host-__devices, siblings) {
+   spin_unlock_irqrestore(host-host_lock, flags);
+   scsi_test_unit_ready(sdev, 1, 1, NULL);
+   spin_lock_irqsave(host-host_lock, flags);
+   continue;
+   }
+   spin_unlock_irqrestore(host-host_lock, flags);
+   mutex_unlock(host-scan_mutex);
+   /*
+* Now scan the host to discover LUNs that may have been added.
+*/
scsi_scan_host(host);
 
kfree(wrk);
-- 
1.7.4.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 3/4] Drivers: scsi: storvsc: Fix a bug in storvsc limits

2014-12-16 Thread K. Y. Srinivasan
Commit 4cd83ecdac20d30725b4f96e5d7814a1e290bc7e changed the limits to
reflect the values on the host. It turns out that WS2008R2 cannot
correctly handle these new limits. Fix this bug by setting the limits
based on the host.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index a7163c6..fdc5164 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1782,6 +1782,9 @@ static int storvsc_probe(struct hv_device *device,
bool dev_is_ide = ((dev_id-driver_data == IDE_GUID) ? true : false);
int target = 0;
struct storvsc_device *stor_device;
+   int max_luns_per_target;
+   int max_targets;
+   int max_channels;
 
/*
 * Based on the windows host we are running on,
@@ -1795,12 +1798,18 @@ static int storvsc_probe(struct hv_device *device,
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
vmstor_current_major = VMSTOR_WIN7_MAJOR;
vmstor_current_minor = VMSTOR_WIN7_MINOR;
+   max_luns_per_target = STORVSC_IDE_MAX_LUNS_PER_TARGET;
+   max_targets = STORVSC_IDE_MAX_TARGETS;
+   max_channels = STORVSC_IDE_MAX_CHANNELS;
break;
default:
sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = 0;
vmstor_current_major = VMSTOR_WIN8_MAJOR;
vmstor_current_minor = VMSTOR_WIN8_MINOR;
+   max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
+   max_targets = STORVSC_MAX_TARGETS;
+   max_channels = STORVSC_MAX_CHANNELS;
break;
}
 
@@ -1848,9 +1857,9 @@ static int storvsc_probe(struct hv_device *device,
break;
 
case SCSI_GUID:
-   host-max_lun = STORVSC_MAX_LUNS_PER_TARGET;
-   host-max_id = STORVSC_MAX_TARGETS;
-   host-max_channel = STORVSC_MAX_CHANNELS - 1;
+   host-max_lun = max_luns_per_target;
+   host-max_id = max_targets;
+   host-max_channel = max_channels - 1;
break;
 
default:
-- 
1.7.4.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 1/4] Drivers: scsi: storvsc: In responce to a scan event, scan the host

2014-12-16 Thread K. Y. Srinivasan
The virtual HBA that storvsc implements can support multiple channels and
targets. So, scan the host when the host notifies that a scan is needed.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   19 +++
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index e3ba251..0a96fef 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -426,21 +426,16 @@ done:
kfree(wrk);
 }
 
-static void storvsc_bus_scan(struct work_struct *work)
+static void storvsc_host_scan(struct work_struct *work)
 {
struct storvsc_scan_work *wrk;
-   int id, order_id;
+   struct Scsi_Host *host;
 
wrk = container_of(work, struct storvsc_scan_work, work);
-   for (id = 0; id  wrk-host-max_id; ++id) {
-   if (wrk-host-reverse_ordering)
-   order_id = wrk-host-max_id - id - 1;
-   else
-   order_id = id;
-
-   scsi_scan_target(wrk-host-shost_gendev, 0,
-   order_id, SCAN_WILD_CARD, 1);
-   }
+   host = wrk-host;
+
+   scsi_scan_host(host);
+
kfree(wrk);
 }
 
@@ -1198,7 +1193,7 @@ static void storvsc_on_receive(struct hv_device *device,
if (!work)
return;
 
-   INIT_WORK(work-work, storvsc_bus_scan);
+   INIT_WORK(work-work, storvsc_host_scan);
work-host = stor_device-host;
schedule_work(work-work);
break;
-- 
1.7.4.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 1/1] Drivers: scsi: storvsc: Get rid of warning messages

2014-09-02 Thread K. Y. Srinivasan
Get rid of the warning messages since they will clutter up various system logs
and are of questionable value to the end user. For debugging purposes, this
information can be gotten by setting the scsi log level appropriately.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   12 
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index fecac5d0..733e5f7 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1152,24 +1152,12 @@ static void storvsc_on_io_completion(struct hv_device 
*device,
stor_pkt-vm_srb.sense_info_length =
vstor_packet-vm_srb.sense_info_length;
 
-   if (vstor_packet-vm_srb.scsi_status != 0 ||
-   vstor_packet-vm_srb.srb_status != SRB_STATUS_SUCCESS){
-   dev_warn(device-device,
-cmd 0x%x scsi status 0x%x srb status 0x%x\n,
-stor_pkt-vm_srb.cdb[0],
-vstor_packet-vm_srb.scsi_status,
-vstor_packet-vm_srb.srb_status);
-   }
 
if ((vstor_packet-vm_srb.scsi_status  0xFF) == 0x02) {
/* CHECK_CONDITION */
if (vstor_packet-vm_srb.srb_status 
SRB_STATUS_AUTOSENSE_VALID) {
/* autosense data available */
-   dev_warn(device-device,
-stor pkt %p autosense data valid - len %d\n,
-request,
-vstor_packet-vm_srb.sense_info_length);
 
memcpy(request-sense_buffer,
   vstor_packet-vm_srb.sense_data,
-- 
1.7.4.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 2/2] Drivers: scsi: storvsc: Force discovery of LUNs that may have been removed.

2014-08-16 Thread K. Y. Srinivasan
The host asks the guest to scan when a LUN is removed or added.
The only way a guest can identify the removed LUN is when an I/O is
attempted on a removed LUN - the SRB status code indicates that the LUN
is invalid. We currently handle this SRB status and remove the device.

Rather than waiting for an I/O to remove the device, force the discovery of
LUNs that may have been removed prior to discovering LUNs that may have
been added.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   26 ++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 02d1db6..fb38ca9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -430,10 +430,36 @@ static void storvsc_host_scan(struct work_struct *work)
 {
struct storvsc_scan_work *wrk;
struct Scsi_Host *host;
+   struct scsi_device *sdev;
+   unsigned long flags;
 
wrk = container_of(work, struct storvsc_scan_work, work);
host = wrk-host;
 
+   /*
+* Before scanning the host, first check to see if any of the
+* currrently known devices have been hot removed. We issue a
+* unit ready command against all currently known devices.
+* This I/O will result in an error for devices that have been
+* removed. As part of handling the I/O error, we remove the device.
+*
+* When a LUN is added or removed, the host sends us a signal to
+* scan the host. Thus we are forced to discover the LUNs that
+* may have been removed this way.
+*/
+   mutex_lock(host-scan_mutex);
+   spin_lock_irqsave(host-host_lock, flags);
+   list_for_each_entry(sdev, host-__devices, siblings) {
+   spin_unlock_irqrestore(host-host_lock, flags);
+   scsi_test_unit_ready(sdev, 1, 1, NULL);
+   spin_lock_irqsave(host-host_lock, flags);
+   continue;
+   }
+   spin_unlock_irqrestore(host-host_lock, flags);
+   mutex_unlock(host-scan_mutex);
+   /*
+* Now scan the host to discover LUNs that may have been added.
+*/
scsi_scan_host(host);
 
kfree(wrk);
-- 
1.7.4.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 0/2] Drivers: scsi: storvsc: Fix issues with hot-add/remove of LUNs

2014-08-16 Thread K. Y. Srinivasan
This patch-set addresses issues with LUN hot-add and remove. When the host
notifies the guest that a scan is needed, scan the host. Also, prior to
discovering new devices that may have been added, ensure we handle the
LUN remove case first.

K. Y. Srinivasan (2):
  Drivers: scsi: storvsc: In responce to a scan event, scan the host
  Drivers: scsi: storvsc: Force discovery of LUNs that may have been
removed.

 drivers/scsi/storvsc_drv.c |   43 ---
 1 files changed, 32 insertions(+), 11 deletions(-)

-- 
1.7.4.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 1/2] Drivers: scsi: storvsc: In responce to a scan event, scan the host

2014-08-16 Thread K. Y. Srinivasan
The virtual HBA that storvsc implements can support multiple channels and
targets. So, scan the host when the host notifies that a scan is needed.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   19 +++
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 15ba695..02d1db6 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -426,21 +426,16 @@ done:
kfree(wrk);
 }
 
-static void storvsc_bus_scan(struct work_struct *work)
+static void storvsc_host_scan(struct work_struct *work)
 {
struct storvsc_scan_work *wrk;
-   int id, order_id;
+   struct Scsi_Host *host;
 
wrk = container_of(work, struct storvsc_scan_work, work);
-   for (id = 0; id  wrk-host-max_id; ++id) {
-   if (wrk-host-reverse_ordering)
-   order_id = wrk-host-max_id - id - 1;
-   else
-   order_id = id;
-
-   scsi_scan_target(wrk-host-shost_gendev, 0,
-   order_id, SCAN_WILD_CARD, 1);
-   }
+   host = wrk-host;
+
+   scsi_scan_host(host);
+
kfree(wrk);
 }
 
@@ -1209,7 +1204,7 @@ static void storvsc_on_receive(struct hv_device *device,
if (!work)
return;
 
-   INIT_WORK(work-work, storvsc_bus_scan);
+   INIT_WORK(work-work, storvsc_host_scan);
work-host = stor_device-host;
schedule_work(work-work);
break;
-- 
1.7.4.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 1/1] Drivers: scsi: storvsc: Add blist flags

2014-07-21 Thread K. Y. Srinivasan
Add blist flags to permit the reading of the VPD pages even when
the target may claim SPC-2 compliance. MSFT targets currently
claim SPC-2 compliance while they implement post SPC-2 features.
With this patch we can correctly handle WRITE_SAME_16 issues.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 29d0329..15ba695 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -327,6 +327,8 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size 
(bytes));
  */
 static int storvsc_timeout = 180;
 
+static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
+
 #define STORVSC_MAX_IO_REQUESTS200
 
 static void storvsc_on_channel_callback(void *context);
@@ -1449,6 +1451,14 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 
sdevice-no_write_same = 1;
 
+   /*
+* Add blist flags to permit the reading of the VPD pages even when
+* the target may claim SPC-2 compliance. MSFT targets currently
+* claim SPC-2 compliance while they implement post SPC-2 features.
+* With this patch we can correctly handle WRITE_SAME_16 issues.
+*/
+   sdevice-sdev_bflags |= msft_blist_flags;
+
return 0;
 }
 
-- 
1.7.4.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 1/1] Drivers: scsi: storvsc: Add blist flags

2014-07-20 Thread K. Y. Srinivasan
Add blist flags to permit the reading of the VPD pages even when
the target may claim SPC-2 compliance. MSFT targets currently
claim SPC-2 compliance while they implement post SPC-2 features.
With this patch we can correctly handle WRITE_SAME_16 issues.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
---
 drivers/scsi/storvsc_drv.c |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 29d0329..2a58dc4 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -42,6 +42,7 @@
 #include scsi/scsi_eh.h
 #include scsi/scsi_devinfo.h
 #include scsi/scsi_dbg.h
+#include scsi_priv.h
 
 /*
  * All wire protocol details (storage protocol between the guest and the host)
@@ -327,6 +328,8 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, Ring buffer size 
(bytes));
  */
 static int storvsc_timeout = 180;
 
+static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
+
 #define STORVSC_MAX_IO_REQUESTS200
 
 static void storvsc_on_channel_callback(void *context);
@@ -1438,6 +1441,8 @@ static void storvsc_device_destroy(struct scsi_device 
*sdevice)
 
 static int storvsc_device_configure(struct scsi_device *sdevice)
 {
+   int blist_flags;
+
scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
STORVSC_MAX_IO_REQUESTS);
 
@@ -1449,6 +1454,14 @@ static int storvsc_device_configure(struct scsi_device 
*sdevice)
 
sdevice-no_write_same = 1;
 
+   blist_flags = scsi_get_device_flags_keyed(sdevice, Msft,
+ Virtual Disk,
+ SCSI_DEVINFO_GLOBAL);
+
+   if (blist_flags != msft_blist_flags)
+   scsi_dev_info_list_add_keyed(1, Msft, Virtual Disk, NULL,
+msft_blist_flags,
+SCSI_DEVINFO_GLOBAL);
return 0;
 }
 
-- 
1.7.4.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 V3 0/7] Drivers: scsi: storvsc: Bug fixes and improvements

2014-07-12 Thread K. Y. Srinivasan
In this patch set I have fixed a few bugs and implemented some enhancements.

In this version of the patch I have addressed comments from
Christoph Hellwig h...@infradead.org

K. Y. Srinivasan (7):
  Drivers: scsi: storvsc: Change the limits to reflect the values on
the host
  Drivers: scsi: storvsc: Set cmd_per_lun to reflect value supported by
the Host
  Drivers: scsi: storvsc: Filter commands based on the storage protocol
version
  Drivers: scsi: storvsc: Fix a bug in handling VMBUS protocol version
  Drivers: scsi: storvsc: Implement a timedout handler
  drivers: scsi: storvsc: Set srb_flags in all cases
  drivers: scsi: storvsc: Correctly handle TEST_UNIT_READY failure

 drivers/scsi/storvsc_drv.c |  111 ++-
 1 files changed, 77 insertions(+), 34 deletions(-)

-- 
1.7.4.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 V3 1/7] Drivers: scsi: storvsc: Change the limits to reflect the values on the host

2014-07-12 Thread K. Y. Srinivasan
Hyper-V hosts can support multiple targets and multiple channels and larger 
number of
LUNs per target. Update the code to reflect this. With this patch we can 
correctly
enumerate all the paths in a multi-path storage environment.

In this version of the patch I have addressed comments from
Christoph Hellwig h...@infradead.org

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |   47 +---
 1 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 9969fa1..8938b13 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -330,17 +330,17 @@ static int storvsc_timeout = 180;
 
 static void storvsc_on_channel_callback(void *context);
 
-/*
- * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
- * reality, the path/target is not used (ie always set to 0) so our
- * scsi host adapter essentially has 1 bus with 1 target that contains
- * up to 256 luns.
- */
-#define STORVSC_MAX_LUNS_PER_TARGET64
-#define STORVSC_MAX_TARGETS1
-#define STORVSC_MAX_CHANNELS   1
+#define STORVSC_MAX_LUNS_PER_TARGET255
+#define STORVSC_MAX_TARGETS2
+#define STORVSC_MAX_CHANNELS   8
 
+#define STORVSC_FC_MAX_LUNS_PER_TARGET 255
+#define STORVSC_FC_MAX_TARGETS 128
+#define STORVSC_FC_MAX_CHANNELS8
 
+#define STORVSC_IDE_MAX_LUNS_PER_TARGET64
+#define STORVSC_IDE_MAX_TARGETS1
+#define STORVSC_IDE_MAX_CHANNELS   1
 
 struct storvsc_cmd_request {
struct list_head entry;
@@ -1691,7 +1691,6 @@ static struct scsi_host_template scsi_driver = {
.slave_destroy =storvsc_device_destroy,
.slave_configure =  storvsc_device_configure,
.cmd_per_lun =  1,
-   /* 64 max_queue * 1 target */
.can_queue =STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id =  -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
@@ -1756,6 +1755,9 @@ static int storvsc_probe(struct hv_device *device,
}
 
 
+   if (dev_id-driver_data == SFC_GUID)
+   scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
+STORVSC_FC_MAX_TARGETS);
host = scsi_host_alloc(scsi_driver,
   sizeof(struct hv_host_device));
if (!host)
@@ -1789,12 +1791,25 @@ static int storvsc_probe(struct hv_device *device,
host_dev-path = stor_device-path_id;
host_dev-target = stor_device-target_id;
 
-   /* max # of devices per target */
-   host-max_lun = STORVSC_MAX_LUNS_PER_TARGET;
-   /* max # of targets per channel */
-   host-max_id = STORVSC_MAX_TARGETS;
-   /* max # of channels */
-   host-max_channel = STORVSC_MAX_CHANNELS - 1;
+   switch (dev_id-driver_data) {
+   case SFC_GUID:
+   host-max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET;
+   host-max_id = STORVSC_FC_MAX_TARGETS;
+   host-max_channel = STORVSC_FC_MAX_CHANNELS - 1;
+   break;
+
+   case SCSI_GUID:
+   host-max_lun = STORVSC_MAX_LUNS_PER_TARGET;
+   host-max_id = STORVSC_MAX_TARGETS;
+   host-max_channel = STORVSC_MAX_CHANNELS - 1;
+   break;
+
+   default:
+   host-max_lun = STORVSC_IDE_MAX_LUNS_PER_TARGET;
+   host-max_id = STORVSC_IDE_MAX_TARGETS;
+   host-max_channel = STORVSC_IDE_MAX_CHANNELS - 1;
+   break;
+   }
/* max cmd length */
host-max_cmd_len = STORVSC_MAX_CMD_LEN;
 
-- 
1.7.4.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 6/7] drivers: scsi: storvsc: Set srb_flags in all cases

2014-07-12 Thread K. Y. Srinivasan
Correctly set SRB flags for all valid I/O directions. Some IHV drivers on the
Windows host require this. The host validates the command and SRB flags
prior to passing the command down to native driver stack.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |   12 +---
 1 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3516761..9342ba4 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1599,26 +1599,24 @@ static int storvsc_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *scmnd)
vm_srb = cmd_request-vstor_packet.vm_srb;
vm_srb-win8_extension.time_out_value = 60;
 
+   vm_srb-win8_extension.srb_flags |=
+   (SRB_FLAGS_QUEUE_ACTION_ENABLE |
+   SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
 
/* Build the SRB */
switch (scmnd-sc_data_direction) {
case DMA_TO_DEVICE:
vm_srb-data_in = WRITE_TYPE;
vm_srb-win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT;
-   vm_srb-win8_extension.srb_flags |=
-   (SRB_FLAGS_QUEUE_ACTION_ENABLE |
-   SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
break;
case DMA_FROM_DEVICE:
vm_srb-data_in = READ_TYPE;
vm_srb-win8_extension.srb_flags |= SRB_FLAGS_DATA_IN;
-   vm_srb-win8_extension.srb_flags |=
-   (SRB_FLAGS_QUEUE_ACTION_ENABLE |
-   SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
break;
default:
vm_srb-data_in = UNKNOWN_TYPE;
-   vm_srb-win8_extension.srb_flags = 0;
+   vm_srb-win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN |
+SRB_FLAGS_DATA_OUT);
break;
}
 
-- 
1.7.4.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 7/7] drivers: scsi: storvsc: Correctly handle TEST_UNIT_READY failure

2014-07-12 Thread K. Y. Srinivasan
On some Windows hosts on FC SANs, TEST_UNIT_READY can return SRB_STATUS_ERROR.
Correctly handle this. Note that there is sufficient sense information to
support scsi error handling even in this case.

In this version of the patch I have addressed comments from
Christoph Hellwig h...@infradead.org

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 9342ba4..29d0329 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1018,6 +1018,13 @@ static void storvsc_handle_error(struct vmscsi_request 
*vm_srb,
case ATA_12:
set_host_byte(scmnd, DID_PASSTHROUGH);
break;
+   /*
+* On Some Windows hosts TEST_UNIT_READY command can return
+* SRB_STATUS_ERROR, let the upper level code deal with it
+* based on the sense information.
+*/
+   case TEST_UNIT_READY:
+   break;
default:
set_host_byte(scmnd, DID_TARGET_FAILURE);
}
-- 
1.7.4.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 V3 2/7] Drivers: scsi: storvsc: Set cmd_per_lun to reflect value supported by the Host

2014-07-12 Thread K. Y. Srinivasan
Set cmd_per_lun to reflect value supported by the Host.
In this version of the patch I have addressed comments from
Christoph Hellwig h...@infradead.org

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: sta...@vger.kernel.org
---
 drivers/scsi/storvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 8938b13..cebcef7 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1690,7 +1690,7 @@ static struct scsi_host_template scsi_driver = {
.slave_alloc =  storvsc_device_alloc,
.slave_destroy =storvsc_device_destroy,
.slave_configure =  storvsc_device_configure,
-   .cmd_per_lun =  1,
+   .cmd_per_lun =  255,
.can_queue =STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id =  -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
-- 
1.7.4.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


  1   2   >