diff mbox series

[3/8] mpt3sas: Add master triggers persistent Trigger Page

Message ID 20201124035019.27975-4-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
Description:
Trigger Page 1 is used store information about master triggers.
Below are the master triggers conditions.

Bit[3]  Trigger condition for Device Removal event
Bit[2]  Trigger condition for TM command issued by driver
Bit[1]  Trigger condition for Adapter reset issued by driver
Bit[0]  Trigger condition for IOC Fault state

During driver load:
 If Master trigger type bit is enabled in the Persistent Trigger Page0
 then read the Persistent Trigger Page1 and update the ioc instances
 diag_trigger_master.MasterData with Persistent Trigger Page1's
 MasterTriggerFlags. This will restores the Master trigger type's
 triggers which are enabled before.

When user modifies the Master trigger type triggers:
 When user sets/clears the Master trigger type triggers then driver
 fisrt checks whether IOC firmware supports trigger pages support
 or not. if firmware supports these pages then driver enables the
 Master trigger type bit in Persistent Trigger Page0 (if it was not
 enabled before) and updates the user provided trigger values in
 Persistent Trigger Page1.

Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c   |  46 ++++++++
 drivers/scsi/mpt3sas/mpt3sas_base.h   |   3 +
 drivers/scsi/mpt3sas/mpt3sas_config.c | 151 ++++++++++++++++++++++++++
 3 files changed, 200 insertions(+)

Comments

kernel test robot Nov. 24, 2020, 7:48 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/9d619bffb390470be629fa99370eb823d64d796e
        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 9d619bffb390470be629fa99370eb823d64d796e
        # 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,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/scsi/mpt3sas/mpt3sas_config.c:1927:1: warning: no previous prototype for '_config_set_driver_trigger_pg1' [-Wmissing-prototypes]
    1927 | _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/scsi/mpt3sas/mpt3sas_config.c:1969:1: warning: no previous prototype for 'mpt3sas_config_update_driver_trigger_pg1' [-Wmissing-prototypes]
    1969 | mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/_config_set_driver_trigger_pg1 +1927 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	
  1879	/**
  1880	 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
  1881	 * @ioc: per adapter object
  1882	 * @mpi_reply: reply mf payload returned from firmware
  1883	 * @config_page: contents of the config page
  1884	 * Context: sleep.
  1885	 *
  1886	 * Returns 0 for success, non-zero for failure.
  1887	 */
  1888	int
  1889	mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
  1890		Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
  1891	{
  1892		Mpi2ConfigRequest_t mpi_request;
  1893		int r;
  1894	
  1895		memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1896		mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1897		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1898		mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1899		mpi_request.ExtPageType =
  1900		    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1901		mpi_request.Header.PageNumber = 1;
  1902		mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
  1903		ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1904		r = _config_request(ioc, &mpi_request, mpi_reply,
  1905		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1906		if (r)
  1907			goto out;
  1908	
  1909		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1910		r = _config_request(ioc, &mpi_request, mpi_reply,
  1911		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1912		    sizeof(*config_page));
  1913	 out:
  1914		return r;
  1915	}
  1916	
  1917	/**
  1918	 * mpt3sas_config_set_driver_trigger_pg1 - write driver trigger page 1
  1919	 * @ioc: per adapter object
  1920	 * @mpi_reply: reply mf payload returned from firmware
  1921	 * @config_page: contents of the config page
  1922	 * Context: sleep.
  1923	 *
  1924	 * Returns 0 for success, non-zero for failure.
  1925	 */
  1926	int
> 1927	_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
  1928		Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
  1929	{
  1930		Mpi2ConfigRequest_t mpi_request;
  1931		int r;
  1932	
  1933		memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1934		mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1935		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1936		mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1937		mpi_request.ExtPageType =
  1938		    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1939		mpi_request.Header.PageNumber = 1;
  1940		mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
  1941		ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1942		r = _config_request(ioc, &mpi_request, mpi_reply,
  1943		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1944		if (r)
  1945			goto out;
  1946	
  1947		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1948		_config_request(ioc, &mpi_request, mpi_reply,
  1949		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1950		    sizeof(*config_page));
  1951		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  1952		r = _config_request(ioc, &mpi_request, mpi_reply,
  1953		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1954		    sizeof(*config_page));
  1955	 out:
  1956		return r;
  1957	}
  1958	

---
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, 9:25 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/9d619bffb390470be629fa99370eb823d64d796e
        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 9d619bffb390470be629fa99370eb823d64d796e
        # 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?
>> drivers/scsi/mpt3sas/mpt3sas_config.c:1927:1: sparse: sparse: symbol '_config_set_driver_trigger_pg1' was not declared. Should it be static?
   drivers/scsi/mpt3sas/mpt3sas_config.c:1969:1: sparse: sparse: symbol 'mpt3sas_config_update_driver_trigger_pg1' 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 919070b..2c13078 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4797,6 +4797,42 @@  _base_update_ioc_page1_inlinewith_perf_mode(struct MPT3SAS_ADAPTER *ioc)
 	}
 }
 
+/**
+ * _base_get_master_diag_triggers - get master diag trigger values from
+ *				persistent pages
+ * @ioc : per adapter object
+ *
+ * Return nothing.
+ */
+static void
+_base_get_master_diag_triggers(struct MPT3SAS_ADAPTER *ioc)
+{
+	Mpi26DriverTriggerPage1_t trigger_pg1;
+	Mpi2ConfigReply_t mpi_reply;
+	int r;
+	u16 ioc_status;
+
+	r = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply,
+	    &trigger_pg1);
+	if (r)
+		return;
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		dinitprintk(ioc,
+		    ioc_err(ioc,
+		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
+		   __func__, ioc_status));
+		return;
+	}
+
+	if (le16_to_cpu(trigger_pg1.NumMasterTrigger))
+		ioc->diag_trigger_master.MasterData |=
+		    le32_to_cpu(
+		    trigger_pg1.MasterTriggers[0].MasterTriggerFlags);
+}
+
 /**
  * _base_check_for_trigger_pages_support - checks whether HBA FW supports
  *					driver trigger pages or not
@@ -4843,10 +4879,20 @@  _base_get_diag_triggers(struct MPT3SAS_ADAPTER *ioc)
 	 */
 	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;
+
+	/*
+	 * Retrieve master diag trigger values from driver trigger pg1
+	 * if master trigger bit enabled in TriggerFlags.
+	 */
+	if ((u16)trigger_flags &
+	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID)
+		_base_get_master_diag_triggers(ioc);
 }
 
 /**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 83b6308..9f5983c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1822,6 +1822,9 @@  int mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc,
 int
 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page);
+int
+mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_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 9f7d4cd..86d1643 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -1876,6 +1876,157 @@  mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
 	return 0;
 }
 
+/**
+ * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
+ * @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_pg1(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_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 = 1;
+	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_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_pg1 - write driver trigger page 1
+ * @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_pg1(struct MPT3SAS_ADAPTER *ioc,
+	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_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 = 1;
+	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_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_pg1 - update driver trigger page 1
+ * @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_pg1(struct MPT3SAS_ADAPTER *ioc,
+	struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
+{
+	Mpi26DriverTriggerPage1_t tg_pg1;
+	Mpi2ConfigReply_t mpi_reply;
+	int rc;
+	u16 ioc_status;
+
+	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
+	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
+	if (rc)
+		return rc;
+
+	rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
+	if (rc)
+		goto out;
+
+	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 pg1, ioc_status(0x%04x)\n",
+		    __func__, ioc_status));
+		rc = -EFAULT;
+		goto out;
+	}
+
+	if (set) {
+		tg_pg1.NumMasterTrigger = cpu_to_le16(1);
+		tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
+		    master_tg->MasterData);
+	} else {
+		tg_pg1.NumMasterTrigger = 0;
+		tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
+	}
+
+	rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
+	if (rc)
+		goto out;
+
+	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 pg1, ioc_status(0x%04x)\n",
+		    __func__, ioc_status));
+		rc = -EFAULT;
+		goto out;
+	}
+
+	return 0;
+
+out:
+	mpt3sas_config_update_driver_trigger_pg0(ioc,
+	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
+
+	return rc;
+}
+
 /**
  * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
  * raid components