xref: /linux/drivers/scsi/mpt3sas/mpt3sas_config.c (revision 073350da0aa2aead9df7927a1c1046ebf5cdd816)
1f92363d1SSreekanth Reddy /*
2f92363d1SSreekanth Reddy  * This module provides common API for accessing firmware configuration pages
3f92363d1SSreekanth Reddy  *
4f92363d1SSreekanth Reddy  * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
5a4ffce0dSSreekanth Reddy  * Copyright (C) 2012-2014  LSI Corporation
6a03bd153SSreekanth Reddy  * Copyright (C) 2013-2014 Avago Technologies
7a03bd153SSreekanth Reddy  *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
8f92363d1SSreekanth Reddy  *
9f92363d1SSreekanth Reddy  * This program is free software; you can redistribute it and/or
10f92363d1SSreekanth Reddy  * modify it under the terms of the GNU General Public License
11f92363d1SSreekanth Reddy  * as published by the Free Software Foundation; either version 2
12f92363d1SSreekanth Reddy  * of the License, or (at your option) any later version.
13f92363d1SSreekanth Reddy  *
14f92363d1SSreekanth Reddy  * This program is distributed in the hope that it will be useful,
15f92363d1SSreekanth Reddy  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16f92363d1SSreekanth Reddy  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17f92363d1SSreekanth Reddy  * GNU General Public License for more details.
18f92363d1SSreekanth Reddy  *
19f92363d1SSreekanth Reddy  * NO WARRANTY
20f92363d1SSreekanth Reddy  * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21f92363d1SSreekanth Reddy  * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22f92363d1SSreekanth Reddy  * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23f92363d1SSreekanth Reddy  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24f92363d1SSreekanth Reddy  * solely responsible for determining the appropriateness of using and
25f92363d1SSreekanth Reddy  * distributing the Program and assumes all risks associated with its
26f92363d1SSreekanth Reddy  * exercise of rights under this Agreement, including but not limited to
27f92363d1SSreekanth Reddy  * the risks and costs of program errors, damage to or loss of data,
28f92363d1SSreekanth Reddy  * programs or equipment, and unavailability or interruption of operations.
29f92363d1SSreekanth Reddy 
30f92363d1SSreekanth Reddy  * DISCLAIMER OF LIABILITY
31f92363d1SSreekanth Reddy  * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32f92363d1SSreekanth Reddy  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33f92363d1SSreekanth Reddy  * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34f92363d1SSreekanth Reddy  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35f92363d1SSreekanth Reddy  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36f92363d1SSreekanth Reddy  * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37f92363d1SSreekanth Reddy  * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38f92363d1SSreekanth Reddy 
39f92363d1SSreekanth Reddy  * You should have received a copy of the GNU General Public License
40f92363d1SSreekanth Reddy  * along with this program; if not, write to the Free Software
41f92363d1SSreekanth Reddy  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
42f92363d1SSreekanth Reddy  * USA.
43f92363d1SSreekanth Reddy  */
44f92363d1SSreekanth Reddy 
45f92363d1SSreekanth Reddy #include <linux/module.h>
46f92363d1SSreekanth Reddy #include <linux/kernel.h>
47f92363d1SSreekanth Reddy #include <linux/init.h>
48f92363d1SSreekanth Reddy #include <linux/errno.h>
49f92363d1SSreekanth Reddy #include <linux/blkdev.h>
50f92363d1SSreekanth Reddy #include <linux/sched.h>
51f92363d1SSreekanth Reddy #include <linux/workqueue.h>
52f92363d1SSreekanth Reddy #include <linux/delay.h>
53f92363d1SSreekanth Reddy #include <linux/pci.h>
54f92363d1SSreekanth Reddy 
55f92363d1SSreekanth Reddy #include "mpt3sas_base.h"
56f92363d1SSreekanth Reddy 
57f92363d1SSreekanth Reddy /* local definitions */
58f92363d1SSreekanth Reddy 
59f92363d1SSreekanth Reddy /* Timeout for config page request (in seconds) */
60f92363d1SSreekanth Reddy #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15
61f92363d1SSreekanth Reddy 
62f92363d1SSreekanth Reddy /* Common sgl flags for READING a config page. */
63f92363d1SSreekanth Reddy #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
64f92363d1SSreekanth Reddy 	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
65f92363d1SSreekanth Reddy 	| MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
66f92363d1SSreekanth Reddy 
67f92363d1SSreekanth Reddy /* Common sgl flags for WRITING a config page. */
68f92363d1SSreekanth Reddy #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
69f92363d1SSreekanth Reddy 	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
70f92363d1SSreekanth Reddy 	| MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
71f92363d1SSreekanth Reddy 	<< MPI2_SGE_FLAGS_SHIFT)
72f92363d1SSreekanth Reddy 
73f92363d1SSreekanth Reddy /**
74f92363d1SSreekanth Reddy  * struct config_request - obtain dma memory via routine
75f92363d1SSreekanth Reddy  * @sz: size
76f92363d1SSreekanth Reddy  * @page: virt pointer
77f92363d1SSreekanth Reddy  * @page_dma: phys pointer
78f92363d1SSreekanth Reddy  *
79f92363d1SSreekanth Reddy  */
80f92363d1SSreekanth Reddy struct config_request {
81f92363d1SSreekanth Reddy 	u16			sz;
82f92363d1SSreekanth Reddy 	void			*page;
83f92363d1SSreekanth Reddy 	dma_addr_t		page_dma;
84f92363d1SSreekanth Reddy };
85f92363d1SSreekanth Reddy 
86f92363d1SSreekanth Reddy /**
87f92363d1SSreekanth Reddy  * _config_display_some_debug - debug routine
88f92363d1SSreekanth Reddy  * @ioc: per adapter object
89f92363d1SSreekanth Reddy  * @smid: system request message index
90f92363d1SSreekanth Reddy  * @calling_function_name: string pass from calling function
91f92363d1SSreekanth Reddy  * @mpi_reply: reply message frame
92f92363d1SSreekanth Reddy  * Context: none.
93f92363d1SSreekanth Reddy  *
94f92363d1SSreekanth Reddy  * Function for displaying debug info helpful when debugging issues
95f92363d1SSreekanth Reddy  * in this module.
96f92363d1SSreekanth Reddy  */
97f92363d1SSreekanth Reddy static void
98f92363d1SSreekanth Reddy _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
99f92363d1SSreekanth Reddy 	char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
100f92363d1SSreekanth Reddy {
101f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t *mpi_request;
102f92363d1SSreekanth Reddy 	char *desc = NULL;
103f92363d1SSreekanth Reddy 
104f92363d1SSreekanth Reddy 	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
105f92363d1SSreekanth Reddy 	switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
106f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_IO_UNIT:
107f92363d1SSreekanth Reddy 		desc = "io_unit";
108f92363d1SSreekanth Reddy 		break;
109f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_IOC:
110f92363d1SSreekanth Reddy 		desc = "ioc";
111f92363d1SSreekanth Reddy 		break;
112f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_BIOS:
113f92363d1SSreekanth Reddy 		desc = "bios";
114f92363d1SSreekanth Reddy 		break;
115f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
116f92363d1SSreekanth Reddy 		desc = "raid_volume";
117f92363d1SSreekanth Reddy 		break;
118f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
1198700bc76SColin Ian King 		desc = "manufacturing";
120f92363d1SSreekanth Reddy 		break;
121f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
122f92363d1SSreekanth Reddy 		desc = "physdisk";
123f92363d1SSreekanth Reddy 		break;
124f92363d1SSreekanth Reddy 	case MPI2_CONFIG_PAGETYPE_EXTENDED:
125f92363d1SSreekanth Reddy 		switch (mpi_request->ExtPageType) {
126f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
127f92363d1SSreekanth Reddy 			desc = "sas_io_unit";
128f92363d1SSreekanth Reddy 			break;
129f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
130f92363d1SSreekanth Reddy 			desc = "sas_expander";
131f92363d1SSreekanth Reddy 			break;
132f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
133f92363d1SSreekanth Reddy 			desc = "sas_device";
134f92363d1SSreekanth Reddy 			break;
135f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
136f92363d1SSreekanth Reddy 			desc = "sas_phy";
137f92363d1SSreekanth Reddy 			break;
138f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_LOG:
139f92363d1SSreekanth Reddy 			desc = "log";
140f92363d1SSreekanth Reddy 			break;
141f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
142f92363d1SSreekanth Reddy 			desc = "enclosure";
143f92363d1SSreekanth Reddy 			break;
144f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
145f92363d1SSreekanth Reddy 			desc = "raid_config";
146f92363d1SSreekanth Reddy 			break;
147f92363d1SSreekanth Reddy 		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
14807f42258SMasanari Iida 			desc = "driver_mapping";
149f92363d1SSreekanth Reddy 			break;
150c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
151c102e00cSSuganath Prabu Subramani 			desc = "sas_port";
152c102e00cSSuganath Prabu Subramani 			break;
153c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
154c102e00cSSuganath Prabu Subramani 			desc = "ext_manufacturing";
155c102e00cSSuganath Prabu Subramani 			break;
156c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
157c102e00cSSuganath Prabu Subramani 			desc = "pcie_io_unit";
158c102e00cSSuganath Prabu Subramani 			break;
159c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
160c102e00cSSuganath Prabu Subramani 			desc = "pcie_switch";
161c102e00cSSuganath Prabu Subramani 			break;
162c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
163c102e00cSSuganath Prabu Subramani 			desc = "pcie_device";
164c102e00cSSuganath Prabu Subramani 			break;
165c102e00cSSuganath Prabu Subramani 		case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
166c102e00cSSuganath Prabu Subramani 			desc = "pcie_link";
167c102e00cSSuganath Prabu Subramani 			break;
168f92363d1SSreekanth Reddy 		}
169f92363d1SSreekanth Reddy 		break;
170f92363d1SSreekanth Reddy 	}
171f92363d1SSreekanth Reddy 
172f92363d1SSreekanth Reddy 	if (!desc)
173f92363d1SSreekanth Reddy 		return;
174f92363d1SSreekanth Reddy 
175919d8a3fSJoe Perches 	ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",
176919d8a3fSJoe Perches 		 calling_function_name, desc,
177f92363d1SSreekanth Reddy 		 mpi_request->Header.PageNumber, mpi_request->Action,
178f92363d1SSreekanth Reddy 		 le32_to_cpu(mpi_request->PageAddress), smid);
179f92363d1SSreekanth Reddy 
180f92363d1SSreekanth Reddy 	if (!mpi_reply)
181f92363d1SSreekanth Reddy 		return;
182f92363d1SSreekanth Reddy 
183f92363d1SSreekanth Reddy 	if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
184919d8a3fSJoe Perches 		ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
185919d8a3fSJoe Perches 			 le16_to_cpu(mpi_reply->IOCStatus),
186f92363d1SSreekanth Reddy 			 le32_to_cpu(mpi_reply->IOCLogInfo));
187f92363d1SSreekanth Reddy }
188f92363d1SSreekanth Reddy 
189f92363d1SSreekanth Reddy /**
190f92363d1SSreekanth Reddy  * _config_alloc_config_dma_memory - obtain physical memory
191f92363d1SSreekanth Reddy  * @ioc: per adapter object
192f92363d1SSreekanth Reddy  * @mem: struct config_request
193f92363d1SSreekanth Reddy  *
194f92363d1SSreekanth Reddy  * A wrapper for obtaining dma-able memory for config page request.
195f92363d1SSreekanth Reddy  *
1964beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
197f92363d1SSreekanth Reddy  */
198f92363d1SSreekanth Reddy static int
199f92363d1SSreekanth Reddy _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
200f92363d1SSreekanth Reddy 	struct config_request *mem)
201f92363d1SSreekanth Reddy {
202f92363d1SSreekanth Reddy 	int r = 0;
203f92363d1SSreekanth Reddy 
204f92363d1SSreekanth Reddy 	if (mem->sz > ioc->config_page_sz) {
205f92363d1SSreekanth Reddy 		mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
206f92363d1SSreekanth Reddy 		    &mem->page_dma, GFP_KERNEL);
207f92363d1SSreekanth Reddy 		if (!mem->page) {
208919d8a3fSJoe Perches 			ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
209919d8a3fSJoe Perches 				__func__, mem->sz);
210f92363d1SSreekanth Reddy 			r = -ENOMEM;
211f92363d1SSreekanth Reddy 		}
212f92363d1SSreekanth Reddy 	} else { /* use tmp buffer if less than 512 bytes */
213f92363d1SSreekanth Reddy 		mem->page = ioc->config_page;
214f92363d1SSreekanth Reddy 		mem->page_dma = ioc->config_page_dma;
215f92363d1SSreekanth Reddy 	}
216182ac784SSuganath Prabu Subramani 	ioc->config_vaddr = mem->page;
217f92363d1SSreekanth Reddy 	return r;
218f92363d1SSreekanth Reddy }
219f92363d1SSreekanth Reddy 
220f92363d1SSreekanth Reddy /**
221f92363d1SSreekanth Reddy  * _config_free_config_dma_memory - wrapper to free the memory
222f92363d1SSreekanth Reddy  * @ioc: per adapter object
223f92363d1SSreekanth Reddy  * @mem: struct config_request
224f92363d1SSreekanth Reddy  *
225f92363d1SSreekanth Reddy  * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
226f92363d1SSreekanth Reddy  *
2274beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
228f92363d1SSreekanth Reddy  */
229f92363d1SSreekanth Reddy static void
230f92363d1SSreekanth Reddy _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
231f92363d1SSreekanth Reddy 	struct config_request *mem)
232f92363d1SSreekanth Reddy {
233f92363d1SSreekanth Reddy 	if (mem->sz > ioc->config_page_sz)
234f92363d1SSreekanth Reddy 		dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
235f92363d1SSreekanth Reddy 		    mem->page_dma);
236f92363d1SSreekanth Reddy }
237f92363d1SSreekanth Reddy 
238f92363d1SSreekanth Reddy /**
239f92363d1SSreekanth Reddy  * mpt3sas_config_done - config page completion routine
240f92363d1SSreekanth Reddy  * @ioc: per adapter object
241f92363d1SSreekanth Reddy  * @smid: system request message index
242f92363d1SSreekanth Reddy  * @msix_index: MSIX table index supplied by the OS
243f92363d1SSreekanth Reddy  * @reply: reply message frame(lower 32bit addr)
244f92363d1SSreekanth Reddy  * Context: none.
245f92363d1SSreekanth Reddy  *
246f92363d1SSreekanth Reddy  * The callback handler when using _config_request.
247f92363d1SSreekanth Reddy  *
2484beb4867SBart Van Assche  * Return: 1 meaning mf should be freed from _base_interrupt
249f92363d1SSreekanth Reddy  *         0 means the mf is freed from this function.
250f92363d1SSreekanth Reddy  */
251f92363d1SSreekanth Reddy u8
252f92363d1SSreekanth Reddy mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
253f92363d1SSreekanth Reddy 	u32 reply)
254f92363d1SSreekanth Reddy {
255f92363d1SSreekanth Reddy 	MPI2DefaultReply_t *mpi_reply;
256f92363d1SSreekanth Reddy 
257f92363d1SSreekanth Reddy 	if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)
258f92363d1SSreekanth Reddy 		return 1;
259f92363d1SSreekanth Reddy 	if (ioc->config_cmds.smid != smid)
260f92363d1SSreekanth Reddy 		return 1;
261f92363d1SSreekanth Reddy 	ioc->config_cmds.status |= MPT3_CMD_COMPLETE;
262f92363d1SSreekanth Reddy 	mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);
263f92363d1SSreekanth Reddy 	if (mpi_reply) {
264f92363d1SSreekanth Reddy 		ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;
265f92363d1SSreekanth Reddy 		memcpy(ioc->config_cmds.reply, mpi_reply,
266f92363d1SSreekanth Reddy 		    mpi_reply->MsgLength*4);
267f92363d1SSreekanth Reddy 	}
268f92363d1SSreekanth Reddy 	ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
2695b061980SSreekanth Reddy 	if (ioc->logging_level & MPT_DEBUG_CONFIG)
270f92363d1SSreekanth Reddy 		_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
271f92363d1SSreekanth Reddy 	ioc->config_cmds.smid = USHRT_MAX;
272f92363d1SSreekanth Reddy 	complete(&ioc->config_cmds.done);
273f92363d1SSreekanth Reddy 	return 1;
274f92363d1SSreekanth Reddy }
275f92363d1SSreekanth Reddy 
276f92363d1SSreekanth Reddy /**
277f92363d1SSreekanth Reddy  * _config_request - main routine for sending config page requests
278f92363d1SSreekanth Reddy  * @ioc: per adapter object
279f92363d1SSreekanth Reddy  * @mpi_request: request message frame
280f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
281f92363d1SSreekanth Reddy  * @timeout: timeout in seconds
282f92363d1SSreekanth Reddy  * @config_page: contents of the config page
283f92363d1SSreekanth Reddy  * @config_page_sz: size of config page
284f92363d1SSreekanth Reddy  * Context: sleep
285f92363d1SSreekanth Reddy  *
286f92363d1SSreekanth Reddy  * A generic API for config page requests to firmware.
287f92363d1SSreekanth Reddy  *
288f92363d1SSreekanth Reddy  * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
289f92363d1SSreekanth Reddy  * this API.
290f92363d1SSreekanth Reddy  *
291f92363d1SSreekanth Reddy  * The callback index is set inside `ioc->config_cb_idx.
292f92363d1SSreekanth Reddy  *
2934beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
294f92363d1SSreekanth Reddy  */
295f92363d1SSreekanth Reddy static int
296f92363d1SSreekanth Reddy _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
297f92363d1SSreekanth Reddy 	*mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
298f92363d1SSreekanth Reddy 	void *config_page, u16 config_page_sz)
299f92363d1SSreekanth Reddy {
300f92363d1SSreekanth Reddy 	u16 smid;
301f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t *config_request;
302f92363d1SSreekanth Reddy 	int r;
303f92363d1SSreekanth Reddy 	u8 retry_count, issue_host_reset = 0;
304f92363d1SSreekanth Reddy 	struct config_request mem;
305f92363d1SSreekanth Reddy 	u32 ioc_status = UINT_MAX;
306f92363d1SSreekanth Reddy 
307f92363d1SSreekanth Reddy 	mutex_lock(&ioc->config_cmds.mutex);
308f92363d1SSreekanth Reddy 	if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
309919d8a3fSJoe Perches 		ioc_err(ioc, "%s: config_cmd in use\n", __func__);
310f92363d1SSreekanth Reddy 		mutex_unlock(&ioc->config_cmds.mutex);
311f92363d1SSreekanth Reddy 		return -EAGAIN;
312f92363d1SSreekanth Reddy 	}
313f92363d1SSreekanth Reddy 
314f92363d1SSreekanth Reddy 	retry_count = 0;
315f92363d1SSreekanth Reddy 	memset(&mem, 0, sizeof(struct config_request));
316f92363d1SSreekanth Reddy 
317f92363d1SSreekanth Reddy 	mpi_request->VF_ID = 0; /* TODO */
318f92363d1SSreekanth Reddy 	mpi_request->VP_ID = 0;
319f92363d1SSreekanth Reddy 
320f92363d1SSreekanth Reddy 	if (config_page) {
321f92363d1SSreekanth Reddy 		mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
322f92363d1SSreekanth Reddy 		mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
323f92363d1SSreekanth Reddy 		mpi_request->Header.PageType = mpi_reply->Header.PageType;
324f92363d1SSreekanth Reddy 		mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
325f92363d1SSreekanth Reddy 		mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
326f92363d1SSreekanth Reddy 		mpi_request->ExtPageType = mpi_reply->ExtPageType;
327f92363d1SSreekanth Reddy 		if (mpi_request->Header.PageLength)
328f92363d1SSreekanth Reddy 			mem.sz = mpi_request->Header.PageLength * 4;
329f92363d1SSreekanth Reddy 		else
330f92363d1SSreekanth Reddy 			mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
331f92363d1SSreekanth Reddy 		r = _config_alloc_config_dma_memory(ioc, &mem);
332f92363d1SSreekanth Reddy 		if (r != 0)
333f92363d1SSreekanth Reddy 			goto out;
334f92363d1SSreekanth Reddy 		if (mpi_request->Action ==
335f92363d1SSreekanth Reddy 		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
336f92363d1SSreekanth Reddy 		    mpi_request->Action ==
337f92363d1SSreekanth Reddy 		    MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
338f92363d1SSreekanth Reddy 			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
339f92363d1SSreekanth Reddy 			    MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
340f92363d1SSreekanth Reddy 			    mem.page_dma);
341f92363d1SSreekanth Reddy 			memcpy(mem.page, config_page, min_t(u16, mem.sz,
342f92363d1SSreekanth Reddy 			    config_page_sz));
343f92363d1SSreekanth Reddy 		} else {
344f92363d1SSreekanth Reddy 			memset(config_page, 0, config_page_sz);
345f92363d1SSreekanth Reddy 			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
346f92363d1SSreekanth Reddy 			    MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
347f92363d1SSreekanth Reddy 			memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
348f92363d1SSreekanth Reddy 		}
349f92363d1SSreekanth Reddy 	}
350f92363d1SSreekanth Reddy 
351f92363d1SSreekanth Reddy  retry_config:
352f92363d1SSreekanth Reddy 	if (retry_count) {
353f92363d1SSreekanth Reddy 		if (retry_count > 2) { /* attempt only 2 retries */
354f92363d1SSreekanth Reddy 			r = -EFAULT;
355f92363d1SSreekanth Reddy 			goto free_mem;
356f92363d1SSreekanth Reddy 		}
357919d8a3fSJoe Perches 		ioc_info(ioc, "%s: attempting retry (%d)\n",
358919d8a3fSJoe Perches 			 __func__, retry_count);
359f92363d1SSreekanth Reddy 	}
360f4305749SSuganath Prabu 
361f4305749SSuganath Prabu 	r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
36219a622c3SSuganath Prabu S 	if (r) {
36319a622c3SSuganath Prabu S 		if (r == -ETIME)
36419a622c3SSuganath Prabu S 			issue_host_reset = 1;
365f92363d1SSreekanth Reddy 		goto free_mem;
36619a622c3SSuganath Prabu S 	}
367f92363d1SSreekanth Reddy 
368f92363d1SSreekanth Reddy 	smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
369f92363d1SSreekanth Reddy 	if (!smid) {
370919d8a3fSJoe Perches 		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
371f92363d1SSreekanth Reddy 		ioc->config_cmds.status = MPT3_CMD_NOT_USED;
372f92363d1SSreekanth Reddy 		r = -EAGAIN;
373f92363d1SSreekanth Reddy 		goto free_mem;
374f92363d1SSreekanth Reddy 	}
375f92363d1SSreekanth Reddy 
376f92363d1SSreekanth Reddy 	r = 0;
377f09219e4SSuganath Prabu S 	memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
378f92363d1SSreekanth Reddy 	ioc->config_cmds.status = MPT3_CMD_PENDING;
379f92363d1SSreekanth Reddy 	config_request = mpt3sas_base_get_msg_frame(ioc, smid);
380f92363d1SSreekanth Reddy 	ioc->config_cmds.smid = smid;
381f92363d1SSreekanth Reddy 	memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
3825b061980SSreekanth Reddy 	if (ioc->logging_level & MPT_DEBUG_CONFIG)
383f92363d1SSreekanth Reddy 		_config_display_some_debug(ioc, smid, "config_request", NULL);
384f92363d1SSreekanth Reddy 	init_completion(&ioc->config_cmds.done);
385078a4cc1SSuganath Prabu S 	ioc->put_smid_default(ioc, smid);
3868bbb1cf6SCalvin Owens 	wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
387f92363d1SSreekanth Reddy 	if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
3885b061980SSreekanth Reddy 		if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
3895b061980SSreekanth Reddy 			_config_display_some_debug(ioc,
3905b061980SSreekanth Reddy 			    smid, "config_request", NULL);
3912eab3eb0SDamien Le Moal 		ioc_err(ioc, "%s: command timeout\n", __func__);
3922eab3eb0SDamien Le Moal 		mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
3932eab3eb0SDamien Le Moal 				mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
394f92363d1SSreekanth Reddy 		retry_count++;
395f92363d1SSreekanth Reddy 		if (ioc->config_cmds.smid == smid)
396f92363d1SSreekanth Reddy 			mpt3sas_base_free_smid(ioc, smid);
397*f61eb121SSreekanth Reddy 		if (ioc->config_cmds.status & MPT3_CMD_RESET)
398f92363d1SSreekanth Reddy 			goto retry_config;
399*f61eb121SSreekanth Reddy 		if (ioc->shost_recovery || ioc->pci_error_recovery) {
400*f61eb121SSreekanth Reddy 			issue_host_reset = 0;
401*f61eb121SSreekanth Reddy 			r = -EFAULT;
402*f61eb121SSreekanth Reddy 		} else
403f92363d1SSreekanth Reddy 			issue_host_reset = 1;
404f92363d1SSreekanth Reddy 		goto free_mem;
405f92363d1SSreekanth Reddy 	}
406f92363d1SSreekanth Reddy 
407f92363d1SSreekanth Reddy 	if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
408f92363d1SSreekanth Reddy 		memcpy(mpi_reply, ioc->config_cmds.reply,
409f92363d1SSreekanth Reddy 		    sizeof(Mpi2ConfigReply_t));
410f92363d1SSreekanth Reddy 
411f92363d1SSreekanth Reddy 		/* Reply Frame Sanity Checks to workaround FW issues */
412f92363d1SSreekanth Reddy 		if ((mpi_request->Header.PageType & 0xF) !=
413f92363d1SSreekanth Reddy 		    (mpi_reply->Header.PageType & 0xF)) {
4145b061980SSreekanth Reddy 			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
4155b061980SSreekanth Reddy 				_config_display_some_debug(ioc,
4165b061980SSreekanth Reddy 				    smid, "config_request", NULL);
417f92363d1SSreekanth Reddy 			_debug_dump_mf(mpi_request, ioc->request_sz/4);
4185b061980SSreekanth Reddy 			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
419506f7f6bSJoe Perches 			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
420f92363d1SSreekanth Reddy 			      ioc->name, __func__,
421506f7f6bSJoe Perches 			      mpi_request->Header.PageType & 0xF,
422506f7f6bSJoe Perches 			      mpi_reply->Header.PageType & 0xF);
423f92363d1SSreekanth Reddy 		}
424f92363d1SSreekanth Reddy 
425f92363d1SSreekanth Reddy 		if (((mpi_request->Header.PageType & 0xF) ==
426f92363d1SSreekanth Reddy 		    MPI2_CONFIG_PAGETYPE_EXTENDED) &&
427f92363d1SSreekanth Reddy 		    mpi_request->ExtPageType != mpi_reply->ExtPageType) {
4285b061980SSreekanth Reddy 			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
4295b061980SSreekanth Reddy 				_config_display_some_debug(ioc,
4305b061980SSreekanth Reddy 				    smid, "config_request", NULL);
431f92363d1SSreekanth Reddy 			_debug_dump_mf(mpi_request, ioc->request_sz/4);
4325b061980SSreekanth Reddy 			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
433506f7f6bSJoe Perches 			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
434506f7f6bSJoe Perches 			      ioc->name, __func__,
435506f7f6bSJoe Perches 			      mpi_request->ExtPageType,
436f92363d1SSreekanth Reddy 			      mpi_reply->ExtPageType);
437f92363d1SSreekanth Reddy 		}
438f92363d1SSreekanth Reddy 		ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
439f92363d1SSreekanth Reddy 		    & MPI2_IOCSTATUS_MASK;
440f92363d1SSreekanth Reddy 	}
441f92363d1SSreekanth Reddy 
442f92363d1SSreekanth Reddy 	if (retry_count)
443919d8a3fSJoe Perches 		ioc_info(ioc, "%s: retry (%d) completed!!\n",
444919d8a3fSJoe Perches 			 __func__, retry_count);
445f92363d1SSreekanth Reddy 
446f92363d1SSreekanth Reddy 	if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
447f92363d1SSreekanth Reddy 	    config_page && mpi_request->Action ==
448f92363d1SSreekanth Reddy 	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
449f92363d1SSreekanth Reddy 		u8 *p = (u8 *)mem.page;
450f92363d1SSreekanth Reddy 
451f92363d1SSreekanth Reddy 		/* Config Page Sanity Checks to workaround FW issues */
452f92363d1SSreekanth Reddy 		if (p) {
453f92363d1SSreekanth Reddy 			if ((mpi_request->Header.PageType & 0xF) !=
454f92363d1SSreekanth Reddy 			    (p[3] & 0xF)) {
4555b061980SSreekanth Reddy 				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
4565b061980SSreekanth Reddy 					_config_display_some_debug(ioc,
4575b061980SSreekanth Reddy 					    smid, "config_request", NULL);
458f92363d1SSreekanth Reddy 				_debug_dump_mf(mpi_request, ioc->request_sz/4);
4595b061980SSreekanth Reddy 				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
460f92363d1SSreekanth Reddy 				_debug_dump_config(p, min_t(u16, mem.sz,
461f92363d1SSreekanth Reddy 				    config_page_sz)/4);
462506f7f6bSJoe Perches 				panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
463f92363d1SSreekanth Reddy 				      ioc->name, __func__,
464506f7f6bSJoe Perches 				      mpi_request->Header.PageType & 0xF,
465506f7f6bSJoe Perches 				      p[3] & 0xF);
466f92363d1SSreekanth Reddy 			}
467f92363d1SSreekanth Reddy 
468f92363d1SSreekanth Reddy 			if (((mpi_request->Header.PageType & 0xF) ==
469f92363d1SSreekanth Reddy 			    MPI2_CONFIG_PAGETYPE_EXTENDED) &&
470f92363d1SSreekanth Reddy 			    (mpi_request->ExtPageType != p[6])) {
4715b061980SSreekanth Reddy 				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
4725b061980SSreekanth Reddy 					_config_display_some_debug(ioc,
4735b061980SSreekanth Reddy 					    smid, "config_request", NULL);
474f92363d1SSreekanth Reddy 				_debug_dump_mf(mpi_request, ioc->request_sz/4);
4755b061980SSreekanth Reddy 				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
476f92363d1SSreekanth Reddy 				_debug_dump_config(p, min_t(u16, mem.sz,
477f92363d1SSreekanth Reddy 				    config_page_sz)/4);
478506f7f6bSJoe Perches 				panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
479f92363d1SSreekanth Reddy 				      ioc->name, __func__,
480f92363d1SSreekanth Reddy 				      mpi_request->ExtPageType, p[6]);
481f92363d1SSreekanth Reddy 			}
482f92363d1SSreekanth Reddy 		}
483f92363d1SSreekanth Reddy 		memcpy(config_page, mem.page, min_t(u16, mem.sz,
484f92363d1SSreekanth Reddy 		    config_page_sz));
485f92363d1SSreekanth Reddy 	}
486f92363d1SSreekanth Reddy 
487f92363d1SSreekanth Reddy  free_mem:
488f92363d1SSreekanth Reddy 	if (config_page)
489f92363d1SSreekanth Reddy 		_config_free_config_dma_memory(ioc, &mem);
490f92363d1SSreekanth Reddy  out:
491f92363d1SSreekanth Reddy 	ioc->config_cmds.status = MPT3_CMD_NOT_USED;
492f92363d1SSreekanth Reddy 	mutex_unlock(&ioc->config_cmds.mutex);
493f92363d1SSreekanth Reddy 
49419a622c3SSuganath Prabu S 	if (issue_host_reset) {
49519a622c3SSuganath Prabu S 		if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {
49698c56ad3SCalvin Owens 			mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
49719a622c3SSuganath Prabu S 			r = -EFAULT;
49819a622c3SSuganath Prabu S 		} else {
49919a622c3SSuganath Prabu S 			if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))
50019a622c3SSuganath Prabu S 				return -EFAULT;
50119a622c3SSuganath Prabu S 			r = -EAGAIN;
50219a622c3SSuganath Prabu S 		}
50319a622c3SSuganath Prabu S 	}
504f92363d1SSreekanth Reddy 	return r;
505f92363d1SSreekanth Reddy }
506f92363d1SSreekanth Reddy 
507f92363d1SSreekanth Reddy /**
508f92363d1SSreekanth Reddy  * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
509f92363d1SSreekanth Reddy  * @ioc: per adapter object
510f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
511f92363d1SSreekanth Reddy  * @config_page: contents of the config page
512f92363d1SSreekanth Reddy  * Context: sleep.
513f92363d1SSreekanth Reddy  *
5144beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
515f92363d1SSreekanth Reddy  */
516f92363d1SSreekanth Reddy int
517f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
518f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
519f92363d1SSreekanth Reddy {
520f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
521f92363d1SSreekanth Reddy 	int r;
522f92363d1SSreekanth Reddy 
523f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
524f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
525f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
526f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
527f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
528f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
529f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
530f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
531f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
532f92363d1SSreekanth Reddy 	if (r)
533f92363d1SSreekanth Reddy 		goto out;
534f92363d1SSreekanth Reddy 
535f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
536f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
537f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
538f92363d1SSreekanth Reddy 	    sizeof(*config_page));
539f92363d1SSreekanth Reddy  out:
540f92363d1SSreekanth Reddy 	return r;
541f92363d1SSreekanth Reddy }
542f92363d1SSreekanth Reddy 
543f92363d1SSreekanth Reddy /**
544f92363d1SSreekanth Reddy  * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
545f92363d1SSreekanth Reddy  * @ioc: per adapter object
546f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
547f92363d1SSreekanth Reddy  * @config_page: contents of the config page
548f92363d1SSreekanth Reddy  * @sz: size of buffer passed in config_page
549f92363d1SSreekanth Reddy  * Context: sleep.
550f92363d1SSreekanth Reddy  *
5514beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
552f92363d1SSreekanth Reddy  */
553f92363d1SSreekanth Reddy int
554f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
555f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
556f92363d1SSreekanth Reddy 	u16 sz)
557f92363d1SSreekanth Reddy {
558f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
559f92363d1SSreekanth Reddy 	int r;
560f92363d1SSreekanth Reddy 
561f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
562f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
563f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
564f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
565f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 7;
566f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
567f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
568f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
569f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
570f92363d1SSreekanth Reddy 	if (r)
571f92363d1SSreekanth Reddy 		goto out;
572f92363d1SSreekanth Reddy 
573f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
574f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
575f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
576f92363d1SSreekanth Reddy 	    sz);
577f92363d1SSreekanth Reddy  out:
578f92363d1SSreekanth Reddy 	return r;
579f92363d1SSreekanth Reddy }
580f92363d1SSreekanth Reddy 
581f92363d1SSreekanth Reddy /**
582f92363d1SSreekanth Reddy  * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
583f92363d1SSreekanth Reddy  * @ioc: per adapter object
584f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
585f92363d1SSreekanth Reddy  * @config_page: contents of the config page
586f92363d1SSreekanth Reddy  * Context: sleep.
587f92363d1SSreekanth Reddy  *
5884beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
589f92363d1SSreekanth Reddy  */
590f92363d1SSreekanth Reddy int
591f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
592f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply,
593f92363d1SSreekanth Reddy 	struct Mpi2ManufacturingPage10_t *config_page)
594f92363d1SSreekanth Reddy {
595f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
596f92363d1SSreekanth Reddy 	int r;
597f92363d1SSreekanth Reddy 
598f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
599f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
600f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
601f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
602f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 10;
603f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
604f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
605f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
606f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
607f92363d1SSreekanth Reddy 	if (r)
608f92363d1SSreekanth Reddy 		goto out;
609f92363d1SSreekanth Reddy 
610f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
611f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
612f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
613f92363d1SSreekanth Reddy 	    sizeof(*config_page));
614f92363d1SSreekanth Reddy  out:
615f92363d1SSreekanth Reddy 	return r;
616f92363d1SSreekanth Reddy }
617f92363d1SSreekanth Reddy 
618f92363d1SSreekanth Reddy /**
619f92363d1SSreekanth Reddy  * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
620f92363d1SSreekanth Reddy  * @ioc: per adapter object
621f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
622f92363d1SSreekanth Reddy  * @config_page: contents of the config page
623f92363d1SSreekanth Reddy  * Context: sleep.
624f92363d1SSreekanth Reddy  *
6254beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
626f92363d1SSreekanth Reddy  */
627f92363d1SSreekanth Reddy int
628f92363d1SSreekanth Reddy mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
629f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply,
630f92363d1SSreekanth Reddy 	struct Mpi2ManufacturingPage11_t *config_page)
631f92363d1SSreekanth Reddy {
632f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
633f92363d1SSreekanth Reddy 	int r;
634f92363d1SSreekanth Reddy 
635f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
636f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
637f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
638f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
639f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 11;
640f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
641f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
642f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
643f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
644f92363d1SSreekanth Reddy 	if (r)
645f92363d1SSreekanth Reddy 		goto out;
646f92363d1SSreekanth Reddy 
647f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
648f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
649f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
650f92363d1SSreekanth Reddy 	    sizeof(*config_page));
651f92363d1SSreekanth Reddy  out:
652f92363d1SSreekanth Reddy 	return r;
653f92363d1SSreekanth Reddy }
654f92363d1SSreekanth Reddy 
655f92363d1SSreekanth Reddy /**
656f92363d1SSreekanth Reddy  * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
657f92363d1SSreekanth Reddy  * @ioc: per adapter object
658f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
659f92363d1SSreekanth Reddy  * @config_page: contents of the config page
660f92363d1SSreekanth Reddy  * Context: sleep.
661f92363d1SSreekanth Reddy  *
6624beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
663f92363d1SSreekanth Reddy  */
664f92363d1SSreekanth Reddy int
665f92363d1SSreekanth Reddy mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
666f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply,
667f92363d1SSreekanth Reddy 	struct Mpi2ManufacturingPage11_t *config_page)
668f92363d1SSreekanth Reddy {
669f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
670f92363d1SSreekanth Reddy 	int r;
671f92363d1SSreekanth Reddy 
672f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
673f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
674f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
675f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
676f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 11;
677f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
678f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
679f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
680f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
681f92363d1SSreekanth Reddy 	if (r)
682f92363d1SSreekanth Reddy 		goto out;
683f92363d1SSreekanth Reddy 
684f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
685f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
686f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
687f92363d1SSreekanth Reddy 	    sizeof(*config_page));
688f92363d1SSreekanth Reddy  out:
689f92363d1SSreekanth Reddy 	return r;
690f92363d1SSreekanth Reddy }
691f92363d1SSreekanth Reddy 
692f92363d1SSreekanth Reddy /**
693f92363d1SSreekanth Reddy  * mpt3sas_config_get_bios_pg2 - obtain bios page 2
694f92363d1SSreekanth Reddy  * @ioc: per adapter object
695f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
696f92363d1SSreekanth Reddy  * @config_page: contents of the config page
697f92363d1SSreekanth Reddy  * Context: sleep.
698f92363d1SSreekanth Reddy  *
6994beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
700f92363d1SSreekanth Reddy  */
701f92363d1SSreekanth Reddy int
702f92363d1SSreekanth Reddy mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
703f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
704f92363d1SSreekanth Reddy {
705f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
706f92363d1SSreekanth Reddy 	int r;
707f92363d1SSreekanth Reddy 
708f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
709f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
710f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
711f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
712f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 2;
713f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
714f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
715f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
716f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
717f92363d1SSreekanth Reddy 	if (r)
718f92363d1SSreekanth Reddy 		goto out;
719f92363d1SSreekanth Reddy 
720f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
721f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
722f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
723f92363d1SSreekanth Reddy 	    sizeof(*config_page));
724f92363d1SSreekanth Reddy  out:
725f92363d1SSreekanth Reddy 	return r;
726f92363d1SSreekanth Reddy }
727f92363d1SSreekanth Reddy 
728f92363d1SSreekanth Reddy /**
729f92363d1SSreekanth Reddy  * mpt3sas_config_get_bios_pg3 - obtain bios page 3
730f92363d1SSreekanth Reddy  * @ioc: per adapter object
731f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
732f92363d1SSreekanth Reddy  * @config_page: contents of the config page
733f92363d1SSreekanth Reddy  * Context: sleep.
734f92363d1SSreekanth Reddy  *
7354beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
736f92363d1SSreekanth Reddy  */
737f92363d1SSreekanth Reddy int
738f92363d1SSreekanth Reddy mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
739f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2BiosPage3_t *config_page)
740f92363d1SSreekanth Reddy {
741f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
742f92363d1SSreekanth Reddy 	int r;
743f92363d1SSreekanth Reddy 
744f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
745f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
746f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
747f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
748f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 3;
749f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
750f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
751f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
752f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
753f92363d1SSreekanth Reddy 	if (r)
754f92363d1SSreekanth Reddy 		goto out;
755f92363d1SSreekanth Reddy 
756f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
757f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
758f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
759f92363d1SSreekanth Reddy 	    sizeof(*config_page));
760f92363d1SSreekanth Reddy  out:
761f92363d1SSreekanth Reddy 	return r;
762f92363d1SSreekanth Reddy }
763f92363d1SSreekanth Reddy 
764f92363d1SSreekanth Reddy /**
765f92363d1SSreekanth Reddy  * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
766f92363d1SSreekanth Reddy  * @ioc: per adapter object
767f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
768f92363d1SSreekanth Reddy  * @config_page: contents of the config page
769f92363d1SSreekanth Reddy  * Context: sleep.
770f92363d1SSreekanth Reddy  *
7714beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
772f92363d1SSreekanth Reddy  */
773f92363d1SSreekanth Reddy int
774f92363d1SSreekanth Reddy mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
775f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
776f92363d1SSreekanth Reddy {
777f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
778f92363d1SSreekanth Reddy 	int r;
779f92363d1SSreekanth Reddy 
780f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
781f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
782f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
783f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
784f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
785f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
786f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
787f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
788f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
789f92363d1SSreekanth Reddy 	if (r)
790f92363d1SSreekanth Reddy 		goto out;
791f92363d1SSreekanth Reddy 
792f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
793f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
794f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
795f92363d1SSreekanth Reddy 	    sizeof(*config_page));
796f92363d1SSreekanth Reddy  out:
797f92363d1SSreekanth Reddy 	return r;
798f92363d1SSreekanth Reddy }
799f92363d1SSreekanth Reddy 
800f92363d1SSreekanth Reddy /**
801f92363d1SSreekanth Reddy  * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
802f92363d1SSreekanth Reddy  * @ioc: per adapter object
803f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
804f92363d1SSreekanth Reddy  * @config_page: contents of the config page
805f92363d1SSreekanth Reddy  * Context: sleep.
806f92363d1SSreekanth Reddy  *
8074beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
808f92363d1SSreekanth Reddy  */
809f92363d1SSreekanth Reddy int
810f92363d1SSreekanth Reddy mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
811f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
812f92363d1SSreekanth Reddy {
813f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
814f92363d1SSreekanth Reddy 	int r;
815f92363d1SSreekanth Reddy 
816f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
817f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
818f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
819f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
820f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
821f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
822f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
823f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
824f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
825f92363d1SSreekanth Reddy 	if (r)
826f92363d1SSreekanth Reddy 		goto out;
827f92363d1SSreekanth Reddy 
828f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
829f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
830f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
831f92363d1SSreekanth Reddy 	    sizeof(*config_page));
832f92363d1SSreekanth Reddy  out:
833f92363d1SSreekanth Reddy 	return r;
834f92363d1SSreekanth Reddy }
835f92363d1SSreekanth Reddy 
836f92363d1SSreekanth Reddy /**
837f92363d1SSreekanth Reddy  * mpt3sas_config_set_iounit_pg1 - set iounit page 1
838f92363d1SSreekanth Reddy  * @ioc: per adapter object
839f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
840f92363d1SSreekanth Reddy  * @config_page: contents of the config page
841f92363d1SSreekanth Reddy  * Context: sleep.
842f92363d1SSreekanth Reddy  *
8434beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
844f92363d1SSreekanth Reddy  */
845f92363d1SSreekanth Reddy int
846f92363d1SSreekanth Reddy mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
847f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
848f92363d1SSreekanth Reddy {
849f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
850f92363d1SSreekanth Reddy 	int r;
851f92363d1SSreekanth Reddy 
852f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
853f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
854f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
855f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
856f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
857f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
858f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
859f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
860f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
861f92363d1SSreekanth Reddy 	if (r)
862f92363d1SSreekanth Reddy 		goto out;
863f92363d1SSreekanth Reddy 
864f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
865f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
866f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
867f92363d1SSreekanth Reddy 	    sizeof(*config_page));
868f92363d1SSreekanth Reddy  out:
869f92363d1SSreekanth Reddy 	return r;
870f92363d1SSreekanth Reddy }
871f92363d1SSreekanth Reddy 
87242263095SSreekanth Reddy /**
87342263095SSreekanth Reddy  * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
87442263095SSreekanth Reddy  * @ioc: per adapter object
87542263095SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
87642263095SSreekanth Reddy  * @config_page: contents of the config page
87742263095SSreekanth Reddy  * @sz: size of buffer passed in config_page
87842263095SSreekanth Reddy  * Context: sleep.
87942263095SSreekanth Reddy  *
8804beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
88142263095SSreekanth Reddy  */
88242263095SSreekanth Reddy int
88342263095SSreekanth Reddy mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
88442263095SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
88542263095SSreekanth Reddy {
88642263095SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
88742263095SSreekanth Reddy 	int r;
88842263095SSreekanth Reddy 
88942263095SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
89042263095SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
89142263095SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
89242263095SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
89342263095SSreekanth Reddy 	mpi_request.Header.PageNumber = 3;
89442263095SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
89542263095SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
89642263095SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
89742263095SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
89842263095SSreekanth Reddy 	if (r)
89942263095SSreekanth Reddy 		goto out;
90042263095SSreekanth Reddy 
90142263095SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
90242263095SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
90342263095SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
90442263095SSreekanth Reddy  out:
90542263095SSreekanth Reddy 	return r;
90642263095SSreekanth Reddy }
90742263095SSreekanth Reddy 
908f92363d1SSreekanth Reddy /**
9092d8ce8c9SSreekanth Reddy  * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
9102d8ce8c9SSreekanth Reddy  * @ioc: per adapter object
9112d8ce8c9SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
9122d8ce8c9SSreekanth Reddy  * @config_page: contents of the config page
9132d8ce8c9SSreekanth Reddy  * Context: sleep.
9142d8ce8c9SSreekanth Reddy  *
9154beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
9162d8ce8c9SSreekanth Reddy  */
9172d8ce8c9SSreekanth Reddy int
9182d8ce8c9SSreekanth Reddy mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
9192d8ce8c9SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
9202d8ce8c9SSreekanth Reddy {
9212d8ce8c9SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
9222d8ce8c9SSreekanth Reddy 	int r;
9232d8ce8c9SSreekanth Reddy 
9242d8ce8c9SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
9252d8ce8c9SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
9262d8ce8c9SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
9272d8ce8c9SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
9282d8ce8c9SSreekanth Reddy 	mpi_request.Header.PageNumber = 8;
9292d8ce8c9SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
9302d8ce8c9SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
9312d8ce8c9SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
9322d8ce8c9SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
9332d8ce8c9SSreekanth Reddy 	if (r)
9342d8ce8c9SSreekanth Reddy 		goto out;
9352d8ce8c9SSreekanth Reddy 
9362d8ce8c9SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
9372d8ce8c9SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
9382d8ce8c9SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
9392d8ce8c9SSreekanth Reddy 	    sizeof(*config_page));
9402d8ce8c9SSreekanth Reddy  out:
9412d8ce8c9SSreekanth Reddy 	return r;
9422d8ce8c9SSreekanth Reddy }
9432d8ce8c9SSreekanth Reddy 
9442d8ce8c9SSreekanth Reddy /**
945f92363d1SSreekanth Reddy  * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
946f92363d1SSreekanth Reddy  * @ioc: per adapter object
947f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
948f92363d1SSreekanth Reddy  * @config_page: contents of the config page
949f92363d1SSreekanth Reddy  * Context: sleep.
950f92363d1SSreekanth Reddy  *
9514beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
952f92363d1SSreekanth Reddy  */
953f92363d1SSreekanth Reddy int
954f92363d1SSreekanth Reddy mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
955f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
956f92363d1SSreekanth Reddy {
957f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
958f92363d1SSreekanth Reddy 	int r;
959f92363d1SSreekanth Reddy 
960f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
961f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
962f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
963f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
964f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 8;
965f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
966f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
967f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
968f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
969f92363d1SSreekanth Reddy 	if (r)
970f92363d1SSreekanth Reddy 		goto out;
971f92363d1SSreekanth Reddy 
972f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
973f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
974f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
975f92363d1SSreekanth Reddy 	    sizeof(*config_page));
976f92363d1SSreekanth Reddy  out:
977f92363d1SSreekanth Reddy 	return r;
978f92363d1SSreekanth Reddy }
9792426f209SSuganath Prabu S /**
9802426f209SSuganath Prabu S  * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
9812426f209SSuganath Prabu S  * @ioc: per adapter object
9822426f209SSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
9832426f209SSuganath Prabu S  * @config_page: contents of the config page
9842426f209SSuganath Prabu S  * Context: sleep.
9852426f209SSuganath Prabu S  *
9862426f209SSuganath Prabu S  * Return: 0 for success, non-zero for failure.
9872426f209SSuganath Prabu S  */
9882426f209SSuganath Prabu S int
9892426f209SSuganath Prabu S mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
9902426f209SSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
9912426f209SSuganath Prabu S {
9922426f209SSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
9932426f209SSuganath Prabu S 	int r;
9942426f209SSuganath Prabu S 
9952426f209SSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
9962426f209SSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
9972426f209SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
9982426f209SSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
9992426f209SSuganath Prabu S 	mpi_request.Header.PageNumber = 1;
10002426f209SSuganath Prabu S 	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
10012426f209SSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
10022426f209SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
10032426f209SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
10042426f209SSuganath Prabu S 	if (r)
10052426f209SSuganath Prabu S 		goto out;
10062426f209SSuganath Prabu S 
10072426f209SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
10082426f209SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
10092426f209SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
10102426f209SSuganath Prabu S 	    sizeof(*config_page));
10112426f209SSuganath Prabu S  out:
10122426f209SSuganath Prabu S 	return r;
10132426f209SSuganath Prabu S }
10142426f209SSuganath Prabu S 
10152426f209SSuganath Prabu S /**
10162426f209SSuganath Prabu S  * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
10172426f209SSuganath Prabu S  * @ioc: per adapter object
10182426f209SSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
10192426f209SSuganath Prabu S  * @config_page: contents of the config page
10202426f209SSuganath Prabu S  * Context: sleep.
10212426f209SSuganath Prabu S  *
10222426f209SSuganath Prabu S  * Return: 0 for success, non-zero for failure.
10232426f209SSuganath Prabu S  */
10242426f209SSuganath Prabu S int
10252426f209SSuganath Prabu S mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
10262426f209SSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
10272426f209SSuganath Prabu S {
10282426f209SSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
10292426f209SSuganath Prabu S 	int r;
10302426f209SSuganath Prabu S 
10312426f209SSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
10322426f209SSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
10332426f209SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
10342426f209SSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
10352426f209SSuganath Prabu S 	mpi_request.Header.PageNumber = 1;
10362426f209SSuganath Prabu S 	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
10372426f209SSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
10382426f209SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
10392426f209SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
10402426f209SSuganath Prabu S 	if (r)
10412426f209SSuganath Prabu S 		goto out;
10422426f209SSuganath Prabu S 
10432426f209SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
10442426f209SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
10452426f209SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
10462426f209SSuganath Prabu S 	    sizeof(*config_page));
10472426f209SSuganath Prabu S  out:
10482426f209SSuganath Prabu S 	return r;
10492426f209SSuganath Prabu S }
1050f92363d1SSreekanth Reddy 
1051f92363d1SSreekanth Reddy /**
1052f92363d1SSreekanth Reddy  * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1053f92363d1SSreekanth Reddy  * @ioc: per adapter object
1054f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1055f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1056f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1057f92363d1SSreekanth Reddy  * @handle: device handle
1058f92363d1SSreekanth Reddy  * Context: sleep.
1059f92363d1SSreekanth Reddy  *
10604beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1061f92363d1SSreekanth Reddy  */
1062f92363d1SSreekanth Reddy int
1063f92363d1SSreekanth Reddy mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1064f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1065f92363d1SSreekanth Reddy 	u32 form, u32 handle)
1066f92363d1SSreekanth Reddy {
1067f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1068f92363d1SSreekanth Reddy 	int r;
1069f92363d1SSreekanth Reddy 
1070f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1071f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1072f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1073f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1074f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1075f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1076f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1077f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1078f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1079f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1080f92363d1SSreekanth Reddy 	if (r)
1081f92363d1SSreekanth Reddy 		goto out;
1082f92363d1SSreekanth Reddy 
1083f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1084f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1085f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1086f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1087f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1088f92363d1SSreekanth Reddy  out:
1089f92363d1SSreekanth Reddy 	return r;
1090f92363d1SSreekanth Reddy }
1091f92363d1SSreekanth Reddy 
1092f92363d1SSreekanth Reddy /**
1093f92363d1SSreekanth Reddy  * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1094f92363d1SSreekanth Reddy  * @ioc: per adapter object
1095f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1096f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1097f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1098f92363d1SSreekanth Reddy  * @handle: device handle
1099f92363d1SSreekanth Reddy  * Context: sleep.
1100f92363d1SSreekanth Reddy  *
11014beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1102f92363d1SSreekanth Reddy  */
1103f92363d1SSreekanth Reddy int
1104f92363d1SSreekanth Reddy mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1105f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1106f92363d1SSreekanth Reddy 	u32 form, u32 handle)
1107f92363d1SSreekanth Reddy {
1108f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1109f92363d1SSreekanth Reddy 	int r;
1110f92363d1SSreekanth Reddy 
1111f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1112f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1113f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1114f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1115f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1116f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1117f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1118f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1119f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1120f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1121f92363d1SSreekanth Reddy 	if (r)
1122f92363d1SSreekanth Reddy 		goto out;
1123f92363d1SSreekanth Reddy 
1124f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1125f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1126f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1127f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1128f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1129f92363d1SSreekanth Reddy  out:
1130f92363d1SSreekanth Reddy 	return r;
1131f92363d1SSreekanth Reddy }
1132f92363d1SSreekanth Reddy 
1133f92363d1SSreekanth Reddy /**
1134c102e00cSSuganath Prabu Subramani  * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1135c102e00cSSuganath Prabu Subramani  * @ioc: per adapter object
1136c102e00cSSuganath Prabu Subramani  * @mpi_reply: reply mf payload returned from firmware
1137c102e00cSSuganath Prabu Subramani  * @config_page: contents of the config page
1138c102e00cSSuganath Prabu Subramani  * @form: GET_NEXT_HANDLE or HANDLE
1139c102e00cSSuganath Prabu Subramani  * @handle: device handle
1140c102e00cSSuganath Prabu Subramani  * Context: sleep.
1141c102e00cSSuganath Prabu Subramani  *
11424beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1143c102e00cSSuganath Prabu Subramani  */
1144c102e00cSSuganath Prabu Subramani int
1145c102e00cSSuganath Prabu Subramani mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1146c102e00cSSuganath Prabu Subramani 	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1147c102e00cSSuganath Prabu Subramani 	u32 form, u32 handle)
1148c102e00cSSuganath Prabu Subramani {
1149c102e00cSSuganath Prabu Subramani 	Mpi2ConfigRequest_t mpi_request;
1150c102e00cSSuganath Prabu Subramani 	int r;
1151c102e00cSSuganath Prabu Subramani 
1152c102e00cSSuganath Prabu Subramani 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1153c102e00cSSuganath Prabu Subramani 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1154c102e00cSSuganath Prabu Subramani 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1155c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1156c102e00cSSuganath Prabu Subramani 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1157c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1158c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageNumber = 0;
1159c102e00cSSuganath Prabu Subramani 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1160c102e00cSSuganath Prabu Subramani 	r = _config_request(ioc, &mpi_request, mpi_reply,
1161c102e00cSSuganath Prabu Subramani 			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1162c102e00cSSuganath Prabu Subramani 	if (r)
1163c102e00cSSuganath Prabu Subramani 		goto out;
1164c102e00cSSuganath Prabu Subramani 
1165c102e00cSSuganath Prabu Subramani 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1166c102e00cSSuganath Prabu Subramani 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1167c102e00cSSuganath Prabu Subramani 	r = _config_request(ioc, &mpi_request, mpi_reply,
1168c102e00cSSuganath Prabu Subramani 			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1169c102e00cSSuganath Prabu Subramani 			sizeof(*config_page));
1170c102e00cSSuganath Prabu Subramani out:
1171c102e00cSSuganath Prabu Subramani 	return r;
1172c102e00cSSuganath Prabu Subramani }
1173c102e00cSSuganath Prabu Subramani 
1174c102e00cSSuganath Prabu Subramani /**
1175787f2448SSuganath Prabu S  * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1
1176787f2448SSuganath Prabu S  * @ioc: per adapter object
1177787f2448SSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
1178787f2448SSuganath Prabu S  * @config_page: contents of the config page
1179787f2448SSuganath Prabu S  * @sz: size of buffer passed in config_page
1180787f2448SSuganath Prabu S  * Context: sleep.
1181787f2448SSuganath Prabu S  *
1182787f2448SSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1183787f2448SSuganath Prabu S  */
1184787f2448SSuganath Prabu S int
1185787f2448SSuganath Prabu S mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1186787f2448SSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,
1187787f2448SSuganath Prabu S 	u16 sz)
1188787f2448SSuganath Prabu S {
1189787f2448SSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
1190787f2448SSuganath Prabu S 	int r;
1191787f2448SSuganath Prabu S 
1192787f2448SSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1193787f2448SSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1194787f2448SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1195787f2448SSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1196787f2448SSuganath Prabu S 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;
1197787f2448SSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;
1198787f2448SSuganath Prabu S 	mpi_request.Header.PageNumber = 1;
1199787f2448SSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1200787f2448SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1201787f2448SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1202787f2448SSuganath Prabu S 	if (r)
1203787f2448SSuganath Prabu S 		goto out;
1204787f2448SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1205787f2448SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1206787f2448SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1207787f2448SSuganath Prabu S out:
1208787f2448SSuganath Prabu S 	return r;
1209787f2448SSuganath Prabu S }
1210787f2448SSuganath Prabu S 
1211787f2448SSuganath Prabu S /**
1212c102e00cSSuganath Prabu Subramani  * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1213c102e00cSSuganath Prabu Subramani  * @ioc: per adapter object
1214c102e00cSSuganath Prabu Subramani  * @mpi_reply: reply mf payload returned from firmware
1215c102e00cSSuganath Prabu Subramani  * @config_page: contents of the config page
1216c102e00cSSuganath Prabu Subramani  * @form: GET_NEXT_HANDLE or HANDLE
1217c102e00cSSuganath Prabu Subramani  * @handle: device handle
1218c102e00cSSuganath Prabu Subramani  * Context: sleep.
1219c102e00cSSuganath Prabu Subramani  *
12204beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1221c102e00cSSuganath Prabu Subramani  */
1222c102e00cSSuganath Prabu Subramani int
1223c102e00cSSuganath Prabu Subramani mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1224c102e00cSSuganath Prabu Subramani 	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1225c102e00cSSuganath Prabu Subramani 	u32 form, u32 handle)
1226c102e00cSSuganath Prabu Subramani {
1227c102e00cSSuganath Prabu Subramani 	Mpi2ConfigRequest_t mpi_request;
1228c102e00cSSuganath Prabu Subramani 	int r;
1229c102e00cSSuganath Prabu Subramani 
1230c102e00cSSuganath Prabu Subramani 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1231c102e00cSSuganath Prabu Subramani 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1232c102e00cSSuganath Prabu Subramani 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1233c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1234c102e00cSSuganath Prabu Subramani 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1235c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1236c102e00cSSuganath Prabu Subramani 	mpi_request.Header.PageNumber = 2;
1237c102e00cSSuganath Prabu Subramani 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1238c102e00cSSuganath Prabu Subramani 	r = _config_request(ioc, &mpi_request, mpi_reply,
1239c102e00cSSuganath Prabu Subramani 			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1240c102e00cSSuganath Prabu Subramani 	if (r)
1241c102e00cSSuganath Prabu Subramani 		goto out;
1242c102e00cSSuganath Prabu Subramani 
1243c102e00cSSuganath Prabu Subramani 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1244c102e00cSSuganath Prabu Subramani 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1245c102e00cSSuganath Prabu Subramani 	r = _config_request(ioc, &mpi_request, mpi_reply,
1246c102e00cSSuganath Prabu Subramani 			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1247c102e00cSSuganath Prabu Subramani 			sizeof(*config_page));
1248c102e00cSSuganath Prabu Subramani out:
1249c102e00cSSuganath Prabu Subramani 	return r;
1250c102e00cSSuganath Prabu Subramani }
1251c102e00cSSuganath Prabu Subramani 
1252c102e00cSSuganath Prabu Subramani /**
1253f92363d1SSreekanth Reddy  * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1254f92363d1SSreekanth Reddy  * @ioc: per adapter object
1255f92363d1SSreekanth Reddy  * @num_phys: pointer returned with the number of phys
1256f92363d1SSreekanth Reddy  * Context: sleep.
1257f92363d1SSreekanth Reddy  *
12584beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1259f92363d1SSreekanth Reddy  */
1260f92363d1SSreekanth Reddy int
1261f92363d1SSreekanth Reddy mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1262f92363d1SSreekanth Reddy {
1263f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1264f92363d1SSreekanth Reddy 	int r;
1265f92363d1SSreekanth Reddy 	u16 ioc_status;
1266f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t mpi_reply;
1267f92363d1SSreekanth Reddy 	Mpi2SasIOUnitPage0_t config_page;
1268f92363d1SSreekanth Reddy 
1269f92363d1SSreekanth Reddy 	*num_phys = 0;
1270f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1271f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1272f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1273f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1274f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1275f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1276f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1277f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1278f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, &mpi_reply,
1279f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1280f92363d1SSreekanth Reddy 	if (r)
1281f92363d1SSreekanth Reddy 		goto out;
1282f92363d1SSreekanth Reddy 
1283f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1284f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, &mpi_reply,
1285f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1286f92363d1SSreekanth Reddy 	    sizeof(Mpi2SasIOUnitPage0_t));
1287f92363d1SSreekanth Reddy 	if (!r) {
1288f92363d1SSreekanth Reddy 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1289f92363d1SSreekanth Reddy 		    MPI2_IOCSTATUS_MASK;
1290f92363d1SSreekanth Reddy 		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1291f92363d1SSreekanth Reddy 			*num_phys = config_page.NumPhys;
1292f92363d1SSreekanth Reddy 	}
1293f92363d1SSreekanth Reddy  out:
1294f92363d1SSreekanth Reddy 	return r;
1295f92363d1SSreekanth Reddy }
1296f92363d1SSreekanth Reddy 
1297f92363d1SSreekanth Reddy /**
1298f92363d1SSreekanth Reddy  * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1299f92363d1SSreekanth Reddy  * @ioc: per adapter object
1300f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1301f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1302f92363d1SSreekanth Reddy  * @sz: size of buffer passed in config_page
1303f92363d1SSreekanth Reddy  * Context: sleep.
1304f92363d1SSreekanth Reddy  *
1305f92363d1SSreekanth Reddy  * Calling function should call config_get_number_hba_phys prior to
1306f92363d1SSreekanth Reddy  * this function, so enough memory is allocated for config_page.
1307f92363d1SSreekanth Reddy  *
13084beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1309f92363d1SSreekanth Reddy  */
1310f92363d1SSreekanth Reddy int
1311f92363d1SSreekanth Reddy mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1312f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1313f92363d1SSreekanth Reddy 	u16 sz)
1314f92363d1SSreekanth Reddy {
1315f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1316f92363d1SSreekanth Reddy 	int r;
1317f92363d1SSreekanth Reddy 
1318f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1319f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1320f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1321f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1322f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1323f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1324f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1325f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1326f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1327f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1328f92363d1SSreekanth Reddy 	if (r)
1329f92363d1SSreekanth Reddy 		goto out;
1330f92363d1SSreekanth Reddy 
1331f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1332f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1333f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1334f92363d1SSreekanth Reddy  out:
1335f92363d1SSreekanth Reddy 	return r;
1336f92363d1SSreekanth Reddy }
1337f92363d1SSreekanth Reddy 
1338f92363d1SSreekanth Reddy /**
1339f92363d1SSreekanth Reddy  * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1340f92363d1SSreekanth Reddy  * @ioc: per adapter object
1341f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1342f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1343f92363d1SSreekanth Reddy  * @sz: size of buffer passed in config_page
1344f92363d1SSreekanth Reddy  * Context: sleep.
1345f92363d1SSreekanth Reddy  *
1346f92363d1SSreekanth Reddy  * Calling function should call config_get_number_hba_phys prior to
1347f92363d1SSreekanth Reddy  * this function, so enough memory is allocated for config_page.
1348f92363d1SSreekanth Reddy  *
13494beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1350f92363d1SSreekanth Reddy  */
1351f92363d1SSreekanth Reddy int
1352f92363d1SSreekanth Reddy mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1353f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1354f92363d1SSreekanth Reddy 	u16 sz)
1355f92363d1SSreekanth Reddy {
1356f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1357f92363d1SSreekanth Reddy 	int r;
1358f92363d1SSreekanth Reddy 
1359f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1360f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1361f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1362f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1363f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1364f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1365f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1366f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1367f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1368f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1369f92363d1SSreekanth Reddy 	if (r)
1370f92363d1SSreekanth Reddy 		goto out;
1371f92363d1SSreekanth Reddy 
1372f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1373f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1374f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1375f92363d1SSreekanth Reddy  out:
1376f92363d1SSreekanth Reddy 	return r;
1377f92363d1SSreekanth Reddy }
1378f92363d1SSreekanth Reddy 
1379f92363d1SSreekanth Reddy /**
1380f92363d1SSreekanth Reddy  * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1381f92363d1SSreekanth Reddy  * @ioc: per adapter object
1382f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1383f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1384f92363d1SSreekanth Reddy  * @sz: size of buffer passed in config_page
1385f92363d1SSreekanth Reddy  * Context: sleep.
1386f92363d1SSreekanth Reddy  *
1387f92363d1SSreekanth Reddy  * Calling function should call config_get_number_hba_phys prior to
1388f92363d1SSreekanth Reddy  * this function, so enough memory is allocated for config_page.
1389f92363d1SSreekanth Reddy  *
13904beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1391f92363d1SSreekanth Reddy  */
1392f92363d1SSreekanth Reddy int
1393f92363d1SSreekanth Reddy mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1394f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1395f92363d1SSreekanth Reddy 	u16 sz)
1396f92363d1SSreekanth Reddy {
1397f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1398f92363d1SSreekanth Reddy 	int r;
1399f92363d1SSreekanth Reddy 
1400f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1401f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1402f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1403f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1404f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1405f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1406f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1407f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1408f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1409f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1410f92363d1SSreekanth Reddy 	if (r)
1411f92363d1SSreekanth Reddy 		goto out;
1412f92363d1SSreekanth Reddy 
1413f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1414f92363d1SSreekanth Reddy 	_config_request(ioc, &mpi_request, mpi_reply,
1415f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1416f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1417f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1418f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1419f92363d1SSreekanth Reddy  out:
1420f92363d1SSreekanth Reddy 	return r;
1421f92363d1SSreekanth Reddy }
1422f92363d1SSreekanth Reddy 
1423f92363d1SSreekanth Reddy /**
1424f92363d1SSreekanth Reddy  * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1425f92363d1SSreekanth Reddy  * @ioc: per adapter object
1426f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1427f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1428f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1429f92363d1SSreekanth Reddy  * @handle: expander handle
1430f92363d1SSreekanth Reddy  * Context: sleep.
1431f92363d1SSreekanth Reddy  *
14324beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1433f92363d1SSreekanth Reddy  */
1434f92363d1SSreekanth Reddy int
1435f92363d1SSreekanth Reddy mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1436f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1437f92363d1SSreekanth Reddy {
1438f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1439f92363d1SSreekanth Reddy 	int r;
1440f92363d1SSreekanth Reddy 
1441f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1442f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1443f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1444f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1445f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1446f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1447f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1448f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1449f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1450f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1451f92363d1SSreekanth Reddy 	if (r)
1452f92363d1SSreekanth Reddy 		goto out;
1453f92363d1SSreekanth Reddy 
1454f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1455f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1456f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1457f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1458f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1459f92363d1SSreekanth Reddy  out:
1460f92363d1SSreekanth Reddy 	return r;
1461f92363d1SSreekanth Reddy }
1462f92363d1SSreekanth Reddy 
1463f92363d1SSreekanth Reddy /**
1464f92363d1SSreekanth Reddy  * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1465f92363d1SSreekanth Reddy  * @ioc: per adapter object
1466f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1467f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1468f92363d1SSreekanth Reddy  * @phy_number: phy number
1469f92363d1SSreekanth Reddy  * @handle: expander handle
1470f92363d1SSreekanth Reddy  * Context: sleep.
1471f92363d1SSreekanth Reddy  *
14724beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1473f92363d1SSreekanth Reddy  */
1474f92363d1SSreekanth Reddy int
1475f92363d1SSreekanth Reddy mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1476f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1477f92363d1SSreekanth Reddy 	u16 handle)
1478f92363d1SSreekanth Reddy {
1479f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1480f92363d1SSreekanth Reddy 	int r;
1481f92363d1SSreekanth Reddy 
1482f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1483f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1484f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1485f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1486f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1487f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1488f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1489f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1490f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1491f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1492f92363d1SSreekanth Reddy 	if (r)
1493f92363d1SSreekanth Reddy 		goto out;
1494f92363d1SSreekanth Reddy 
1495f92363d1SSreekanth Reddy 	mpi_request.PageAddress =
1496f92363d1SSreekanth Reddy 	    cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1497f92363d1SSreekanth Reddy 	    (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1498f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1499f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1500f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1501f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1502f92363d1SSreekanth Reddy  out:
1503f92363d1SSreekanth Reddy 	return r;
1504f92363d1SSreekanth Reddy }
1505f92363d1SSreekanth Reddy 
1506f92363d1SSreekanth Reddy /**
1507f92363d1SSreekanth Reddy  * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1508f92363d1SSreekanth Reddy  * @ioc: per adapter object
1509f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1510f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1511f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1512f92363d1SSreekanth Reddy  * @handle: expander handle
1513f92363d1SSreekanth Reddy  * Context: sleep.
1514f92363d1SSreekanth Reddy  *
15154beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1516f92363d1SSreekanth Reddy  */
1517f92363d1SSreekanth Reddy int
1518f92363d1SSreekanth Reddy mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1519f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1520f92363d1SSreekanth Reddy {
1521f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1522f92363d1SSreekanth Reddy 	int r;
1523f92363d1SSreekanth Reddy 
1524f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1525f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1526f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1527f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1528f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1529f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1530f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1531f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1532f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1533f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1534f92363d1SSreekanth Reddy 	if (r)
1535f92363d1SSreekanth Reddy 		goto out;
1536f92363d1SSreekanth Reddy 
1537f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1538f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1539f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1540f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1541f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1542f92363d1SSreekanth Reddy  out:
1543f92363d1SSreekanth Reddy 	return r;
1544f92363d1SSreekanth Reddy }
1545f92363d1SSreekanth Reddy 
1546f92363d1SSreekanth Reddy /**
1547f92363d1SSreekanth Reddy  * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1548f92363d1SSreekanth Reddy  * @ioc: per adapter object
1549f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1550f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1551f92363d1SSreekanth Reddy  * @phy_number: phy number
1552f92363d1SSreekanth Reddy  * Context: sleep.
1553f92363d1SSreekanth Reddy  *
15544beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1555f92363d1SSreekanth Reddy  */
1556f92363d1SSreekanth Reddy int
1557f92363d1SSreekanth Reddy mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1558f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1559f92363d1SSreekanth Reddy {
1560f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1561f92363d1SSreekanth Reddy 	int r;
1562f92363d1SSreekanth Reddy 
1563f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1564f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1565f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1566f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1567f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1568f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1569f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1570f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1571f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1572f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1573f92363d1SSreekanth Reddy 	if (r)
1574f92363d1SSreekanth Reddy 		goto out;
1575f92363d1SSreekanth Reddy 
1576f92363d1SSreekanth Reddy 	mpi_request.PageAddress =
1577f92363d1SSreekanth Reddy 	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1578f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1579f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1580f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1581f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1582f92363d1SSreekanth Reddy  out:
1583f92363d1SSreekanth Reddy 	return r;
1584f92363d1SSreekanth Reddy }
1585f92363d1SSreekanth Reddy 
1586f92363d1SSreekanth Reddy /**
1587f92363d1SSreekanth Reddy  * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1588f92363d1SSreekanth Reddy  * @ioc: per adapter object
1589f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1590f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1591f92363d1SSreekanth Reddy  * @phy_number: phy number
1592f92363d1SSreekanth Reddy  * Context: sleep.
1593f92363d1SSreekanth Reddy  *
15944beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1595f92363d1SSreekanth Reddy  */
1596f92363d1SSreekanth Reddy int
1597f92363d1SSreekanth Reddy mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1598f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1599f92363d1SSreekanth Reddy {
1600f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1601f92363d1SSreekanth Reddy 	int r;
1602f92363d1SSreekanth Reddy 
1603f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1604f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1605f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1606f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1607f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1608f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1609f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1610f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1611f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1612f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1613f92363d1SSreekanth Reddy 	if (r)
1614f92363d1SSreekanth Reddy 		goto out;
1615f92363d1SSreekanth Reddy 
1616f92363d1SSreekanth Reddy 	mpi_request.PageAddress =
1617f92363d1SSreekanth Reddy 	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1618f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1619f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1620f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1621f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1622f92363d1SSreekanth Reddy  out:
1623f92363d1SSreekanth Reddy 	return r;
1624f92363d1SSreekanth Reddy }
1625f92363d1SSreekanth Reddy 
1626f92363d1SSreekanth Reddy /**
1627f92363d1SSreekanth Reddy  * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1628f92363d1SSreekanth Reddy  * @ioc: per adapter object
1629f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1630f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1631f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1632f92363d1SSreekanth Reddy  * @handle: volume handle
1633f92363d1SSreekanth Reddy  * Context: sleep.
1634f92363d1SSreekanth Reddy  *
16354beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1636f92363d1SSreekanth Reddy  */
1637f92363d1SSreekanth Reddy int
1638f92363d1SSreekanth Reddy mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1639f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1640f92363d1SSreekanth Reddy 	u32 handle)
1641f92363d1SSreekanth Reddy {
1642f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1643f92363d1SSreekanth Reddy 	int r;
1644f92363d1SSreekanth Reddy 
1645f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1646f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1647f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1648f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1649f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 1;
1650f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1651f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1652f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1653f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1654f92363d1SSreekanth Reddy 	if (r)
1655f92363d1SSreekanth Reddy 		goto out;
1656f92363d1SSreekanth Reddy 
1657f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1658f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1659f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1660f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1661f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1662f92363d1SSreekanth Reddy  out:
1663f92363d1SSreekanth Reddy 	return r;
1664f92363d1SSreekanth Reddy }
1665f92363d1SSreekanth Reddy 
1666f92363d1SSreekanth Reddy /**
1667f92363d1SSreekanth Reddy  * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1668f92363d1SSreekanth Reddy  * @ioc: per adapter object
1669f92363d1SSreekanth Reddy  * @handle: volume handle
1670f92363d1SSreekanth Reddy  * @num_pds: returns pds count
1671f92363d1SSreekanth Reddy  * Context: sleep.
1672f92363d1SSreekanth Reddy  *
16734beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1674f92363d1SSreekanth Reddy  */
1675f92363d1SSreekanth Reddy int
1676f92363d1SSreekanth Reddy mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1677f92363d1SSreekanth Reddy 	u8 *num_pds)
1678f92363d1SSreekanth Reddy {
1679f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1680f92363d1SSreekanth Reddy 	Mpi2RaidVolPage0_t config_page;
1681f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t mpi_reply;
1682f92363d1SSreekanth Reddy 	int r;
1683f92363d1SSreekanth Reddy 	u16 ioc_status;
1684f92363d1SSreekanth Reddy 
1685f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1686f92363d1SSreekanth Reddy 	*num_pds = 0;
1687f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1688f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1689f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1690f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1691f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1692f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1693f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, &mpi_reply,
1694f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1695f92363d1SSreekanth Reddy 	if (r)
1696f92363d1SSreekanth Reddy 		goto out;
1697f92363d1SSreekanth Reddy 
1698f92363d1SSreekanth Reddy 	mpi_request.PageAddress =
1699f92363d1SSreekanth Reddy 	    cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1700f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1701f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, &mpi_reply,
1702f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1703f92363d1SSreekanth Reddy 	    sizeof(Mpi2RaidVolPage0_t));
1704f92363d1SSreekanth Reddy 	if (!r) {
1705f92363d1SSreekanth Reddy 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1706f92363d1SSreekanth Reddy 		    MPI2_IOCSTATUS_MASK;
1707f92363d1SSreekanth Reddy 		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1708f92363d1SSreekanth Reddy 			*num_pds = config_page.NumPhysDisks;
1709f92363d1SSreekanth Reddy 	}
1710f92363d1SSreekanth Reddy 
1711f92363d1SSreekanth Reddy  out:
1712f92363d1SSreekanth Reddy 	return r;
1713f92363d1SSreekanth Reddy }
1714f92363d1SSreekanth Reddy 
1715f92363d1SSreekanth Reddy /**
1716f92363d1SSreekanth Reddy  * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1717f92363d1SSreekanth Reddy  * @ioc: per adapter object
1718f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1719f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1720f92363d1SSreekanth Reddy  * @form: GET_NEXT_HANDLE or HANDLE
1721f92363d1SSreekanth Reddy  * @handle: volume handle
1722f92363d1SSreekanth Reddy  * @sz: size of buffer passed in config_page
1723f92363d1SSreekanth Reddy  * Context: sleep.
1724f92363d1SSreekanth Reddy  *
17254beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1726f92363d1SSreekanth Reddy  */
1727f92363d1SSreekanth Reddy int
1728f92363d1SSreekanth Reddy mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1729f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1730f92363d1SSreekanth Reddy 	u32 handle, u16 sz)
1731f92363d1SSreekanth Reddy {
1732f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1733f92363d1SSreekanth Reddy 	int r;
1734f92363d1SSreekanth Reddy 
1735f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1736f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1737f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1738f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1739f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1740f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1741f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1742f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1743f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1744f92363d1SSreekanth Reddy 	if (r)
1745f92363d1SSreekanth Reddy 		goto out;
1746f92363d1SSreekanth Reddy 
1747f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | handle);
1748f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1749f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1750f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1751f92363d1SSreekanth Reddy  out:
1752f92363d1SSreekanth Reddy 	return r;
1753f92363d1SSreekanth Reddy }
1754f92363d1SSreekanth Reddy 
1755f92363d1SSreekanth Reddy /**
1756f92363d1SSreekanth Reddy  * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1757f92363d1SSreekanth Reddy  * @ioc: per adapter object
1758f92363d1SSreekanth Reddy  * @mpi_reply: reply mf payload returned from firmware
1759f92363d1SSreekanth Reddy  * @config_page: contents of the config page
1760f92363d1SSreekanth Reddy  * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1761f92363d1SSreekanth Reddy  * @form_specific: specific to the form
1762f92363d1SSreekanth Reddy  * Context: sleep.
1763f92363d1SSreekanth Reddy  *
17644beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
1765f92363d1SSreekanth Reddy  */
1766f92363d1SSreekanth Reddy int
1767f92363d1SSreekanth Reddy mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1768f92363d1SSreekanth Reddy 	*mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1769f92363d1SSreekanth Reddy 	u32 form_specific)
1770f92363d1SSreekanth Reddy {
1771f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
1772f92363d1SSreekanth Reddy 	int r;
1773f92363d1SSreekanth Reddy 
1774f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1775f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1776f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1777f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1778f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
1779f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1780f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1781f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1782f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1783f92363d1SSreekanth Reddy 	if (r)
1784f92363d1SSreekanth Reddy 		goto out;
1785f92363d1SSreekanth Reddy 
1786f92363d1SSreekanth Reddy 	mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1787f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1788f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, mpi_reply,
1789f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1790f92363d1SSreekanth Reddy 	    sizeof(*config_page));
1791f92363d1SSreekanth Reddy  out:
1792f92363d1SSreekanth Reddy 	return r;
1793f92363d1SSreekanth Reddy }
1794f92363d1SSreekanth Reddy 
1795f92363d1SSreekanth Reddy /**
1796aec93e8eSSuganath Prabu S  * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
1797aec93e8eSSuganath Prabu S  * @ioc: per adapter object
1798aec93e8eSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
1799aec93e8eSSuganath Prabu S  * @config_page: contents of the config page
1800aec93e8eSSuganath Prabu S  * Context: sleep.
1801aec93e8eSSuganath Prabu S  *
1802aec93e8eSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1803aec93e8eSSuganath Prabu S  */
1804aec93e8eSSuganath Prabu S int
1805aec93e8eSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1806aec93e8eSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1807aec93e8eSSuganath Prabu S {
1808aec93e8eSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
1809aec93e8eSSuganath Prabu S 	int r;
1810aec93e8eSSuganath Prabu S 
1811aec93e8eSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1812aec93e8eSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1813aec93e8eSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1814aec93e8eSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1815aec93e8eSSuganath Prabu S 	mpi_request.ExtPageType =
1816aec93e8eSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1817aec93e8eSSuganath Prabu S 	mpi_request.Header.PageNumber = 0;
1818aec93e8eSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1819aec93e8eSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1820aec93e8eSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1821aec93e8eSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1822aec93e8eSSuganath Prabu S 	if (r)
1823aec93e8eSSuganath Prabu S 		goto out;
1824aec93e8eSSuganath Prabu S 
1825aec93e8eSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1826aec93e8eSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1827aec93e8eSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1828aec93e8eSSuganath Prabu S 	    sizeof(*config_page));
1829aec93e8eSSuganath Prabu S  out:
1830aec93e8eSSuganath Prabu S 	return r;
1831aec93e8eSSuganath Prabu S }
1832aec93e8eSSuganath Prabu S 
1833aec93e8eSSuganath Prabu S /**
1834cf9e575eSLee Jones  * _config_set_driver_trigger_pg0 - write driver trigger page 0
1835aec93e8eSSuganath Prabu S  * @ioc: per adapter object
1836aec93e8eSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
1837aec93e8eSSuganath Prabu S  * @config_page: contents of the config page
1838aec93e8eSSuganath Prabu S  * Context: sleep.
1839aec93e8eSSuganath Prabu S  *
1840aec93e8eSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1841aec93e8eSSuganath Prabu S  */
1842aec93e8eSSuganath Prabu S static int
1843aec93e8eSSuganath Prabu S _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1844aec93e8eSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1845aec93e8eSSuganath Prabu S {
1846aec93e8eSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
1847aec93e8eSSuganath Prabu S 	int r;
1848aec93e8eSSuganath Prabu S 
1849aec93e8eSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1850aec93e8eSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1851aec93e8eSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1852aec93e8eSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1853aec93e8eSSuganath Prabu S 	mpi_request.ExtPageType =
1854aec93e8eSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1855aec93e8eSSuganath Prabu S 	mpi_request.Header.PageNumber = 0;
1856aec93e8eSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1857aec93e8eSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1858aec93e8eSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1859aec93e8eSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1860aec93e8eSSuganath Prabu S 	if (r)
1861aec93e8eSSuganath Prabu S 		goto out;
1862aec93e8eSSuganath Prabu S 
1863aec93e8eSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1864aec93e8eSSuganath Prabu S 	_config_request(ioc, &mpi_request, mpi_reply,
1865aec93e8eSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1866aec93e8eSSuganath Prabu S 	    sizeof(*config_page));
1867aec93e8eSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1868aec93e8eSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1869aec93e8eSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1870aec93e8eSSuganath Prabu S 	    sizeof(*config_page));
1871aec93e8eSSuganath Prabu S  out:
1872aec93e8eSSuganath Prabu S 	return r;
1873aec93e8eSSuganath Prabu S }
1874aec93e8eSSuganath Prabu S 
1875aec93e8eSSuganath Prabu S /**
1876aec93e8eSSuganath Prabu S  * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
1877aec93e8eSSuganath Prabu S  * @ioc: per adapter object
1878aec93e8eSSuganath Prabu S  * @trigger_flag: trigger type bit map
1879aec93e8eSSuganath Prabu S  * @set: set ot clear trigger values
1880aec93e8eSSuganath Prabu S  * Context: sleep.
1881aec93e8eSSuganath Prabu S  *
1882aec93e8eSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1883aec93e8eSSuganath Prabu S  */
1884aec93e8eSSuganath Prabu S static int
1885aec93e8eSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1886aec93e8eSSuganath Prabu S 	u16 trigger_flag, bool set)
1887aec93e8eSSuganath Prabu S {
1888aec93e8eSSuganath Prabu S 	Mpi26DriverTriggerPage0_t tg_pg0;
1889aec93e8eSSuganath Prabu S 	Mpi2ConfigReply_t mpi_reply;
1890aec93e8eSSuganath Prabu S 	int rc;
1891aec93e8eSSuganath Prabu S 	u16 flags, ioc_status;
1892aec93e8eSSuganath Prabu S 
1893aec93e8eSSuganath Prabu S 	rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1894aec93e8eSSuganath Prabu S 	if (rc)
1895aec93e8eSSuganath Prabu S 		return rc;
1896aec93e8eSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1897aec93e8eSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
1898aec93e8eSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1899aec93e8eSSuganath Prabu S 		dcprintk(ioc,
1900aec93e8eSSuganath Prabu S 		    ioc_err(ioc,
1901aec93e8eSSuganath Prabu S 		    "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
1902aec93e8eSSuganath Prabu S 		    __func__, ioc_status));
1903aec93e8eSSuganath Prabu S 		return -EFAULT;
1904aec93e8eSSuganath Prabu S 	}
1905aec93e8eSSuganath Prabu S 
1906aec93e8eSSuganath Prabu S 	if (set)
1907aec93e8eSSuganath Prabu S 		flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
1908aec93e8eSSuganath Prabu S 	else
1909aec93e8eSSuganath Prabu S 		flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
1910aec93e8eSSuganath Prabu S 
1911aec93e8eSSuganath Prabu S 	tg_pg0.TriggerFlags = cpu_to_le16(flags);
1912aec93e8eSSuganath Prabu S 
1913aec93e8eSSuganath Prabu S 	rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1914aec93e8eSSuganath Prabu S 	if (rc)
1915aec93e8eSSuganath Prabu S 		return rc;
1916aec93e8eSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1917aec93e8eSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
1918aec93e8eSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1919aec93e8eSSuganath Prabu S 		dcprintk(ioc,
1920aec93e8eSSuganath Prabu S 		    ioc_err(ioc,
1921aec93e8eSSuganath Prabu S 		    "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
1922aec93e8eSSuganath Prabu S 		    __func__, ioc_status));
1923aec93e8eSSuganath Prabu S 		return -EFAULT;
1924aec93e8eSSuganath Prabu S 	}
1925aec93e8eSSuganath Prabu S 
1926aec93e8eSSuganath Prabu S 	return 0;
1927aec93e8eSSuganath Prabu S }
1928aec93e8eSSuganath Prabu S 
1929aec93e8eSSuganath Prabu S /**
1930bb855f2aSSuganath Prabu S  * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
1931bb855f2aSSuganath Prabu S  * @ioc: per adapter object
1932bb855f2aSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
1933bb855f2aSSuganath Prabu S  * @config_page: contents of the config page
1934bb855f2aSSuganath Prabu S  * Context: sleep.
1935bb855f2aSSuganath Prabu S  *
1936bb855f2aSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1937bb855f2aSSuganath Prabu S  */
1938bb855f2aSSuganath Prabu S int
1939bb855f2aSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1940bb855f2aSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1941bb855f2aSSuganath Prabu S {
1942bb855f2aSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
1943bb855f2aSSuganath Prabu S 	int r;
1944bb855f2aSSuganath Prabu S 
1945bb855f2aSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1946bb855f2aSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1947bb855f2aSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1948bb855f2aSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1949bb855f2aSSuganath Prabu S 	mpi_request.ExtPageType =
1950bb855f2aSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1951bb855f2aSSuganath Prabu S 	mpi_request.Header.PageNumber = 1;
1952bb855f2aSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1953bb855f2aSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1954bb855f2aSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1955bb855f2aSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1956bb855f2aSSuganath Prabu S 	if (r)
1957bb855f2aSSuganath Prabu S 		goto out;
1958bb855f2aSSuganath Prabu S 
1959bb855f2aSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1960bb855f2aSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1961bb855f2aSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1962bb855f2aSSuganath Prabu S 	    sizeof(*config_page));
1963bb855f2aSSuganath Prabu S  out:
1964bb855f2aSSuganath Prabu S 	return r;
1965bb855f2aSSuganath Prabu S }
1966bb855f2aSSuganath Prabu S 
1967bb855f2aSSuganath Prabu S /**
1968cf9e575eSLee Jones  * _config_set_driver_trigger_pg1 - write driver trigger page 1
1969bb855f2aSSuganath Prabu S  * @ioc: per adapter object
1970bb855f2aSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
1971bb855f2aSSuganath Prabu S  * @config_page: contents of the config page
1972bb855f2aSSuganath Prabu S  * Context: sleep.
1973bb855f2aSSuganath Prabu S  *
1974bb855f2aSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
1975bb855f2aSSuganath Prabu S  */
1976bb855f2aSSuganath Prabu S static int
1977bb855f2aSSuganath Prabu S _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1978bb855f2aSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1979bb855f2aSSuganath Prabu S {
1980bb855f2aSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
1981bb855f2aSSuganath Prabu S 	int r;
1982bb855f2aSSuganath Prabu S 
1983bb855f2aSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1984bb855f2aSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1985bb855f2aSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1986bb855f2aSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1987bb855f2aSSuganath Prabu S 	mpi_request.ExtPageType =
1988bb855f2aSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1989bb855f2aSSuganath Prabu S 	mpi_request.Header.PageNumber = 1;
1990bb855f2aSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1991bb855f2aSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1992bb855f2aSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
1993bb855f2aSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1994bb855f2aSSuganath Prabu S 	if (r)
1995bb855f2aSSuganath Prabu S 		goto out;
1996bb855f2aSSuganath Prabu S 
1997bb855f2aSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1998bb855f2aSSuganath Prabu S 	_config_request(ioc, &mpi_request, mpi_reply,
1999bb855f2aSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2000bb855f2aSSuganath Prabu S 	    sizeof(*config_page));
2001bb855f2aSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2002bb855f2aSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
2003bb855f2aSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2004bb855f2aSSuganath Prabu S 	    sizeof(*config_page));
2005bb855f2aSSuganath Prabu S  out:
2006bb855f2aSSuganath Prabu S 	return r;
2007bb855f2aSSuganath Prabu S }
2008bb855f2aSSuganath Prabu S 
2009bb855f2aSSuganath Prabu S /**
2010bb855f2aSSuganath Prabu S  * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
2011bb855f2aSSuganath Prabu S  * @ioc: per adapter object
2012bb855f2aSSuganath Prabu S  * @master_tg: Master trigger bit map
2013bb855f2aSSuganath Prabu S  * @set: set ot clear trigger values
2014bb855f2aSSuganath Prabu S  * Context: sleep.
2015bb855f2aSSuganath Prabu S  *
2016bb855f2aSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
2017bb855f2aSSuganath Prabu S  */
2018bb855f2aSSuganath Prabu S int
2019bb855f2aSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2020bb855f2aSSuganath Prabu S 	struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
2021bb855f2aSSuganath Prabu S {
2022bb855f2aSSuganath Prabu S 	Mpi26DriverTriggerPage1_t tg_pg1;
2023bb855f2aSSuganath Prabu S 	Mpi2ConfigReply_t mpi_reply;
2024bb855f2aSSuganath Prabu S 	int rc;
2025bb855f2aSSuganath Prabu S 	u16 ioc_status;
2026bb855f2aSSuganath Prabu S 
2027bb855f2aSSuganath Prabu S 	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2028bb855f2aSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
2029bb855f2aSSuganath Prabu S 	if (rc)
2030bb855f2aSSuganath Prabu S 		return rc;
2031bb855f2aSSuganath Prabu S 
2032bb855f2aSSuganath Prabu S 	rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2033bb855f2aSSuganath Prabu S 	if (rc)
2034bb855f2aSSuganath Prabu S 		goto out;
2035bb855f2aSSuganath Prabu S 
2036bb855f2aSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2037bb855f2aSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
2038bb855f2aSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2039bb855f2aSSuganath Prabu S 		dcprintk(ioc,
2040bb855f2aSSuganath Prabu S 		    ioc_err(ioc,
2041bb855f2aSSuganath Prabu S 		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2042bb855f2aSSuganath Prabu S 		    __func__, ioc_status));
2043bb855f2aSSuganath Prabu S 		rc = -EFAULT;
2044bb855f2aSSuganath Prabu S 		goto out;
2045bb855f2aSSuganath Prabu S 	}
2046bb855f2aSSuganath Prabu S 
2047bb855f2aSSuganath Prabu S 	if (set) {
2048bb855f2aSSuganath Prabu S 		tg_pg1.NumMasterTrigger = cpu_to_le16(1);
2049bb855f2aSSuganath Prabu S 		tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
2050bb855f2aSSuganath Prabu S 		    master_tg->MasterData);
2051bb855f2aSSuganath Prabu S 	} else {
2052bb855f2aSSuganath Prabu S 		tg_pg1.NumMasterTrigger = 0;
2053bb855f2aSSuganath Prabu S 		tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
2054bb855f2aSSuganath Prabu S 	}
2055bb855f2aSSuganath Prabu S 
2056bb855f2aSSuganath Prabu S 	rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2057bb855f2aSSuganath Prabu S 	if (rc)
2058bb855f2aSSuganath Prabu S 		goto out;
2059bb855f2aSSuganath Prabu S 
2060bb855f2aSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2061bb855f2aSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
2062bb855f2aSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2063bb855f2aSSuganath Prabu S 		dcprintk(ioc,
2064bb855f2aSSuganath Prabu S 		    ioc_err(ioc,
2065bb855f2aSSuganath Prabu S 		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2066bb855f2aSSuganath Prabu S 		    __func__, ioc_status));
2067bb855f2aSSuganath Prabu S 		rc = -EFAULT;
2068bb855f2aSSuganath Prabu S 		goto out;
2069bb855f2aSSuganath Prabu S 	}
2070bb855f2aSSuganath Prabu S 
2071bb855f2aSSuganath Prabu S 	return 0;
2072bb855f2aSSuganath Prabu S 
2073bb855f2aSSuganath Prabu S out:
2074bb855f2aSSuganath Prabu S 	mpt3sas_config_update_driver_trigger_pg0(ioc,
2075bb855f2aSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
2076bb855f2aSSuganath Prabu S 
2077bb855f2aSSuganath Prabu S 	return rc;
2078bb855f2aSSuganath Prabu S }
2079bb855f2aSSuganath Prabu S 
2080bb855f2aSSuganath Prabu S /**
208171b3fb8fSSuganath Prabu S  * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
208271b3fb8fSSuganath Prabu S  * @ioc: per adapter object
208371b3fb8fSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
208471b3fb8fSSuganath Prabu S  * @config_page: contents of the config page
208571b3fb8fSSuganath Prabu S  * Context: sleep.
208671b3fb8fSSuganath Prabu S  *
208771b3fb8fSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
208871b3fb8fSSuganath Prabu S  */
208971b3fb8fSSuganath Prabu S int
209071b3fb8fSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
209171b3fb8fSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
209271b3fb8fSSuganath Prabu S {
209371b3fb8fSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
209471b3fb8fSSuganath Prabu S 	int r;
209571b3fb8fSSuganath Prabu S 
209671b3fb8fSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
209771b3fb8fSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
209871b3fb8fSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
209971b3fb8fSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
210071b3fb8fSSuganath Prabu S 	mpi_request.ExtPageType =
210171b3fb8fSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
210271b3fb8fSSuganath Prabu S 	mpi_request.Header.PageNumber = 2;
210371b3fb8fSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
210471b3fb8fSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
210571b3fb8fSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
210671b3fb8fSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
210771b3fb8fSSuganath Prabu S 	if (r)
210871b3fb8fSSuganath Prabu S 		goto out;
210971b3fb8fSSuganath Prabu S 
211071b3fb8fSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
211171b3fb8fSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
211271b3fb8fSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
211371b3fb8fSSuganath Prabu S 	    sizeof(*config_page));
211471b3fb8fSSuganath Prabu S  out:
211571b3fb8fSSuganath Prabu S 	return r;
211671b3fb8fSSuganath Prabu S }
211771b3fb8fSSuganath Prabu S 
211871b3fb8fSSuganath Prabu S /**
2119cf9e575eSLee Jones  * _config_set_driver_trigger_pg2 - write driver trigger page 2
212071b3fb8fSSuganath Prabu S  * @ioc: per adapter object
212171b3fb8fSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
212271b3fb8fSSuganath Prabu S  * @config_page: contents of the config page
212371b3fb8fSSuganath Prabu S  * Context: sleep.
212471b3fb8fSSuganath Prabu S  *
212571b3fb8fSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
212671b3fb8fSSuganath Prabu S  */
212771b3fb8fSSuganath Prabu S static int
212871b3fb8fSSuganath Prabu S _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
212971b3fb8fSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
213071b3fb8fSSuganath Prabu S {
213171b3fb8fSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
213271b3fb8fSSuganath Prabu S 	int r;
213371b3fb8fSSuganath Prabu S 
213471b3fb8fSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
213571b3fb8fSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
213671b3fb8fSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
213771b3fb8fSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
213871b3fb8fSSuganath Prabu S 	mpi_request.ExtPageType =
213971b3fb8fSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
214071b3fb8fSSuganath Prabu S 	mpi_request.Header.PageNumber = 2;
214171b3fb8fSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
214271b3fb8fSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
214371b3fb8fSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
214471b3fb8fSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
214571b3fb8fSSuganath Prabu S 	if (r)
214671b3fb8fSSuganath Prabu S 		goto out;
214771b3fb8fSSuganath Prabu S 
214871b3fb8fSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
214971b3fb8fSSuganath Prabu S 	_config_request(ioc, &mpi_request, mpi_reply,
215071b3fb8fSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
215171b3fb8fSSuganath Prabu S 	    sizeof(*config_page));
215271b3fb8fSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
215371b3fb8fSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
215471b3fb8fSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
215571b3fb8fSSuganath Prabu S 	    sizeof(*config_page));
215671b3fb8fSSuganath Prabu S  out:
215771b3fb8fSSuganath Prabu S 	return r;
215871b3fb8fSSuganath Prabu S }
215971b3fb8fSSuganath Prabu S 
216071b3fb8fSSuganath Prabu S /**
216171b3fb8fSSuganath Prabu S  * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
216271b3fb8fSSuganath Prabu S  * @ioc: per adapter object
216371b3fb8fSSuganath Prabu S  * @event_tg: list of Event Triggers
216471b3fb8fSSuganath Prabu S  * @set: set ot clear trigger values
216571b3fb8fSSuganath Prabu S  * Context: sleep.
216671b3fb8fSSuganath Prabu S  *
216771b3fb8fSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
216871b3fb8fSSuganath Prabu S  */
216971b3fb8fSSuganath Prabu S int
217071b3fb8fSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
217171b3fb8fSSuganath Prabu S 	struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
217271b3fb8fSSuganath Prabu S {
217371b3fb8fSSuganath Prabu S 	Mpi26DriverTriggerPage2_t tg_pg2;
217471b3fb8fSSuganath Prabu S 	Mpi2ConfigReply_t mpi_reply;
217571b3fb8fSSuganath Prabu S 	int rc, i, count;
217671b3fb8fSSuganath Prabu S 	u16 ioc_status;
217771b3fb8fSSuganath Prabu S 
217871b3fb8fSSuganath Prabu S 	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
217971b3fb8fSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
218071b3fb8fSSuganath Prabu S 	if (rc)
218171b3fb8fSSuganath Prabu S 		return rc;
218271b3fb8fSSuganath Prabu S 
218371b3fb8fSSuganath Prabu S 	rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
218471b3fb8fSSuganath Prabu S 	if (rc)
218571b3fb8fSSuganath Prabu S 		goto out;
218671b3fb8fSSuganath Prabu S 
218771b3fb8fSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
218871b3fb8fSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
218971b3fb8fSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
219071b3fb8fSSuganath Prabu S 		dcprintk(ioc,
219171b3fb8fSSuganath Prabu S 		    ioc_err(ioc,
219271b3fb8fSSuganath Prabu S 		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
219371b3fb8fSSuganath Prabu S 		    __func__, ioc_status));
219471b3fb8fSSuganath Prabu S 		rc = -EFAULT;
219571b3fb8fSSuganath Prabu S 		goto out;
219671b3fb8fSSuganath Prabu S 	}
219771b3fb8fSSuganath Prabu S 
219871b3fb8fSSuganath Prabu S 	if (set) {
219971b3fb8fSSuganath Prabu S 		count = event_tg->ValidEntries;
220071b3fb8fSSuganath Prabu S 		tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
220171b3fb8fSSuganath Prabu S 		for (i = 0; i < count; i++) {
220271b3fb8fSSuganath Prabu S 			tg_pg2.MPIEventTriggers[i].MPIEventCode =
220371b3fb8fSSuganath Prabu S 			    cpu_to_le16(
220471b3fb8fSSuganath Prabu S 			    event_tg->EventTriggerEntry[i].EventValue);
220571b3fb8fSSuganath Prabu S 			tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
220671b3fb8fSSuganath Prabu S 			    cpu_to_le16(
220771b3fb8fSSuganath Prabu S 			    event_tg->EventTriggerEntry[i].LogEntryQualifier);
220871b3fb8fSSuganath Prabu S 		}
220971b3fb8fSSuganath Prabu S 	} else {
221071b3fb8fSSuganath Prabu S 		tg_pg2.NumMPIEventTrigger = 0;
221171b3fb8fSSuganath Prabu S 		memset(&tg_pg2.MPIEventTriggers[0], 0,
221271b3fb8fSSuganath Prabu S 		    NUM_VALID_ENTRIES * sizeof(
221371b3fb8fSSuganath Prabu S 		    MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY));
221471b3fb8fSSuganath Prabu S 	}
221571b3fb8fSSuganath Prabu S 
221671b3fb8fSSuganath Prabu S 	rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
221771b3fb8fSSuganath Prabu S 	if (rc)
221871b3fb8fSSuganath Prabu S 		goto out;
221971b3fb8fSSuganath Prabu S 
222071b3fb8fSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
222171b3fb8fSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
222271b3fb8fSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
222371b3fb8fSSuganath Prabu S 		dcprintk(ioc,
222471b3fb8fSSuganath Prabu S 		    ioc_err(ioc,
222571b3fb8fSSuganath Prabu S 		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
222671b3fb8fSSuganath Prabu S 		    __func__, ioc_status));
222771b3fb8fSSuganath Prabu S 		rc = -EFAULT;
222871b3fb8fSSuganath Prabu S 		goto out;
222971b3fb8fSSuganath Prabu S 	}
223071b3fb8fSSuganath Prabu S 
223171b3fb8fSSuganath Prabu S 	return 0;
223271b3fb8fSSuganath Prabu S 
223371b3fb8fSSuganath Prabu S out:
223471b3fb8fSSuganath Prabu S 	mpt3sas_config_update_driver_trigger_pg0(ioc,
223571b3fb8fSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
223671b3fb8fSSuganath Prabu S 
223771b3fb8fSSuganath Prabu S 	return rc;
223871b3fb8fSSuganath Prabu S }
223971b3fb8fSSuganath Prabu S 
224071b3fb8fSSuganath Prabu S /**
22412a5c3a35SSuganath Prabu S  * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
22422a5c3a35SSuganath Prabu S  * @ioc: per adapter object
22432a5c3a35SSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
22442a5c3a35SSuganath Prabu S  * @config_page: contents of the config page
22452a5c3a35SSuganath Prabu S  * Context: sleep.
22462a5c3a35SSuganath Prabu S  *
22472a5c3a35SSuganath Prabu S  * Returns 0 for success, non-zero for failure.
22482a5c3a35SSuganath Prabu S  */
22492a5c3a35SSuganath Prabu S int
22502a5c3a35SSuganath Prabu S mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
22512a5c3a35SSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
22522a5c3a35SSuganath Prabu S {
22532a5c3a35SSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
22542a5c3a35SSuganath Prabu S 	int r;
22552a5c3a35SSuganath Prabu S 
22562a5c3a35SSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
22572a5c3a35SSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
22582a5c3a35SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
22592a5c3a35SSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
22602a5c3a35SSuganath Prabu S 	mpi_request.ExtPageType =
22612a5c3a35SSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
22622a5c3a35SSuganath Prabu S 	mpi_request.Header.PageNumber = 3;
22632a5c3a35SSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
22642a5c3a35SSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
22652a5c3a35SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
22662a5c3a35SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
22672a5c3a35SSuganath Prabu S 	if (r)
22682a5c3a35SSuganath Prabu S 		goto out;
22692a5c3a35SSuganath Prabu S 
22702a5c3a35SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
22712a5c3a35SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
22722a5c3a35SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
22732a5c3a35SSuganath Prabu S 	    sizeof(*config_page));
22742a5c3a35SSuganath Prabu S  out:
22752a5c3a35SSuganath Prabu S 	return r;
22762a5c3a35SSuganath Prabu S }
22772a5c3a35SSuganath Prabu S 
22782a5c3a35SSuganath Prabu S /**
2279cf9e575eSLee Jones  * _config_set_driver_trigger_pg3 - write driver trigger page 3
22802a5c3a35SSuganath Prabu S  * @ioc: per adapter object
22812a5c3a35SSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
22822a5c3a35SSuganath Prabu S  * @config_page: contents of the config page
22832a5c3a35SSuganath Prabu S  * Context: sleep.
22842a5c3a35SSuganath Prabu S  *
22852a5c3a35SSuganath Prabu S  * Returns 0 for success, non-zero for failure.
22862a5c3a35SSuganath Prabu S  */
22872a5c3a35SSuganath Prabu S static int
22882a5c3a35SSuganath Prabu S _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
22892a5c3a35SSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
22902a5c3a35SSuganath Prabu S {
22912a5c3a35SSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
22922a5c3a35SSuganath Prabu S 	int r;
22932a5c3a35SSuganath Prabu S 
22942a5c3a35SSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
22952a5c3a35SSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
22962a5c3a35SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
22972a5c3a35SSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
22982a5c3a35SSuganath Prabu S 	mpi_request.ExtPageType =
22992a5c3a35SSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
23002a5c3a35SSuganath Prabu S 	mpi_request.Header.PageNumber = 3;
23012a5c3a35SSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
23022a5c3a35SSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
23032a5c3a35SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
23042a5c3a35SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
23052a5c3a35SSuganath Prabu S 	if (r)
23062a5c3a35SSuganath Prabu S 		goto out;
23072a5c3a35SSuganath Prabu S 
23082a5c3a35SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
23092a5c3a35SSuganath Prabu S 	_config_request(ioc, &mpi_request, mpi_reply,
23102a5c3a35SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
23112a5c3a35SSuganath Prabu S 	    sizeof(*config_page));
23122a5c3a35SSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
23132a5c3a35SSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
23142a5c3a35SSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
23152a5c3a35SSuganath Prabu S 	    sizeof(*config_page));
23162a5c3a35SSuganath Prabu S  out:
23172a5c3a35SSuganath Prabu S 	return r;
23182a5c3a35SSuganath Prabu S }
23192a5c3a35SSuganath Prabu S 
23202a5c3a35SSuganath Prabu S /**
23212a5c3a35SSuganath Prabu S  * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
23222a5c3a35SSuganath Prabu S  * @ioc: per adapter object
23232a5c3a35SSuganath Prabu S  * @scsi_tg: scsi trigger list
23242a5c3a35SSuganath Prabu S  * @set: set ot clear trigger values
23252a5c3a35SSuganath Prabu S  * Context: sleep.
23262a5c3a35SSuganath Prabu S  *
23272a5c3a35SSuganath Prabu S  * Returns 0 for success, non-zero for failure.
23282a5c3a35SSuganath Prabu S  */
23292a5c3a35SSuganath Prabu S int
23302a5c3a35SSuganath Prabu S mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
23312a5c3a35SSuganath Prabu S 	struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
23322a5c3a35SSuganath Prabu S {
23332a5c3a35SSuganath Prabu S 	Mpi26DriverTriggerPage3_t tg_pg3;
23342a5c3a35SSuganath Prabu S 	Mpi2ConfigReply_t mpi_reply;
23352a5c3a35SSuganath Prabu S 	int rc, i, count;
23362a5c3a35SSuganath Prabu S 	u16 ioc_status;
23372a5c3a35SSuganath Prabu S 
23382a5c3a35SSuganath Prabu S 	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
23392a5c3a35SSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
23402a5c3a35SSuganath Prabu S 	if (rc)
23412a5c3a35SSuganath Prabu S 		return rc;
23422a5c3a35SSuganath Prabu S 
23432a5c3a35SSuganath Prabu S 	rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
23442a5c3a35SSuganath Prabu S 	if (rc)
23452a5c3a35SSuganath Prabu S 		goto out;
23462a5c3a35SSuganath Prabu S 
23472a5c3a35SSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
23482a5c3a35SSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
23492a5c3a35SSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
23502a5c3a35SSuganath Prabu S 		dcprintk(ioc,
23512a5c3a35SSuganath Prabu S 		    ioc_err(ioc,
23522a5c3a35SSuganath Prabu S 		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
23532a5c3a35SSuganath Prabu S 		    __func__, ioc_status));
23542a5c3a35SSuganath Prabu S 		return -EFAULT;
23552a5c3a35SSuganath Prabu S 	}
23562a5c3a35SSuganath Prabu S 
23572a5c3a35SSuganath Prabu S 	if (set) {
23582a5c3a35SSuganath Prabu S 		count = scsi_tg->ValidEntries;
23592a5c3a35SSuganath Prabu S 		tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
23602a5c3a35SSuganath Prabu S 		for (i = 0; i < count; i++) {
23612a5c3a35SSuganath Prabu S 			tg_pg3.SCSISenseTriggers[i].ASCQ =
23622a5c3a35SSuganath Prabu S 			    scsi_tg->SCSITriggerEntry[i].ASCQ;
23632a5c3a35SSuganath Prabu S 			tg_pg3.SCSISenseTriggers[i].ASC =
23642a5c3a35SSuganath Prabu S 			    scsi_tg->SCSITriggerEntry[i].ASC;
23652a5c3a35SSuganath Prabu S 			tg_pg3.SCSISenseTriggers[i].SenseKey =
23662a5c3a35SSuganath Prabu S 			    scsi_tg->SCSITriggerEntry[i].SenseKey;
23672a5c3a35SSuganath Prabu S 		}
23682a5c3a35SSuganath Prabu S 	} else {
23692a5c3a35SSuganath Prabu S 		tg_pg3.NumSCSISenseTrigger = 0;
23702a5c3a35SSuganath Prabu S 		memset(&tg_pg3.SCSISenseTriggers[0], 0,
23712a5c3a35SSuganath Prabu S 		    NUM_VALID_ENTRIES * sizeof(
23722a5c3a35SSuganath Prabu S 		    MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY));
23732a5c3a35SSuganath Prabu S 	}
23742a5c3a35SSuganath Prabu S 
23752a5c3a35SSuganath Prabu S 	rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
23762a5c3a35SSuganath Prabu S 	if (rc)
23772a5c3a35SSuganath Prabu S 		goto out;
23782a5c3a35SSuganath Prabu S 
23792a5c3a35SSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
23802a5c3a35SSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
23812a5c3a35SSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
23822a5c3a35SSuganath Prabu S 		dcprintk(ioc,
23832a5c3a35SSuganath Prabu S 		    ioc_err(ioc,
23842a5c3a35SSuganath Prabu S 		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
23852a5c3a35SSuganath Prabu S 		     __func__, ioc_status));
23862a5c3a35SSuganath Prabu S 		return -EFAULT;
23872a5c3a35SSuganath Prabu S 	}
23882a5c3a35SSuganath Prabu S 
23892a5c3a35SSuganath Prabu S 	return 0;
23902a5c3a35SSuganath Prabu S out:
23912a5c3a35SSuganath Prabu S 	mpt3sas_config_update_driver_trigger_pg0(ioc,
23922a5c3a35SSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
23932a5c3a35SSuganath Prabu S 
23942a5c3a35SSuganath Prabu S 	return rc;
23952a5c3a35SSuganath Prabu S }
23962a5c3a35SSuganath Prabu S 
23972a5c3a35SSuganath Prabu S /**
23980e17a87cSSuganath Prabu S  * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
23990e17a87cSSuganath Prabu S  * @ioc: per adapter object
24000e17a87cSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
24010e17a87cSSuganath Prabu S  * @config_page: contents of the config page
24020e17a87cSSuganath Prabu S  * Context: sleep.
24030e17a87cSSuganath Prabu S  *
24040e17a87cSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
24050e17a87cSSuganath Prabu S  */
24060e17a87cSSuganath Prabu S int
24070e17a87cSSuganath Prabu S mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
24080e17a87cSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
24090e17a87cSSuganath Prabu S {
24100e17a87cSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
24110e17a87cSSuganath Prabu S 	int r;
24120e17a87cSSuganath Prabu S 
24130e17a87cSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
24140e17a87cSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
24150e17a87cSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
24160e17a87cSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
24170e17a87cSSuganath Prabu S 	mpi_request.ExtPageType =
24180e17a87cSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
24190e17a87cSSuganath Prabu S 	mpi_request.Header.PageNumber = 4;
24200e17a87cSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
24210e17a87cSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
24220e17a87cSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
24230e17a87cSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
24240e17a87cSSuganath Prabu S 	if (r)
24250e17a87cSSuganath Prabu S 		goto out;
24260e17a87cSSuganath Prabu S 
24270e17a87cSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
24280e17a87cSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
24290e17a87cSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
24300e17a87cSSuganath Prabu S 	    sizeof(*config_page));
24310e17a87cSSuganath Prabu S  out:
24320e17a87cSSuganath Prabu S 	return r;
24330e17a87cSSuganath Prabu S }
24340e17a87cSSuganath Prabu S 
24350e17a87cSSuganath Prabu S /**
2436cf9e575eSLee Jones  * _config_set_driver_trigger_pg4 - write driver trigger page 4
24370e17a87cSSuganath Prabu S  * @ioc: per adapter object
24380e17a87cSSuganath Prabu S  * @mpi_reply: reply mf payload returned from firmware
24390e17a87cSSuganath Prabu S  * @config_page: contents of the config page
24400e17a87cSSuganath Prabu S  * Context: sleep.
24410e17a87cSSuganath Prabu S  *
24420e17a87cSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
24430e17a87cSSuganath Prabu S  */
24440e17a87cSSuganath Prabu S static int
24450e17a87cSSuganath Prabu S _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
24460e17a87cSSuganath Prabu S 	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
24470e17a87cSSuganath Prabu S {
24480e17a87cSSuganath Prabu S 	Mpi2ConfigRequest_t mpi_request;
24490e17a87cSSuganath Prabu S 	int r;
24500e17a87cSSuganath Prabu S 
24510e17a87cSSuganath Prabu S 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
24520e17a87cSSuganath Prabu S 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
24530e17a87cSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
24540e17a87cSSuganath Prabu S 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
24550e17a87cSSuganath Prabu S 	mpi_request.ExtPageType =
24560e17a87cSSuganath Prabu S 	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
24570e17a87cSSuganath Prabu S 	mpi_request.Header.PageNumber = 4;
24580e17a87cSSuganath Prabu S 	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
24590e17a87cSSuganath Prabu S 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
24600e17a87cSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
24610e17a87cSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
24620e17a87cSSuganath Prabu S 	if (r)
24630e17a87cSSuganath Prabu S 		goto out;
24640e17a87cSSuganath Prabu S 
24650e17a87cSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
24660e17a87cSSuganath Prabu S 	_config_request(ioc, &mpi_request, mpi_reply,
24670e17a87cSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
24680e17a87cSSuganath Prabu S 	    sizeof(*config_page));
24690e17a87cSSuganath Prabu S 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
24700e17a87cSSuganath Prabu S 	r = _config_request(ioc, &mpi_request, mpi_reply,
24710e17a87cSSuganath Prabu S 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
24720e17a87cSSuganath Prabu S 	    sizeof(*config_page));
24730e17a87cSSuganath Prabu S  out:
24740e17a87cSSuganath Prabu S 	return r;
24750e17a87cSSuganath Prabu S }
24760e17a87cSSuganath Prabu S 
24770e17a87cSSuganath Prabu S /**
24780e17a87cSSuganath Prabu S  * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
24790e17a87cSSuganath Prabu S  * @ioc: per adapter object
24800e17a87cSSuganath Prabu S  * @mpi_tg: mpi trigger list
24810e17a87cSSuganath Prabu S  * @set: set ot clear trigger values
24820e17a87cSSuganath Prabu S  * Context: sleep.
24830e17a87cSSuganath Prabu S  *
24840e17a87cSSuganath Prabu S  * Returns 0 for success, non-zero for failure.
24850e17a87cSSuganath Prabu S  */
24860e17a87cSSuganath Prabu S int
24870e17a87cSSuganath Prabu S mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
24880e17a87cSSuganath Prabu S 	struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
24890e17a87cSSuganath Prabu S {
24900e17a87cSSuganath Prabu S 	Mpi26DriverTriggerPage4_t tg_pg4;
24910e17a87cSSuganath Prabu S 	Mpi2ConfigReply_t mpi_reply;
24920e17a87cSSuganath Prabu S 	int rc, i, count;
24930e17a87cSSuganath Prabu S 	u16 ioc_status;
24940e17a87cSSuganath Prabu S 
24950e17a87cSSuganath Prabu S 	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
24960e17a87cSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
24970e17a87cSSuganath Prabu S 	if (rc)
24980e17a87cSSuganath Prabu S 		return rc;
24990e17a87cSSuganath Prabu S 
25000e17a87cSSuganath Prabu S 	rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
25010e17a87cSSuganath Prabu S 	if (rc)
25020e17a87cSSuganath Prabu S 		goto out;
25030e17a87cSSuganath Prabu S 
25040e17a87cSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
25050e17a87cSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
25060e17a87cSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
25070e17a87cSSuganath Prabu S 		dcprintk(ioc,
25080e17a87cSSuganath Prabu S 		    ioc_err(ioc,
25090e17a87cSSuganath Prabu S 		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
25100e17a87cSSuganath Prabu S 		    __func__, ioc_status));
25110e17a87cSSuganath Prabu S 		rc = -EFAULT;
25120e17a87cSSuganath Prabu S 		goto out;
25130e17a87cSSuganath Prabu S 	}
25140e17a87cSSuganath Prabu S 
25150e17a87cSSuganath Prabu S 	if (set) {
25160e17a87cSSuganath Prabu S 		count = mpi_tg->ValidEntries;
25170e17a87cSSuganath Prabu S 		tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
25180e17a87cSSuganath Prabu S 		for (i = 0; i < count; i++) {
25190e17a87cSSuganath Prabu S 			tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
25200e17a87cSSuganath Prabu S 			    cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
25210e17a87cSSuganath Prabu S 			tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
25220e17a87cSSuganath Prabu S 			    cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
25230e17a87cSSuganath Prabu S 		}
25240e17a87cSSuganath Prabu S 	} else {
25250e17a87cSSuganath Prabu S 		tg_pg4.NumIOCStatusLogInfoTrigger = 0;
25260e17a87cSSuganath Prabu S 		memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
25270e17a87cSSuganath Prabu S 		    NUM_VALID_ENTRIES * sizeof(
25280e17a87cSSuganath Prabu S 		    MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY));
25290e17a87cSSuganath Prabu S 	}
25300e17a87cSSuganath Prabu S 
25310e17a87cSSuganath Prabu S 	rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
25320e17a87cSSuganath Prabu S 	if (rc)
25330e17a87cSSuganath Prabu S 		goto out;
25340e17a87cSSuganath Prabu S 
25350e17a87cSSuganath Prabu S 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
25360e17a87cSSuganath Prabu S 	    MPI2_IOCSTATUS_MASK;
25370e17a87cSSuganath Prabu S 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
25380e17a87cSSuganath Prabu S 		dcprintk(ioc,
25390e17a87cSSuganath Prabu S 		    ioc_err(ioc,
25400e17a87cSSuganath Prabu S 		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
25410e17a87cSSuganath Prabu S 		    __func__, ioc_status));
25420e17a87cSSuganath Prabu S 		rc = -EFAULT;
25430e17a87cSSuganath Prabu S 		goto out;
25440e17a87cSSuganath Prabu S 	}
25450e17a87cSSuganath Prabu S 
25460e17a87cSSuganath Prabu S 	return 0;
25470e17a87cSSuganath Prabu S 
25480e17a87cSSuganath Prabu S out:
25490e17a87cSSuganath Prabu S 	mpt3sas_config_update_driver_trigger_pg0(ioc,
25500e17a87cSSuganath Prabu S 	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
25510e17a87cSSuganath Prabu S 
25520e17a87cSSuganath Prabu S 	return rc;
25530e17a87cSSuganath Prabu S }
25540e17a87cSSuganath Prabu S 
25550e17a87cSSuganath Prabu S /**
2556f92363d1SSreekanth Reddy  * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
2557f92363d1SSreekanth Reddy  * raid components
2558f92363d1SSreekanth Reddy  * @ioc: per adapter object
2559f92363d1SSreekanth Reddy  * @pd_handle: phys disk handle
2560f92363d1SSreekanth Reddy  * @volume_handle: volume handle
2561f92363d1SSreekanth Reddy  * Context: sleep.
2562f92363d1SSreekanth Reddy  *
25634beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
2564f92363d1SSreekanth Reddy  */
2565f92363d1SSreekanth Reddy int
2566f92363d1SSreekanth Reddy mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
2567f92363d1SSreekanth Reddy 	u16 *volume_handle)
2568f92363d1SSreekanth Reddy {
2569f92363d1SSreekanth Reddy 	Mpi2RaidConfigurationPage0_t *config_page = NULL;
2570f92363d1SSreekanth Reddy 	Mpi2ConfigRequest_t mpi_request;
2571f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t mpi_reply;
2572f92363d1SSreekanth Reddy 	int r, i, config_page_sz;
2573f92363d1SSreekanth Reddy 	u16 ioc_status;
2574f92363d1SSreekanth Reddy 	int config_num;
2575f92363d1SSreekanth Reddy 	u16 element_type;
2576f92363d1SSreekanth Reddy 	u16 phys_disk_dev_handle;
2577f92363d1SSreekanth Reddy 
2578f92363d1SSreekanth Reddy 	*volume_handle = 0;
2579f92363d1SSreekanth Reddy 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2580f92363d1SSreekanth Reddy 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2581f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2582f92363d1SSreekanth Reddy 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2583f92363d1SSreekanth Reddy 	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
2584f92363d1SSreekanth Reddy 	mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
2585f92363d1SSreekanth Reddy 	mpi_request.Header.PageNumber = 0;
2586f92363d1SSreekanth Reddy 	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2587f92363d1SSreekanth Reddy 	r = _config_request(ioc, &mpi_request, &mpi_reply,
2588f92363d1SSreekanth Reddy 	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2589f92363d1SSreekanth Reddy 	if (r)
2590f92363d1SSreekanth Reddy 		goto out;
2591f92363d1SSreekanth Reddy 
2592f92363d1SSreekanth Reddy 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2593f92363d1SSreekanth Reddy 	config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
2594f92363d1SSreekanth Reddy 	config_page = kmalloc(config_page_sz, GFP_KERNEL);
2595f92363d1SSreekanth Reddy 	if (!config_page) {
2596f92363d1SSreekanth Reddy 		r = -1;
2597f92363d1SSreekanth Reddy 		goto out;
2598f92363d1SSreekanth Reddy 	}
2599f92363d1SSreekanth Reddy 
2600f92363d1SSreekanth Reddy 	config_num = 0xff;
2601f92363d1SSreekanth Reddy 	while (1) {
2602f92363d1SSreekanth Reddy 		mpi_request.PageAddress = cpu_to_le32(config_num +
2603f92363d1SSreekanth Reddy 		    MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
2604f92363d1SSreekanth Reddy 		r = _config_request(ioc, &mpi_request, &mpi_reply,
2605f92363d1SSreekanth Reddy 		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2606f92363d1SSreekanth Reddy 		    config_page_sz);
2607f92363d1SSreekanth Reddy 		if (r)
2608f92363d1SSreekanth Reddy 			goto out;
2609f92363d1SSreekanth Reddy 		r = -1;
2610f92363d1SSreekanth Reddy 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2611f92363d1SSreekanth Reddy 		    MPI2_IOCSTATUS_MASK;
2612f92363d1SSreekanth Reddy 		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
2613f92363d1SSreekanth Reddy 			goto out;
2614f92363d1SSreekanth Reddy 		for (i = 0; i < config_page->NumElements; i++) {
2615f92363d1SSreekanth Reddy 			element_type = le16_to_cpu(config_page->
2616f92363d1SSreekanth Reddy 			    ConfigElement[i].ElementFlags) &
2617f92363d1SSreekanth Reddy 			    MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
2618f92363d1SSreekanth Reddy 			if (element_type ==
2619f92363d1SSreekanth Reddy 			    MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
2620f92363d1SSreekanth Reddy 			    element_type ==
2621f92363d1SSreekanth Reddy 			    MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
2622f92363d1SSreekanth Reddy 				phys_disk_dev_handle =
2623f92363d1SSreekanth Reddy 				    le16_to_cpu(config_page->ConfigElement[i].
2624f92363d1SSreekanth Reddy 				    PhysDiskDevHandle);
2625f92363d1SSreekanth Reddy 				if (phys_disk_dev_handle == pd_handle) {
2626f92363d1SSreekanth Reddy 					*volume_handle =
2627f92363d1SSreekanth Reddy 					    le16_to_cpu(config_page->
2628f92363d1SSreekanth Reddy 					    ConfigElement[i].VolDevHandle);
2629f92363d1SSreekanth Reddy 					r = 0;
2630f92363d1SSreekanth Reddy 					goto out;
2631f92363d1SSreekanth Reddy 				}
2632f92363d1SSreekanth Reddy 			} else if (element_type ==
2633f92363d1SSreekanth Reddy 			    MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
2634f92363d1SSreekanth Reddy 				*volume_handle = 0;
2635f92363d1SSreekanth Reddy 				r = 0;
2636f92363d1SSreekanth Reddy 				goto out;
2637f92363d1SSreekanth Reddy 			}
2638f92363d1SSreekanth Reddy 		}
2639f92363d1SSreekanth Reddy 		config_num = config_page->ConfigNum;
2640f92363d1SSreekanth Reddy 	}
2641f92363d1SSreekanth Reddy  out:
2642f92363d1SSreekanth Reddy 	kfree(config_page);
2643f92363d1SSreekanth Reddy 	return r;
2644f92363d1SSreekanth Reddy }
2645f92363d1SSreekanth Reddy 
2646f92363d1SSreekanth Reddy /**
2647f92363d1SSreekanth Reddy  * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
2648f92363d1SSreekanth Reddy  * @ioc: per adapter object
2649f92363d1SSreekanth Reddy  * @volume_handle: volume handle
2650f92363d1SSreekanth Reddy  * @wwid: volume wwid
2651f92363d1SSreekanth Reddy  * Context: sleep.
2652f92363d1SSreekanth Reddy  *
26534beb4867SBart Van Assche  * Return: 0 for success, non-zero for failure.
2654f92363d1SSreekanth Reddy  */
2655f92363d1SSreekanth Reddy int
2656f92363d1SSreekanth Reddy mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
2657f92363d1SSreekanth Reddy 	u64 *wwid)
2658f92363d1SSreekanth Reddy {
2659f92363d1SSreekanth Reddy 	Mpi2ConfigReply_t mpi_reply;
2660f92363d1SSreekanth Reddy 	Mpi2RaidVolPage1_t raid_vol_pg1;
2661f92363d1SSreekanth Reddy 
2662f92363d1SSreekanth Reddy 	*wwid = 0;
2663f92363d1SSreekanth Reddy 	if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
2664f92363d1SSreekanth Reddy 	    &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
2665f92363d1SSreekanth Reddy 	    volume_handle))) {
2666f92363d1SSreekanth Reddy 		*wwid = le64_to_cpu(raid_vol_pg1.WWID);
2667f92363d1SSreekanth Reddy 		return 0;
2668f92363d1SSreekanth Reddy 	} else
2669f92363d1SSreekanth Reddy 		return -1;
2670f92363d1SSreekanth Reddy }
2671