1  /*
2   * This module provides common API for accessing firmware configuration pages
3   *
4   * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
5   * Copyright (C) 2012-2014  LSI Corporation
6   * Copyright (C) 2013-2014 Avago Technologies
7   *  (mailto: MPT-FusionLinux.pdl@avagotech.com)
8   *
9   * This program is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU General Public License
11   * as published by the Free Software Foundation; either version 2
12   * of the License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   *
19   * NO WARRANTY
20   * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
21   * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
22   * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
23   * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
24   * solely responsible for determining the appropriateness of using and
25   * distributing the Program and assumes all risks associated with its
26   * exercise of rights under this Agreement, including but not limited to
27   * the risks and costs of program errors, damage to or loss of data,
28   * programs or equipment, and unavailability or interruption of operations.
29  
30   * DISCLAIMER OF LIABILITY
31   * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
32   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33   * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
34   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
35   * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36   * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
37   * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38  
39   * You should have received a copy of the GNU General Public License
40   * along with this program; if not, write to the Free Software
41   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
42   * USA.
43   */
44  
45  #include <linux/module.h>
46  #include <linux/kernel.h>
47  #include <linux/init.h>
48  #include <linux/errno.h>
49  #include <linux/blkdev.h>
50  #include <linux/sched.h>
51  #include <linux/workqueue.h>
52  #include <linux/delay.h>
53  #include <linux/pci.h>
54  
55  #include "mpt3sas_base.h"
56  
57  /* local definitions */
58  
59  /* Timeout for config page request (in seconds) */
60  #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15
61  
62  /* Common sgl flags for READING a config page. */
63  #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
64  	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
65  	| MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
66  
67  /* Common sgl flags for WRITING a config page. */
68  #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
69  	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
70  	| MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
71  	<< MPI2_SGE_FLAGS_SHIFT)
72  
73  /**
74   * struct config_request - obtain dma memory via routine
75   * @sz: size
76   * @page: virt pointer
77   * @page_dma: phys pointer
78   *
79   */
80  struct config_request {
81  	u16			sz;
82  	void			*page;
83  	dma_addr_t		page_dma;
84  };
85  
86  /**
87   * _config_display_some_debug - debug routine
88   * @ioc: per adapter object
89   * @smid: system request message index
90   * @calling_function_name: string pass from calling function
91   * @mpi_reply: reply message frame
92   * Context: none.
93   *
94   * Function for displaying debug info helpful when debugging issues
95   * in this module.
96   */
97  static void
_config_display_some_debug(struct MPT3SAS_ADAPTER * ioc,u16 smid,char * calling_function_name,MPI2DefaultReply_t * mpi_reply)98  _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
99  	char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
100  {
101  	Mpi2ConfigRequest_t *mpi_request;
102  	char *desc = NULL;
103  
104  	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
105  	switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
106  	case MPI2_CONFIG_PAGETYPE_IO_UNIT:
107  		desc = "io_unit";
108  		break;
109  	case MPI2_CONFIG_PAGETYPE_IOC:
110  		desc = "ioc";
111  		break;
112  	case MPI2_CONFIG_PAGETYPE_BIOS:
113  		desc = "bios";
114  		break;
115  	case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
116  		desc = "raid_volume";
117  		break;
118  	case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
119  		desc = "manufacturing";
120  		break;
121  	case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
122  		desc = "physdisk";
123  		break;
124  	case MPI2_CONFIG_PAGETYPE_EXTENDED:
125  		switch (mpi_request->ExtPageType) {
126  		case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
127  			desc = "sas_io_unit";
128  			break;
129  		case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
130  			desc = "sas_expander";
131  			break;
132  		case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
133  			desc = "sas_device";
134  			break;
135  		case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
136  			desc = "sas_phy";
137  			break;
138  		case MPI2_CONFIG_EXTPAGETYPE_LOG:
139  			desc = "log";
140  			break;
141  		case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
142  			desc = "enclosure";
143  			break;
144  		case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
145  			desc = "raid_config";
146  			break;
147  		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
148  			desc = "driver_mapping";
149  			break;
150  		case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
151  			desc = "sas_port";
152  			break;
153  		case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
154  			desc = "ext_manufacturing";
155  			break;
156  		case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
157  			desc = "pcie_io_unit";
158  			break;
159  		case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
160  			desc = "pcie_switch";
161  			break;
162  		case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
163  			desc = "pcie_device";
164  			break;
165  		case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
166  			desc = "pcie_link";
167  			break;
168  		}
169  		break;
170  	}
171  
172  	if (!desc)
173  		return;
174  
175  	ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",
176  		 calling_function_name, desc,
177  		 mpi_request->Header.PageNumber, mpi_request->Action,
178  		 le32_to_cpu(mpi_request->PageAddress), smid);
179  
180  	if (!mpi_reply)
181  		return;
182  
183  	if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
184  		ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
185  			 le16_to_cpu(mpi_reply->IOCStatus),
186  			 le32_to_cpu(mpi_reply->IOCLogInfo));
187  }
188  
189  /**
190   * _config_alloc_config_dma_memory - obtain physical memory
191   * @ioc: per adapter object
192   * @mem: struct config_request
193   *
194   * A wrapper for obtaining dma-able memory for config page request.
195   *
196   * Return: 0 for success, non-zero for failure.
197   */
198  static int
_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER * ioc,struct config_request * mem)199  _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
200  	struct config_request *mem)
201  {
202  	int r = 0;
203  
204  	if (mem->sz > ioc->config_page_sz) {
205  		mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
206  		    &mem->page_dma, GFP_KERNEL);
207  		if (!mem->page) {
208  			ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
209  				__func__, mem->sz);
210  			r = -ENOMEM;
211  		}
212  	} else { /* use tmp buffer if less than 512 bytes */
213  		mem->page = ioc->config_page;
214  		mem->page_dma = ioc->config_page_dma;
215  	}
216  	ioc->config_vaddr = mem->page;
217  	return r;
218  }
219  
220  /**
221   * _config_free_config_dma_memory - wrapper to free the memory
222   * @ioc: per adapter object
223   * @mem: struct config_request
224   *
225   * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
226   *
227   * Return: 0 for success, non-zero for failure.
228   */
229  static void
_config_free_config_dma_memory(struct MPT3SAS_ADAPTER * ioc,struct config_request * mem)230  _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
231  	struct config_request *mem)
232  {
233  	if (mem->sz > ioc->config_page_sz)
234  		dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
235  		    mem->page_dma);
236  }
237  
238  /**
239   * mpt3sas_config_done - config page completion routine
240   * @ioc: per adapter object
241   * @smid: system request message index
242   * @msix_index: MSIX table index supplied by the OS
243   * @reply: reply message frame(lower 32bit addr)
244   * Context: none.
245   *
246   * The callback handler when using _config_request.
247   *
248   * Return: 1 meaning mf should be freed from _base_interrupt
249   *         0 means the mf is freed from this function.
250   */
251  u8
mpt3sas_config_done(struct MPT3SAS_ADAPTER * ioc,u16 smid,u8 msix_index,u32 reply)252  mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
253  	u32 reply)
254  {
255  	MPI2DefaultReply_t *mpi_reply;
256  
257  	if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)
258  		return 1;
259  	if (ioc->config_cmds.smid != smid)
260  		return 1;
261  	ioc->config_cmds.status |= MPT3_CMD_COMPLETE;
262  	mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);
263  	if (mpi_reply) {
264  		ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;
265  		memcpy(ioc->config_cmds.reply, mpi_reply,
266  		    mpi_reply->MsgLength*4);
267  	}
268  	ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
269  	if (ioc->logging_level & MPT_DEBUG_CONFIG)
270  		_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
271  	ioc->config_cmds.smid = USHRT_MAX;
272  	complete(&ioc->config_cmds.done);
273  	return 1;
274  }
275  
276  /**
277   * _config_request - main routine for sending config page requests
278   * @ioc: per adapter object
279   * @mpi_request: request message frame
280   * @mpi_reply: reply mf payload returned from firmware
281   * @timeout: timeout in seconds
282   * @config_page: contents of the config page
283   * @config_page_sz: size of config page
284   * Context: sleep
285   *
286   * A generic API for config page requests to firmware.
287   *
288   * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
289   * this API.
290   *
291   * The callback index is set inside `ioc->config_cb_idx.
292   *
293   * Return: 0 for success, non-zero for failure.
294   */
295  static int
_config_request(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigRequest_t * mpi_request,Mpi2ConfigReply_t * mpi_reply,int timeout,void * config_page,u16 config_page_sz)296  _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
297  	*mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
298  	void *config_page, u16 config_page_sz)
299  {
300  	u16 smid;
301  	Mpi2ConfigRequest_t *config_request;
302  	int r;
303  	u8 retry_count, issue_host_reset = 0;
304  	struct config_request mem;
305  	u32 ioc_status = UINT_MAX;
306  
307  	mutex_lock(&ioc->config_cmds.mutex);
308  	if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
309  		ioc_err(ioc, "%s: config_cmd in use\n", __func__);
310  		mutex_unlock(&ioc->config_cmds.mutex);
311  		return -EAGAIN;
312  	}
313  
314  	retry_count = 0;
315  	memset(&mem, 0, sizeof(struct config_request));
316  
317  	mpi_request->VF_ID = 0; /* TODO */
318  	mpi_request->VP_ID = 0;
319  
320  	if (config_page) {
321  		mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
322  		mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
323  		mpi_request->Header.PageType = mpi_reply->Header.PageType;
324  		mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
325  		mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
326  		mpi_request->ExtPageType = mpi_reply->ExtPageType;
327  		if (mpi_request->Header.PageLength)
328  			mem.sz = mpi_request->Header.PageLength * 4;
329  		else
330  			mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
331  		r = _config_alloc_config_dma_memory(ioc, &mem);
332  		if (r != 0)
333  			goto out;
334  		if (mpi_request->Action ==
335  		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
336  		    mpi_request->Action ==
337  		    MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
338  			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
339  			    MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
340  			    mem.page_dma);
341  			memcpy(mem.page, config_page, min_t(u16, mem.sz,
342  			    config_page_sz));
343  		} else {
344  			memset(config_page, 0, config_page_sz);
345  			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
346  			    MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
347  			memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
348  		}
349  	}
350  
351   retry_config:
352  	if (retry_count) {
353  		if (retry_count > 2) { /* attempt only 2 retries */
354  			r = -EFAULT;
355  			goto free_mem;
356  		}
357  		ioc_info(ioc, "%s: attempting retry (%d)\n",
358  			 __func__, retry_count);
359  	}
360  
361  	r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
362  	if (r) {
363  		if (r == -ETIME)
364  			issue_host_reset = 1;
365  		goto free_mem;
366  	}
367  
368  	smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
369  	if (!smid) {
370  		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
371  		ioc->config_cmds.status = MPT3_CMD_NOT_USED;
372  		r = -EAGAIN;
373  		goto free_mem;
374  	}
375  
376  	r = 0;
377  	memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
378  	ioc->config_cmds.status = MPT3_CMD_PENDING;
379  	config_request = mpt3sas_base_get_msg_frame(ioc, smid);
380  	ioc->config_cmds.smid = smid;
381  	memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
382  	if (ioc->logging_level & MPT_DEBUG_CONFIG)
383  		_config_display_some_debug(ioc, smid, "config_request", NULL);
384  	init_completion(&ioc->config_cmds.done);
385  	ioc->put_smid_default(ioc, smid);
386  	wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
387  	if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
388  		if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
389  			_config_display_some_debug(ioc,
390  			    smid, "config_request", NULL);
391  		ioc_err(ioc, "%s: command timeout\n", __func__);
392  		mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
393  				mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
394  		retry_count++;
395  		if (ioc->config_cmds.smid == smid)
396  			mpt3sas_base_free_smid(ioc, smid);
397  		if (ioc->config_cmds.status & MPT3_CMD_RESET)
398  			goto retry_config;
399  		if (ioc->shost_recovery || ioc->pci_error_recovery) {
400  			issue_host_reset = 0;
401  			r = -EFAULT;
402  		} else
403  			issue_host_reset = 1;
404  		goto free_mem;
405  	}
406  
407  	if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
408  		memcpy(mpi_reply, ioc->config_cmds.reply,
409  		    sizeof(Mpi2ConfigReply_t));
410  
411  		/* Reply Frame Sanity Checks to workaround FW issues */
412  		if ((mpi_request->Header.PageType & 0xF) !=
413  		    (mpi_reply->Header.PageType & 0xF)) {
414  			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
415  				_config_display_some_debug(ioc,
416  				    smid, "config_request", NULL);
417  			_debug_dump_mf(mpi_request, ioc->request_sz/4);
418  			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
419  			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
420  			      ioc->name, __func__,
421  			      mpi_request->Header.PageType & 0xF,
422  			      mpi_reply->Header.PageType & 0xF);
423  		}
424  
425  		if (((mpi_request->Header.PageType & 0xF) ==
426  		    MPI2_CONFIG_PAGETYPE_EXTENDED) &&
427  		    mpi_request->ExtPageType != mpi_reply->ExtPageType) {
428  			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
429  				_config_display_some_debug(ioc,
430  				    smid, "config_request", NULL);
431  			_debug_dump_mf(mpi_request, ioc->request_sz/4);
432  			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
433  			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
434  			      ioc->name, __func__,
435  			      mpi_request->ExtPageType,
436  			      mpi_reply->ExtPageType);
437  		}
438  		ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
439  		    & MPI2_IOCSTATUS_MASK;
440  	}
441  
442  	if (retry_count)
443  		ioc_info(ioc, "%s: retry (%d) completed!!\n",
444  			 __func__, retry_count);
445  
446  	if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
447  	    config_page && mpi_request->Action ==
448  	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
449  		u8 *p = (u8 *)mem.page;
450  
451  		/* Config Page Sanity Checks to workaround FW issues */
452  		if (p) {
453  			if ((mpi_request->Header.PageType & 0xF) !=
454  			    (p[3] & 0xF)) {
455  				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
456  					_config_display_some_debug(ioc,
457  					    smid, "config_request", NULL);
458  				_debug_dump_mf(mpi_request, ioc->request_sz/4);
459  				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
460  				_debug_dump_config(p, min_t(u16, mem.sz,
461  				    config_page_sz)/4);
462  				panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
463  				      ioc->name, __func__,
464  				      mpi_request->Header.PageType & 0xF,
465  				      p[3] & 0xF);
466  			}
467  
468  			if (((mpi_request->Header.PageType & 0xF) ==
469  			    MPI2_CONFIG_PAGETYPE_EXTENDED) &&
470  			    (mpi_request->ExtPageType != p[6])) {
471  				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
472  					_config_display_some_debug(ioc,
473  					    smid, "config_request", NULL);
474  				_debug_dump_mf(mpi_request, ioc->request_sz/4);
475  				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);
476  				_debug_dump_config(p, min_t(u16, mem.sz,
477  				    config_page_sz)/4);
478  				panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
479  				      ioc->name, __func__,
480  				      mpi_request->ExtPageType, p[6]);
481  			}
482  		}
483  		memcpy(config_page, mem.page, min_t(u16, mem.sz,
484  		    config_page_sz));
485  	}
486  
487   free_mem:
488  	if (config_page)
489  		_config_free_config_dma_memory(ioc, &mem);
490   out:
491  	ioc->config_cmds.status = MPT3_CMD_NOT_USED;
492  	mutex_unlock(&ioc->config_cmds.mutex);
493  
494  	if (issue_host_reset) {
495  		if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {
496  			mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
497  			r = -EFAULT;
498  		} else {
499  			if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))
500  				return -EFAULT;
501  			r = -EAGAIN;
502  		}
503  	}
504  	return r;
505  }
506  
507  /**
508   * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
509   * @ioc: per adapter object
510   * @mpi_reply: reply mf payload returned from firmware
511   * @config_page: contents of the config page
512   * Context: sleep.
513   *
514   * Return: 0 for success, non-zero for failure.
515   */
516  int
mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ManufacturingPage0_t * config_page)517  mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
518  	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
519  {
520  	Mpi2ConfigRequest_t mpi_request;
521  	int r;
522  
523  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
524  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
525  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
526  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
527  	mpi_request.Header.PageNumber = 0;
528  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
529  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
530  	r = _config_request(ioc, &mpi_request, mpi_reply,
531  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
532  	if (r)
533  		goto out;
534  
535  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
536  	r = _config_request(ioc, &mpi_request, mpi_reply,
537  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
538  	    sizeof(*config_page));
539   out:
540  	return r;
541  }
542  
543  /**
544   * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1
545   * @ioc: per adapter object
546   * @mpi_reply: reply mf payload returned from firmware
547   * @config_page: contents of the config page
548   * Context: sleep.
549   *
550   * Return: 0 for success, non-zero for failure.
551   */
552  int
mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ManufacturingPage1_t * config_page)553  mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc,
554  	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page)
555  {
556  	Mpi2ConfigRequest_t mpi_request;
557  	int r;
558  
559  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
560  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
561  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
562  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
563  	mpi_request.Header.PageNumber = 1;
564  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION;
565  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
566  	r = _config_request(ioc, &mpi_request, mpi_reply,
567  		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
568  	if (r)
569  		goto out;
570  
571  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
572  	r = _config_request(ioc, &mpi_request, mpi_reply,
573  		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
574  		sizeof(*config_page));
575   out:
576  	return r;
577  }
578  
579  /**
580   * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
581   * @ioc: per adapter object
582   * @mpi_reply: reply mf payload returned from firmware
583   * @config_page: contents of the config page
584   * @sz: size of buffer passed in config_page
585   * Context: sleep.
586   *
587   * Return: 0 for success, non-zero for failure.
588   */
589  int
mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ManufacturingPage7_t * config_page,u16 sz)590  mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
591  	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
592  	u16 sz)
593  {
594  	Mpi2ConfigRequest_t mpi_request;
595  	int r;
596  
597  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
598  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
599  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
600  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
601  	mpi_request.Header.PageNumber = 7;
602  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
603  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
604  	r = _config_request(ioc, &mpi_request, mpi_reply,
605  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
606  	if (r)
607  		goto out;
608  
609  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
610  	r = _config_request(ioc, &mpi_request, mpi_reply,
611  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
612  	    sz);
613   out:
614  	return r;
615  }
616  
617  /**
618   * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
619   * @ioc: per adapter object
620   * @mpi_reply: reply mf payload returned from firmware
621   * @config_page: contents of the config page
622   * Context: sleep.
623   *
624   * Return: 0 for success, non-zero for failure.
625   */
626  int
mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage10_t * config_page)627  mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
628  	Mpi2ConfigReply_t *mpi_reply,
629  	struct Mpi2ManufacturingPage10_t *config_page)
630  {
631  	Mpi2ConfigRequest_t mpi_request;
632  	int r;
633  
634  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
635  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
636  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
637  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
638  	mpi_request.Header.PageNumber = 10;
639  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
640  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
641  	r = _config_request(ioc, &mpi_request, mpi_reply,
642  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
643  	if (r)
644  		goto out;
645  
646  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
647  	r = _config_request(ioc, &mpi_request, mpi_reply,
648  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
649  	    sizeof(*config_page));
650   out:
651  	return r;
652  }
653  
654  /**
655   * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
656   * @ioc: per adapter object
657   * @mpi_reply: reply mf payload returned from firmware
658   * @config_page: contents of the config page
659   * Context: sleep.
660   *
661   * Return: 0 for success, non-zero for failure.
662   */
663  int
mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage11_t * config_page)664  mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
665  	Mpi2ConfigReply_t *mpi_reply,
666  	struct Mpi2ManufacturingPage11_t *config_page)
667  {
668  	Mpi2ConfigRequest_t mpi_request;
669  	int r;
670  
671  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
672  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
673  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
674  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
675  	mpi_request.Header.PageNumber = 11;
676  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
677  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
678  	r = _config_request(ioc, &mpi_request, mpi_reply,
679  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
680  	if (r)
681  		goto out;
682  
683  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
684  	r = _config_request(ioc, &mpi_request, mpi_reply,
685  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
686  	    sizeof(*config_page));
687   out:
688  	return r;
689  }
690  
691  /**
692   * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
693   * @ioc: per adapter object
694   * @mpi_reply: reply mf payload returned from firmware
695   * @config_page: contents of the config page
696   * Context: sleep.
697   *
698   * Return: 0 for success, non-zero for failure.
699   */
700  int
mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,struct Mpi2ManufacturingPage11_t * config_page)701  mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
702  	Mpi2ConfigReply_t *mpi_reply,
703  	struct Mpi2ManufacturingPage11_t *config_page)
704  {
705  	Mpi2ConfigRequest_t mpi_request;
706  	int r;
707  
708  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
709  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
710  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
711  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
712  	mpi_request.Header.PageNumber = 11;
713  	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
714  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
715  	r = _config_request(ioc, &mpi_request, mpi_reply,
716  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
717  	if (r)
718  		goto out;
719  
720  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
721  	r = _config_request(ioc, &mpi_request, mpi_reply,
722  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
723  	    sizeof(*config_page));
724   out:
725  	return r;
726  }
727  
728  /**
729   * mpt3sas_config_get_bios_pg2 - obtain bios page 2
730   * @ioc: per adapter object
731   * @mpi_reply: reply mf payload returned from firmware
732   * @config_page: contents of the config page
733   * Context: sleep.
734   *
735   * Return: 0 for success, non-zero for failure.
736   */
737  int
mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage2_t * config_page)738  mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
739  	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
740  {
741  	Mpi2ConfigRequest_t mpi_request;
742  	int r;
743  
744  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
745  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
746  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
747  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
748  	mpi_request.Header.PageNumber = 2;
749  	mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
750  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
751  	r = _config_request(ioc, &mpi_request, mpi_reply,
752  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
753  	if (r)
754  		goto out;
755  
756  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
757  	r = _config_request(ioc, &mpi_request, mpi_reply,
758  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
759  	    sizeof(*config_page));
760   out:
761  	return r;
762  }
763  
764  /**
765   * mpt3sas_config_get_bios_pg3 - obtain bios page 3
766   * @ioc: per adapter object
767   * @mpi_reply: reply mf payload returned from firmware
768   * @config_page: contents of the config page
769   * Context: sleep.
770   *
771   * Return: 0 for success, non-zero for failure.
772   */
773  int
mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage3_t * config_page)774  mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
775  	*mpi_reply, Mpi2BiosPage3_t *config_page)
776  {
777  	Mpi2ConfigRequest_t mpi_request;
778  	int r;
779  
780  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
781  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
782  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
783  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
784  	mpi_request.Header.PageNumber = 3;
785  	mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
786  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
787  	r = _config_request(ioc, &mpi_request, mpi_reply,
788  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
789  	if (r)
790  		goto out;
791  
792  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
793  	r = _config_request(ioc, &mpi_request, mpi_reply,
794  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
795  	    sizeof(*config_page));
796  
797   out:
798  	return r;
799  }
800  
801  /**
802   * mpt3sas_config_set_bios_pg4 - write out bios page 4
803   * @ioc: per adapter object
804   * @mpi_reply: reply mf payload returned from firmware
805   * @config_page: contents of the config page
806   * @sz_config_pg: sizeof the config page
807   * Context: sleep.
808   *
809   * Return: 0 for success, non-zero for failure.
810   */
811  int
mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage4_t * config_page,int sz_config_pg)812  mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
813  	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
814  	int sz_config_pg)
815  {
816  	Mpi2ConfigRequest_t mpi_request;
817  	int r;
818  
819  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
820  
821  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
822  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
823  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
824  	mpi_request.Header.PageNumber = 4;
825  	mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;
826  
827  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
828  
829  	r = _config_request(ioc, &mpi_request, mpi_reply,
830  		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
831  	if (r)
832  		goto out;
833  
834  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
835  	r = _config_request(ioc, &mpi_request, mpi_reply,
836  		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
837  		sz_config_pg);
838   out:
839  	return r;
840  }
841  
842  /**
843   * mpt3sas_config_get_bios_pg4 - read bios page 4
844   * @ioc: per adapter object
845   * @mpi_reply: reply mf payload returned from firmware
846   * @config_page: contents of the config page
847   * @sz_config_pg: sizeof the config page
848   * Context: sleep.
849   *
850   * Return: 0 for success, non-zero for failure.
851   */
852  int
mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2BiosPage4_t * config_page,int sz_config_pg)853  mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
854  	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
855  	int sz_config_pg)
856  {
857  	Mpi2ConfigRequest_t mpi_request;
858  	int r;
859  
860  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
861  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
862  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
863  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
864  	mpi_request.Header.PageNumber = 4;
865  	mpi_request.Header.PageVersion =  MPI2_BIOSPAGE4_PAGEVERSION;
866  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
867  	r = _config_request(ioc, &mpi_request, mpi_reply,
868  		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
869  	if (r)
870  		goto out;
871  
872  	/*
873  	 * The sizeof the page is variable. Allow for just the
874  	 * size to be returned
875  	 */
876  	if (config_page && sz_config_pg) {
877  		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
878  
879  		r = _config_request(ioc, &mpi_request, mpi_reply,
880  			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
881  			sz_config_pg);
882  	}
883  
884  out:
885  	return r;
886  }
887  
888  /**
889   * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
890   * @ioc: per adapter object
891   * @mpi_reply: reply mf payload returned from firmware
892   * @config_page: contents of the config page
893   * Context: sleep.
894   *
895   * Return: 0 for success, non-zero for failure.
896   */
897  int
mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage0_t * config_page)898  mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
899  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
900  {
901  	Mpi2ConfigRequest_t mpi_request;
902  	int r;
903  
904  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
905  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
906  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
907  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
908  	mpi_request.Header.PageNumber = 0;
909  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
910  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
911  	r = _config_request(ioc, &mpi_request, mpi_reply,
912  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
913  	if (r)
914  		goto out;
915  
916  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
917  	r = _config_request(ioc, &mpi_request, mpi_reply,
918  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
919  	    sizeof(*config_page));
920   out:
921  	return r;
922  }
923  
924  /**
925   * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
926   * @ioc: per adapter object
927   * @mpi_reply: reply mf payload returned from firmware
928   * @config_page: contents of the config page
929   * Context: sleep.
930   *
931   * Return: 0 for success, non-zero for failure.
932   */
933  int
mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage1_t * config_page)934  mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
935  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
936  {
937  	Mpi2ConfigRequest_t mpi_request;
938  	int r;
939  
940  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
941  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
942  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
943  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
944  	mpi_request.Header.PageNumber = 1;
945  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
946  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
947  	r = _config_request(ioc, &mpi_request, mpi_reply,
948  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
949  	if (r)
950  		goto out;
951  
952  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
953  	r = _config_request(ioc, &mpi_request, mpi_reply,
954  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
955  	    sizeof(*config_page));
956   out:
957  	return r;
958  }
959  
960  /**
961   * mpt3sas_config_set_iounit_pg1 - set iounit page 1
962   * @ioc: per adapter object
963   * @mpi_reply: reply mf payload returned from firmware
964   * @config_page: contents of the config page
965   * Context: sleep.
966   *
967   * Return: 0 for success, non-zero for failure.
968   */
969  int
mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage1_t * config_page)970  mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
971  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
972  {
973  	Mpi2ConfigRequest_t mpi_request;
974  	int r;
975  
976  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
977  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
978  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
979  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
980  	mpi_request.Header.PageNumber = 1;
981  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
982  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
983  	r = _config_request(ioc, &mpi_request, mpi_reply,
984  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
985  	if (r)
986  		goto out;
987  
988  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
989  	r = _config_request(ioc, &mpi_request, mpi_reply,
990  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
991  	    sizeof(*config_page));
992   out:
993  	return r;
994  }
995  
996  /**
997   * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
998   * @ioc: per adapter object
999   * @mpi_reply: reply mf payload returned from firmware
1000   * @config_page: contents of the config page
1001   * @sz: size of buffer passed in config_page
1002   * Context: sleep.
1003   *
1004   * Return: 0 for success, non-zero for failure.
1005   */
1006  int
mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage3_t * config_page,u16 sz)1007  mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
1008  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
1009  {
1010  	Mpi2ConfigRequest_t mpi_request;
1011  	int r;
1012  
1013  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1014  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1015  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1016  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
1017  	mpi_request.Header.PageNumber = 3;
1018  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
1019  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1020  	r = _config_request(ioc, &mpi_request, mpi_reply,
1021  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1022  	if (r)
1023  		goto out;
1024  
1025  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1026  	r = _config_request(ioc, &mpi_request, mpi_reply,
1027  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1028   out:
1029  	return r;
1030  }
1031  
1032  /**
1033   * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
1034   * @ioc: per adapter object
1035   * @mpi_reply: reply mf payload returned from firmware
1036   * @config_page: contents of the config page
1037   * Context: sleep.
1038   *
1039   * Return: 0 for success, non-zero for failure.
1040   */
1041  int
mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOUnitPage8_t * config_page)1042  mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
1043  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
1044  {
1045  	Mpi2ConfigRequest_t mpi_request;
1046  	int r;
1047  
1048  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1049  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1050  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1051  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
1052  	mpi_request.Header.PageNumber = 8;
1053  	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
1054  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1055  	r = _config_request(ioc, &mpi_request, mpi_reply,
1056  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1057  	if (r)
1058  		goto out;
1059  
1060  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1061  	r = _config_request(ioc, &mpi_request, mpi_reply,
1062  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1063  	    sizeof(*config_page));
1064   out:
1065  	return r;
1066  }
1067  
1068  /**
1069   * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
1070   * @ioc: per adapter object
1071   * @mpi_reply: reply mf payload returned from firmware
1072   * @config_page: contents of the config page
1073   * Context: sleep.
1074   *
1075   * Return: 0 for success, non-zero for failure.
1076   */
1077  int
mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage8_t * config_page)1078  mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
1079  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
1080  {
1081  	Mpi2ConfigRequest_t mpi_request;
1082  	int r;
1083  
1084  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1085  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1086  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1087  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1088  	mpi_request.Header.PageNumber = 8;
1089  	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1090  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1091  	r = _config_request(ioc, &mpi_request, mpi_reply,
1092  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1093  	if (r)
1094  		goto out;
1095  
1096  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1097  	r = _config_request(ioc, &mpi_request, mpi_reply,
1098  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1099  	    sizeof(*config_page));
1100   out:
1101  	return r;
1102  }
1103  /**
1104   * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
1105   * @ioc: per adapter object
1106   * @mpi_reply: reply mf payload returned from firmware
1107   * @config_page: contents of the config page
1108   * Context: sleep.
1109   *
1110   * Return: 0 for success, non-zero for failure.
1111   */
1112  int
mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage1_t * config_page)1113  mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1114  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1115  {
1116  	Mpi2ConfigRequest_t mpi_request;
1117  	int r;
1118  
1119  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1120  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1121  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1122  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1123  	mpi_request.Header.PageNumber = 1;
1124  	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1125  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1126  	r = _config_request(ioc, &mpi_request, mpi_reply,
1127  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1128  	if (r)
1129  		goto out;
1130  
1131  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1132  	r = _config_request(ioc, &mpi_request, mpi_reply,
1133  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1134  	    sizeof(*config_page));
1135   out:
1136  	return r;
1137  }
1138  
1139  /**
1140   * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
1141   * @ioc: per adapter object
1142   * @mpi_reply: reply mf payload returned from firmware
1143   * @config_page: contents of the config page
1144   * Context: sleep.
1145   *
1146   * Return: 0 for success, non-zero for failure.
1147   */
1148  int
mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2IOCPage1_t * config_page)1149  mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1150  	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1151  {
1152  	Mpi2ConfigRequest_t mpi_request;
1153  	int r;
1154  
1155  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1156  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1157  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1158  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1159  	mpi_request.Header.PageNumber = 1;
1160  	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1161  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1162  	r = _config_request(ioc, &mpi_request, mpi_reply,
1163  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1164  	if (r)
1165  		goto out;
1166  
1167  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1168  	r = _config_request(ioc, &mpi_request, mpi_reply,
1169  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1170  	    sizeof(*config_page));
1171   out:
1172  	return r;
1173  }
1174  
1175  /**
1176   * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1177   * @ioc: per adapter object
1178   * @mpi_reply: reply mf payload returned from firmware
1179   * @config_page: contents of the config page
1180   * @form: GET_NEXT_HANDLE or HANDLE
1181   * @handle: device handle
1182   * Context: sleep.
1183   *
1184   * Return: 0 for success, non-zero for failure.
1185   */
1186  int
mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasDevicePage0_t * config_page,u32 form,u32 handle)1187  mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1188  	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1189  	u32 form, u32 handle)
1190  {
1191  	Mpi2ConfigRequest_t mpi_request;
1192  	int r;
1193  
1194  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1195  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1196  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1197  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1198  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1199  	mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1200  	mpi_request.Header.PageNumber = 0;
1201  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1202  	r = _config_request(ioc, &mpi_request, mpi_reply,
1203  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1204  	if (r)
1205  		goto out;
1206  
1207  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1208  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1209  	r = _config_request(ioc, &mpi_request, mpi_reply,
1210  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1211  	    sizeof(*config_page));
1212   out:
1213  	return r;
1214  }
1215  
1216  /**
1217   * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1218   * @ioc: per adapter object
1219   * @mpi_reply: reply mf payload returned from firmware
1220   * @config_page: contents of the config page
1221   * @form: GET_NEXT_HANDLE or HANDLE
1222   * @handle: device handle
1223   * Context: sleep.
1224   *
1225   * Return: 0 for success, non-zero for failure.
1226   */
1227  int
mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasDevicePage1_t * config_page,u32 form,u32 handle)1228  mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1229  	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1230  	u32 form, u32 handle)
1231  {
1232  	Mpi2ConfigRequest_t mpi_request;
1233  	int r;
1234  
1235  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1236  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1237  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1238  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1239  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1240  	mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1241  	mpi_request.Header.PageNumber = 1;
1242  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1243  	r = _config_request(ioc, &mpi_request, mpi_reply,
1244  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1245  	if (r)
1246  		goto out;
1247  
1248  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1249  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1250  	r = _config_request(ioc, &mpi_request, mpi_reply,
1251  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1252  	    sizeof(*config_page));
1253   out:
1254  	return r;
1255  }
1256  
1257  /**
1258   * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1259   * @ioc: per adapter object
1260   * @mpi_reply: reply mf payload returned from firmware
1261   * @config_page: contents of the config page
1262   * @form: GET_NEXT_HANDLE or HANDLE
1263   * @handle: device handle
1264   * Context: sleep.
1265   *
1266   * Return: 0 for success, non-zero for failure.
1267   */
1268  int
mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage0_t * config_page,u32 form,u32 handle)1269  mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1270  	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1271  	u32 form, u32 handle)
1272  {
1273  	Mpi2ConfigRequest_t mpi_request;
1274  	int r;
1275  
1276  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1277  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1278  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1279  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1280  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1281  	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1282  	mpi_request.Header.PageNumber = 0;
1283  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1284  	r = _config_request(ioc, &mpi_request, mpi_reply,
1285  			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1286  	if (r)
1287  		goto out;
1288  
1289  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1290  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1291  	r = _config_request(ioc, &mpi_request, mpi_reply,
1292  			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1293  			sizeof(*config_page));
1294  out:
1295  	return r;
1296  }
1297  
1298  /**
1299   * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1
1300   * @ioc: per adapter object
1301   * @mpi_reply: reply mf payload returned from firmware
1302   * @config_page: contents of the config page
1303   * @sz: size of buffer passed in config_page
1304   * Context: sleep.
1305   *
1306   * Returns 0 for success, non-zero for failure.
1307   */
1308  int
mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeIOUnitPage1_t * config_page,u16 sz)1309  mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1310  	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,
1311  	u16 sz)
1312  {
1313  	Mpi2ConfigRequest_t mpi_request;
1314  	int r;
1315  
1316  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1317  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1318  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1319  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1320  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;
1321  	mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;
1322  	mpi_request.Header.PageNumber = 1;
1323  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1324  	r = _config_request(ioc, &mpi_request, mpi_reply,
1325  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1326  	if (r)
1327  		goto out;
1328  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1329  	r = _config_request(ioc, &mpi_request, mpi_reply,
1330  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1331  out:
1332  	return r;
1333  }
1334  
1335  /**
1336   * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1337   * @ioc: per adapter object
1338   * @mpi_reply: reply mf payload returned from firmware
1339   * @config_page: contents of the config page
1340   * @form: GET_NEXT_HANDLE or HANDLE
1341   * @handle: device handle
1342   * Context: sleep.
1343   *
1344   * Return: 0 for success, non-zero for failure.
1345   */
1346  int
mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26PCIeDevicePage2_t * config_page,u32 form,u32 handle)1347  mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1348  	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1349  	u32 form, u32 handle)
1350  {
1351  	Mpi2ConfigRequest_t mpi_request;
1352  	int r;
1353  
1354  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1355  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1356  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1357  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1358  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1359  	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1360  	mpi_request.Header.PageNumber = 2;
1361  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1362  	r = _config_request(ioc, &mpi_request, mpi_reply,
1363  			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1364  	if (r)
1365  		goto out;
1366  
1367  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1368  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1369  	r = _config_request(ioc, &mpi_request, mpi_reply,
1370  			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1371  			sizeof(*config_page));
1372  out:
1373  	return r;
1374  }
1375  
1376  /**
1377   * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1378   * @ioc: per adapter object
1379   * @num_phys: pointer returned with the number of phys
1380   * Context: sleep.
1381   *
1382   * Return: 0 for success, non-zero for failure.
1383   */
1384  int
mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER * ioc,u8 * num_phys)1385  mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1386  {
1387  	Mpi2ConfigRequest_t mpi_request;
1388  	int r;
1389  	u16 ioc_status;
1390  	Mpi2ConfigReply_t mpi_reply;
1391  	Mpi2SasIOUnitPage0_t config_page;
1392  
1393  	*num_phys = 0;
1394  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1395  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1396  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1397  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1398  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1399  	mpi_request.Header.PageNumber = 0;
1400  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1401  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1402  	r = _config_request(ioc, &mpi_request, &mpi_reply,
1403  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1404  	if (r)
1405  		goto out;
1406  
1407  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1408  	r = _config_request(ioc, &mpi_request, &mpi_reply,
1409  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1410  	    sizeof(Mpi2SasIOUnitPage0_t));
1411  	if (!r) {
1412  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1413  		    MPI2_IOCSTATUS_MASK;
1414  		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1415  			*num_phys = config_page.NumPhys;
1416  	}
1417   out:
1418  	return r;
1419  }
1420  
1421  /**
1422   * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1423   * @ioc: per adapter object
1424   * @mpi_reply: reply mf payload returned from firmware
1425   * @config_page: contents of the config page
1426   * @sz: size of buffer passed in config_page
1427   * Context: sleep.
1428   *
1429   * Calling function should call config_get_number_hba_phys prior to
1430   * this function, so enough memory is allocated for config_page.
1431   *
1432   * Return: 0 for success, non-zero for failure.
1433   */
1434  int
mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage0_t * config_page,u16 sz)1435  mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1436  	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1437  	u16 sz)
1438  {
1439  	Mpi2ConfigRequest_t mpi_request;
1440  	int r;
1441  
1442  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1443  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1444  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1445  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1446  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1447  	mpi_request.Header.PageNumber = 0;
1448  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1449  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1450  	r = _config_request(ioc, &mpi_request, mpi_reply,
1451  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1452  	if (r)
1453  		goto out;
1454  
1455  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1456  	r = _config_request(ioc, &mpi_request, mpi_reply,
1457  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1458   out:
1459  	return r;
1460  }
1461  
1462  /**
1463   * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1464   * @ioc: per adapter object
1465   * @mpi_reply: reply mf payload returned from firmware
1466   * @config_page: contents of the config page
1467   * @sz: size of buffer passed in config_page
1468   * Context: sleep.
1469   *
1470   * Calling function should call config_get_number_hba_phys prior to
1471   * this function, so enough memory is allocated for config_page.
1472   *
1473   * Return: 0 for success, non-zero for failure.
1474   */
1475  int
mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage1_t * config_page,u16 sz)1476  mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1477  	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1478  	u16 sz)
1479  {
1480  	Mpi2ConfigRequest_t mpi_request;
1481  	int r;
1482  
1483  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1484  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1485  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1486  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1487  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1488  	mpi_request.Header.PageNumber = 1;
1489  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1490  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1491  	r = _config_request(ioc, &mpi_request, mpi_reply,
1492  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1493  	if (r)
1494  		goto out;
1495  
1496  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1497  	r = _config_request(ioc, &mpi_request, mpi_reply,
1498  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1499   out:
1500  	return r;
1501  }
1502  
1503  /**
1504   * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1505   * @ioc: per adapter object
1506   * @mpi_reply: reply mf payload returned from firmware
1507   * @config_page: contents of the config page
1508   * @sz: size of buffer passed in config_page
1509   * Context: sleep.
1510   *
1511   * Calling function should call config_get_number_hba_phys prior to
1512   * this function, so enough memory is allocated for config_page.
1513   *
1514   * Return: 0 for success, non-zero for failure.
1515   */
1516  int
mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasIOUnitPage1_t * config_page,u16 sz)1517  mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1518  	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1519  	u16 sz)
1520  {
1521  	Mpi2ConfigRequest_t mpi_request;
1522  	int r;
1523  
1524  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1525  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1526  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1527  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1528  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1529  	mpi_request.Header.PageNumber = 1;
1530  	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1531  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1532  	r = _config_request(ioc, &mpi_request, mpi_reply,
1533  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1534  	if (r)
1535  		goto out;
1536  
1537  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1538  	_config_request(ioc, &mpi_request, mpi_reply,
1539  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1540  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1541  	r = _config_request(ioc, &mpi_request, mpi_reply,
1542  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1543   out:
1544  	return r;
1545  }
1546  
1547  /**
1548   * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1549   * @ioc: per adapter object
1550   * @mpi_reply: reply mf payload returned from firmware
1551   * @config_page: contents of the config page
1552   * @form: GET_NEXT_HANDLE or HANDLE
1553   * @handle: expander handle
1554   * Context: sleep.
1555   *
1556   * Return: 0 for success, non-zero for failure.
1557   */
1558  int
mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ExpanderPage0_t * config_page,u32 form,u32 handle)1559  mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1560  	*mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1561  {
1562  	Mpi2ConfigRequest_t mpi_request;
1563  	int r;
1564  
1565  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1566  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1567  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1568  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1569  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1570  	mpi_request.Header.PageNumber = 0;
1571  	mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1572  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1573  	r = _config_request(ioc, &mpi_request, mpi_reply,
1574  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1575  	if (r)
1576  		goto out;
1577  
1578  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1579  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1580  	r = _config_request(ioc, &mpi_request, mpi_reply,
1581  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1582  	    sizeof(*config_page));
1583   out:
1584  	return r;
1585  }
1586  
1587  /**
1588   * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1589   * @ioc: per adapter object
1590   * @mpi_reply: reply mf payload returned from firmware
1591   * @config_page: contents of the config page
1592   * @phy_number: phy number
1593   * @handle: expander handle
1594   * Context: sleep.
1595   *
1596   * Return: 0 for success, non-zero for failure.
1597   */
1598  int
mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2ExpanderPage1_t * config_page,u32 phy_number,u16 handle)1599  mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1600  	*mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1601  	u16 handle)
1602  {
1603  	Mpi2ConfigRequest_t mpi_request;
1604  	int r;
1605  
1606  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1607  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1608  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1609  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1610  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1611  	mpi_request.Header.PageNumber = 1;
1612  	mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1613  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1614  	r = _config_request(ioc, &mpi_request, mpi_reply,
1615  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1616  	if (r)
1617  		goto out;
1618  
1619  	mpi_request.PageAddress =
1620  	    cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1621  	    (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1622  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1623  	r = _config_request(ioc, &mpi_request, mpi_reply,
1624  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1625  	    sizeof(*config_page));
1626   out:
1627  	return r;
1628  }
1629  
1630  /**
1631   * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1632   * @ioc: per adapter object
1633   * @mpi_reply: reply mf payload returned from firmware
1634   * @config_page: contents of the config page
1635   * @form: GET_NEXT_HANDLE or HANDLE
1636   * @handle: expander handle
1637   * Context: sleep.
1638   *
1639   * Return: 0 for success, non-zero for failure.
1640   */
1641  int
mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasEnclosurePage0_t * config_page,u32 form,u32 handle)1642  mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1643  	*mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1644  {
1645  	Mpi2ConfigRequest_t mpi_request;
1646  	int r;
1647  
1648  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1649  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1650  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1651  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1652  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1653  	mpi_request.Header.PageNumber = 0;
1654  	mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1655  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1656  	r = _config_request(ioc, &mpi_request, mpi_reply,
1657  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1658  	if (r)
1659  		goto out;
1660  
1661  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1662  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1663  	r = _config_request(ioc, &mpi_request, mpi_reply,
1664  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1665  	    sizeof(*config_page));
1666   out:
1667  	return r;
1668  }
1669  
1670  /**
1671   * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1672   * @ioc: per adapter object
1673   * @mpi_reply: reply mf payload returned from firmware
1674   * @config_page: contents of the config page
1675   * @phy_number: phy number
1676   * Context: sleep.
1677   *
1678   * Return: 0 for success, non-zero for failure.
1679   */
1680  int
mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasPhyPage0_t * config_page,u32 phy_number)1681  mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1682  	*mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1683  {
1684  	Mpi2ConfigRequest_t mpi_request;
1685  	int r;
1686  
1687  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1688  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1689  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1690  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1691  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1692  	mpi_request.Header.PageNumber = 0;
1693  	mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1694  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1695  	r = _config_request(ioc, &mpi_request, mpi_reply,
1696  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1697  	if (r)
1698  		goto out;
1699  
1700  	mpi_request.PageAddress =
1701  	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1702  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1703  	r = _config_request(ioc, &mpi_request, mpi_reply,
1704  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1705  	    sizeof(*config_page));
1706   out:
1707  	return r;
1708  }
1709  
1710  /**
1711   * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1712   * @ioc: per adapter object
1713   * @mpi_reply: reply mf payload returned from firmware
1714   * @config_page: contents of the config page
1715   * @phy_number: phy number
1716   * Context: sleep.
1717   *
1718   * Return: 0 for success, non-zero for failure.
1719   */
1720  int
mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2SasPhyPage1_t * config_page,u32 phy_number)1721  mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1722  	*mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1723  {
1724  	Mpi2ConfigRequest_t mpi_request;
1725  	int r;
1726  
1727  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1728  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1729  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1730  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1731  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1732  	mpi_request.Header.PageNumber = 1;
1733  	mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1734  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1735  	r = _config_request(ioc, &mpi_request, mpi_reply,
1736  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1737  	if (r)
1738  		goto out;
1739  
1740  	mpi_request.PageAddress =
1741  	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1742  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1743  	r = _config_request(ioc, &mpi_request, mpi_reply,
1744  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1745  	    sizeof(*config_page));
1746   out:
1747  	return r;
1748  }
1749  
1750  /**
1751   * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1752   * @ioc: per adapter object
1753   * @mpi_reply: reply mf payload returned from firmware
1754   * @config_page: contents of the config page
1755   * @form: GET_NEXT_HANDLE or HANDLE
1756   * @handle: volume handle
1757   * Context: sleep.
1758   *
1759   * Return: 0 for success, non-zero for failure.
1760   */
1761  int
mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage1_t * config_page,u32 form,u32 handle)1762  mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1763  	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1764  	u32 handle)
1765  {
1766  	Mpi2ConfigRequest_t mpi_request;
1767  	int r;
1768  
1769  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1770  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1771  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1772  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1773  	mpi_request.Header.PageNumber = 1;
1774  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1775  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1776  	r = _config_request(ioc, &mpi_request, mpi_reply,
1777  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1778  	if (r)
1779  		goto out;
1780  
1781  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1782  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1783  	r = _config_request(ioc, &mpi_request, mpi_reply,
1784  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1785  	    sizeof(*config_page));
1786   out:
1787  	return r;
1788  }
1789  
1790  /**
1791   * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1792   * @ioc: per adapter object
1793   * @handle: volume handle
1794   * @num_pds: returns pds count
1795   * Context: sleep.
1796   *
1797   * Return: 0 for success, non-zero for failure.
1798   */
1799  int
mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER * ioc,u16 handle,u8 * num_pds)1800  mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1801  	u8 *num_pds)
1802  {
1803  	Mpi2ConfigRequest_t mpi_request;
1804  	Mpi2RaidVolPage0_t config_page;
1805  	Mpi2ConfigReply_t mpi_reply;
1806  	int r;
1807  	u16 ioc_status;
1808  
1809  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1810  	*num_pds = 0;
1811  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1812  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1813  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1814  	mpi_request.Header.PageNumber = 0;
1815  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1816  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1817  	r = _config_request(ioc, &mpi_request, &mpi_reply,
1818  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1819  	if (r)
1820  		goto out;
1821  
1822  	mpi_request.PageAddress =
1823  	    cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1824  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1825  	r = _config_request(ioc, &mpi_request, &mpi_reply,
1826  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1827  	    sizeof(Mpi2RaidVolPage0_t));
1828  	if (!r) {
1829  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1830  		    MPI2_IOCSTATUS_MASK;
1831  		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1832  			*num_pds = config_page.NumPhysDisks;
1833  	}
1834  
1835   out:
1836  	return r;
1837  }
1838  
1839  /**
1840   * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1841   * @ioc: per adapter object
1842   * @mpi_reply: reply mf payload returned from firmware
1843   * @config_page: contents of the config page
1844   * @form: GET_NEXT_HANDLE or HANDLE
1845   * @handle: volume handle
1846   * @sz: size of buffer passed in config_page
1847   * Context: sleep.
1848   *
1849   * Return: 0 for success, non-zero for failure.
1850   */
1851  int
mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidVolPage0_t * config_page,u32 form,u32 handle,u16 sz)1852  mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1853  	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1854  	u32 handle, u16 sz)
1855  {
1856  	Mpi2ConfigRequest_t mpi_request;
1857  	int r;
1858  
1859  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1860  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1861  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1862  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1863  	mpi_request.Header.PageNumber = 0;
1864  	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1865  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1866  	r = _config_request(ioc, &mpi_request, mpi_reply,
1867  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1868  	if (r)
1869  		goto out;
1870  
1871  	mpi_request.PageAddress = cpu_to_le32(form | handle);
1872  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1873  	r = _config_request(ioc, &mpi_request, mpi_reply,
1874  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1875   out:
1876  	return r;
1877  }
1878  
1879  /**
1880   * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1881   * @ioc: per adapter object
1882   * @mpi_reply: reply mf payload returned from firmware
1883   * @config_page: contents of the config page
1884   * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1885   * @form_specific: specific to the form
1886   * Context: sleep.
1887   *
1888   * Return: 0 for success, non-zero for failure.
1889   */
1890  int
mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi2RaidPhysDiskPage0_t * config_page,u32 form,u32 form_specific)1891  mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1892  	*mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1893  	u32 form_specific)
1894  {
1895  	Mpi2ConfigRequest_t mpi_request;
1896  	int r;
1897  
1898  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1899  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1900  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1901  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1902  	mpi_request.Header.PageNumber = 0;
1903  	mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1904  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1905  	r = _config_request(ioc, &mpi_request, mpi_reply,
1906  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1907  	if (r)
1908  		goto out;
1909  
1910  	mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1911  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1912  	r = _config_request(ioc, &mpi_request, mpi_reply,
1913  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1914  	    sizeof(*config_page));
1915   out:
1916  	return r;
1917  }
1918  
1919  /**
1920   * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
1921   * @ioc: per adapter object
1922   * @mpi_reply: reply mf payload returned from firmware
1923   * @config_page: contents of the config page
1924   * Context: sleep.
1925   *
1926   * Returns 0 for success, non-zero for failure.
1927   */
1928  int
mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage0_t * config_page)1929  mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1930  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1931  {
1932  	Mpi2ConfigRequest_t mpi_request;
1933  	int r;
1934  
1935  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1936  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1937  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1938  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1939  	mpi_request.ExtPageType =
1940  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1941  	mpi_request.Header.PageNumber = 0;
1942  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1943  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1944  	r = _config_request(ioc, &mpi_request, mpi_reply,
1945  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1946  	if (r)
1947  		goto out;
1948  
1949  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1950  	r = _config_request(ioc, &mpi_request, mpi_reply,
1951  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1952  	    sizeof(*config_page));
1953   out:
1954  	return r;
1955  }
1956  
1957  /**
1958   * _config_set_driver_trigger_pg0 - write driver trigger page 0
1959   * @ioc: per adapter object
1960   * @mpi_reply: reply mf payload returned from firmware
1961   * @config_page: contents of the config page
1962   * Context: sleep.
1963   *
1964   * Returns 0 for success, non-zero for failure.
1965   */
1966  static int
_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage0_t * config_page)1967  _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1968  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1969  {
1970  	Mpi2ConfigRequest_t mpi_request;
1971  	int r;
1972  
1973  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1974  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
1975  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1976  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1977  	mpi_request.ExtPageType =
1978  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1979  	mpi_request.Header.PageNumber = 0;
1980  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1981  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1982  	r = _config_request(ioc, &mpi_request, mpi_reply,
1983  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1984  	if (r)
1985  		goto out;
1986  
1987  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1988  	_config_request(ioc, &mpi_request, mpi_reply,
1989  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1990  	    sizeof(*config_page));
1991  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1992  	r = _config_request(ioc, &mpi_request, mpi_reply,
1993  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1994  	    sizeof(*config_page));
1995   out:
1996  	return r;
1997  }
1998  
1999  /**
2000   * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
2001   * @ioc: per adapter object
2002   * @trigger_flag: trigger type bit map
2003   * @set: set ot clear trigger values
2004   * Context: sleep.
2005   *
2006   * Returns 0 for success, non-zero for failure.
2007   */
2008  static int
mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER * ioc,u16 trigger_flag,bool set)2009  mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
2010  	u16 trigger_flag, bool set)
2011  {
2012  	Mpi26DriverTriggerPage0_t tg_pg0;
2013  	Mpi2ConfigReply_t mpi_reply;
2014  	int rc;
2015  	u16 flags, ioc_status;
2016  
2017  	rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
2018  	if (rc)
2019  		return rc;
2020  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2021  	    MPI2_IOCSTATUS_MASK;
2022  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2023  		dcprintk(ioc,
2024  		    ioc_err(ioc,
2025  		    "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
2026  		    __func__, ioc_status));
2027  		return -EFAULT;
2028  	}
2029  
2030  	if (set)
2031  		flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
2032  	else
2033  		flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
2034  
2035  	tg_pg0.TriggerFlags = cpu_to_le16(flags);
2036  
2037  	rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
2038  	if (rc)
2039  		return rc;
2040  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2041  	    MPI2_IOCSTATUS_MASK;
2042  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2043  		dcprintk(ioc,
2044  		    ioc_err(ioc,
2045  		    "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
2046  		    __func__, ioc_status));
2047  		return -EFAULT;
2048  	}
2049  
2050  	return 0;
2051  }
2052  
2053  /**
2054   * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
2055   * @ioc: per adapter object
2056   * @mpi_reply: reply mf payload returned from firmware
2057   * @config_page: contents of the config page
2058   * Context: sleep.
2059   *
2060   * Returns 0 for success, non-zero for failure.
2061   */
2062  int
mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage1_t * config_page)2063  mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2064  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
2065  {
2066  	Mpi2ConfigRequest_t mpi_request;
2067  	int r;
2068  
2069  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2070  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2071  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2072  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2073  	mpi_request.ExtPageType =
2074  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2075  	mpi_request.Header.PageNumber = 1;
2076  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
2077  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2078  	r = _config_request(ioc, &mpi_request, mpi_reply,
2079  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2080  	if (r)
2081  		goto out;
2082  
2083  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2084  	r = _config_request(ioc, &mpi_request, mpi_reply,
2085  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2086  	    sizeof(*config_page));
2087   out:
2088  	return r;
2089  }
2090  
2091  /**
2092   * _config_set_driver_trigger_pg1 - write driver trigger page 1
2093   * @ioc: per adapter object
2094   * @mpi_reply: reply mf payload returned from firmware
2095   * @config_page: contents of the config page
2096   * Context: sleep.
2097   *
2098   * Returns 0 for success, non-zero for failure.
2099   */
2100  static int
_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage1_t * config_page)2101  _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2102  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
2103  {
2104  	Mpi2ConfigRequest_t mpi_request;
2105  	int r;
2106  
2107  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2108  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2109  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2110  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2111  	mpi_request.ExtPageType =
2112  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2113  	mpi_request.Header.PageNumber = 1;
2114  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
2115  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2116  	r = _config_request(ioc, &mpi_request, mpi_reply,
2117  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2118  	if (r)
2119  		goto out;
2120  
2121  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2122  	_config_request(ioc, &mpi_request, mpi_reply,
2123  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2124  	    sizeof(*config_page));
2125  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2126  	r = _config_request(ioc, &mpi_request, mpi_reply,
2127  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2128  	    sizeof(*config_page));
2129   out:
2130  	return r;
2131  }
2132  
2133  /**
2134   * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
2135   * @ioc: per adapter object
2136   * @master_tg: Master trigger bit map
2137   * @set: set ot clear trigger values
2138   * Context: sleep.
2139   *
2140   * Returns 0 for success, non-zero for failure.
2141   */
2142  int
mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_MASTER_TRIGGER_T * master_tg,bool set)2143  mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
2144  	struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
2145  {
2146  	Mpi26DriverTriggerPage1_t tg_pg1;
2147  	Mpi2ConfigReply_t mpi_reply;
2148  	int rc;
2149  	u16 ioc_status;
2150  
2151  	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2152  	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
2153  	if (rc)
2154  		return rc;
2155  
2156  	rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2157  	if (rc)
2158  		goto out;
2159  
2160  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2161  	    MPI2_IOCSTATUS_MASK;
2162  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2163  		dcprintk(ioc,
2164  		    ioc_err(ioc,
2165  		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2166  		    __func__, ioc_status));
2167  		rc = -EFAULT;
2168  		goto out;
2169  	}
2170  
2171  	if (set) {
2172  		tg_pg1.NumMasterTrigger = cpu_to_le16(1);
2173  		tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
2174  		    master_tg->MasterData);
2175  	} else {
2176  		tg_pg1.NumMasterTrigger = 0;
2177  		tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
2178  	}
2179  
2180  	rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2181  	if (rc)
2182  		goto out;
2183  
2184  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2185  	    MPI2_IOCSTATUS_MASK;
2186  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2187  		dcprintk(ioc,
2188  		    ioc_err(ioc,
2189  		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2190  		    __func__, ioc_status));
2191  		rc = -EFAULT;
2192  		goto out;
2193  	}
2194  
2195  	return 0;
2196  
2197  out:
2198  	mpt3sas_config_update_driver_trigger_pg0(ioc,
2199  	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
2200  
2201  	return rc;
2202  }
2203  
2204  /**
2205   * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
2206   * @ioc: per adapter object
2207   * @mpi_reply: reply mf payload returned from firmware
2208   * @config_page: contents of the config page
2209   * Context: sleep.
2210   *
2211   * Returns 0 for success, non-zero for failure.
2212   */
2213  int
mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage2_t * config_page)2214  mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2215  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2216  {
2217  	Mpi2ConfigRequest_t mpi_request;
2218  	int r;
2219  
2220  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2221  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2222  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2223  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2224  	mpi_request.ExtPageType =
2225  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2226  	mpi_request.Header.PageNumber = 2;
2227  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2228  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2229  	r = _config_request(ioc, &mpi_request, mpi_reply,
2230  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2231  	if (r)
2232  		goto out;
2233  
2234  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2235  	r = _config_request(ioc, &mpi_request, mpi_reply,
2236  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2237  	    sizeof(*config_page));
2238   out:
2239  	return r;
2240  }
2241  
2242  /**
2243   * _config_set_driver_trigger_pg2 - write driver trigger page 2
2244   * @ioc: per adapter object
2245   * @mpi_reply: reply mf payload returned from firmware
2246   * @config_page: contents of the config page
2247   * Context: sleep.
2248   *
2249   * Returns 0 for success, non-zero for failure.
2250   */
2251  static int
_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage2_t * config_page)2252  _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2253  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2254  {
2255  	Mpi2ConfigRequest_t mpi_request;
2256  	int r;
2257  
2258  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2259  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2260  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2261  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2262  	mpi_request.ExtPageType =
2263  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2264  	mpi_request.Header.PageNumber = 2;
2265  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2266  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2267  	r = _config_request(ioc, &mpi_request, mpi_reply,
2268  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2269  	if (r)
2270  		goto out;
2271  
2272  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2273  	_config_request(ioc, &mpi_request, mpi_reply,
2274  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2275  	    sizeof(*config_page));
2276  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2277  	r = _config_request(ioc, &mpi_request, mpi_reply,
2278  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2279  	    sizeof(*config_page));
2280   out:
2281  	return r;
2282  }
2283  
2284  /**
2285   * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
2286   * @ioc: per adapter object
2287   * @event_tg: list of Event Triggers
2288   * @set: set ot clear trigger values
2289   * Context: sleep.
2290   *
2291   * Returns 0 for success, non-zero for failure.
2292   */
2293  int
mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_EVENT_TRIGGERS_T * event_tg,bool set)2294  mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2295  	struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
2296  {
2297  	Mpi26DriverTriggerPage2_t tg_pg2;
2298  	Mpi2ConfigReply_t mpi_reply;
2299  	int rc, i, count;
2300  	u16 ioc_status;
2301  
2302  	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2303  	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
2304  	if (rc)
2305  		return rc;
2306  
2307  	rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2308  	if (rc)
2309  		goto out;
2310  
2311  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2312  	    MPI2_IOCSTATUS_MASK;
2313  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2314  		dcprintk(ioc,
2315  		    ioc_err(ioc,
2316  		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2317  		    __func__, ioc_status));
2318  		rc = -EFAULT;
2319  		goto out;
2320  	}
2321  
2322  	if (set) {
2323  		count = event_tg->ValidEntries;
2324  		tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
2325  		for (i = 0; i < count; i++) {
2326  			tg_pg2.MPIEventTriggers[i].MPIEventCode =
2327  			    cpu_to_le16(
2328  			    event_tg->EventTriggerEntry[i].EventValue);
2329  			tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
2330  			    cpu_to_le16(
2331  			    event_tg->EventTriggerEntry[i].LogEntryQualifier);
2332  		}
2333  	} else {
2334  		tg_pg2.NumMPIEventTrigger = 0;
2335  		memset(&tg_pg2.MPIEventTriggers[0], 0,
2336  		    NUM_VALID_ENTRIES * sizeof(
2337  		    MPI26_DRIVER_MPI_EVENT_TRIGGER_ENTRY));
2338  	}
2339  
2340  	rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2341  	if (rc)
2342  		goto out;
2343  
2344  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2345  	    MPI2_IOCSTATUS_MASK;
2346  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2347  		dcprintk(ioc,
2348  		    ioc_err(ioc,
2349  		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2350  		    __func__, ioc_status));
2351  		rc = -EFAULT;
2352  		goto out;
2353  	}
2354  
2355  	return 0;
2356  
2357  out:
2358  	mpt3sas_config_update_driver_trigger_pg0(ioc,
2359  	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
2360  
2361  	return rc;
2362  }
2363  
2364  /**
2365   * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
2366   * @ioc: per adapter object
2367   * @mpi_reply: reply mf payload returned from firmware
2368   * @config_page: contents of the config page
2369   * Context: sleep.
2370   *
2371   * Returns 0 for success, non-zero for failure.
2372   */
2373  int
mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage3_t * config_page)2374  mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2375  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2376  {
2377  	Mpi2ConfigRequest_t mpi_request;
2378  	int r;
2379  
2380  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2381  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2382  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2383  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2384  	mpi_request.ExtPageType =
2385  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2386  	mpi_request.Header.PageNumber = 3;
2387  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2388  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2389  	r = _config_request(ioc, &mpi_request, mpi_reply,
2390  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2391  	if (r)
2392  		goto out;
2393  
2394  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2395  	r = _config_request(ioc, &mpi_request, mpi_reply,
2396  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2397  	    sizeof(*config_page));
2398   out:
2399  	return r;
2400  }
2401  
2402  /**
2403   * _config_set_driver_trigger_pg3 - write driver trigger page 3
2404   * @ioc: per adapter object
2405   * @mpi_reply: reply mf payload returned from firmware
2406   * @config_page: contents of the config page
2407   * Context: sleep.
2408   *
2409   * Returns 0 for success, non-zero for failure.
2410   */
2411  static int
_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage3_t * config_page)2412  _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2413  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2414  {
2415  	Mpi2ConfigRequest_t mpi_request;
2416  	int r;
2417  
2418  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2419  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2420  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2421  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2422  	mpi_request.ExtPageType =
2423  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2424  	mpi_request.Header.PageNumber = 3;
2425  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2426  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2427  	r = _config_request(ioc, &mpi_request, mpi_reply,
2428  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2429  	if (r)
2430  		goto out;
2431  
2432  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2433  	_config_request(ioc, &mpi_request, mpi_reply,
2434  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2435  	    sizeof(*config_page));
2436  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2437  	r = _config_request(ioc, &mpi_request, mpi_reply,
2438  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2439  	    sizeof(*config_page));
2440   out:
2441  	return r;
2442  }
2443  
2444  /**
2445   * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
2446   * @ioc: per adapter object
2447   * @scsi_tg: scsi trigger list
2448   * @set: set ot clear trigger values
2449   * Context: sleep.
2450   *
2451   * Returns 0 for success, non-zero for failure.
2452   */
2453  int
mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_SCSI_TRIGGERS_T * scsi_tg,bool set)2454  mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2455  	struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
2456  {
2457  	Mpi26DriverTriggerPage3_t tg_pg3;
2458  	Mpi2ConfigReply_t mpi_reply;
2459  	int rc, i, count;
2460  	u16 ioc_status;
2461  
2462  	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2463  	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
2464  	if (rc)
2465  		return rc;
2466  
2467  	rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2468  	if (rc)
2469  		goto out;
2470  
2471  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2472  	    MPI2_IOCSTATUS_MASK;
2473  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2474  		dcprintk(ioc,
2475  		    ioc_err(ioc,
2476  		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2477  		    __func__, ioc_status));
2478  		return -EFAULT;
2479  	}
2480  
2481  	if (set) {
2482  		count = scsi_tg->ValidEntries;
2483  		tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
2484  		for (i = 0; i < count; i++) {
2485  			tg_pg3.SCSISenseTriggers[i].ASCQ =
2486  			    scsi_tg->SCSITriggerEntry[i].ASCQ;
2487  			tg_pg3.SCSISenseTriggers[i].ASC =
2488  			    scsi_tg->SCSITriggerEntry[i].ASC;
2489  			tg_pg3.SCSISenseTriggers[i].SenseKey =
2490  			    scsi_tg->SCSITriggerEntry[i].SenseKey;
2491  		}
2492  	} else {
2493  		tg_pg3.NumSCSISenseTrigger = 0;
2494  		memset(&tg_pg3.SCSISenseTriggers[0], 0,
2495  		    NUM_VALID_ENTRIES * sizeof(
2496  		    MPI26_DRIVER_SCSI_SENSE_TRIGGER_ENTRY));
2497  	}
2498  
2499  	rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2500  	if (rc)
2501  		goto out;
2502  
2503  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2504  	    MPI2_IOCSTATUS_MASK;
2505  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2506  		dcprintk(ioc,
2507  		    ioc_err(ioc,
2508  		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2509  		     __func__, ioc_status));
2510  		return -EFAULT;
2511  	}
2512  
2513  	return 0;
2514  out:
2515  	mpt3sas_config_update_driver_trigger_pg0(ioc,
2516  	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
2517  
2518  	return rc;
2519  }
2520  
2521  /**
2522   * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
2523   * @ioc: per adapter object
2524   * @mpi_reply: reply mf payload returned from firmware
2525   * @config_page: contents of the config page
2526   * Context: sleep.
2527   *
2528   * Returns 0 for success, non-zero for failure.
2529   */
2530  int
mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage4_t * config_page)2531  mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2532  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2533  {
2534  	Mpi2ConfigRequest_t mpi_request;
2535  	int r;
2536  
2537  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2538  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2539  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2540  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2541  	mpi_request.ExtPageType =
2542  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2543  	mpi_request.Header.PageNumber = 4;
2544  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2545  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2546  	r = _config_request(ioc, &mpi_request, mpi_reply,
2547  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2548  	if (r)
2549  		goto out;
2550  
2551  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2552  	r = _config_request(ioc, &mpi_request, mpi_reply,
2553  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2554  	    sizeof(*config_page));
2555   out:
2556  	return r;
2557  }
2558  
2559  /**
2560   * _config_set_driver_trigger_pg4 - write driver trigger page 4
2561   * @ioc: per adapter object
2562   * @mpi_reply: reply mf payload returned from firmware
2563   * @config_page: contents of the config page
2564   * Context: sleep.
2565   *
2566   * Returns 0 for success, non-zero for failure.
2567   */
2568  static int
_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,Mpi2ConfigReply_t * mpi_reply,Mpi26DriverTriggerPage4_t * config_page)2569  _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2570  	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2571  {
2572  	Mpi2ConfigRequest_t mpi_request;
2573  	int r;
2574  
2575  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2576  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2577  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2578  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2579  	mpi_request.ExtPageType =
2580  	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2581  	mpi_request.Header.PageNumber = 4;
2582  	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2583  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2584  	r = _config_request(ioc, &mpi_request, mpi_reply,
2585  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2586  	if (r)
2587  		goto out;
2588  
2589  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2590  	_config_request(ioc, &mpi_request, mpi_reply,
2591  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2592  	    sizeof(*config_page));
2593  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2594  	r = _config_request(ioc, &mpi_request, mpi_reply,
2595  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2596  	    sizeof(*config_page));
2597   out:
2598  	return r;
2599  }
2600  
2601  /**
2602   * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
2603   * @ioc: per adapter object
2604   * @mpi_tg: mpi trigger list
2605   * @set: set ot clear trigger values
2606   * Context: sleep.
2607   *
2608   * Returns 0 for success, non-zero for failure.
2609   */
2610  int
mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER * ioc,struct SL_WH_MPI_TRIGGERS_T * mpi_tg,bool set)2611  mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2612  	struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
2613  {
2614  	Mpi26DriverTriggerPage4_t tg_pg4;
2615  	Mpi2ConfigReply_t mpi_reply;
2616  	int rc, i, count;
2617  	u16 ioc_status;
2618  
2619  	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2620  	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
2621  	if (rc)
2622  		return rc;
2623  
2624  	rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2625  	if (rc)
2626  		goto out;
2627  
2628  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2629  	    MPI2_IOCSTATUS_MASK;
2630  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2631  		dcprintk(ioc,
2632  		    ioc_err(ioc,
2633  		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2634  		    __func__, ioc_status));
2635  		rc = -EFAULT;
2636  		goto out;
2637  	}
2638  
2639  	if (set) {
2640  		count = mpi_tg->ValidEntries;
2641  		tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
2642  		for (i = 0; i < count; i++) {
2643  			tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
2644  			    cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
2645  			tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
2646  			    cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
2647  		}
2648  	} else {
2649  		tg_pg4.NumIOCStatusLogInfoTrigger = 0;
2650  		memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
2651  		    NUM_VALID_ENTRIES * sizeof(
2652  		    MPI26_DRIVER_IOCSTATUS_LOGINFO_TRIGGER_ENTRY));
2653  	}
2654  
2655  	rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2656  	if (rc)
2657  		goto out;
2658  
2659  	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2660  	    MPI2_IOCSTATUS_MASK;
2661  	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2662  		dcprintk(ioc,
2663  		    ioc_err(ioc,
2664  		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2665  		    __func__, ioc_status));
2666  		rc = -EFAULT;
2667  		goto out;
2668  	}
2669  
2670  	return 0;
2671  
2672  out:
2673  	mpt3sas_config_update_driver_trigger_pg0(ioc,
2674  	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
2675  
2676  	return rc;
2677  }
2678  
2679  /**
2680   * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
2681   * raid components
2682   * @ioc: per adapter object
2683   * @pd_handle: phys disk handle
2684   * @volume_handle: volume handle
2685   * Context: sleep.
2686   *
2687   * Return: 0 for success, non-zero for failure.
2688   */
2689  int
mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER * ioc,u16 pd_handle,u16 * volume_handle)2690  mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
2691  	u16 *volume_handle)
2692  {
2693  	Mpi2RaidConfigurationPage0_t *config_page = NULL;
2694  	Mpi2ConfigRequest_t mpi_request;
2695  	Mpi2ConfigReply_t mpi_reply;
2696  	int r, i, config_page_sz;
2697  	u16 ioc_status;
2698  	int config_num;
2699  	u16 element_type;
2700  	u16 phys_disk_dev_handle;
2701  
2702  	*volume_handle = 0;
2703  	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2704  	mpi_request.Function = MPI2_FUNCTION_CONFIG;
2705  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2706  	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2707  	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
2708  	mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
2709  	mpi_request.Header.PageNumber = 0;
2710  	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2711  	r = _config_request(ioc, &mpi_request, &mpi_reply,
2712  	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2713  	if (r)
2714  		goto out;
2715  
2716  	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2717  	config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
2718  	config_page = kmalloc(config_page_sz, GFP_KERNEL);
2719  	if (!config_page) {
2720  		r = -1;
2721  		goto out;
2722  	}
2723  
2724  	config_num = 0xff;
2725  	while (1) {
2726  		mpi_request.PageAddress = cpu_to_le32(config_num +
2727  		    MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
2728  		r = _config_request(ioc, &mpi_request, &mpi_reply,
2729  		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2730  		    config_page_sz);
2731  		if (r)
2732  			goto out;
2733  		r = -1;
2734  		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2735  		    MPI2_IOCSTATUS_MASK;
2736  		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
2737  			goto out;
2738  		for (i = 0; i < config_page->NumElements; i++) {
2739  			element_type = le16_to_cpu(config_page->
2740  			    ConfigElement[i].ElementFlags) &
2741  			    MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
2742  			if (element_type ==
2743  			    MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
2744  			    element_type ==
2745  			    MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
2746  				phys_disk_dev_handle =
2747  				    le16_to_cpu(config_page->ConfigElement[i].
2748  				    PhysDiskDevHandle);
2749  				if (phys_disk_dev_handle == pd_handle) {
2750  					*volume_handle =
2751  					    le16_to_cpu(config_page->
2752  					    ConfigElement[i].VolDevHandle);
2753  					r = 0;
2754  					goto out;
2755  				}
2756  			} else if (element_type ==
2757  			    MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
2758  				*volume_handle = 0;
2759  				r = 0;
2760  				goto out;
2761  			}
2762  		}
2763  		config_num = config_page->ConfigNum;
2764  	}
2765   out:
2766  	kfree(config_page);
2767  	return r;
2768  }
2769  
2770  /**
2771   * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
2772   * @ioc: per adapter object
2773   * @volume_handle: volume handle
2774   * @wwid: volume wwid
2775   * Context: sleep.
2776   *
2777   * Return: 0 for success, non-zero for failure.
2778   */
2779  int
mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER * ioc,u16 volume_handle,u64 * wwid)2780  mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
2781  	u64 *wwid)
2782  {
2783  	Mpi2ConfigReply_t mpi_reply;
2784  	Mpi2RaidVolPage1_t raid_vol_pg1;
2785  
2786  	*wwid = 0;
2787  	if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
2788  	    &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
2789  	    volume_handle))) {
2790  		*wwid = le64_to_cpu(raid_vol_pg1.WWID);
2791  		return 0;
2792  	} else
2793  		return -1;
2794  }
2795