Re: [PATCH v2 01/14] mpt3sas: Bug fix for big endian systems.

2018-05-01 Thread Sreekanth Reddy
On Wed, May 2, 2018 at 9:21 AM, Martin K. Petersen
 wrote:
>
> Hi Chaitra,
>
>>>  for (i = 0; i < ioc->combined_reply_index_count; i++) {
>>> -ioc->replyPostRegisterIndex[i] = (resource_size_t
>> *)
>>> - ((u8 *)&ioc->chip->Doorbell +
>>> +ioc->replyPostRegisterIndex[i] =
>>> +(volatile void __iomem *)
>>> + ((u8 __force *)&ioc->chip->Doorbell +
>>>   MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
>>>   (i *
>> MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET));
>>
>> Why the double type casts? You've already changed replyPostRegisterIndex
>> to be 'volatile void __iomem **' in the header file. So why not:
>>
>> ioc->replyPostRegisterIndex[i] =
>> &ioc->chip->Doorbell +
>> MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
>> i * 
>> MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET;
>
> You didn't address my question about why the type casts were required in
> the first place? I get cautious when I see nested casting...
>

Martin,

In v3 patch,we have removed this nested casting and just used (u8
__force) to fix the sparse warning.

~ Sreekanth


>> Also looks like ioc->reply_post_host_index handling a few lines further
>> down could lose the type casts.
>
> See above.
>
> --
> Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH v2 01/14] mpt3sas: Bug fix for big endian systems.

2018-05-01 Thread Martin K. Petersen

Hi Chaitra,

>>  for (i = 0; i < ioc->combined_reply_index_count; i++) {
>> -ioc->replyPostRegisterIndex[i] = (resource_size_t
> *)
>> - ((u8 *)&ioc->chip->Doorbell +
>> +ioc->replyPostRegisterIndex[i] =
>> +(volatile void __iomem *)
>> + ((u8 __force *)&ioc->chip->Doorbell +
>>   MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
>>   (i *
> MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET));
>
> Why the double type casts? You've already changed replyPostRegisterIndex
> to be 'volatile void __iomem **' in the header file. So why not:
>
> ioc->replyPostRegisterIndex[i] =
> &ioc->chip->Doorbell +
> MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET +
> i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET;

You didn't address my question about why the type casts were required in
the first place? I get cautious when I see nested casting...

> Also looks like ioc->reply_post_host_index handling a few lines further
> down could lose the type casts.

See above.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: mpt3sas: fix spelling mistake: "disbale" -> "disable"

2018-05-01 Thread Martin K. Petersen

Colin,

> Trivial fix to spelling mistake in module parameter description text

Ditto. Also hand-applied to 4.18/scsi-queue.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: megaraid_sas: fix spelling mistake: "disbale" -> "disable"

2018-05-01 Thread Martin K. Petersen

Colin,

> Trivial fix to spelling mistake in module parameter description text

Mangled patch. Applied by hand.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: esas2r: fix spelling mistake: "asynchromous" -> "asynchronous"

2018-05-01 Thread Martin K. Petersen

Colin,

> Trivial fix to spelling mistake in module description text

Applied to 4.18/scsi-queue.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: isci: remove redundant check on in_connection_align_insertion_frequency

2018-05-01 Thread Martin K. Petersen

Colin,

> The sanity check on u->in_connection_align_insertion_frequency is
> being performed twice and hence the first check can be removed since
> it is redundant. Cleans up cppcheck warning:
>
> drivers/scsi/ibmvscsi/ibmvscsi.c:1711: (warning) Identical inner 'if'
> condition is always true.

Applied to 4.18/scsi-queue. Thanks.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] aacraid: Correct hba_send to include iu_type

2018-05-01 Thread Martin K. Petersen

Dave,

> commit b60710ec7d7ab ("aacraid: enable sending of TMFs from aac_hba_send()")
>
> allows aac_hba_send() to send scsi commands, and TMF requests, but the 
> existing
> code only updates the iu_type for scsi commands. For TMF requests we are 
> sending
> an unknown iu_type to firmware, which causes a fault.
>
> Include iu_type prior to determining the validity of the command

Applied to 4.17/scsi-fixes. Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: vmw-pvscsi: return DID_BUS_BUSY for adapter-initated aborts

2018-05-01 Thread Martin K. Petersen

Jim,

> The vmw_pvscsi driver returns DID_ABORT for commands aborted internally
> by the adapter, leading to the filesystem going read-only. Change the
> result to DID_BUS_BUSY, causing the kernel to retry the command.

Applied to 4.17/scsi-fixes, thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


[RESEND V2 4/6] tcmu: refactor nl dev_cfg attr with new nl helpers

2018-05-01 Thread Zhu Lingshan
use new netlink events helpers tcmu_netlink_init() and
tcmu_netlink_send() to refactor netlink event attribute
TCMU_ATTR_DEV_CFG(belongs to TCMU_CMD_RECONFIG_DEVICE)
which is also dev_config in configFS.

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - return tcmu_netlink_event_send() directly, instead of a ret value.

 drivers/target/target_core_user.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index 24e1f0b3662e..21ce7dd8420d 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -2237,6 +2237,27 @@ static ssize_t tcmu_dev_config_show(struct config_item 
*item, char *page)
return snprintf(page, PAGE_SIZE, "%s\n", udev->dev_config);
 }
 
+static int tcmu_send_dev_config_event(struct tcmu_dev *udev,
+ const char *reconfig_data)
+{
+   struct sk_buff *skb = NULL;
+   void *msg_header = NULL;
+   int ret = 0;
+
+   ret = tcmu_netlink_event_init(udev, TCMU_CMD_RECONFIG_DEVICE,
+ &skb, &msg_header);
+   if (ret < 0)
+   return ret;
+   ret = nla_put_string(skb, TCMU_ATTR_DEV_CFG, reconfig_data);
+   if (ret < 0) {
+   nlmsg_free(skb);
+   return ret;
+   }
+   return tcmu_netlink_event_send(udev, TCMU_CMD_RECONFIG_DEVICE,
+  &skb, &msg_header);
+}
+
+
 static ssize_t tcmu_dev_config_store(struct config_item *item, const char 
*page,
 size_t count)
 {
@@ -2251,8 +2272,7 @@ static ssize_t tcmu_dev_config_store(struct config_item 
*item, const char *page,
 
/* Check if device has been configured before */
if (tcmu_dev_configured(udev)) {
-   ret = tcmu_netlink_event(udev, TCMU_CMD_RECONFIG_DEVICE,
-TCMU_ATTR_DEV_CFG, page);
+   ret = tcmu_send_dev_config_event(udev, page);
if (ret) {
pr_err("Unable to reconfigure device\n");
return ret;
-- 
2.14.3



[RESEND V2 5/6] tcmu: refactor nl dev_size attr with new helpers

2018-05-01 Thread Zhu Lingshan
use new netlink events helpers tcmu_netlink_init() and
tcmu_netlink_send() to refactor netlink event attribute
TCMU_ATTR_DEV_SIZE(belongs to TCMU_CMD_RECONFIG_DEVICE)
which is also dev_size in configFS.

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - return tcmu_netlink_event_send() directly, instead of a ret value.
  
 drivers/target/target_core_user.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index 21ce7dd8420d..c5bc2e1a9c49 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -2299,6 +2299,26 @@ static ssize_t tcmu_dev_size_show(struct config_item 
*item, char *page)
return snprintf(page, PAGE_SIZE, "%zu\n", udev->dev_size);
 }
 
+static int tcmu_send_dev_size_event(struct tcmu_dev *udev, u64 size)
+{
+   struct sk_buff *skb = NULL;
+   void *msg_header = NULL;
+   int ret = 0;
+
+   ret = tcmu_netlink_event_init(udev, TCMU_CMD_RECONFIG_DEVICE,
+ &skb, &msg_header);
+   if (ret < 0)
+   return ret;
+   ret = nla_put_u64_64bit(skb, TCMU_ATTR_DEV_SIZE,
+   size, TCMU_ATTR_PAD);
+   if (ret < 0) {
+   nlmsg_free(skb);
+   return ret;
+   }
+   return tcmu_netlink_event_send(udev, TCMU_CMD_RECONFIG_DEVICE,
+  &skb, &msg_header);
+}
+
 static ssize_t tcmu_dev_size_store(struct config_item *item, const char *page,
   size_t count)
 {
@@ -2314,8 +2334,7 @@ static ssize_t tcmu_dev_size_store(struct config_item 
*item, const char *page,
 
/* Check if device has been configured before */
if (tcmu_dev_configured(udev)) {
-   ret = tcmu_netlink_event(udev, TCMU_CMD_RECONFIG_DEVICE,
-TCMU_ATTR_DEV_SIZE, &val);
+   ret = tcmu_send_dev_size_event(udev, val);
if (ret) {
pr_err("Unable to reconfigure device\n");
return ret;
-- 
2.14.3



[RESEND V2 6/6] tcmu: refactor nl wr_cache attr with new helpers

2018-05-01 Thread Zhu Lingshan
use new netlink events helpers tcmu_netlink_init() and
tcmu_netlink_send() to refactor netlink event attribute
TCMU_ATTR_WRITECACHE(belongs to TCMU_CMD_RECONFIG_DEVICE)
which is also emulate_write_cache in configFS.

Removed tcmu_netlink_event() since we have new netlink
events helpers now.

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - return tcmu_netlink_event_send() directly, instead of a ret value.

 drivers/target/target_core_user.c | 89 +--
 1 file changed, 20 insertions(+), 69 deletions(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index c5bc2e1a9c49..5e7bb69488e1 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1586,73 +1586,6 @@ static int tcmu_wait_genl_cmd_reply(struct tcmu_dev 
*udev)
return ret;
 }
 
-static int tcmu_netlink_event(struct tcmu_dev *udev, enum tcmu_genl_cmd cmd,
- int reconfig_attr, const void *reconfig_data)
-{
-   struct sk_buff *skb;
-   void *msg_header;
-   int ret = -ENOMEM;
-
-   skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
-   if (!skb)
-   return ret;
-
-   msg_header = genlmsg_put(skb, 0, 0, &tcmu_genl_family, 0, cmd);
-   if (!msg_header)
-   goto free_skb;
-
-   ret = nla_put_string(skb, TCMU_ATTR_DEVICE, udev->uio_info.name);
-   if (ret < 0)
-   goto free_skb;
-
-   ret = nla_put_u32(skb, TCMU_ATTR_MINOR, udev->uio_info.uio_dev->minor);
-   if (ret < 0)
-   goto free_skb;
-
-   ret = nla_put_u32(skb, TCMU_ATTR_DEVICE_ID, udev->se_dev.dev_index);
-   if (ret < 0)
-   goto free_skb;
-
-   if (cmd == TCMU_CMD_RECONFIG_DEVICE) {
-   switch (reconfig_attr) {
-   case TCMU_ATTR_DEV_CFG:
-   ret = nla_put_string(skb, reconfig_attr, reconfig_data);
-   break;
-   case TCMU_ATTR_DEV_SIZE:
-   ret = nla_put_u64_64bit(skb, reconfig_attr,
-   *((u64 *)reconfig_data),
-   TCMU_ATTR_PAD);
-   break;
-   case TCMU_ATTR_WRITECACHE:
-   ret = nla_put_u8(skb, reconfig_attr,
- *((u8 *)reconfig_data));
-   break;
-   default:
-   BUG();
-   }
-
-   if (ret < 0)
-   goto free_skb;
-   }
-
-   genlmsg_end(skb, msg_header);
-
-   tcmu_init_genl_cmd_reply(udev, cmd);
-
-   ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0,
-   TCMU_MCGRP_CONFIG, GFP_KERNEL);
-   /* We don't care if no one is listening */
-   if (ret == -ESRCH)
-   ret = 0;
-   if (!ret)
-   ret = tcmu_wait_genl_cmd_reply(udev);
-
-   return ret;
-free_skb:
-   nlmsg_free(skb);
-   return ret;
-}
-
 static int tcmu_netlink_event_init(struct tcmu_dev *udev,
   enum tcmu_genl_cmd cmd,
   struct sk_buff **buf, void **hdr)
@@ -2382,6 +2315,25 @@ static ssize_t tcmu_emulate_write_cache_show(struct 
config_item *item,
return snprintf(page, PAGE_SIZE, "%i\n", da->emulate_write_cache);
 }
 
+static int tcmu_send_emulate_write_cache(struct tcmu_dev *udev, u8 val)
+{
+   struct sk_buff *skb = NULL;
+   void *msg_header = NULL;
+   int ret = 0;
+
+   ret = tcmu_netlink_event_init(udev, TCMU_CMD_RECONFIG_DEVICE,
+ &skb, &msg_header);
+   if (ret < 0)
+   return ret;
+   ret = nla_put_u8(skb, TCMU_ATTR_WRITECACHE, val);
+   if (ret < 0) {
+   nlmsg_free(skb);
+   return ret;
+   }
+   return tcmu_netlink_event_send(udev, TCMU_CMD_RECONFIG_DEVICE,
+  &skb, &msg_header);
+}
+
 static ssize_t tcmu_emulate_write_cache_store(struct config_item *item,
  const char *page, size_t count)
 {
@@ -2397,8 +2349,7 @@ static ssize_t tcmu_emulate_write_cache_store(struct 
config_item *item,
 
/* Check if device has been configured before */
if (tcmu_dev_configured(udev)) {
-   ret = tcmu_netlink_event(udev, TCMU_CMD_RECONFIG_DEVICE,
-TCMU_ATTR_WRITECACHE, &val);
+   ret = tcmu_send_emulate_write_cache(udev, val);
if (ret) {
pr_err("Unable to reconfigure device\n");
return ret;
-- 
2.14.3



[RESEND V2 3/6] tcmu: refactor rm_device cmd with new nl helpers

2018-05-01 Thread Zhu Lingshan
use new netlink events helpers tcmu_netlink_init() and
tcmu_netlink_send() to refactor netlink event
TCMU_CMD_REMOVED_DEVICE

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - return tcmu_netlink_event_send() directly, instead of a ret value.

 drivers/target/target_core_user.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index 52d0e868a192..24e1f0b3662e 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1727,6 +1727,20 @@ static int tcmu_send_dev_add_event(struct tcmu_dev *udev)
 
 }
 
+static int tcmu_send_dev_remove_event(struct tcmu_dev *udev)
+{
+   struct sk_buff *skb = NULL;
+   void *msg_header = NULL;
+   int ret = 0;
+
+   ret = tcmu_netlink_event_init(udev, TCMU_CMD_REMOVED_DEVICE,
+ &skb, &msg_header);
+   if (ret < 0)
+   return ret;
+   return tcmu_netlink_event_send(udev, TCMU_CMD_REMOVED_DEVICE,
+  &skb, &msg_header);
+}
+
 static int tcmu_update_uio_info(struct tcmu_dev *udev)
 {
struct tcmu_hba *hba = udev->hba->hba_ptr;
@@ -1886,7 +1900,7 @@ static void tcmu_destroy_device(struct se_device *dev)
list_del(&udev->node);
mutex_unlock(&root_udev_mutex);
 
-   tcmu_netlink_event(udev, TCMU_CMD_REMOVED_DEVICE, 0, NULL);
+   tcmu_send_dev_remove_event(udev);
 
uio_unregister_device(&udev->uio_info);
 
-- 
2.14.3



[RESEND V2 2/6] tcmu: refactor add_device cmd with new nl helpers

2018-05-01 Thread Zhu Lingshan
use new netlink events helpers tcmu_netlink_init() and
tcmu_netlink_send() to refactor netlink event
TCMU_CMD_ADDED_DEVICE

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - return tcmu_netlink_event_send() directly, instead of a ret value.

 drivers/target/target_core_user.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index d8f6a53f6bca..52d0e868a192 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1712,6 +1712,21 @@ static int tcmu_netlink_event_send(struct tcmu_dev *udev,
return ret;
 }
 
+static int tcmu_send_dev_add_event(struct tcmu_dev *udev)
+{
+   struct sk_buff *skb = NULL;
+   void *msg_header = NULL;
+   int ret = 0;
+
+   ret = tcmu_netlink_event_init(udev, TCMU_CMD_ADDED_DEVICE, &skb,
+ &msg_header);
+   if (ret < 0)
+   return ret;
+   return tcmu_netlink_event_send(udev, TCMU_CMD_ADDED_DEVICE, &skb,
+  &msg_header);
+
+}
+
 static int tcmu_update_uio_info(struct tcmu_dev *udev)
 {
struct tcmu_hba *hba = udev->hba->hba_ptr;
@@ -1821,7 +1836,7 @@ static int tcmu_configure_device(struct se_device *dev)
 */
kref_get(&udev->kref);
 
-   ret = tcmu_netlink_event(udev, TCMU_CMD_ADDED_DEVICE, 0, NULL);
+   ret = tcmu_send_dev_add_event(udev);
if (ret)
goto err_netlink;
 
-- 
2.14.3



[RESEND V2 1/6] tcmu: add new netlink events helpers

2018-05-01 Thread Zhu Lingshan
Add new netlink events helpers tcmu_netlink_event_init() and
tcmu_netlink_event_send(). These new functions intend to replace
exsiting netlink events helper function tcmu_netlink_event().

The exsiting function tcmu_netlink_event() works well for events
like TCMU_ADDED_DEVICE and TCMU_REMOVED_DEVICE which only has one
netlink attribute. But if there is a command requires more than
one attributes to send out, we have to use a struct to adapt the
paremeter reconfig_data, it is hard to use one struct or a union
in one struct to adapt every command with different attributes,
it may get long and ugly.

With the new two functions, we can call tcmu_netlink_event_init()
to initialize a netlink event, then add all attributes we need by
using nla_put_xxx(), at last use tcmu_netlink_event_send() to
send it out. So that we don't need to use a long struct or union
if we want to send mulitple attributes for different commands.

Signed-off-by: Zhu Lingshan 
---
Changes in V2:
  - Add new blank lines for better code style, easier to
scan the chunks

 drivers/target/target_core_user.c | 59 +++
 1 file changed, 59 insertions(+)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index 4ad89ea71a70..d8f6a53f6bca 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1653,6 +1653,65 @@ static int tcmu_netlink_event(struct tcmu_dev *udev, 
enum tcmu_genl_cmd cmd,
return ret;
 }
 
+static int tcmu_netlink_event_init(struct tcmu_dev *udev,
+  enum tcmu_genl_cmd cmd,
+  struct sk_buff **buf, void **hdr)
+{
+   struct sk_buff *skb;
+   void *msg_header;
+   int ret = -ENOMEM;
+
+   skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+   if (!skb)
+   return ret;
+
+   msg_header = genlmsg_put(skb, 0, 0, &tcmu_genl_family, 0, cmd);
+   if (!msg_header)
+   goto free_skb;
+
+   ret = nla_put_string(skb, TCMU_ATTR_DEVICE, udev->uio_info.name);
+   if (ret < 0)
+   goto free_skb;
+
+   ret = nla_put_u32(skb, TCMU_ATTR_MINOR, udev->uio_info.uio_dev->minor);
+   if (ret < 0)
+   goto free_skb;
+
+   ret = nla_put_u32(skb, TCMU_ATTR_DEVICE_ID, udev->se_dev.dev_index);
+   if (ret < 0)
+   goto free_skb;
+
+   *buf = skb;
+   *hdr = msg_header;
+   return ret;
+
+free_skb:
+   nlmsg_free(skb);
+   return ret;
+}
+
+static int tcmu_netlink_event_send(struct tcmu_dev *udev,
+  enum tcmu_genl_cmd cmd,
+  struct sk_buff **buf, void **hdr)
+{
+   int ret = 0;
+   struct sk_buff *skb = *buf;
+   void *msg_header = *hdr;
+
+   genlmsg_end(skb, msg_header);
+
+   tcmu_init_genl_cmd_reply(udev, cmd);
+
+   ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0,
+ TCMU_MCGRP_CONFIG, GFP_KERNEL);
+   /* We don't care if no one is listening */
+   if (ret == -ESRCH)
+   ret = 0;
+   if (!ret)
+   ret = tcmu_wait_genl_cmd_reply(udev);
+   return ret;
+}
+
 static int tcmu_update_uio_info(struct tcmu_dev *udev)
 {
struct tcmu_hba *hba = udev->hba->hba_ptr;
-- 
2.14.3



Re: [PATCH] scsi_transport_sas: don't bounce highmem pages for the smp handler

2018-05-01 Thread Martin K. Petersen

Christoph,

> All three instance of ->smp_handler deal with highmem backed requests
> just fine.

Applied to 4.18/scsi-queue. Thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] bsg referencing bus driver module

2018-05-01 Thread Anatoliy Glagolev
Any comments on the new patch (which, I think, addresses the concern
about module being stuck in unloadable state forever; if not, there
would be a leak in the bsg layer)? Or on dropping a reference
to bsg_class_device's parent early before the bsg_class_device
itself is gone, to implement James's idea of cutting of the bsg
layer at fc_bsg_remove time?

Thanks.

On Thu, Apr 26, 2018 at 06:01:00PM -0600, Anatoliy Glagolev wrote:
> Any thoughts on this? Can we really drop a reference from a child device
> (bsg_class_device) to a parent device (Scsi_Host) while the child device
> is still around at fc_bsg_remove time?
> 
> If not, please consider a fix with module references. I realized that
> the previous version of the fix had a problem since bsg_open may run
> more often than bsg_release. Sending a newer version... The new fix
> piggybacks on the bsg layer logic allocating/freeing bsg_device structs.
> When all those structs are gone there are no references to Scsi_Host from
> the user-mode side. The only remaining references are from a SCSI bus
> driver (like qla2xxx) itself; it is safe to drop the module reference
> at that time.
> 
> 
> From c744d4fd93578545ad12faa35a3354364793b124 Mon Sep 17 00:00:00 2001
> From: Anatoliy Glagolev 
> Date: Wed, 25 Apr 2018 19:16:10 -0600
> Subject: [PATCH] bsg referencing parent module
> Signed-off-by: Anatoliy Glagolev 
> 
> Fixing a bug when bsg layer holds the last reference to device
> when the device's module has been unloaded. Upon dropping the
> reference the device's release function may touch memory of
> the unloaded module.
> ---
>  block/bsg-lib.c  | 24 ++--
>  block/bsg.c  | 22 +-
>  drivers/scsi/scsi_transport_fc.c |  8 ++--
>  include/linux/bsg-lib.h  |  4 
>  include/linux/bsg.h  |  5 +
>  5 files changed, 58 insertions(+), 5 deletions(-)
> 
> diff --git a/block/bsg-lib.c b/block/bsg-lib.c
> index fc2e5ff..bb11786 100644
> --- a/block/bsg-lib.c
> +++ b/block/bsg-lib.c
> @@ -309,6 +309,25 @@ struct request_queue *bsg_setup_queue(struct device 
> *dev, const char *name,
>   bsg_job_fn *job_fn, int dd_job_size,
>   void (*release)(struct device *))
>  {
> + return bsg_setup_queue_ex(dev, name, job_fn, dd_job_size, release,
> + NULL);
> +}
> +EXPORT_SYMBOL_GPL(bsg_setup_queue);
> +
> +/**
> + * bsg_setup_queue_ex - Create and add the bsg hooks so we can receive 
> requests
> + * @dev: device to attach bsg device to
> + * @name: device to give bsg device
> + * @job_fn: bsg job handler
> + * @dd_job_size: size of LLD data needed for each job
> + * @release: @dev release function
> + * @dev_module: @dev's module
> + */
> +struct request_queue *bsg_setup_queue_ex(struct device *dev, const char 
> *name,
> + bsg_job_fn *job_fn, int dd_job_size,
> + void (*release)(struct device *),
> + struct module *dev_module)
> +{
>   struct request_queue *q;
>   int ret;
>  
> @@ -331,7 +350,8 @@ struct request_queue *bsg_setup_queue(struct device *dev, 
> const char *name,
>   blk_queue_softirq_done(q, bsg_softirq_done);
>   blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
>  
> - ret = bsg_register_queue(q, dev, name, &bsg_transport_ops, release);
> + ret = bsg_register_queue_ex(q, dev, name, &bsg_transport_ops, release,
> + dev_module);
>   if (ret) {
>   printk(KERN_ERR "%s: bsg interface failed to "
>  "initialize - register queue\n", dev->kobj.name);
> @@ -343,4 +363,4 @@ struct request_queue *bsg_setup_queue(struct device *dev, 
> const char *name,
>   blk_cleanup_queue(q);
>   return ERR_PTR(ret);
>  }
> -EXPORT_SYMBOL_GPL(bsg_setup_queue);
> +EXPORT_SYMBOL_GPL(bsg_setup_queue_ex);
> diff --git a/block/bsg.c b/block/bsg.c
> index defa06c..950cd31 100644
> --- a/block/bsg.c
> +++ b/block/bsg.c
> @@ -666,6 +666,7 @@ static int bsg_put_device(struct bsg_device *bd)
>  {
>   int ret = 0, do_free;
>   struct request_queue *q = bd->queue;
> + struct module *parent_module = q->bsg_dev.parent_module;
>  
>   mutex_lock(&bsg_mutex);
>  
> @@ -695,8 +696,11 @@ static int bsg_put_device(struct bsg_device *bd)
>   kfree(bd);
>  out:
>   kref_put(&q->bsg_dev.ref, bsg_kref_release_function);
> - if (do_free)
> + if (do_free) {
>   blk_put_queue(q);
> + if (parent_module)
> + module_put(parent_module);
> + }
>   return ret;
>  }
>  
> @@ -706,12 +710,19 @@ static struct bsg_device *bsg_add_device(struct inode 
> *inode,
>  {
>   struct bsg_device *bd;
>   unsigned char buf[32];
> + struct module *parent_module = rq->bsg_dev.parent_module;
>  
>   if (!blk_get_queue(rq))
>   return ERR_PTR(-ENXIO);
>  
> + if (parent_module) {
> + if (!try_module_get(parent_module))
> + return ER

[PATCH 10/12] qla2xxx: Prevent relogin loop by removing stale code

2018-05-01 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 3405cb9031b6..1aa3720ea2ed 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1332,20 +1332,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
fc_port_t *fcport;
 
switch (ea->event) {
-   case FCME_RSCN:
-   case FCME_GIDPN_DONE:
-   case FCME_GPSC_DONE:
-   case FCME_GPNID_DONE:
-   case FCME_GNNID_DONE:
-   if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
-   test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))
-   return;
-   break;
-   default:
-   break;
-   }
-
-   switch (ea->event) {
case FCME_RELOGIN:
if (test_bit(UNLOADING, &vha->dpc_flags))
return;
-- 
2.12.0



[PATCH 09/12] qla2xxx: Remove stale debug value for login_retry flag

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 792c09470c5a..3405cb9031b6 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4517,7 +4517,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
fcport->deleted = QLA_SESS_DELETED;
fcport->login_retry = vha->hw->login_retry_count;
-   fcport->login_retry = 5;
fcport->logout_on_delete = 1;
 
if (!fcport->ct_desc.ct_sns) {
-- 
2.12.0



[PATCH 12/12] qla2xxx: Update driver version to 10.00.00.07-k

2018-05-01 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index 0c55d7057280..1ad7582220c3 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "10.00.00.06-k"
+#define QLA2XXX_VERSION  "10.00.00.07-k"
 
 #define QLA_DRIVER_MAJOR_VER   10
 #define QLA_DRIVER_MINOR_VER   0
-- 
2.12.0



[PATCH 07/12] qla2xxx: Fix Inquiry command being dropped in Target mode

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

When a connection is established, the target core session
may not be created immediately. Current code will drop/terminate
the command based on the session state. This patch will return
BUSY status for any commands arriving on wire before the session
is created.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 3e8bf728e884..5e81b64c8ef5 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -5140,10 +5140,15 @@ static int __qlt_send_busy(struct qla_qpair *qpair,
struct fc_port *sess = NULL;
unsigned long flags;
u16 temp;
+   port_id_t id;
+
+   id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2];
+   id.b.area = atio->u.isp24.fcp_hdr.s_id[1];
+   id.b.domain = atio->u.isp24.fcp_hdr.s_id[0];
+   id.b.rsvd_1 = 0;
 
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
-   sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha,
-   atio->u.isp24.fcp_hdr.s_id);
+   sess = qla2x00_find_fcport_by_nportid(vha, &id, 1);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
if (!sess) {
qlt_send_term_exchange(qpair, NULL, atio, 1, 0);
-- 
2.12.0



[PATCH 11/12] qla2xxx: Fix TMF and Multi-Queue config

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

For target mode, task management command is queued to specific
cpu base on where the scsi command is residing.  This prevent
race condition of task management command getting ahead of
regular scsi command.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c  | 135 ++---
 drivers/scsi/qla2xxx/qla_target.h  |   4 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  27 
 3 files changed, 141 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index a77703f655ed..b85c833099ff 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1924,13 +1924,84 @@ static void abort_cmds_for_lun(struct scsi_qla_host 
*vha,
spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
 }
 
+static struct qla_qpair_hint *qlt_find_qphint(struct scsi_qla_host *vha,
+uint64_t unpacked_lun)
+{
+   struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+   struct qla_qpair_hint *h = NULL;
+
+   if (vha->flags.qpairs_available) {
+   h = btree_lookup64(&tgt->lun_qpair_map, unpacked_lun);
+   if (!h)
+   h = &tgt->qphints[0];
+   } else {
+   h = &tgt->qphints[0];
+   }
+
+   return h;
+}
+
+static void qlt_do_tmr_work(struct work_struct *work)
+{
+   struct qla_tgt_mgmt_cmd *mcmd =
+   container_of(work, struct qla_tgt_mgmt_cmd, work);
+   struct qla_hw_data *ha = mcmd->vha->hw;
+   int rc = EIO;
+   uint32_t tag;
+   unsigned long flags;
+
+   switch (mcmd->tmr_func) {
+   case QLA_TGT_ABTS:
+   tag = mcmd->orig_iocb.abts.exchange_addr_to_abort;
+   break;
+   default:
+   tag = 0;
+   break;
+   }
+
+   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, mcmd->unpacked_lun,
+   mcmd->tmr_func, tag);
+
+   if (rc != 0) {
+   spin_lock_irqsave(mcmd->qpair->qp_lock_ptr, flags);
+   switch (mcmd->tmr_func) {
+   case QLA_TGT_ABTS:
+   qlt_24xx_send_abts_resp(mcmd->qpair,
+   &mcmd->orig_iocb.abts,
+   FCP_TMF_REJECTED, false);
+   break;
+   case QLA_TGT_LUN_RESET:
+   case QLA_TGT_CLEAR_TS:
+   case QLA_TGT_ABORT_TS:
+   case QLA_TGT_CLEAR_ACA:
+   case QLA_TGT_TARGET_RESET:
+   qlt_send_busy(mcmd->qpair, &mcmd->orig_iocb.atio,
+   qla_sam_status);
+   break;
+
+   case QLA_TGT_ABORT_ALL:
+   case QLA_TGT_NEXUS_LOSS_SESS:
+   case QLA_TGT_NEXUS_LOSS:
+   qlt_send_notify_ack(mcmd->qpair,
+   &mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0);
+   break;
+   }
+   spin_unlock_irqrestore(mcmd->qpair->qp_lock_ptr, flags);
+
+   ql_dbg(ql_dbg_tgt_mgt, mcmd->vha, 0xf052,
+   "qla_target(%d):  tgt_ops->handle_tmr() failed: %d\n",
+   mcmd->vha->vp_idx, rc);
+   mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool);
+   }
+}
+
 /* ha->hardware_lock supposed to be held on entry */
 static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct abts_recv_from_24xx *abts, struct fc_port *sess)
 {
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
-   int rc;
+   struct qla_qpair_hint *h = &vha->vha_tgt.qla_tgt->qphints[0];
 
if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
/* send TASK_ABORT response immediately */
@@ -1955,23 +2026,29 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host 
*vha,
memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
mcmd->reset_count = ha->base_qpair->chip_reset;
mcmd->tmr_func = QLA_TGT_ABTS;
-   mcmd->qpair = ha->base_qpair;
+   mcmd->qpair = h->qpair;
mcmd->vha = vha;
 
/*
 * LUN is looked up by target-core internally based on the passed
 * abts->exchange_addr_to_abort tag.
 */
-   rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, mcmd->tmr_func,
-   abts->exchange_addr_to_abort);
-   if (rc != 0) {
-   ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
-   "qla_target(%d):  tgt_ops->handle_tmr()"
-   " failed: %d", vha->vp_idx, rc);
-   mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool);
-   return -EFAULT;
+   mcmd->se_cmd.cpuid = h->cpuid;
+
+   if (ha->tgt.tgt_ops->find_cmd_by_tag) {
+   struct qla_tgt_cmd *abort_cmd;
+
+   abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
+   abts->exchange_addr_to_abort);
+   if (abort_cmd && abort_cmd->qpair) {
+

[PATCH 03/12] qla2xxx: Fix Rport and session state getting out of sync

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

This patch fixes rport state and session state getting
out of sync.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 025dc2d3f3de..85640707cceb 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -601,24 +601,18 @@ void qla2x00_async_nack_sp_done(void *s, int res)
 
vha->fcport_count++;
 
-   if (!IS_IIDMA_CAPABLE(vha->hw) ||
-   !vha->hw->flags.gpsc_supported) {
-   ql_dbg(ql_dbg_disc, vha, 0x20f3,
-   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
-   __func__, __LINE__,
-   sp->fcport->port_name,
-   vha->fcport_count);
-   sp->fcport->disc_state = DSC_UPD_FCPORT;
-   qla24xx_post_upd_fcport_work(vha, sp->fcport);
-   } else {
-   ql_dbg(ql_dbg_disc, vha, 0x20f5,
-   "%s %d %8phC post gpsc fcp_cnt %d\n",
-   __func__, __LINE__,
-   sp->fcport->port_name,
-   vha->fcport_count);
-
-   qla24xx_post_gpsc_work(vha, sp->fcport);
-   }
+   ql_dbg(ql_dbg_disc, vha, 0x20f3,
+   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
+   __func__, __LINE__,
+   sp->fcport->port_name,
+   vha->fcport_count);
+   sp->fcport->disc_state = DSC_UPD_FCPORT;
+   qla24xx_post_upd_fcport_work(vha, sp->fcport);
+   } else {
+   sp->fcport->login_retry = 0;
+   sp->fcport->disc_state = DSC_LOGIN_COMPLETE;
+   sp->fcport->deleted = 0;
+   sp->fcport->logout_on_delete = 1;
}
break;
 
-- 
2.12.0



[PATCH 06/12] qla2xxx: Move GPSC and GFPNID out of session management

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

Move GPSC & GFPNID commands out of session management to reduce
time lag in reporting the session state to remote port. These
commands are not essential when it comes to maintaining the
rport state. Delay sending these commands after rport state is
set to Online.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  3 +-
 drivers/scsi/qla2xxx/qla_gbl.h|  3 +-
 drivers/scsi/qla2xxx/qla_gs.c | 10 +
 drivers/scsi/qla2xxx/qla_init.c   | 78 +++
 drivers/scsi/qla2xxx/qla_os.c |  4 ++
 drivers/scsi/qla2xxx/qla_target.c |  1 -
 6 files changed, 55 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index b4d98e3f2416..eab40acde9ea 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2285,8 +2285,6 @@ enum discovery_state {
DSC_LOGIN_PEND,
DSC_LOGIN_FAILED,
DSC_GPDB,
-   DSC_GFPN_ID,
-   DSC_GPSC,
DSC_UPD_FCPORT,
DSC_LOGIN_COMPLETE,
DSC_ADISC,
@@ -3234,6 +3232,7 @@ enum qla_work_type {
QLA_EVT_GNNID,
QLA_EVT_GFPNID,
QLA_EVT_SP_RETRY,
+   QLA_EVT_IIDMA,
 };
 
 
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 3c4c84ed0f0f..f68eb6096559 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -116,7 +116,8 @@ extern int qla2x00_post_async_prlo_work(struct 
scsi_qla_host *, fc_port_t *,
 uint16_t *);
 extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *,
 fc_port_t *, uint16_t *);
-
+int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
+void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
 /*
  * Global Data in qla_os.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 939ac8435f19..4bc2b66b299f 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3175,7 +3175,6 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t 
*fcport)
 
 done_free_sp:
sp->free(sp);
-   fcport->flags &= ~FCF_ASYNC_SENT;
 done:
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return rval;
@@ -3239,7 +3238,7 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
return;
}
 
-   qla24xx_post_upd_fcport_work(vha, ea->fcport);
+   qla_post_iidma_work(vha, fcport);
 }
 
 static void qla24xx_async_gpsc_sp_done(void *s, int res)
@@ -3257,8 +3256,6 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
"Async done-%s res %x, WWPN %8phC \n",
sp->name, res, fcport->port_name);
 
-   fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
-
if (res == (DID_ERROR << 16)) {
/* entry status error */
goto done;
@@ -3327,7 +3324,6 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t 
*fcport)
if (!sp)
goto done;
 
-   fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gpsc";
sp->gen1 = fcport->rscn_gen;
@@ -4555,7 +4551,6 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t 
*fcport)
 
 done_free_sp:
sp->free(sp);
-   fcport->flags &= ~FCF_ASYNC_SENT;
 done:
return rval;
 }
@@ -4617,7 +4612,6 @@ static void qla2x00_async_gfpnid_sp_done(void *s, int res)
struct event_arg ea;
u64 wwn;
 
-   fcport->flags &= ~FCF_ASYNC_SENT;
wwn = wwn_to_u64(fpn);
if (wwn)
memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
@@ -4646,12 +4640,10 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, 
fc_port_t *fcport)
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
return rval;
 
-   fcport->disc_state = DSC_GFPN_ID;
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto done;
 
-   fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gfpnid";
sp->gen1 = fcport->rscn_gen;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 98d4b315d66a..792c09470c5a 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1021,30 +1021,11 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
vha->fcport_count++;
ea->fcport->login_succ = 1;
 
-   if (!IS_IIDMA_CAPABLE(vha->hw) ||
-   !vha->hw->flags.gpsc_supported) {
-   ql_dbg(ql_dbg_disc, vha, 0x20d6,
-   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
-   __func__, __LINE__,  ea->fcport->port_name,
-   vha->fcport_count);
-
-   qla24xx_post_upd_fcport_work(vha, ea->fcport);
-   } else

[PATCH 04/12] qla2xxx: Delete session for nport id change

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

This patch fixes regression introduced by commit a4239945b8ad
("scsi: qla2xxx: Add switch command to simplify fabric discovery").
to schedule session deletion, when Nport ID changes.

Fixes: a4239945b8ad ("scsi: qla2xxx: Add switch command to simplify fabric 
discovery")
Cc: 
Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 9e914f9c3ffb..05abe5aaab7f 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3915,7 +3915,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
continue;
fcport->scan_state = QLA_FCPORT_FOUND;
-   fcport->d_id.b24 = rp->id.b24;
found = true;
/*
 * If device was not a fabric device before.
@@ -3923,7 +3922,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, 
srb_t *sp)
if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
qla2x00_clear_loop_id(fcport);
fcport->flags |= FCF_FABRIC_DEVICE;
+   } else if (fcport->d_id.b24 != rp->id.b24) {
+   qlt_schedule_sess_for_deletion(fcport);
}
+   fcport->d_id.b24 = rp->id.b24;
break;
}
 
-- 
2.12.0



[PATCH 05/12] qla2xxx: Reduce redundant ADISC command for RSCNs

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

For each RSCN that triggers a rescan of the fabric,
ADISC is used to revalidate an existing session. if the
RSCN is not affecting all existing sessions, then driver
should not send redundant ADISC for all existing sessions.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h  |  1 +
 drivers/scsi/qla2xxx/qla_gs.c   | 27 ---
 drivers/scsi/qla2xxx/qla_init.c |  6 ++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c36e37fdc201..b4d98e3f2416 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2352,6 +2352,7 @@ typedef struct fc_port {
unsigned int login_succ:1;
unsigned int query:1;
unsigned int id_changed:1;
+   unsigned int rscn_rcvd:1;
 
struct work_struct nvme_del_work;
struct completion nvme_del_done;
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 05abe5aaab7f..939ac8435f19 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3862,6 +3862,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
bool found;
struct fab_scan_rp *rp;
unsigned long flags;
+   u8 recheck = 0;
 
ql_dbg(ql_dbg_disc, vha, 0x,
"%s enter\n", __func__);
@@ -3914,6 +3915,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t 
*sp)
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
continue;
+   fcport->rscn_rcvd = 0;
fcport->scan_state = QLA_FCPORT_FOUND;
found = true;
/*
@@ -3942,10 +3944,13 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, 
srb_t *sp)
 * Logout all previous fabric dev marked lost, except FCP2 devices.
 */
list_for_each_entry(fcport, &vha->vp_fcports, list) {
-   if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
+   if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
+   fcport->rscn_rcvd = 0;
continue;
+   }
 
if (fcport->scan_state != QLA_FCPORT_FOUND) {
+   fcport->rscn_rcvd = 0;
if ((qla_dual_mode_enabled(vha) ||
qla_ini_mode_enabled(vha)) &&
atomic_read(&fcport->state) == FCS_ONLINE) {
@@ -3963,15 +3968,31 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, 
srb_t *sp)
continue;
}
}
-   } else
-   qla24xx_fcport_handle_login(vha, fcport);
+   } else {
+   if (fcport->rscn_rcvd ||
+   fcport->disc_state != DSC_LOGIN_COMPLETE) {
+   fcport->rscn_rcvd = 0;
+   qla24xx_fcport_handle_login(vha, fcport);
+   }
+   }
}
 
+   recheck = 1;
 out:
qla24xx_sp_unmap(vha, sp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
+
+   if (recheck) {
+   list_for_each_entry(fcport, &vha->vp_fcports, list) {
+   if (fcport->rscn_rcvd) {
+   set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+   set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+   break;
+   }
+   }
+   }
 }
 
 static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b9050cb52c0e..98d4b315d66a 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1348,6 +1348,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
fc_port_t *f, *tf;
uint32_t id = 0, mask, rid;
unsigned long flags;
+   fc_port_t *fcport;
 
switch (ea->event) {
case FCME_RSCN:
@@ -1375,6 +1376,11 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, 
struct event_arg *ea)
return;
switch (ea->id.b.rsvd_1) {
case RSCN_PORT_ADDR:
+   fcport = qla2x00_find_fcport_by_nportid
+   (vha, &ea->id, 1);
+   if (fcport)
+   fcport->rscn_rcvd = 1;
+
spin_lock_irqsave(&vha->work_lock, flags);
if (vha->scan.scan_flags == 0) {
ql

[PATCH 00/12] qla2xxx: Updates for driver

2018-05-01 Thread Himanshu Madhani
Hi Martin, 

This series contains updates for driver.

Please apply this to 4.18 scsi-misc branch at your earliest convenience.

Thanks,
Himanshu

Himanshu Madhani (3):
  qla2xxx: Add Laser Control for ISP26XX/27XX
  qla2xxx: Prevent relogin loop by removing stale code
  qla2xxx: Update driver version to 10.00.00.07-k

Quinn Tran (9):
  qla2xxx: Fix sending ADISC command for login
  qla2xxx: Fix Rport and session state getting out of sync
  qla2xxx: Delete session for nport id change
  qla2xxx: Reduce redundant ADISC command for RSCNs
  qla2xxx: Move GPSC and GFPNID out of session management
  qla2xxx: Fix Inquiry command being dropped in Target mode
  qla2xxx: Use predefined get_datalen_for_atio() inline function
  qla2xxx: Remove stale debug value for login_retry flag
  qla2xxx: Fix TMF and Multi-Queue config

 drivers/scsi/qla2xxx/qla_def.h |  11 ++-
 drivers/scsi/qla2xxx/qla_fw.h  |   2 +
 drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
 drivers/scsi/qla2xxx/qla_gs.c  |  41 +---
 drivers/scsi/qla2xxx/qla_init.c| 105 ++--
 drivers/scsi/qla2xxx/qla_inline.h  |  22 +
 drivers/scsi/qla2xxx/qla_os.c  |  76 +++
 drivers/scsi/qla2xxx/qla_target.c  | 192 ++---
 drivers/scsi/qla2xxx/qla_target.h  |   4 +-
 drivers/scsi/qla2xxx/qla_version.h |   2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |  27 ++
 11 files changed, 362 insertions(+), 123 deletions(-)

-- 
2.12.0



[PATCH 01/12] qla2xxx: Add Laser Control for ISP26XX/27XX

2018-05-01 Thread Himanshu Madhani
From: Himanshu Madhani 

This patch disables laser while unloading driver for 16/32G adapters.

Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  7 
 drivers/scsi/qla2xxx/qla_fw.h |  2 ++
 drivers/scsi/qla2xxx/qla_inline.h | 22 
 drivers/scsi/qla2xxx/qla_os.c | 72 +++
 4 files changed, 103 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index eb2ec1fb07cb..c36e37fdc201 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -201,6 +201,10 @@
 #define LASER_ON_2031  0x01800100
 #define LASER_OFF_2031 0x01800180
 
+/* ISP27XX: Values for Laser ON/Off */
+#define LASER_ON_27XX   0x0040
+#define LASER_OFF_27XX  0x00400040
+
 /*
  * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
  * 133Mhz slot.
@@ -705,6 +709,8 @@ struct device_reg_2xxx {
 #define GPIO_LED_ALL_OFF   0x
 #define GPIO_LED_RED_ON_OTHER_OFF  0x0001  /* isp2322 */
 #define GPIO_LED_RGA_ON0x00C1  /* isp2322: red green 
amber */
+#define GPIO_LASER_MASKBIT_6
+#define GPIO_LASER_DISABLE BIT_2
 
union {
struct {
@@ -3161,6 +3167,7 @@ struct isp_operations {
int (*abort_isp) (struct scsi_qla_host *);
int (*iospace_config)(struct qla_hw_data*);
int (*initialize_adapter)(struct scsi_qla_host *);
+   void (*disable_laser)(struct scsi_qla_host *);
 };
 
 /* MSI-X Support */
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 5d8688e5bc7c..b11ae7d04c43 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1096,6 +1096,8 @@ struct device_reg_24xx {
 #define GPDX_LED_AMBER_ON  BIT_4
/* Data in/out. */
 #define GPDX_DATA_INOUT(BIT_1|BIT_0)
+#define GPDX_LASER_MASKBIT_22
+#define GPDX_LASER_DISABLE BIT_6
 
uint32_t gpioe; /* GPIO Enable register. */
/* Enable update mask. */
diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 37ae0f6d8ae5..6ac96322fec1 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -367,3 +367,25 @@ qla_83xx_start_iocbs(struct qla_qpair *qpair)
 
WRT_REG_DWORD(req->req_q_in, req->ring_index);
 }
+
+static inline void
+qla24xx_drive_gpio(scsi_qla_host_t *vha)
+{
+   struct qla_hw_data *ha = vha->hw;
+
+   /* Take control of GPIO register. */
+   ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL;
+   qla2x00_set_fw_options(vha, ha->fw_options);
+   qla2x00_get_fw_options(vha, ha->fw_options);
+}
+
+static inline void
+qla24xx_relinquish_gpio(scsi_qla_host_t *vha)
+{
+   struct qla_hw_data *ha = vha->hw;
+
+   /* Restore control of GPIO register. */
+   ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL;
+   qla2x00_set_fw_options(vha, ha->fw_options);
+   qla2x00_get_fw_options(vha, ha->fw_options);
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 15eaa6dded04..bec8459523bd 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -302,6 +302,8 @@ static void qla2x00_clear_drv_active(struct qla_hw_data *);
 static void qla2x00_free_device(scsi_qla_host_t *);
 static int qla2xxx_map_queues(struct Scsi_Host *shost);
 static void qla2x00_destroy_deferred_work(struct qla_hw_data *);
+static void qla83xx_disable_laser(scsi_qla_host_t *);
+static void qla27xx_disable_laser(scsi_qla_host_t *);
 
 struct scsi_host_template qla2xxx_driver_template = {
.module = THIS_MODULE,
@@ -2156,6 +2158,7 @@ static struct isp_operations qla2100_isp_ops = {
.abort_isp  = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
.initialize_adapter = qla2x00_initialize_adapter,
+   .disable_laser  = NULL,
 };
 
 static struct isp_operations qla2300_isp_ops = {
@@ -2195,6 +2198,7 @@ static struct isp_operations qla2300_isp_ops = {
.abort_isp  = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
.initialize_adapter = qla2x00_initialize_adapter,
+   .disable_laser  = NULL,
 };
 
 static struct isp_operations qla24xx_isp_ops = {
@@ -2234,6 +2238,7 @@ static struct isp_operations qla24xx_isp_ops = {
.abort_isp  = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
.initialize_adapter = qla2x00_initialize_adapter,
+   .disable_laser  = NULL,
 };
 
 static struct isp_operations qla25xx_isp_ops = {
@@ -2273,6 +2278,7 @@ static struct isp_operations qla25xx_isp_ops = {
.abort_isp  

[PATCH 02/12] qla2xxx: Fix sending ADISC command for login

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

This patch fixes login_retry login for ADISC command.

when login_retry count reaches 0, futher attempt to send
ADISC command is ignored by the code. Remove this redundant
login_retry count check from qla24xx_fcport_handle_login()

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 8f55dd44adae..b9050cb52c0e 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1167,9 +1167,6 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
fcport->login_gen, fcport->login_retry,
fcport->loop_id, fcport->scan_state);
 
-   if (fcport->login_retry == 0)
-   return 0;
-
if (fcport->scan_state != QLA_FCPORT_FOUND)
return 0;
 
@@ -1194,7 +1191,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
return 0;
}
 
-   fcport->login_retry--;
+   if (fcport->login_retry > 0)
+   fcport->login_retry--;
 
switch (fcport->disc_state) {
case DSC_DELETED:
-- 
2.12.0



[PATCH 08/12] qla2xxx: Use predefined get_datalen_for_atio() inline function

2018-05-01 Thread Himanshu Madhani
From: Quinn Tran 

o Uses predefine inline function to access add_cdb_len field
in ATIO.
o Return SS_RESIDUAL_UNDER status when sending BUSY

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 5e81b64c8ef5..a77703f655ed 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -3550,13 +3550,6 @@ static int __qlt_send_term_exchange(struct qla_qpair 
*qpair,
temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
ctio24->u.status1.ox_id = cpu_to_le16(temp);
 
-   /* Most likely, it isn't needed */
-   ctio24->u.status1.residual = get_unaligned((uint32_t *)
-   &atio->u.isp24.fcp_cmnd.add_cdb[
-   atio->u.isp24.fcp_cmnd.add_cdb_len]);
-   if (ctio24->u.status1.residual != 0)
-   ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;
-
/* Memory Barrier */
wmb();
if (qpair->reqq_start_iocbs)
@@ -4051,9 +4044,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
 
fcp_task_attr = qlt_get_fcp_task_attr(vha,
atio->u.isp24.fcp_cmnd.task_attr);
-   data_length = be32_to_cpu(get_unaligned((uint32_t *)
-   &atio->u.isp24.fcp_cmnd.add_cdb[
-   atio->u.isp24.fcp_cmnd.add_cdb_len]));
+   data_length = get_datalen_for_atio(atio);
 
ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length,
  fcp_task_attr, data_dir, bidi);
@@ -5187,6 +5178,12 @@ static int __qlt_send_busy(struct qla_qpair *qpair,
 */
ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
ctio24->u.status1.scsi_status = cpu_to_le16(status);
+
+   ctio24->u.status1.residual = get_datalen_for_atio(atio);
+
+   if (ctio24->u.status1.residual != 0)
+   ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;
+
/* Memory Barrier */
wmb();
if (qpair->reqq_start_iocbs)
-- 
2.12.0