diff mbox series

[2/8] mpt3sas: Add persistent trigger pages support

Message ID 20201124035019.27975-3-suganath-prabu.subramani@broadcom.com (mailing list archive)
State Superseded
Headers show
Series mpt3sas: Features to enhance driver debugging. | expand

Commit Message

Suganath Prabu S Nov. 24, 2020, 3:50 a.m. UTC
Problem statement:
User sets the tigger value inorder to collect the IOC's
Host tace buffer automicatically upon detecting the trigger
condition. But the tigger values that the user has set are not
persistent across the system reboot or reload of driver. User
has to set them eveytime upon rebooting, realoding the driver
or when HBA is moved to another system.

Solution:
Inorder to make the user trigger settings persistant, these trigger
values needs to be saved in IOC's pages and IOC provides below pages
to save them,

* Driver Persistent Trigger Page 0 :
    This page is used to know list of trigger types that are enabled
* Driver Persistent Trigger Page 1 :
    This page stores the list of Mater triggers that are enabled
* Driver Persistent Trigger Page 2 :
    This page stores the list of MPI Event Triggers that are enabled
* Driver Persistent Trigger Page 3 :
    This page stores the list of SCSI Sense Triggers that are enabled
* Driver Persistent Trigger Page 4 :
    This page stores the list of IOCStatus-LogInfo Triggers that are
    enabled.

* Whenever user configure the trigger values then driver writes the
  configured trigger values in the corresponding trigger pages.
* During next driver load time, driver reads the trigger values
  from these pages and configures the trigger values accordingly.
* During firmware upload operation,
  * if the newer firmware supports these driver trigger pages
    then driver write backs the configured diag trigger values
    on driver trigger pages of IOC.
  * if the newer firmware doesn't supports these driver trigger
    pages then driver clear the supporting trigger flag so that
    whenever user modifies the trigger values then driver
    won't do any config write operations to driver trigger pages.

Current patch change set:
* During driver load, driver will first read Persistent Trigger Page0.
  - If this page's read operation fails then it means that IOC
    firmware doesn't support these Persistent Trigger Pages, i.e.
    current feature of saving/restoring the tigger values is not
    enabled in the IOC. So, driver can't read/store user trigger values
    from/to Persistent triggers pages.
  - If this Page's read opearation is successful then it means that
    IOC firmware supports storing the trigger values on persistent
    trigger pages. So, driver sets the supports_trigger_pages ioc
    variable to one. On reading this page, driver will get to know
    which are all the trigger types that are enabled before the
    driver load.

* And added below helper functions to read & modify
  Persistent Trigger Page0.
  - mpt3sas_config_get_driver_trigger_pg0 : reads the page,
  - mpt3sas_config_set_driver_trigger_pg0 : writes the page,
  - mpt3sas_config_update_driver_trigger_pg0 :
    When user adds any new trigger values then driver enable
    the corresponding trigger type bit in 'TriggerFlags' field of
    Persistent Trigger Page0 (if it was not enabled before)
    before adding these trigger values to corresponding
    Persistent Trigger type pages.

Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c          |  70 ++++++++++
 drivers/scsi/mpt3sas/mpt3sas_base.h          |   5 +
 drivers/scsi/mpt3sas/mpt3sas_config.c        | 134 +++++++++++++++++++
 drivers/scsi/mpt3sas/mpt3sas_trigger_pages.h |  95 +++++++++++++
 4 files changed, 304 insertions(+)
 create mode 100644 drivers/scsi/mpt3sas/mpt3sas_trigger_pages.h

Comments

kernel test robot Nov. 24, 2020, 6:34 a.m. UTC | #1
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on mkp-scsi/for-next v5.10-rc5 next-20201123]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Features-to-enhance-driver-debugging/20201124-115842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: x86_64-rhel (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/6ef897d0859c5415dc82c174e1f2a83b286e9ae2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Suganath-Prabu-S/mpt3sas-Features-to-enhance-driver-debugging/20201124-115842
        git checkout 6ef897d0859c5415dc82c174e1f2a83b286e9ae2
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/scsi/mpt3sas/mpt3sas_config.c:1793:1: warning: no previous prototype for '_config_set_driver_trigger_pg0' [-Wmissing-prototypes]
    1793 | _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/scsi/mpt3sas/mpt3sas_config.c:1835:1: warning: no previous prototype for 'mpt3sas_config_update_driver_trigger_pg0' [-Wmissing-prototypes]
    1835 | mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/_config_set_driver_trigger_pg0 +1793 drivers/scsi/mpt3sas/mpt3sas_config.c

  1782	
  1783	/**
  1784	 * mpt3sas_config_set_driver_trigger_pg0 - write driver trigger page 0
  1785	 * @ioc: per adapter object
  1786	 * @mpi_reply: reply mf payload returned from firmware
  1787	 * @config_page: contents of the config page
  1788	 * Context: sleep.
  1789	 *
  1790	 * Returns 0 for success, non-zero for failure.
  1791	 */
  1792	int
> 1793	_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
  1794		Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
  1795	{
  1796		Mpi2ConfigRequest_t mpi_request;
  1797		int r;
  1798	
  1799		memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1800		mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1801		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1802		mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1803		mpi_request.ExtPageType =
  1804		    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1805		mpi_request.Header.PageNumber = 0;
  1806		mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
  1807		ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1808		r = _config_request(ioc, &mpi_request, mpi_reply,
  1809		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1810		if (r)
  1811			goto out;
  1812	
  1813		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1814		_config_request(ioc, &mpi_request, mpi_reply,
  1815		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1816		    sizeof(*config_page));
  1817		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  1818		r = _config_request(ioc, &mpi_request, mpi_reply,
  1819		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1820		    sizeof(*config_page));
  1821	 out:
  1822		return r;
  1823	}
  1824	
  1825	/**
  1826	 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
  1827	 * @ioc: per adapter object
  1828	 * @trigger_flags: trigger type bit map
  1829	 * @set: set ot clear trigger values
  1830	 * Context: sleep.
  1831	 *
  1832	 * Returns 0 for success, non-zero for failure.
  1833	 */
  1834	int
> 1835	mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
  1836		u16 trigger_flag, bool set)
  1837	{
  1838		Mpi26DriverTriggerPage0_t tg_pg0;
  1839		Mpi2ConfigReply_t mpi_reply;
  1840		int rc;
  1841		u16 flags, ioc_status;
  1842	
  1843		rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
  1844		if (rc)
  1845			return rc;
  1846		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1847		    MPI2_IOCSTATUS_MASK;
  1848		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1849			dcprintk(ioc,
  1850			    ioc_err(ioc,
  1851			    "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
  1852			    __func__, ioc_status));
  1853			return -EFAULT;
  1854		}
  1855	
  1856		if (set)
  1857			flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
  1858		else
  1859			flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
  1860	
  1861		tg_pg0.TriggerFlags = cpu_to_le16(flags);
  1862	
  1863		rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
  1864		if (rc)
  1865			return rc;
  1866		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1867		    MPI2_IOCSTATUS_MASK;
  1868		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1869			dcprintk(ioc,
  1870			    ioc_err(ioc,
  1871			    "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
  1872			    __func__, ioc_status));
  1873			return -EFAULT;
  1874		}
  1875	
  1876		return 0;
  1877	}
  1878	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Nov. 24, 2020, 8:41 a.m. UTC | #2
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on mkp-scsi/for-next v5.10-rc5 next-20201123]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Features-to-enhance-driver-debugging/20201124-115842
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: i386-randconfig-s001-20201124 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-151-g540c2c4b-dirty
        # https://github.com/0day-ci/linux/commit/6ef897d0859c5415dc82c174e1f2a83b286e9ae2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Suganath-Prabu-S/mpt3sas-Features-to-enhance-driver-debugging/20201124-115842
        git checkout 6ef897d0859c5415dc82c174e1f2a83b286e9ae2
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


"sparse warnings: (new ones prefixed by >>)"
>> drivers/scsi/mpt3sas/mpt3sas_config.c:1793:1: sparse: sparse: symbol '_config_set_driver_trigger_pg0' was not declared. Should it be static?
>> drivers/scsi/mpt3sas/mpt3sas_config.c:1835:1: sparse: sparse: symbol 'mpt3sas_config_update_driver_trigger_pg0' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 18d5c3c..919070b 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -975,6 +975,20 @@  _base_sas_ioc_info(struct MPT3SAS_ADAPTER *ioc, MPI2DefaultReply_t *mpi_reply,
 
 	if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
 		return;
+	/*
+	 * Older Firmware version doesn't support driver trigger pages.
+	 * So, skip displaying 'config invalid type' type
+	 * of error message.
+	 */
+	if (request_hdr->Function == MPI2_FUNCTION_CONFIG) {
+		Mpi2ConfigRequest_t *rqst = (Mpi2ConfigRequest_t *)request_hdr;
+
+		if ((rqst->ExtPageType ==
+		    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER) &&
+		    !(ioc->logging_level & MPT_DEBUG_CONFIG)) {
+			return;
+		}
+	}
 
 	switch (ioc_status) {
 
@@ -4783,6 +4797,58 @@  _base_update_ioc_page1_inlinewith_perf_mode(struct MPT3SAS_ADAPTER *ioc)
 	}
 }
 
+/**
+ * _base_check_for_trigger_pages_support - checks whether HBA FW supports
+ *					driver trigger pages or not
+ * @ioc : per adapter object
+ *
+ * Returns trigger flags mask if HBA FW supports driver trigger pages,
+ * otherwise returns EFAULT.
+ */
+static int
+_base_check_for_trigger_pages_support(struct MPT3SAS_ADAPTER *ioc)
+{
+	Mpi26DriverTriggerPage0_t trigger_pg0;
+	int r = 0;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 ioc_status;
+
+	r = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply,
+	    &trigger_pg0);
+	if (r)
+		return -EFAULT;
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+		return -EFAULT;
+
+	return le16_to_cpu(trigger_pg0.TriggerFlags);
+}
+
+/**
+ * _base_get_diag_triggers - Retrieve diag trigger values from
+ *				persistent pages.
+ * @ioc : per adapter object
+ *
+ * Return nothing.
+ */
+static void
+_base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc)
+{
+	u16 trigger_flags;
+
+	/*
+	 * Default setting of master trigger.
+	 */
+	ioc->diag_trigger_master.MasterData =
+	    (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);
+	trigger_flags = _base_check_for_trigger_pages_support(ioc);
+	if (trigger_flags < 0)
+		return;
+	ioc->supports_trigger_pages = 1;
+}
+
 /**
  * _base_static_config_pages - static start of day config pages
  * @ioc: per adapter object
@@ -4869,6 +4935,10 @@  _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 		ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors;
 	if (ioc->is_aero_ioc)
 		_base_update_ioc_page1_inlinewith_perf_mode(ioc);
+	if (ioc->is_gen35_ioc) {
+		if (ioc->is_driver_loading)
+			_base_get_diag_triggers(ioc);
+	}
 }
 
 /**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index cc4815c..83b6308 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -71,6 +71,7 @@ 
 
 #include "mpt3sas_debug.h"
 #include "mpt3sas_trigger_diag.h"
+#include "mpt3sas_trigger_pages.h"
 
 /* driver versioning info */
 #define MPT3SAS_DRIVER_NAME		"mpt3sas"
@@ -1541,6 +1542,7 @@  struct MPT3SAS_ADAPTER {
 	struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
 	struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
 	struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
+	u8		supports_trigger_pages;
 	void		*device_remove_in_progress;
 	u16		device_remove_in_progress_sz;
 	u8		is_gen35_ioc;
@@ -1817,6 +1819,9 @@  int mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
 	u16 *volume_handle);
 int mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc,
 	u16 volume_handle, u64 *wwid);
+int
+mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page);
 
 /* ctl shared API */
 extern struct device_attribute *mpt3sas_host_attrs[];
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 4a0ddc7..9f7d4cd 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -1742,6 +1742,140 @@  mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	return r;
 }
 
+/**
+ * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
+{
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
+
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	mpi_request.ExtPageType =
+	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
+	mpi_request.Header.PageNumber = 0;
+	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
+	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
+
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
+ out:
+	return r;
+}
+
+/**
+ * mpt3sas_config_set_driver_trigger_pg0 - write driver trigger page 0
+ * @ioc: per adapter object
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
+{
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
+
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	mpi_request.ExtPageType =
+	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
+	mpi_request.Header.PageNumber = 0;
+	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
+	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
+
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	_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;
+}
+
+/**
+ * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
+ * @ioc: per adapter object
+ * @trigger_flags: trigger type bit map
+ * @set: set ot clear trigger values
+ * Context: sleep.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
+	u16 trigger_flag, bool set)
+{
+	Mpi26DriverTriggerPage0_t tg_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	int rc;
+	u16 flags, ioc_status;
+
+	rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
+	if (rc)
+		return rc;
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		dcprintk(ioc,
+		    ioc_err(ioc,
+		    "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
+		    __func__, ioc_status));
+		return -EFAULT;
+	}
+
+	if (set)
+		flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
+	else
+		flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
+
+	tg_pg0.TriggerFlags = cpu_to_le16(flags);
+
+	rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
+	if (rc)
+		return rc;
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		dcprintk(ioc,
+		    ioc_err(ioc,
+		    "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
+		    __func__, ioc_status));
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
 /**
  * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
  * raid components
diff --git a/drivers/scsi/mpt3sas/mpt3sas_trigger_pages.h b/drivers/scsi/mpt3sas/mpt3sas_trigger_pages.h
new file mode 100644
index 0000000..24e30f3
--- /dev/null
+++ b/drivers/scsi/mpt3sas/mpt3sas_trigger_pages.h
@@ -0,0 +1,95 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This is the Fusion MPT base driver providing common API layer interface
+ * to store diag trigger values into persistent driver triggers pages
+ * for MPT (Message Passing Technology) based controllers.
+ *
+ * Copyright (C) 2020  Broadcom Inc.
+ *
+ * Authors: Broadcom Inc.
+ * Sreekanth Reddy  <sreekanth.reddy@broadcom.com>
+ *
+ * Send feedback to : MPT-FusionLinux.pdl@broadcom.com)
+ */
+
+#include "mpi/mpi2_cnfg.h"
+
+#ifndef MPI2_TRIGGER_PAGES_H
+#define MPI2_TRIGGER_PAGES_H
+
+#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER    (0xE0)
+#define MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION               (0x01)
+typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_0 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER	Header;	/* 0x00  */
+	U16	TriggerFlags;		/* 0x08  */
+	U16	Reserved0xA;		/* 0x0A */
+	U32	Reserved0xC[61];	/* 0x0C */
+} _MPI26_CONFIG_PAGE_DRIVER_TIGGER_0, Mpi26DriverTriggerPage0_t;
+
+/* Trigger Flags */
+#define  MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID       (0x0001)
+#define  MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID    (0x0002)
+#define  MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID   (0x0004)
+#define  MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID      (0x0008)
+
+#define MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION               (0x01)
+typedef struct _MPI26_DRIVER_MASTER_TIGGER_ENTRY {
+	U32	MasterTriggerFlags;
+} MPI26_DRIVER_MASTER_TIGGER_ENTRY;
+
+#define MPI26_MAX_MASTER_TRIGGERS                                   (1)
+typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_1 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER	Header;	/* 0x00 */
+	U16	NumMasterTrigger;	/* 0x08 */
+	U16	Reserved0xA;		/* 0x0A */
+	MPI26_DRIVER_MASTER_TIGGER_ENTRY MasterTriggers[MPI26_MAX_MASTER_TRIGGERS];	/* 0x0C */
+} MPI26_CONFIG_PAGE_DRIVER_TIGGER_1, Mpi26DriverTriggerPage1_t;
+
+#define MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION               (0x01)
+typedef struct _MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY {
+	U16	MPIEventCode;		/* 0x00 */
+	U16	MPIEventCodeSpecific;	/* 0x02 */
+} MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY;
+
+#define MPI26_MAX_MPI_EVENT_TRIGGERS                            (20)
+typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_2 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER        Header;	/* 0x00  */
+	U16	NumMPIEventTrigger;     /* 0x08  */
+	U16	Reserved0xA;		/* 0x0A */
+	MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY MPIEventTriggers[MPI26_MAX_MPI_EVENT_TRIGGERS]; /* 0x0C */
+} MPI26_CONFIG_PAGE_DRIVER_TIGGER_2, Mpi26DriverTriggerPage2_t;
+
+#define MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION               (0x01)
+typedef struct _MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY {
+	U8     ASCQ;		/* 0x00 */
+	U8     ASC;		/* 0x01 */
+	U8     SenseKey;	/* 0x02 */
+	U8     Reserved;	/* 0x03 */
+} MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY;
+
+#define MPI26_MAX_SCSI_SENSE_TRIGGERS                            (20)
+typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_3 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER	Header;	/* 0x00  */
+	U16	NumSCSISenseTrigger;			/* 0x08  */
+	U16	Reserved0xA;				/* 0x0A */
+	MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY SCSISenseTriggers[MPI26_MAX_SCSI_SENSE_TRIGGERS];	/* 0x0C */
+} MPI26_CONFIG_PAGE_DRIVER_TIGGER_3, Mpi26DriverTriggerPage3_t;
+
+#define MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION               (0x01)
+typedef struct _MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY {
+	U16        IOCStatus;      /* 0x00 */
+	U16        Reserved;       /* 0x02 */
+	U32        LogInfo;        /* 0x04 */
+} MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY;
+
+#define MPI26_MAX_LOGINFO_TRIGGERS                            (20)
+typedef struct _MPI26_CONFIG_PAGE_DRIVER_TIGGER_4 {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER	Header;	/* 0x00  */
+	U16	NumIOCStatusLogInfoTrigger;		/* 0x08  */
+	U16	Reserved0xA;				/* 0x0A */
+	MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY IOCStatusLoginfoTriggers[MPI26_MAX_LOGINFO_TRIGGERS];	/* 0x0C */
+} MPI26_CONFIG_PAGE_DRIVER_TIGGER_4, Mpi26DriverTriggerPage4_t;
+
+#endif
+