[PATCH] scsi: megaraid: fix spelling mistake "maibox" -> "mailbox"

2018-09-23 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake in warning message and comments

Signed-off-by: Colin Ian King 
---
 drivers/scsi/megaraid/megaraid_mbox.c | 4 ++--
 drivers/scsi/megaraid/megaraid_mbox.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_mbox.c 
b/drivers/scsi/megaraid/megaraid_mbox.c
index 530358cdcb39..2013523605c5 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -484,7 +484,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
// Start the mailbox based controller
if (megaraid_init_mbox(adapter) != 0) {
con_log(CL_ANN, (KERN_WARNING
-   "megaraid: maibox adapter did not initialize\n"));
+   "megaraid: mailbox adapter did not initialize\n"));
 
goto out_free_adapter;
}
@@ -950,7 +950,7 @@ megaraid_fini_mbox(adapter_t *adapter)
  * megaraid_alloc_cmd_packets - allocate shared mailbox
  * @adapter: soft state of the raid controller
  *
- * Allocate and align the shared mailbox. This maibox is used to issue
+ * Allocate and align the shared mailbox. This mailbox is used to issue
  * all the commands. For IO based controllers, the mailbox is also registered
  * with the FW. Allocate memory for all commands as well.
  * This is our big allocator.
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h 
b/drivers/scsi/megaraid/megaraid_mbox.h
index c1d86d961a92..e075aeb4012f 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.h
+++ b/drivers/scsi/megaraid/megaraid_mbox.h
@@ -117,7 +117,7 @@
  * @raw_mbox   : raw mailbox pointer
  * @mbox   : mailbox
  * @mbox64 : extended mailbox
- * @mbox_dma_h : maibox dma address
+ * @mbox_dma_h : mailbox dma address
  * @sgl64  : 64-bit scatter-gather list
  * @sgl32  : 32-bit scatter-gather list
  * @sgl_dma_h  : dma handle for the scatter-gather list
-- 
2.17.1



[PATCH] scsi: ufs: use PTR_ERR_OR_ZERO in ufs_hisi_get_resource()

2018-09-23 Thread Josh Abraham
This patch uses PTR_ERR_OR_ZERO instead of IF_ERR() return PTR_ERR().

Signed-off-by: Joshua Abraham 
---
 drivers/scsi/ufs/ufs-hisi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c
index 46df707e6f2c..e79499469cb3 100644
--- a/drivers/scsi/ufs/ufs-hisi.c
+++ b/drivers/scsi/ufs/ufs-hisi.c
@@ -505,10 +505,8 @@ static int ufs_hisi_get_resource(struct ufs_hisi_host 
*host)
/* get resource of ufs sys ctrl */
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
host->ufs_sys_ctrl = devm_ioremap_resource(dev, mem_res);
-   if (IS_ERR(host->ufs_sys_ctrl))
-   return PTR_ERR(host->ufs_sys_ctrl);
 
-   return 0;
+   return PTR_ERR_OR_ZERO(host->ufs_sys_ctrl);
 }
 
 static void ufs_hisi_set_pm_lvl(struct ufs_hba *hba)
-- 
2.17.1



[PATCH V14 1/2] scsi: ufs: set the device reference clock setting

2018-09-23 Thread Sayali Lokhande
From: Subhash Jadavani 

UFS host supplies the reference clock to UFS device and UFS device
specification allows host to provide one of the 4 frequencies (19.2 MHz,
26 MHz, 38.4 MHz, 52 MHz) for reference clock. Host should set the
device reference clock frequency setting in the device based on what
frequency it is supplying to UFS device.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
Signed-off-by: Sayali Lokhande 
Reviewed-by: Evan Green 
---
 drivers/scsi/ufs/ufs.h   | 14 +++
 drivers/scsi/ufs/ufshcd-pltfrm.c |  2 +
 drivers/scsi/ufs/ufshcd.c| 87 
 drivers/scsi/ufs/ufshcd.h|  2 +
 4 files changed, 105 insertions(+)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 14e5bf7..a2e76b1 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -378,6 +378,20 @@ enum query_opcode {
UPIU_QUERY_OPCODE_TOGGLE_FLAG   = 0x8,
 };
 
+/* bRefClkFreq attribute values */
+enum ufs_ref_clk_freq {
+   REF_CLK_FREQ_19_2_MHZ   = 0,
+   REF_CLK_FREQ_26_MHZ = 1,
+   REF_CLK_FREQ_38_4_MHZ   = 2,
+   REF_CLK_FREQ_52_MHZ = 3,
+   REF_CLK_FREQ_INVAL  = -1,
+};
+
+struct ufs_ref_clk {
+   u32 freq_hz;
+   enum ufs_ref_clk_freq val;
+};
+
 /* Query response result code */
 enum {
QUERY_RESULT_SUCCESS= 0x00,
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index e82bde0..0953563 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -343,6 +343,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
 
+   ufshcd_parse_dev_ref_clk_freq(hba);
+
ufshcd_init_lanes_per_dir(hba);
 
err = ufshcd_init(hba, mmio_base, irq);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c5b1bf1..64c62db 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6296,6 +6296,86 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
+static struct ufs_ref_clk ufs_ref_clk_freqs[] = {
+   {1920, REF_CLK_FREQ_19_2_MHZ},
+   {2600, REF_CLK_FREQ_26_MHZ},
+   {3840, REF_CLK_FREQ_38_4_MHZ},
+   {5200, REF_CLK_FREQ_52_MHZ},
+   {0, REF_CLK_FREQ_INVAL},
+};
+
+static inline enum ufs_ref_clk_freq
+ufs_get_bref_clk_from_hz(u32 freq)
+{
+   int i = 0;
+
+   while (ufs_ref_clk_freqs[i].freq_hz != freq) {
+   if (!ufs_ref_clk_freqs[i].freq_hz)
+   return REF_CLK_FREQ_INVAL;
+   i++;
+   }
+
+   return ufs_ref_clk_freqs[i].val;
+}
+
+void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba)
+{
+   struct device *dev = hba->dev;
+   struct device_node *np = dev->of_node;
+   struct clk *refclk = NULL;
+   u32 freq = 0;
+
+   if (!np)
+   return;
+
+   refclk = of_clk_get_by_name(np, "ref_clk");
+   if (!refclk)
+   return;
+
+   freq = clk_get_rate(refclk);
+
+   hba->dev_ref_clk_freq =
+   ufs_get_bref_clk_from_hz(freq);
+
+   if (hba->dev_ref_clk_freq == REF_CLK_FREQ_INVAL)
+   dev_err(hba->dev,
+   "%s: invalid ref_clk setting = %d\n",
+   __func__, freq);
+}
+
+static int ufshcd_set_dev_ref_clk(struct ufs_hba *hba)
+{
+   int err, ref_clk = -1;
+   u32 freq = hba->dev_ref_clk_freq;
+
+   err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+   QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0, &ref_clk);
+
+   if (err) {
+   dev_err(hba->dev, "%s: failed reading bRefClkFreq. err = %d\n",
+__func__, err);
+   goto out;
+   }
+
+   if (ref_clk == hba->dev_ref_clk_freq)
+   goto out; /* nothing to update */
+
+   err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
+   QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0, &freq);
+
+   if (err) {
+   dev_err(hba->dev, "%s: bRefClkFreq setting to %u Hz failed\n",
+   __func__, ufs_ref_clk_freqs[freq].freq_hz);
+   goto out;
+   }
+
+   dev_dbg(hba->dev, "%s: bRefClkFreq setting to %u Hz succeeded\n",
+   __func__, ufs_ref_clk_freqs[freq].freq_hz);
+
+out:
+   return err;
+}
+
 /**
  * ufshcd_probe_hba - probe hba to detect device and initialize
  * @hba: per-adapter instance
@@ -6361,6 +6441,12 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
"%s: Failed getting max supported power mode\n",
__func__);
} else {
+   /*
+* Set the right value to bRefClkFreq before attempting to
+* switch to HS gears.
+*/
+   if (hba->dev_ref_clk_freq != REF_CLK_FREQ_INVAL)
+   

[PATCH V14 2/2] scsi: ufs: Add configfs support for UFS provisioning

2018-09-23 Thread Sayali Lokhande
This patch adds configfs support to provision UFS device at
runtime. This feature can be primarily useful in factory or
assembly line as some devices may be required to be configured
multiple times during initial system development phase.
Configuration Descriptors can be written multiple times until
bConfigDescrLock attribute is zero.

Configuration descriptor buffer consists of Device and Unit
descriptor configurable parameters which are parsed from vendor
specific provisioning file and then passed via configfs node at
runtime to provision ufs device.
CONFIG_CONFIGFS_FS and CONFIG_SCSI_UFS_PROVISION needs to be enabled
for using this feature.

Usage:
1) To read current configuration descriptor with index X
   (where index X can be 0/1/2/3) :
   cat /config//ufs_config_desc_X

2) To write configuration descriptor with index X :
   echo  > /config//ufs_config_desc_X

Signed-off-by: Sayali Lokhande 
---
 Documentation/ABI/testing/configfs-driver-ufs |  12 ++
 drivers/scsi/ufs/Kconfig  |  10 ++
 drivers/scsi/ufs/Makefile |   1 +
 drivers/scsi/ufs/ufs-configfs.c   | 237 ++
 drivers/scsi/ufs/ufshcd.c |   3 +-
 drivers/scsi/ufs/ufshcd.h |  18 ++
 6 files changed, 280 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/configfs-driver-ufs
 create mode 100644 drivers/scsi/ufs/ufs-configfs.c

diff --git a/Documentation/ABI/testing/configfs-driver-ufs 
b/Documentation/ABI/testing/configfs-driver-ufs
new file mode 100644
index 000..6743ea9
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-driver-ufs
@@ -0,0 +1,12 @@
+What:  /config/*/ufs_config_desc_X
+Date:  Jun 2018
+KernelVersion: 4.20
+Description:
+   This file shows bytes of the current ufs configuration 
descriptor
+   with index X (where X = 0/1/2/3) set in device. This can be 
used to
+   provision ufs device if bConfigDescrLock is 0.
+   For more details, refer 14.1.6.3 Configuration Descriptor and
+   table 14-12 - Unit Descriptor configurable parameters from 
specs for
+   description and format of each configuration descriptor 
parameter.
+   Parameters of Configuration descriptor buffer for respective 
index
+   needs to be passed as bytes in space separated format.
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e27b4d4..6e7ff35 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -100,3 +100,13 @@ config SCSI_UFS_QCOM
 
  Select this if you have UFS controller on QCOM chipset.
  If unsure, say N.
+
+config SCSI_UFS_PROVISION
+   bool "Runtime UFS Provisioning support"
+   depends on SCSI_UFSHCD && CONFIGFS_FS
+   help
+ This enables runtime UFS provisioning support. This can be used
+ primarily during assembly line as some devices may be required to
+ be configured multiple times during initial development phase.
+
+ If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 918f579..09880b9 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o 
ufshcd-dwc.o tc-d
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
 ufshcd-core-objs := ufshcd.o ufs-sysfs.o
+obj-$(CONFIG_SCSI_UFS_PROVISION) += ufs-configfs.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-configfs.c b/drivers/scsi/ufs/ufs-configfs.c
new file mode 100644
index 000..8f6a5d3
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-configfs.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018, Linux Foundation.
+
+#include 
+#include 
+#include 
+
+#include "ufs.h"
+#include "ufshcd.h"
+
+static inline struct ufs_hba *config_item_to_hba(struct config_item *item)
+{
+   struct config_group *group = to_config_group(item);
+   struct configfs_subsystem *subsys = to_configfs_subsystem(group);
+   struct ufs_hba *hba = container_of(subsys, struct ufs_hba, subsys);
+
+   return hba;
+}
+
+static ssize_t ufs_config_desc_show(struct config_item *item, char *buf,
+   u8 index)
+{
+   struct ufs_hba *hba = config_item_to_hba(item);
+   u8 *desc_buf = NULL;
+   int desc_buf_len = hba->desc_size.conf_desc;
+   int i, ret, curr_len = 0;
+
+   desc_buf = kzalloc(desc_buf_len, GFP_KERNEL);
+   if (!desc_buf)
+   return -ENOMEM;
+
+   ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC,
+   QUERY_DESC_IDN_CONFIGURATION, index,
+   0, desc_buf, &desc_buf_len);
+   if (ret)
+   goto out;
+
+   

Re: aacraid: latest driver results in Host adapter abort request. / Outstanding commands on (0,0,0,0):

2018-09-23 Thread Stefan Priebe - Profihost AG


Am 22.09.2018 um 23:40 schrieb Bart Van Assche:
> On 9/18/18 11:10 PM, Stefan Priebe - Profihost AG wrote:
>> after upgrading the aacraid driver / kernel from aacraid 50792 to
>> aacraid 50877.
> 
> The aacraid driver version was updated to 50792 in commit 0662cc968ace
> ("scsi: aacraid: Update driver version") and to 50877 in commit
> 1cdb74b80f93 ("scsi: aacraid: Update driver version to 50877"). That
> means that the regression you encountered got introduced after commit
> 0662cc968ace. 114 changes got checked in after that commit. That's too
> much to find the root cause by rereading all these changes. Is there any
> way to trigger the problem faster such that it becomes feasible to run a
> bisect?

Sadly i'm not able. May be also something else in the kernel has changed.

I'm now trying the original out of tree driver from microsemi / adaptec:
Adaptec aacraid driver 1.2.1.56008src

No idea how those driver versions corespond to the kernel ones.

Greets,
Stefan

> $ git log 0662cc968ace..master drivers/scsi/aacraid | grep -c ^commit
> 114
> 
> Bart.


Re: aacraid: latest driver results in Host adapter abort request. / Outstanding commands on (0,0,0,0):

2018-09-23 Thread Stefan Priebe - Profihost AG
Am 23.09.2018 um 20:22 schrieb Stefan Priebe - Profihost AG:
> 
> Am 22.09.2018 um 23:40 schrieb Bart Van Assche:
>> On 9/18/18 11:10 PM, Stefan Priebe - Profihost AG wrote:
>>> after upgrading the aacraid driver / kernel from aacraid 50792 to
>>> aacraid 50877.
>>
>> The aacraid driver version was updated to 50792 in commit 0662cc968ace
>> ("scsi: aacraid: Update driver version") and to 50877 in commit
>> 1cdb74b80f93 ("scsi: aacraid: Update driver version to 50877"). That
>> means that the regression you encountered got introduced after commit
>> 0662cc968ace. 114 changes got checked in after that commit. That's too
>> much to find the root cause by rereading all these changes. Is there any
>> way to trigger the problem faster such that it becomes feasible to run a
>> bisect?
> 
> Sadly i'm not able. May be also something else in the kernel has changed.
> 
> I'm now trying the original out of tree driver from microsemi / adaptec:
> Adaptec aacraid driver 1.2.1.56008src
> 
> No idea how those driver versions corespond to the kernel ones.

OK the out of tree also timed out and the whole system went unreachable.
The output just looked different:
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Host
adapter abort request (0,0,1,0)
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Timed
out Command: 2a 00 c0 98 6f a2 00 00 28 00 00 00 00 00 00 00
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:FIB =
950ca6706780 : bac49220 Command = 502 XferState = 830ad Wait Time =
120Sec
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Host
adapter abort request (0,0,1,0)
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Timed
out Command: 2a 00 c0 98 6d a2 00 02 00 00 00 00 00 00 00 00
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:FIB =
950ca67066c8 : bac48a00 Command = 502 XferState = 830ad Wait Time =
120Sec
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Host
adapter abort request (0,0,1,0)
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Timed
out Command: 2a 00 c0 98 6b a2 00 02 00 00 00 00 00 00 00 00
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:FIB =
950ca6706610 : bac481e0 Command = 502 XferState = 830ad Wait Time =
120Sec
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Host
adapter abort request (0,0,1,0)
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:Timed
out Command: 2a 00 c0 98 69 a2 00 02 00 00 00 00 00 00 00 00
2018-09-24 03:00:29 aacraid :03:00.0: AAC0:aac_eh_abort:FIB =
950ca6706558 : bac479c0 Command = 502 XferState = 830ad Wait Time =
120Sec

all series 6 controllers are those with problems when high load happens.

Greets,
Stefan
> 
>> $ git log 0662cc968ace..master drivers/scsi/aacraid | grep -c ^commit
>> 114
>>
>> Bart.


[PATCH V14 0/2] Add UFS provisioning support in driver

2018-09-23 Thread Sayali Lokhande


This patch adds Configfs support to provision UFS device at
runtime. This feature can be primarily useful in factory or
assembly line as some devices may be required to be configured
multiple times during initial system development phase.
Configuration Descriptors can be written multiple times until
bConfigDescrLock attribute is zero.

Configuration descriptor buffer consists of Device and Unit
descriptor configurable parameters which are parsed from vendor
specific provisioning file and then passed via configfs node at
runtime to provision ufs device.

Changes since V13:
1)scsi: ufs: set the device reference clock setting
Removed extra comment.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Used snprintf for limiting configfs item name length to
20 and thus avoid overrun.

Changes since V12:
1)scsi: ufs: set the device reference clock setting
No update.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Minor fixes related to return statement, updated indentation
as per checkpatch script and added logic to first read config
descriptor before updating with user provied buffer so
that old configuration can be retained in case user buffer
length is less than expected config descriptor length.

Changes since V11:
1)scsi: ufs: set the device reference clock setting
No update.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Minor fixes related to missing kfree(), return statement
and indentation.

Changes since V10:
1)scsi: ufs: set the device reference clock setting
No update.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Added support for all config descriptors (namely with
index 0,1,2,3). Updated config descriptor length to reflect
actual length of each descriptor instead of hard coded macro.
Updated documentation as per new added fields (for each config
descriptor). Added support for multiple ufs hba's.

Changes since V9:
1)scsi: ufs: set the device reference clock setting
Minor fixes related to naming format, if check conditions.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Minor fixes related to naming format, function return type.

Changes since V8:
1)scsi: ufs: set the device reference clock setting
Updated one common enum for both ref_clk_freq in Hz and bref_attr
and used same in parsing api. Moved call to parse api to
ufshcd_alloc_host() instead of calling from pltfrm_init(), so that
it can be called via other paths(which dont use pltfrm_init) and
hba->dev_ref_clk can get intialized to either valid/invalid value.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Updated error returns and removed few unnecessary sanity check as
per comments.

Changes since V7:
1)scsi: ufs: set the device reference clock setting
Updated return statements and condition checks as per comments.
Added struct ufs_ref_clk_freqs which holds both bref_clk_attr val
and respective ref clk frequency in Hz and used same while parsing
ref_clk.

2)scsi: ufs: Add configfs support for UFS provisioning
Updated return statements and conditional check as per comments.

Changes since V6:
1)scsi: ufs: set the device reference clock setting
Re-introduced this patch to provisioning patch set(as per comments
from Evan). Used of_clk_get_by_name() and clk_get_rate() to set
ref_clk frequency instead of passing freq via DT.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Updated error handling in case if kstrtoint fails while parsing
input configuration buffer.

Changes since V5:
1)scsi: ufs: set the device reference clock setting
Removed this patch from provisioning patch set(as its not required
to be set as dependent changes).
This will be uploaded as a separate patch later.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Removed few extra debug prints. Updated permission of ufs_provision
attribute from 0666 to 0644. Pass UFS device name as part of
ufshcd_configfs_init() to support multiple UFS controller for
embedded and removable UFS card.

Changes since V4:
1)scsi: ufs: set the device reference clock setting
Used "assigned-clock-rates" DT property to pass required ref clk
frequency.

2)scsi: ufs: Add configfs support for ufs provisioning
Combined previous patch(2) and patch(3) into single patch which
adds configfs provisioning support in driver.
Removed extra sw provisioning related fields (like lun_to_grow,
commit) a

[PATCH v3 0/6] mpt3sas: Hot-Plug Surprise removal support on IOC.

2018-09-23 Thread Suganath Prabu S
Posting below set of patches to support PCIe Hot Plug surprise removal,
and few defect fixes.

This is NOT the normal PCIe Hot Plug support, whereby the user informs the
OS that a hot removal is desired, the OS does an orderly shutdown of the
driver on the device, special hot plug circuitry removes power from the
PCIe slot, then the user can remove the device and replace it
(where orderly bring-up of the device is done).

With a true surprise removal (just removing HBA from a slot)
there is a possibility to get all kinds of PCIe transaction errors,
Below patches addresses those issues and remove HBA without bringing
the system down.

For surprise removal detection, driver does a PCI
read of IOC's vendor field in IOC's PCI configuration space.
If the read value is 0x this indicates that the device
might have hot removed and the device will be removed from driver.

V1 changes:
In Patch 0001 - unlock mutex, if active reset is in progress.

V2 changes:
Replaced mpt3sas_base_pci_device_is_unplugged with
pci_device_is_present.

V3 Change Set:
Simplified function "mpt3sas_base_pci_device_is_available" and
made inline

Suganath Prabu S (6):
  mpt3sas: Introduce  mpt3sas_base_pci_device_is_available
  mpt3sas: Separate out  mpt3sas_wait_for_ioc_to_operational
  mpt3sas: Introdude  _scsih_get_shost_and_ioc.
  mpt3sas: Fix Sync cache command failure during driver  unload.
  mpt3sas: Fix driver modifying NVRAM/persistent data.
  mpt3sas: Bump driver version to 27.100.00.00.

 drivers/scsi/mpt3sas/mpt3sas_base.c  | 135 +++---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  11 +-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  32 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  26 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 189 +++
 drivers/scsi/mpt3sas/mpt3sas_transport.c |  82 +++---
 6 files changed, 298 insertions(+), 177 deletions(-)

-- 
1.8.3.1



[PATCH v3 2/6] mpt3sas: Separate out mpt3sas_wait_for_ioc_to_operational

2018-09-23 Thread Suganath Prabu S
Introduce mpt3sas_wait_for_ioc_to_operational.

This section of code "wait for IOC to be operational"
is used in many places across the driver,
and hence moved this section of code in to the function
"mpt3sas_wait_for_ioc_to_operational".

Also added HBA hot unplug checks, and this returns with
error code EFAULT, if it detects HBA is hot unplugged
or IOC is not in operational state.

V2 change set:
used pci_device_is_present instead of
mpt3sas_base_pci_device_is_unplugged

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 92 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  4 ++
 drivers/scsi/mpt3sas/mpt3sas_config.c| 28 +++---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 26 ++---
 drivers/scsi/mpt3sas/mpt3sas_transport.c | 75 +-
 5 files changed, 81 insertions(+), 144 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index c98d8e2..55e6fd0 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5176,6 +5176,53 @@ _base_send_ioc_reset(struct MPT3SAS_ADAPTER *ioc, u8 
reset_type, int timeout)
 }
 
 /**
+ * mpt3sas_wait_for_ioc_to_operational - IOC's operational
+ * state and HBA hot unplug status are checked here.
+ * @ioc: per adapter object
+ * @wait_count: timeout in seconds
+ *
+ * Return:  Returns EFAULT, if HBA is hot unplugged or IOC is
+ * not in operational state, within the wait_count.
+ * And returns 0, If not hot unplugged Or ioc is in
+ * operational state.
+ */
+
+int
+mpt3sas_wait_for_ioc_to_operational(struct MPT3SAS_ADAPTER *ioc,
+   int wait_count)
+{
+   int wait_state_count = 0;
+   u32 ioc_state;
+
+   if (!pci_device_is_present(ioc->pdev))
+   return -EFAULT;
+
+   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
+   while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+
+   if (!pci_device_is_present(ioc->pdev))
+   return -EFAULT;
+
+   if (wait_state_count++ == wait_count) {
+   pr_err(MPT3SAS_FMT
+   "%s: failed due to ioc not operational\n",
+   ioc->name, __func__);
+   return -EFAULT;
+   }
+   ssleep(1);
+   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
+   pr_info(MPT3SAS_FMT "%s: waiting for "
+   "operational state(count=%d)\n", ioc->name,
+   __func__, wait_state_count);
+   }
+   if (wait_state_count)
+   pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
+   ioc->name, __func__);
+
+   return 0;
+}
+
+/**
  * _base_handshake_req_reply_wait - send request thru doorbell interface
  * @ioc: per adapter object
  * @request_bytes: request length
@@ -5316,11 +5363,9 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
Mpi2SasIoUnitControlRequest_t *mpi_request)
 {
u16 smid;
-   u32 ioc_state;
u8 issue_reset = 0;
int rc;
void *request;
-   u16 wait_state_count;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5334,22 +5379,10 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
goto out;
}
 
-   wait_state_count = 0;
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-   if (wait_state_count++ == 10) {
-   pr_err(MPT3SAS_FMT
-   "%s: failed due to ioc not operational\n",
-   ioc->name, __func__);
-   rc = -EFAULT;
-   goto out;
-   }
-   ssleep(1);
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   pr_info(MPT3SAS_FMT
-   "%s: waiting for operational state(count=%d)\n",
-   ioc->name, __func__, wait_state_count);
-   }
+   rc = mpt3sas_wait_for_ioc_to_operational(ioc,
+   IOC_OPERATIONAL_WAIT_COUNT);
+   if (rc)
+   goto out;
 
smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
if (!smid) {
@@ -5416,11 +5449,9 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request)
 {
u16 smid;
-   u32 ioc_state;
u8 issue_reset = 0;
int rc;
void *request;
-   u16 wait_state_count;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5434,23 +5465,10 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
goto out;
}
 
-   wait_state_count = 0;
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   while (ioc_state != MPI2_IOC_STAT

[PATCH v3 1/6] mpt3sas: Introduce mpt3sas_base_pci_device_is_available

2018-09-23 Thread Suganath Prabu S
* Driver uses "pci_device_is_present" to check whether
If Hot unplugged:
the outstanding IOs with 'DID_NO_CONNECT' before removing the drives
attached to the HBA.
"DID_NO_CONNECT" status and free the smid, if driver detects that
HBA is hot unplugged.

* In the hard reset flush out all the outstanding IOs even if diag reset
fails and also if driver detects that HBA is hot unplugged.

v1 change set:
==
unlock mutex before goto "out_unlocked",
if active reset is in progress.

v2 change set:
==
1) Use pci_device_is_present instead of
mpt3sas_base_pci_device_is_unplugged.
2) As suggested by Lukas, removed using
watchdog thread for checking hba hot unplug(Patch 02 of V1).
Added Hot unplug checks in scan finish and reset paths.

v3 Change Set:
=
Simplified function "mpt3sas_base_pci_device_is_available" and
made inline.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 41 +
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  3 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 50 
 3 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 59d7844..c98d8e2 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -543,6 +543,20 @@ static int mpt3sas_remove_dead_ioc_func(void *arg)
 }
 
 /**
+ * mpt3sas_base_pci_device_is_available - check whether pci device is
+ * available for any transactions with FW
+ *
+ * @ioc: per adapter object
+ *
+ * Return 1 if pci device state is up and running else return 0.
+ */
+inline bool
+mpt3sas_base_pci_device_is_available(struct MPT3SAS_ADAPTER *ioc)
+{
+   return !ioc->pci_error_recovery && pci_device_is_present(ioc->pdev);
+}
+
+/**
  * _base_fault_reset_work - workq handling ioc fault conditions
  * @work: input argument, used to derive ioc
  *
@@ -6122,6 +6136,11 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
 
count = 0;
do {
+   if (!pci_device_is_present(ioc->pdev)) {
+   ioc->remove_host = 1;
+   pr_err(MPT3SAS_FMT "Hba Hot unplugged\n", ioc->name);
+   goto out;
+   }
/* Write magic sequence to WriteSequence register
 * Loop until in diagnostic mode
 */
@@ -6853,6 +6872,14 @@ mpt3sas_wait_for_commands_to_complete(struct 
MPT3SAS_ADAPTER *ioc)
 
ioc->pending_io_count = 0;
 
+   if (!mpt3sas_base_pci_device_is_available(ioc)) {
+   pr_err(MPT3SAS_FMT
+   "%s: pci error recovery reset or"
+   " pci device unplug occurred\n",
+   ioc->name, __func__);
+   return;
+   }
+
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL)
return;
@@ -6899,6 +6926,20 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER 
*ioc,
/* wait for an active reset in progress to complete */
mutex_lock(&ioc->reset_in_progress_mutex);
 
+   if (!mpt3sas_base_pci_device_is_available(ioc)) {
+   pr_err(MPT3SAS_FMT
+   "%s: pci error recovery reset or"
+   " pci device unplug occurred\n",
+   ioc->name, __func__);
+   if (!pci_device_is_present(ioc->pdev))
+   ioc->schedule_dead_ioc_flush_running_cmds(ioc);
+   r = 0;
+   mutex_unlock(&ioc->reset_in_progress_mutex);
+   goto out_unlocked;
+   }
+
+   mpt3sas_halt_firmware(ioc);
+
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
ioc->shost_recovery = 1;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 96dc15e..a802ad4 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1474,7 +1474,8 @@ void mpt3sas_base_update_missing_delay(struct 
MPT3SAS_ADAPTER *ioc,
u16 device_missing_delay, u8 io_missing_delay);
 
 int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
-
+inline bool  mpt3sas_base_pci_device_is_available(
+   struct MPT3SAS_ADAPTER *ioc);
 void
 mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 53133cf..566a550 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2846,9 +2846,19 @@ scsih_abort(struct scsi_cmnd *scmd)
"attempting task abort! scmd(%p)\n", scmd);
_scsih_tm_display_info(ioc, scmd);
 
+   if (!pci_device_is_present(ioc->pdev) || ioc->remove_host) {
+   sdev_printk(KERN_INFO, scmd->device, "%s scmd(%p)\n",
+

[PATCH v3 5/6] mpt3sas: Fix driver modifying NVRAM/persistent data.

2018-09-23 Thread Suganath Prabu S
* If EEDPTagMode field in manufacturing page11 is set,
unset it. This is needed to fix a hardware bug
in SAS3/SAS2 cards, So, skipping EEDPTagMode changes
in Manufacturing page11 for SAS35 controllers.

* Fix driver modifying NVRAM/persistent data in
Manufacturing page11 along with current copy. Driver should
change only current copy of Manufacturing page11

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c   | 2 +-
 drivers/scsi/mpt3sas/mpt3sas_config.c | 4 
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 55e6fd0..87a67fe 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4122,7 +4122,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 * flag unset in NVDATA.
 */
mpt3sas_config_get_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11);
-   if (ioc->manu_pg11.EEDPTagMode == 0) {
+   if ((!ioc->is_gen35_ioc) && (ioc->manu_pg11.EEDPTagMode == 0)) {
pr_err("%s: overriding NVDATA EEDPTagMode setting\n",
ioc->name);
ioc->manu_pg11.EEDPTagMode &= ~0x3;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 5713a2d..f2a326a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -676,10 +676,6 @@ mpt3sas_config_set_manufacturing_pg11(struct 
MPT3SAS_ADAPTER *ioc,
r = _config_request(ioc, &mpi_request, mpi_reply,
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
sizeof(*config_page));
-   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
-   r = _config_request(ioc, &mpi_request, mpi_reply,
-   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-   sizeof(*config_page));
  out:
return r;
 }
-- 
1.8.3.1



[PATCH v3 3/6] mpt3sas: Introdude _scsih_get_shost_and_ioc.

2018-09-23 Thread Suganath Prabu S
The code for getting shost and IOC is redundant so
moved that to function "scsih_get_shost_and_ioc".
Also checks for NULL are added to IOC and shost.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 98 ++--
 1 file changed, 82 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 566a550..f6e92eb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -9809,6 +9809,35 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_get_shost_and_ioc - get shost and ioc
+ * and verify whether they are NULL or not
+ * @pdev: PCI device struct
+ * @shost: address of scsi host pointer
+ * @ioc: address of HBA adapter pointer
+ *
+ * Return zero if *shost and *ioc are not NULL otherwise return error number.
+ */
+static int
+_scsih_get_shost_and_ioc(struct pci_dev *pdev,
+   struct Scsi_Host **shost, struct MPT3SAS_ADAPTER **ioc)
+{
+   *shost = pci_get_drvdata(pdev);
+   if (*shost == NULL) {
+   dev_err(&pdev->dev, "pdev's driver data is null\n");
+   return -ENXIO;
+   }
+
+   *ioc = shost_priv(*shost);
+   if (*ioc == NULL) {
+   dev_err(&pdev->dev, "shost's private data is null\n");
+   return -ENXIO;
+   }
+
+   return 0;
+}
+
+
+/**
  * scsih_remove - detach and remove add host
  * @pdev: PCI device struct
  *
@@ -9816,8 +9845,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
  */
 static void scsih_remove(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
struct _sas_port *mpt3sas_port, *next_port;
struct _raid_device *raid_device, *next;
struct MPT3SAS_TARGET *sas_target_priv_data;
@@ -9825,6 +9854,10 @@ static void scsih_remove(struct pci_dev *pdev)
struct workqueue_struct *wq;
unsigned long flags;
 
+   if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) {
+   dev_err(&pdev->dev, "unable to remove device\n");
+   return;
+   }
ioc->remove_host = 1;
 
mpt3sas_wait_for_commands_to_complete(ioc);
@@ -9898,11 +9931,16 @@ static void scsih_remove(struct pci_dev *pdev)
 static void
 scsih_shutdown(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
struct workqueue_struct *wq;
unsigned long flags;
 
+   if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) {
+   dev_err(&pdev->dev, "unable to shutdown device\n");
+   return;
+   }
+
ioc->remove_host = 1;
 
mpt3sas_wait_for_commands_to_complete(ioc);
@@ -10727,10 +10765,16 @@ out_add_shost_fail:
 static int
 scsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
pci_power_t device_state;
+   int rc;
 
+   rc = _scsih_get_shost_and_ioc(pdev, &shost, &ioc);
+   if (rc) {
+   dev_err(&pdev->dev, "unable to suspend device\n");
+   return rc;
+   }
mpt3sas_base_stop_watchdog(ioc);
flush_scheduled_work();
scsi_block_requests(shost);
@@ -10754,11 +10798,17 @@ scsih_suspend(struct pci_dev *pdev, pm_message_t 
state)
 static int
 scsih_resume(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
pci_power_t device_state = pdev->current_state;
int r;
 
+   r = _scsih_get_shost_and_ioc(pdev, &shost, &ioc);
+   if (r) {
+   dev_err(&pdev->dev, "unable to resume device\n");
+   return r;
+   }
+
pr_info(MPT3SAS_FMT
"pdev=0x%p, slot=%s, previous operating state [D%d]\n",
ioc->name, pdev, pci_name(pdev), device_state);
@@ -10790,9 +10840,13 @@ scsih_resume(struct pci_dev *pdev)
 static pci_ers_result_t
 scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
 
+   if (_scsih_get_shost_and_ioc(pdev, &shost, &ioc)) {
+   dev_err(&pdev->dev, "device unavailable\n");
+   return PCI_ERS_RESULT_DISCONNECT;
+   }
pr_info(MPT3SAS_FMT "PCI err

[PATCH v3 6/6] mpt3sas: Bump driver version to 27.100.00.00.

2018-09-23 Thread Suganath Prabu S
Modify driver version to 27.100.00.00
(which is equivalent to PH8 OOB driver)

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index f0351a2..b880d79 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,8 +74,8 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "26.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  26
+#define MPT3SAS_DRIVER_VERSION "27.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  27
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[PATCH v3 4/6] mpt3sas: Fix Sync cache command failure during driver unload.

2018-09-23 Thread Suganath Prabu S
This is to fix Sync cache and start stop command
 failures with DID_NO_CONNECT during driver unload.

1) Release drives first from SML, then remove internally
in driver.
2) And allow sync cache and Start stop commands to firmware,
even when remove_host flag is set

v2 Changeset:
Replaced this function mpt3sas_base_pci_device_is_unplugged
with pci_device_is_present

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 41 ++--
 drivers/scsi/mpt3sas/mpt3sas_transport.c |  7 --
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index f6e92eb..5d15d06 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3806,6 +3806,43 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
return _scsih_check_for_pending_tm(ioc, smid);
 }
 
+/** _scsih_allow_scmd_to_device - check whether scmd needs to
+ *  issue to IOC or not.
+ * @ioc: per adapter object
+ * @scmd: pointer to scsi command object
+ *
+ * Returns true if scmd can be issued to IOC otherwise returns false.
+ */
+inline bool _scsih_allow_scmd_to_device(struct MPT3SAS_ADAPTER *ioc,
+   struct scsi_cmnd *scmd)
+{
+
+   if (ioc->pci_error_recovery)
+   return false;
+
+   if (ioc->hba_mpi_version_belonged == MPI2_VERSION) {
+   if (ioc->remove_host)
+   return false;
+
+   return true;
+   }
+
+
+   if (ioc->remove_host) {
+   if (!pci_device_is_present(ioc->pdev))
+   return false;
+
+   switch (scmd->cmnd[0]) {
+   case SYNCHRONIZE_CACHE:
+   case START_STOP:
+   return true;
+   default:
+   return false;
+   }
+   }
+
+   return true;
+}
 
 /**
  * _scsih_sas_control_complete - completion routine
@@ -4640,7 +4677,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
return 0;
}
 
-   if (ioc->pci_error_recovery || ioc->remove_host) {
+   if (!(_scsih_allow_scmd_to_device(ioc, scmd))) {
scmd->result = DID_NO_CONNECT << 16;
scmd->scsi_done(scmd);
return 0;
@@ -9874,6 +9911,7 @@ static void scsih_remove(struct pci_dev *pdev)
 
/* release all the volumes */
_scsih_ir_shutdown(ioc);
+   sas_remove_host(shost);
list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list,
list) {
if (raid_device->starget) {
@@ -9916,7 +9954,6 @@ static void scsih_remove(struct pci_dev *pdev)
ioc->sas_hba.num_phys = 0;
}
 
-   sas_remove_host(shost);
mpt3sas_base_detach(ioc);
spin_lock(&gioc_lock);
list_del(&ioc->list);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c 
b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index b10d73e..742da74 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -817,10 +817,13 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER 
*ioc, u64 sas_address,
mpt3sas_port->remote_identify.sas_address,
mpt3sas_phy->phy_id);
mpt3sas_phy->phy_belongs_to_port = 0;
-   sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
+   if (!ioc->remove_host)
+   sas_port_delete_phy(mpt3sas_port->port,
+   mpt3sas_phy->phy);
list_del(&mpt3sas_phy->port_siblings);
}
-   sas_port_delete(mpt3sas_port->port);
+   if (!ioc->remove_host)
+   sas_port_delete(mpt3sas_port->port);
kfree(mpt3sas_port);
 }
 
-- 
1.8.3.1