Merge tag 'for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux...
[linux-2.6-microblaze.git] / drivers / scsi / mpt3sas / mpt3sas_config.c
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
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
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
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
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
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                 goto free_mem;
364
365         smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
366         if (!smid) {
367                 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
368                 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
369                 r = -EAGAIN;
370                 goto free_mem;
371         }
372
373         r = 0;
374         memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
375         ioc->config_cmds.status = MPT3_CMD_PENDING;
376         config_request = mpt3sas_base_get_msg_frame(ioc, smid);
377         ioc->config_cmds.smid = smid;
378         memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
379         if (ioc->logging_level & MPT_DEBUG_CONFIG)
380                 _config_display_some_debug(ioc, smid, "config_request", NULL);
381         init_completion(&ioc->config_cmds.done);
382         ioc->put_smid_default(ioc, smid);
383         wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
384         if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
385                 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
386                         _config_display_some_debug(ioc,
387                             smid, "config_request", NULL);
388                 ioc_err(ioc, "%s: command timeout\n", __func__);
389                 mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
390                                 mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
391                 retry_count++;
392                 if (ioc->config_cmds.smid == smid)
393                         mpt3sas_base_free_smid(ioc, smid);
394                 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
395                     MPT3_CMD_RESET) || ioc->pci_error_recovery)
396                         goto retry_config;
397                 issue_host_reset = 1;
398                 r = -EFAULT;
399                 goto free_mem;
400         }
401
402         if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
403                 memcpy(mpi_reply, ioc->config_cmds.reply,
404                     sizeof(Mpi2ConfigReply_t));
405
406                 /* Reply Frame Sanity Checks to workaround FW issues */
407                 if ((mpi_request->Header.PageType & 0xF) !=
408                     (mpi_reply->Header.PageType & 0xF)) {
409                         if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
410                                 _config_display_some_debug(ioc,
411                                     smid, "config_request", NULL);
412                         _debug_dump_mf(mpi_request, ioc->request_sz/4);
413                         _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
414                         panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
415                               ioc->name, __func__,
416                               mpi_request->Header.PageType & 0xF,
417                               mpi_reply->Header.PageType & 0xF);
418                 }
419
420                 if (((mpi_request->Header.PageType & 0xF) ==
421                     MPI2_CONFIG_PAGETYPE_EXTENDED) &&
422                     mpi_request->ExtPageType != mpi_reply->ExtPageType) {
423                         if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
424                                 _config_display_some_debug(ioc,
425                                     smid, "config_request", NULL);
426                         _debug_dump_mf(mpi_request, ioc->request_sz/4);
427                         _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
428                         panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
429                               ioc->name, __func__,
430                               mpi_request->ExtPageType,
431                               mpi_reply->ExtPageType);
432                 }
433                 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
434                     & MPI2_IOCSTATUS_MASK;
435         }
436
437         if (retry_count)
438                 ioc_info(ioc, "%s: retry (%d) completed!!\n",
439                          __func__, retry_count);
440
441         if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
442             config_page && mpi_request->Action ==
443             MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
444                 u8 *p = (u8 *)mem.page;
445
446                 /* Config Page Sanity Checks to workaround FW issues */
447                 if (p) {
448                         if ((mpi_request->Header.PageType & 0xF) !=
449                             (p[3] & 0xF)) {
450                                 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
451                                         _config_display_some_debug(ioc,
452                                             smid, "config_request", NULL);
453                                 _debug_dump_mf(mpi_request, ioc->request_sz/4);
454                                 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
455                                 _debug_dump_config(p, min_t(u16, mem.sz,
456                                     config_page_sz)/4);
457                                 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
458                                       ioc->name, __func__,
459                                       mpi_request->Header.PageType & 0xF,
460                                       p[3] & 0xF);
461                         }
462
463                         if (((mpi_request->Header.PageType & 0xF) ==
464                             MPI2_CONFIG_PAGETYPE_EXTENDED) &&
465                             (mpi_request->ExtPageType != p[6])) {
466                                 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
467                                         _config_display_some_debug(ioc,
468                                             smid, "config_request", NULL);
469                                 _debug_dump_mf(mpi_request, ioc->request_sz/4);
470                                 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
471                                 _debug_dump_config(p, min_t(u16, mem.sz,
472                                     config_page_sz)/4);
473                                 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
474                                       ioc->name, __func__,
475                                       mpi_request->ExtPageType, p[6]);
476                         }
477                 }
478                 memcpy(config_page, mem.page, min_t(u16, mem.sz,
479                     config_page_sz));
480         }
481
482  free_mem:
483         if (config_page)
484                 _config_free_config_dma_memory(ioc, &mem);
485  out:
486         ioc->config_cmds.status = MPT3_CMD_NOT_USED;
487         mutex_unlock(&ioc->config_cmds.mutex);
488
489         if (issue_host_reset)
490                 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
491         return r;
492 }
493
494 /**
495  * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
496  * @ioc: per adapter object
497  * @mpi_reply: reply mf payload returned from firmware
498  * @config_page: contents of the config page
499  * Context: sleep.
500  *
501  * Return: 0 for success, non-zero for failure.
502  */
503 int
504 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
505         Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
506 {
507         Mpi2ConfigRequest_t mpi_request;
508         int r;
509
510         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
511         mpi_request.Function = MPI2_FUNCTION_CONFIG;
512         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
513         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
514         mpi_request.Header.PageNumber = 0;
515         mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
516         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
517         r = _config_request(ioc, &mpi_request, mpi_reply,
518             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
519         if (r)
520                 goto out;
521
522         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
523         r = _config_request(ioc, &mpi_request, mpi_reply,
524             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
525             sizeof(*config_page));
526  out:
527         return r;
528 }
529
530 /**
531  * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
532  * @ioc: per adapter object
533  * @mpi_reply: reply mf payload returned from firmware
534  * @config_page: contents of the config page
535  * @sz: size of buffer passed in config_page
536  * Context: sleep.
537  *
538  * Return: 0 for success, non-zero for failure.
539  */
540 int
541 mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
542         Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
543         u16 sz)
544 {
545         Mpi2ConfigRequest_t mpi_request;
546         int r;
547
548         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
549         mpi_request.Function = MPI2_FUNCTION_CONFIG;
550         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
551         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
552         mpi_request.Header.PageNumber = 7;
553         mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
554         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
555         r = _config_request(ioc, &mpi_request, mpi_reply,
556             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
557         if (r)
558                 goto out;
559
560         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
561         r = _config_request(ioc, &mpi_request, mpi_reply,
562             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
563             sz);
564  out:
565         return r;
566 }
567
568 /**
569  * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
570  * @ioc: per adapter object
571  * @mpi_reply: reply mf payload returned from firmware
572  * @config_page: contents of the config page
573  * Context: sleep.
574  *
575  * Return: 0 for success, non-zero for failure.
576  */
577 int
578 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
579         Mpi2ConfigReply_t *mpi_reply,
580         struct Mpi2ManufacturingPage10_t *config_page)
581 {
582         Mpi2ConfigRequest_t mpi_request;
583         int r;
584
585         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
586         mpi_request.Function = MPI2_FUNCTION_CONFIG;
587         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
588         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
589         mpi_request.Header.PageNumber = 10;
590         mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
591         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
592         r = _config_request(ioc, &mpi_request, mpi_reply,
593             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
594         if (r)
595                 goto out;
596
597         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
598         r = _config_request(ioc, &mpi_request, mpi_reply,
599             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
600             sizeof(*config_page));
601  out:
602         return r;
603 }
604
605 /**
606  * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
607  * @ioc: per adapter object
608  * @mpi_reply: reply mf payload returned from firmware
609  * @config_page: contents of the config page
610  * Context: sleep.
611  *
612  * Return: 0 for success, non-zero for failure.
613  */
614 int
615 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
616         Mpi2ConfigReply_t *mpi_reply,
617         struct Mpi2ManufacturingPage11_t *config_page)
618 {
619         Mpi2ConfigRequest_t mpi_request;
620         int r;
621
622         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
623         mpi_request.Function = MPI2_FUNCTION_CONFIG;
624         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
625         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
626         mpi_request.Header.PageNumber = 11;
627         mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
628         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
629         r = _config_request(ioc, &mpi_request, mpi_reply,
630             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
631         if (r)
632                 goto out;
633
634         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
635         r = _config_request(ioc, &mpi_request, mpi_reply,
636             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
637             sizeof(*config_page));
638  out:
639         return r;
640 }
641
642 /**
643  * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
644  * @ioc: per adapter object
645  * @mpi_reply: reply mf payload returned from firmware
646  * @config_page: contents of the config page
647  * Context: sleep.
648  *
649  * Return: 0 for success, non-zero for failure.
650  */
651 int
652 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
653         Mpi2ConfigReply_t *mpi_reply,
654         struct Mpi2ManufacturingPage11_t *config_page)
655 {
656         Mpi2ConfigRequest_t mpi_request;
657         int r;
658
659         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
660         mpi_request.Function = MPI2_FUNCTION_CONFIG;
661         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
662         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
663         mpi_request.Header.PageNumber = 11;
664         mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
665         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
666         r = _config_request(ioc, &mpi_request, mpi_reply,
667             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
668         if (r)
669                 goto out;
670
671         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
672         r = _config_request(ioc, &mpi_request, mpi_reply,
673             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
674             sizeof(*config_page));
675  out:
676         return r;
677 }
678
679 /**
680  * mpt3sas_config_get_bios_pg2 - obtain bios page 2
681  * @ioc: per adapter object
682  * @mpi_reply: reply mf payload returned from firmware
683  * @config_page: contents of the config page
684  * Context: sleep.
685  *
686  * Return: 0 for success, non-zero for failure.
687  */
688 int
689 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
690         Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
691 {
692         Mpi2ConfigRequest_t mpi_request;
693         int r;
694
695         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
696         mpi_request.Function = MPI2_FUNCTION_CONFIG;
697         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
698         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
699         mpi_request.Header.PageNumber = 2;
700         mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
701         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
702         r = _config_request(ioc, &mpi_request, mpi_reply,
703             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
704         if (r)
705                 goto out;
706
707         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
708         r = _config_request(ioc, &mpi_request, mpi_reply,
709             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
710             sizeof(*config_page));
711  out:
712         return r;
713 }
714
715 /**
716  * mpt3sas_config_get_bios_pg3 - obtain bios page 3
717  * @ioc: per adapter object
718  * @mpi_reply: reply mf payload returned from firmware
719  * @config_page: contents of the config page
720  * Context: sleep.
721  *
722  * Return: 0 for success, non-zero for failure.
723  */
724 int
725 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
726         *mpi_reply, Mpi2BiosPage3_t *config_page)
727 {
728         Mpi2ConfigRequest_t mpi_request;
729         int r;
730
731         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
732         mpi_request.Function = MPI2_FUNCTION_CONFIG;
733         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
734         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
735         mpi_request.Header.PageNumber = 3;
736         mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
737         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
738         r = _config_request(ioc, &mpi_request, mpi_reply,
739             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
740         if (r)
741                 goto out;
742
743         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
744         r = _config_request(ioc, &mpi_request, mpi_reply,
745             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
746             sizeof(*config_page));
747  out:
748         return r;
749 }
750
751 /**
752  * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
753  * @ioc: per adapter object
754  * @mpi_reply: reply mf payload returned from firmware
755  * @config_page: contents of the config page
756  * Context: sleep.
757  *
758  * Return: 0 for success, non-zero for failure.
759  */
760 int
761 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
762         Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
763 {
764         Mpi2ConfigRequest_t mpi_request;
765         int r;
766
767         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
768         mpi_request.Function = MPI2_FUNCTION_CONFIG;
769         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
770         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
771         mpi_request.Header.PageNumber = 0;
772         mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
773         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
774         r = _config_request(ioc, &mpi_request, mpi_reply,
775             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
776         if (r)
777                 goto out;
778
779         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
780         r = _config_request(ioc, &mpi_request, mpi_reply,
781             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
782             sizeof(*config_page));
783  out:
784         return r;
785 }
786
787 /**
788  * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
789  * @ioc: per adapter object
790  * @mpi_reply: reply mf payload returned from firmware
791  * @config_page: contents of the config page
792  * Context: sleep.
793  *
794  * Return: 0 for success, non-zero for failure.
795  */
796 int
797 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
798         Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
799 {
800         Mpi2ConfigRequest_t mpi_request;
801         int r;
802
803         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
804         mpi_request.Function = MPI2_FUNCTION_CONFIG;
805         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
806         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
807         mpi_request.Header.PageNumber = 1;
808         mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
809         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
810         r = _config_request(ioc, &mpi_request, mpi_reply,
811             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
812         if (r)
813                 goto out;
814
815         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
816         r = _config_request(ioc, &mpi_request, mpi_reply,
817             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
818             sizeof(*config_page));
819  out:
820         return r;
821 }
822
823 /**
824  * mpt3sas_config_set_iounit_pg1 - set iounit page 1
825  * @ioc: per adapter object
826  * @mpi_reply: reply mf payload returned from firmware
827  * @config_page: contents of the config page
828  * Context: sleep.
829  *
830  * Return: 0 for success, non-zero for failure.
831  */
832 int
833 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
834         Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
835 {
836         Mpi2ConfigRequest_t mpi_request;
837         int r;
838
839         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
840         mpi_request.Function = MPI2_FUNCTION_CONFIG;
841         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
842         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
843         mpi_request.Header.PageNumber = 1;
844         mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
845         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
846         r = _config_request(ioc, &mpi_request, mpi_reply,
847             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
848         if (r)
849                 goto out;
850
851         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
852         r = _config_request(ioc, &mpi_request, mpi_reply,
853             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
854             sizeof(*config_page));
855  out:
856         return r;
857 }
858
859 /**
860  * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
861  * @ioc: per adapter object
862  * @mpi_reply: reply mf payload returned from firmware
863  * @config_page: contents of the config page
864  * @sz: size of buffer passed in config_page
865  * Context: sleep.
866  *
867  * Return: 0 for success, non-zero for failure.
868  */
869 int
870 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
871         Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
872 {
873         Mpi2ConfigRequest_t mpi_request;
874         int r;
875
876         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
877         mpi_request.Function = MPI2_FUNCTION_CONFIG;
878         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
879         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
880         mpi_request.Header.PageNumber = 3;
881         mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
882         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
883         r = _config_request(ioc, &mpi_request, mpi_reply,
884             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
885         if (r)
886                 goto out;
887
888         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
889         r = _config_request(ioc, &mpi_request, mpi_reply,
890             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
891  out:
892         return r;
893 }
894
895 /**
896  * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
897  * @ioc: per adapter object
898  * @mpi_reply: reply mf payload returned from firmware
899  * @config_page: contents of the config page
900  * Context: sleep.
901  *
902  * Return: 0 for success, non-zero for failure.
903  */
904 int
905 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
906         Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
907 {
908         Mpi2ConfigRequest_t mpi_request;
909         int r;
910
911         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
912         mpi_request.Function = MPI2_FUNCTION_CONFIG;
913         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
914         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
915         mpi_request.Header.PageNumber = 8;
916         mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
917         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
918         r = _config_request(ioc, &mpi_request, mpi_reply,
919             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
920         if (r)
921                 goto out;
922
923         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
924         r = _config_request(ioc, &mpi_request, mpi_reply,
925             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
926             sizeof(*config_page));
927  out:
928         return r;
929 }
930
931 /**
932  * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
933  * @ioc: per adapter object
934  * @mpi_reply: reply mf payload returned from firmware
935  * @config_page: contents of the config page
936  * Context: sleep.
937  *
938  * Return: 0 for success, non-zero for failure.
939  */
940 int
941 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
942         Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
943 {
944         Mpi2ConfigRequest_t mpi_request;
945         int r;
946
947         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
948         mpi_request.Function = MPI2_FUNCTION_CONFIG;
949         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
950         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
951         mpi_request.Header.PageNumber = 8;
952         mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
953         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
954         r = _config_request(ioc, &mpi_request, mpi_reply,
955             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
956         if (r)
957                 goto out;
958
959         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
960         r = _config_request(ioc, &mpi_request, mpi_reply,
961             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
962             sizeof(*config_page));
963  out:
964         return r;
965 }
966 /**
967  * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
968  * @ioc: per adapter object
969  * @mpi_reply: reply mf payload returned from firmware
970  * @config_page: contents of the config page
971  * Context: sleep.
972  *
973  * Return: 0 for success, non-zero for failure.
974  */
975 int
976 mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
977         Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
978 {
979         Mpi2ConfigRequest_t mpi_request;
980         int r;
981
982         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
983         mpi_request.Function = MPI2_FUNCTION_CONFIG;
984         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
985         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
986         mpi_request.Header.PageNumber = 1;
987         mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
988         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
989         r = _config_request(ioc, &mpi_request, mpi_reply,
990             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
991         if (r)
992                 goto out;
993
994         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
995         r = _config_request(ioc, &mpi_request, mpi_reply,
996             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
997             sizeof(*config_page));
998  out:
999         return r;
1000 }
1001
1002 /**
1003  * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
1004  * @ioc: per adapter object
1005  * @mpi_reply: reply mf payload returned from firmware
1006  * @config_page: contents of the config page
1007  * Context: sleep.
1008  *
1009  * Return: 0 for success, non-zero for failure.
1010  */
1011 int
1012 mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1013         Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1014 {
1015         Mpi2ConfigRequest_t mpi_request;
1016         int r;
1017
1018         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1019         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1020         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1021         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1022         mpi_request.Header.PageNumber = 1;
1023         mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1024         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1025         r = _config_request(ioc, &mpi_request, mpi_reply,
1026             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1027         if (r)
1028                 goto out;
1029
1030         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1031         r = _config_request(ioc, &mpi_request, mpi_reply,
1032             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1033             sizeof(*config_page));
1034  out:
1035         return r;
1036 }
1037
1038 /**
1039  * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1040  * @ioc: per adapter object
1041  * @mpi_reply: reply mf payload returned from firmware
1042  * @config_page: contents of the config page
1043  * @form: GET_NEXT_HANDLE or HANDLE
1044  * @handle: device handle
1045  * Context: sleep.
1046  *
1047  * Return: 0 for success, non-zero for failure.
1048  */
1049 int
1050 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1051         Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1052         u32 form, u32 handle)
1053 {
1054         Mpi2ConfigRequest_t mpi_request;
1055         int r;
1056
1057         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1058         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1059         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1060         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1061         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1062         mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1063         mpi_request.Header.PageNumber = 0;
1064         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1065         r = _config_request(ioc, &mpi_request, mpi_reply,
1066             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1067         if (r)
1068                 goto out;
1069
1070         mpi_request.PageAddress = cpu_to_le32(form | handle);
1071         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1072         r = _config_request(ioc, &mpi_request, mpi_reply,
1073             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1074             sizeof(*config_page));
1075  out:
1076         return r;
1077 }
1078
1079 /**
1080  * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1081  * @ioc: per adapter object
1082  * @mpi_reply: reply mf payload returned from firmware
1083  * @config_page: contents of the config page
1084  * @form: GET_NEXT_HANDLE or HANDLE
1085  * @handle: device handle
1086  * Context: sleep.
1087  *
1088  * Return: 0 for success, non-zero for failure.
1089  */
1090 int
1091 mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1092         Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1093         u32 form, u32 handle)
1094 {
1095         Mpi2ConfigRequest_t mpi_request;
1096         int r;
1097
1098         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1099         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1100         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1101         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1102         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1103         mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1104         mpi_request.Header.PageNumber = 1;
1105         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1106         r = _config_request(ioc, &mpi_request, mpi_reply,
1107             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1108         if (r)
1109                 goto out;
1110
1111         mpi_request.PageAddress = cpu_to_le32(form | handle);
1112         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1113         r = _config_request(ioc, &mpi_request, mpi_reply,
1114             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1115             sizeof(*config_page));
1116  out:
1117         return r;
1118 }
1119
1120 /**
1121  * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1122  * @ioc: per adapter object
1123  * @mpi_reply: reply mf payload returned from firmware
1124  * @config_page: contents of the config page
1125  * @form: GET_NEXT_HANDLE or HANDLE
1126  * @handle: device handle
1127  * Context: sleep.
1128  *
1129  * Return: 0 for success, non-zero for failure.
1130  */
1131 int
1132 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1133         Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1134         u32 form, u32 handle)
1135 {
1136         Mpi2ConfigRequest_t mpi_request;
1137         int r;
1138
1139         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1140         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1141         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1142         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1143         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1144         mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1145         mpi_request.Header.PageNumber = 0;
1146         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1147         r = _config_request(ioc, &mpi_request, mpi_reply,
1148                         MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1149         if (r)
1150                 goto out;
1151
1152         mpi_request.PageAddress = cpu_to_le32(form | handle);
1153         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1154         r = _config_request(ioc, &mpi_request, mpi_reply,
1155                         MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1156                         sizeof(*config_page));
1157 out:
1158         return r;
1159 }
1160
1161 /**
1162  * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1163  * @ioc: per adapter object
1164  * @mpi_reply: reply mf payload returned from firmware
1165  * @config_page: contents of the config page
1166  * @form: GET_NEXT_HANDLE or HANDLE
1167  * @handle: device handle
1168  * Context: sleep.
1169  *
1170  * Return: 0 for success, non-zero for failure.
1171  */
1172 int
1173 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1174         Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1175         u32 form, u32 handle)
1176 {
1177         Mpi2ConfigRequest_t mpi_request;
1178         int r;
1179
1180         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1181         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1182         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1183         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1184         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1185         mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1186         mpi_request.Header.PageNumber = 2;
1187         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1188         r = _config_request(ioc, &mpi_request, mpi_reply,
1189                         MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1190         if (r)
1191                 goto out;
1192
1193         mpi_request.PageAddress = cpu_to_le32(form | handle);
1194         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1195         r = _config_request(ioc, &mpi_request, mpi_reply,
1196                         MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1197                         sizeof(*config_page));
1198 out:
1199         return r;
1200 }
1201
1202 /**
1203  * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1204  * @ioc: per adapter object
1205  * @num_phys: pointer returned with the number of phys
1206  * Context: sleep.
1207  *
1208  * Return: 0 for success, non-zero for failure.
1209  */
1210 int
1211 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1212 {
1213         Mpi2ConfigRequest_t mpi_request;
1214         int r;
1215         u16 ioc_status;
1216         Mpi2ConfigReply_t mpi_reply;
1217         Mpi2SasIOUnitPage0_t config_page;
1218
1219         *num_phys = 0;
1220         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1221         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1222         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1223         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1224         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1225         mpi_request.Header.PageNumber = 0;
1226         mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1227         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1228         r = _config_request(ioc, &mpi_request, &mpi_reply,
1229             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1230         if (r)
1231                 goto out;
1232
1233         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1234         r = _config_request(ioc, &mpi_request, &mpi_reply,
1235             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1236             sizeof(Mpi2SasIOUnitPage0_t));
1237         if (!r) {
1238                 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1239                     MPI2_IOCSTATUS_MASK;
1240                 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1241                         *num_phys = config_page.NumPhys;
1242         }
1243  out:
1244         return r;
1245 }
1246
1247 /**
1248  * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1249  * @ioc: per adapter object
1250  * @mpi_reply: reply mf payload returned from firmware
1251  * @config_page: contents of the config page
1252  * @sz: size of buffer passed in config_page
1253  * Context: sleep.
1254  *
1255  * Calling function should call config_get_number_hba_phys prior to
1256  * this function, so enough memory is allocated for config_page.
1257  *
1258  * Return: 0 for success, non-zero for failure.
1259  */
1260 int
1261 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1262         Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1263         u16 sz)
1264 {
1265         Mpi2ConfigRequest_t mpi_request;
1266         int r;
1267
1268         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1269         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1270         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1271         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1272         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1273         mpi_request.Header.PageNumber = 0;
1274         mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1275         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1276         r = _config_request(ioc, &mpi_request, mpi_reply,
1277             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1278         if (r)
1279                 goto out;
1280
1281         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1282         r = _config_request(ioc, &mpi_request, mpi_reply,
1283             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1284  out:
1285         return r;
1286 }
1287
1288 /**
1289  * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1290  * @ioc: per adapter object
1291  * @mpi_reply: reply mf payload returned from firmware
1292  * @config_page: contents of the config page
1293  * @sz: size of buffer passed in config_page
1294  * Context: sleep.
1295  *
1296  * Calling function should call config_get_number_hba_phys prior to
1297  * this function, so enough memory is allocated for config_page.
1298  *
1299  * Return: 0 for success, non-zero for failure.
1300  */
1301 int
1302 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1303         Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1304         u16 sz)
1305 {
1306         Mpi2ConfigRequest_t mpi_request;
1307         int r;
1308
1309         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1310         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1311         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1312         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1313         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1314         mpi_request.Header.PageNumber = 1;
1315         mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1316         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1317         r = _config_request(ioc, &mpi_request, mpi_reply,
1318             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1319         if (r)
1320                 goto out;
1321
1322         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1323         r = _config_request(ioc, &mpi_request, mpi_reply,
1324             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1325  out:
1326         return r;
1327 }
1328
1329 /**
1330  * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1331  * @ioc: per adapter object
1332  * @mpi_reply: reply mf payload returned from firmware
1333  * @config_page: contents of the config page
1334  * @sz: size of buffer passed in config_page
1335  * Context: sleep.
1336  *
1337  * Calling function should call config_get_number_hba_phys prior to
1338  * this function, so enough memory is allocated for config_page.
1339  *
1340  * Return: 0 for success, non-zero for failure.
1341  */
1342 int
1343 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1344         Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1345         u16 sz)
1346 {
1347         Mpi2ConfigRequest_t mpi_request;
1348         int r;
1349
1350         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1351         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1352         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1353         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1354         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1355         mpi_request.Header.PageNumber = 1;
1356         mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1357         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1358         r = _config_request(ioc, &mpi_request, mpi_reply,
1359             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1360         if (r)
1361                 goto out;
1362
1363         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1364         _config_request(ioc, &mpi_request, mpi_reply,
1365             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1366         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1367         r = _config_request(ioc, &mpi_request, mpi_reply,
1368             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1369  out:
1370         return r;
1371 }
1372
1373 /**
1374  * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1375  * @ioc: per adapter object
1376  * @mpi_reply: reply mf payload returned from firmware
1377  * @config_page: contents of the config page
1378  * @form: GET_NEXT_HANDLE or HANDLE
1379  * @handle: expander handle
1380  * Context: sleep.
1381  *
1382  * Return: 0 for success, non-zero for failure.
1383  */
1384 int
1385 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1386         *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1387 {
1388         Mpi2ConfigRequest_t mpi_request;
1389         int r;
1390
1391         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1392         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1393         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1394         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1395         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1396         mpi_request.Header.PageNumber = 0;
1397         mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1398         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1399         r = _config_request(ioc, &mpi_request, mpi_reply,
1400             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1401         if (r)
1402                 goto out;
1403
1404         mpi_request.PageAddress = cpu_to_le32(form | handle);
1405         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1406         r = _config_request(ioc, &mpi_request, mpi_reply,
1407             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1408             sizeof(*config_page));
1409  out:
1410         return r;
1411 }
1412
1413 /**
1414  * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1415  * @ioc: per adapter object
1416  * @mpi_reply: reply mf payload returned from firmware
1417  * @config_page: contents of the config page
1418  * @phy_number: phy number
1419  * @handle: expander handle
1420  * Context: sleep.
1421  *
1422  * Return: 0 for success, non-zero for failure.
1423  */
1424 int
1425 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1426         *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1427         u16 handle)
1428 {
1429         Mpi2ConfigRequest_t mpi_request;
1430         int r;
1431
1432         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1433         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1434         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1435         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1436         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1437         mpi_request.Header.PageNumber = 1;
1438         mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1439         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1440         r = _config_request(ioc, &mpi_request, mpi_reply,
1441             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1442         if (r)
1443                 goto out;
1444
1445         mpi_request.PageAddress =
1446             cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1447             (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1448         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1449         r = _config_request(ioc, &mpi_request, mpi_reply,
1450             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1451             sizeof(*config_page));
1452  out:
1453         return r;
1454 }
1455
1456 /**
1457  * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1458  * @ioc: per adapter object
1459  * @mpi_reply: reply mf payload returned from firmware
1460  * @config_page: contents of the config page
1461  * @form: GET_NEXT_HANDLE or HANDLE
1462  * @handle: expander handle
1463  * Context: sleep.
1464  *
1465  * Return: 0 for success, non-zero for failure.
1466  */
1467 int
1468 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1469         *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1470 {
1471         Mpi2ConfigRequest_t mpi_request;
1472         int r;
1473
1474         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1475         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1476         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1477         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1478         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1479         mpi_request.Header.PageNumber = 0;
1480         mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1481         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1482         r = _config_request(ioc, &mpi_request, mpi_reply,
1483             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1484         if (r)
1485                 goto out;
1486
1487         mpi_request.PageAddress = cpu_to_le32(form | handle);
1488         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1489         r = _config_request(ioc, &mpi_request, mpi_reply,
1490             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1491             sizeof(*config_page));
1492  out:
1493         return r;
1494 }
1495
1496 /**
1497  * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1498  * @ioc: per adapter object
1499  * @mpi_reply: reply mf payload returned from firmware
1500  * @config_page: contents of the config page
1501  * @phy_number: phy number
1502  * Context: sleep.
1503  *
1504  * Return: 0 for success, non-zero for failure.
1505  */
1506 int
1507 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1508         *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1509 {
1510         Mpi2ConfigRequest_t mpi_request;
1511         int r;
1512
1513         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1514         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1515         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1516         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1517         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1518         mpi_request.Header.PageNumber = 0;
1519         mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1520         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1521         r = _config_request(ioc, &mpi_request, mpi_reply,
1522             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1523         if (r)
1524                 goto out;
1525
1526         mpi_request.PageAddress =
1527             cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1528         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1529         r = _config_request(ioc, &mpi_request, mpi_reply,
1530             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1531             sizeof(*config_page));
1532  out:
1533         return r;
1534 }
1535
1536 /**
1537  * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1538  * @ioc: per adapter object
1539  * @mpi_reply: reply mf payload returned from firmware
1540  * @config_page: contents of the config page
1541  * @phy_number: phy number
1542  * Context: sleep.
1543  *
1544  * Return: 0 for success, non-zero for failure.
1545  */
1546 int
1547 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1548         *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1549 {
1550         Mpi2ConfigRequest_t mpi_request;
1551         int r;
1552
1553         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1554         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1555         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1556         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1557         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1558         mpi_request.Header.PageNumber = 1;
1559         mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1560         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1561         r = _config_request(ioc, &mpi_request, mpi_reply,
1562             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1563         if (r)
1564                 goto out;
1565
1566         mpi_request.PageAddress =
1567             cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1568         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1569         r = _config_request(ioc, &mpi_request, mpi_reply,
1570             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1571             sizeof(*config_page));
1572  out:
1573         return r;
1574 }
1575
1576 /**
1577  * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1578  * @ioc: per adapter object
1579  * @mpi_reply: reply mf payload returned from firmware
1580  * @config_page: contents of the config page
1581  * @form: GET_NEXT_HANDLE or HANDLE
1582  * @handle: volume handle
1583  * Context: sleep.
1584  *
1585  * Return: 0 for success, non-zero for failure.
1586  */
1587 int
1588 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1589         Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1590         u32 handle)
1591 {
1592         Mpi2ConfigRequest_t mpi_request;
1593         int r;
1594
1595         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1596         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1597         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1598         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1599         mpi_request.Header.PageNumber = 1;
1600         mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1601         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1602         r = _config_request(ioc, &mpi_request, mpi_reply,
1603             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1604         if (r)
1605                 goto out;
1606
1607         mpi_request.PageAddress = cpu_to_le32(form | handle);
1608         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1609         r = _config_request(ioc, &mpi_request, mpi_reply,
1610             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1611             sizeof(*config_page));
1612  out:
1613         return r;
1614 }
1615
1616 /**
1617  * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1618  * @ioc: per adapter object
1619  * @handle: volume handle
1620  * @num_pds: returns pds count
1621  * Context: sleep.
1622  *
1623  * Return: 0 for success, non-zero for failure.
1624  */
1625 int
1626 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1627         u8 *num_pds)
1628 {
1629         Mpi2ConfigRequest_t mpi_request;
1630         Mpi2RaidVolPage0_t config_page;
1631         Mpi2ConfigReply_t mpi_reply;
1632         int r;
1633         u16 ioc_status;
1634
1635         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1636         *num_pds = 0;
1637         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1638         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1639         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1640         mpi_request.Header.PageNumber = 0;
1641         mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1642         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1643         r = _config_request(ioc, &mpi_request, &mpi_reply,
1644             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1645         if (r)
1646                 goto out;
1647
1648         mpi_request.PageAddress =
1649             cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1650         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1651         r = _config_request(ioc, &mpi_request, &mpi_reply,
1652             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1653             sizeof(Mpi2RaidVolPage0_t));
1654         if (!r) {
1655                 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1656                     MPI2_IOCSTATUS_MASK;
1657                 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1658                         *num_pds = config_page.NumPhysDisks;
1659         }
1660
1661  out:
1662         return r;
1663 }
1664
1665 /**
1666  * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1667  * @ioc: per adapter object
1668  * @mpi_reply: reply mf payload returned from firmware
1669  * @config_page: contents of the config page
1670  * @form: GET_NEXT_HANDLE or HANDLE
1671  * @handle: volume handle
1672  * @sz: size of buffer passed in config_page
1673  * Context: sleep.
1674  *
1675  * Return: 0 for success, non-zero for failure.
1676  */
1677 int
1678 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1679         Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1680         u32 handle, u16 sz)
1681 {
1682         Mpi2ConfigRequest_t mpi_request;
1683         int r;
1684
1685         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1686         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1687         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1688         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1689         mpi_request.Header.PageNumber = 0;
1690         mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1691         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1692         r = _config_request(ioc, &mpi_request, mpi_reply,
1693             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1694         if (r)
1695                 goto out;
1696
1697         mpi_request.PageAddress = cpu_to_le32(form | handle);
1698         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1699         r = _config_request(ioc, &mpi_request, mpi_reply,
1700             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1701  out:
1702         return r;
1703 }
1704
1705 /**
1706  * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1707  * @ioc: per adapter object
1708  * @mpi_reply: reply mf payload returned from firmware
1709  * @config_page: contents of the config page
1710  * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1711  * @form_specific: specific to the form
1712  * Context: sleep.
1713  *
1714  * Return: 0 for success, non-zero for failure.
1715  */
1716 int
1717 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1718         *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1719         u32 form_specific)
1720 {
1721         Mpi2ConfigRequest_t mpi_request;
1722         int r;
1723
1724         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1725         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1726         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1727         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1728         mpi_request.Header.PageNumber = 0;
1729         mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1730         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1731         r = _config_request(ioc, &mpi_request, mpi_reply,
1732             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1733         if (r)
1734                 goto out;
1735
1736         mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1737         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1738         r = _config_request(ioc, &mpi_request, mpi_reply,
1739             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1740             sizeof(*config_page));
1741  out:
1742         return r;
1743 }
1744
1745 /**
1746  * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
1747  * @ioc: per adapter object
1748  * @mpi_reply: reply mf payload returned from firmware
1749  * @config_page: contents of the config page
1750  * Context: sleep.
1751  *
1752  * Returns 0 for success, non-zero for failure.
1753  */
1754 int
1755 mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1756         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1757 {
1758         Mpi2ConfigRequest_t mpi_request;
1759         int r;
1760
1761         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1762         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1763         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1764         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1765         mpi_request.ExtPageType =
1766             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1767         mpi_request.Header.PageNumber = 0;
1768         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1769         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1770         r = _config_request(ioc, &mpi_request, mpi_reply,
1771             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1772         if (r)
1773                 goto out;
1774
1775         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1776         r = _config_request(ioc, &mpi_request, mpi_reply,
1777             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1778             sizeof(*config_page));
1779  out:
1780         return r;
1781 }
1782
1783 /**
1784  * mpt3sas_config_set_driver_trigger_pg0 - write driver trigger page 0
1785  * @ioc: per adapter object
1786  * @mpi_reply: reply mf payload returned from firmware
1787  * @config_page: contents of the config page
1788  * Context: sleep.
1789  *
1790  * Returns 0 for success, non-zero for failure.
1791  */
1792 static int
1793 _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1794         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
1795 {
1796         Mpi2ConfigRequest_t mpi_request;
1797         int r;
1798
1799         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1800         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1801         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1802         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1803         mpi_request.ExtPageType =
1804             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1805         mpi_request.Header.PageNumber = 0;
1806         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
1807         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1808         r = _config_request(ioc, &mpi_request, mpi_reply,
1809             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1810         if (r)
1811                 goto out;
1812
1813         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1814         _config_request(ioc, &mpi_request, mpi_reply,
1815             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1816             sizeof(*config_page));
1817         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1818         r = _config_request(ioc, &mpi_request, mpi_reply,
1819             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1820             sizeof(*config_page));
1821  out:
1822         return r;
1823 }
1824
1825 /**
1826  * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
1827  * @ioc: per adapter object
1828  * @trigger_flag: trigger type bit map
1829  * @set: set ot clear trigger values
1830  * Context: sleep.
1831  *
1832  * Returns 0 for success, non-zero for failure.
1833  */
1834 static int
1835 mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
1836         u16 trigger_flag, bool set)
1837 {
1838         Mpi26DriverTriggerPage0_t tg_pg0;
1839         Mpi2ConfigReply_t mpi_reply;
1840         int rc;
1841         u16 flags, ioc_status;
1842
1843         rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1844         if (rc)
1845                 return rc;
1846         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1847             MPI2_IOCSTATUS_MASK;
1848         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1849                 dcprintk(ioc,
1850                     ioc_err(ioc,
1851                     "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
1852                     __func__, ioc_status));
1853                 return -EFAULT;
1854         }
1855
1856         if (set)
1857                 flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
1858         else
1859                 flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
1860
1861         tg_pg0.TriggerFlags = cpu_to_le16(flags);
1862
1863         rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
1864         if (rc)
1865                 return rc;
1866         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1867             MPI2_IOCSTATUS_MASK;
1868         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1869                 dcprintk(ioc,
1870                     ioc_err(ioc,
1871                     "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
1872                     __func__, ioc_status));
1873                 return -EFAULT;
1874         }
1875
1876         return 0;
1877 }
1878
1879 /**
1880  * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
1881  * @ioc: per adapter object
1882  * @mpi_reply: reply mf payload returned from firmware
1883  * @config_page: contents of the config page
1884  * Context: sleep.
1885  *
1886  * Returns 0 for success, non-zero for failure.
1887  */
1888 int
1889 mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1890         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1891 {
1892         Mpi2ConfigRequest_t mpi_request;
1893         int r;
1894
1895         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1896         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1897         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1898         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1899         mpi_request.ExtPageType =
1900             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1901         mpi_request.Header.PageNumber = 1;
1902         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1903         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1904         r = _config_request(ioc, &mpi_request, mpi_reply,
1905             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1906         if (r)
1907                 goto out;
1908
1909         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1910         r = _config_request(ioc, &mpi_request, mpi_reply,
1911             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1912             sizeof(*config_page));
1913  out:
1914         return r;
1915 }
1916
1917 /**
1918  * mpt3sas_config_set_driver_trigger_pg1 - write driver trigger page 1
1919  * @ioc: per adapter object
1920  * @mpi_reply: reply mf payload returned from firmware
1921  * @config_page: contents of the config page
1922  * Context: sleep.
1923  *
1924  * Returns 0 for success, non-zero for failure.
1925  */
1926 static int
1927 _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1928         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
1929 {
1930         Mpi2ConfigRequest_t mpi_request;
1931         int r;
1932
1933         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1934         mpi_request.Function = MPI2_FUNCTION_CONFIG;
1935         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1936         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1937         mpi_request.ExtPageType =
1938             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
1939         mpi_request.Header.PageNumber = 1;
1940         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
1941         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1942         r = _config_request(ioc, &mpi_request, mpi_reply,
1943             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1944         if (r)
1945                 goto out;
1946
1947         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1948         _config_request(ioc, &mpi_request, mpi_reply,
1949             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1950             sizeof(*config_page));
1951         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1952         r = _config_request(ioc, &mpi_request, mpi_reply,
1953             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1954             sizeof(*config_page));
1955  out:
1956         return r;
1957 }
1958
1959 /**
1960  * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
1961  * @ioc: per adapter object
1962  * @master_tg: Master trigger bit map
1963  * @set: set ot clear trigger values
1964  * Context: sleep.
1965  *
1966  * Returns 0 for success, non-zero for failure.
1967  */
1968 int
1969 mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
1970         struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
1971 {
1972         Mpi26DriverTriggerPage1_t tg_pg1;
1973         Mpi2ConfigReply_t mpi_reply;
1974         int rc;
1975         u16 ioc_status;
1976
1977         rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
1978             MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
1979         if (rc)
1980                 return rc;
1981
1982         rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
1983         if (rc)
1984                 goto out;
1985
1986         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1987             MPI2_IOCSTATUS_MASK;
1988         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1989                 dcprintk(ioc,
1990                     ioc_err(ioc,
1991                     "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
1992                     __func__, ioc_status));
1993                 rc = -EFAULT;
1994                 goto out;
1995         }
1996
1997         if (set) {
1998                 tg_pg1.NumMasterTrigger = cpu_to_le16(1);
1999                 tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
2000                     master_tg->MasterData);
2001         } else {
2002                 tg_pg1.NumMasterTrigger = 0;
2003                 tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
2004         }
2005
2006         rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
2007         if (rc)
2008                 goto out;
2009
2010         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2011             MPI2_IOCSTATUS_MASK;
2012         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2013                 dcprintk(ioc,
2014                     ioc_err(ioc,
2015                     "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
2016                     __func__, ioc_status));
2017                 rc = -EFAULT;
2018                 goto out;
2019         }
2020
2021         return 0;
2022
2023 out:
2024         mpt3sas_config_update_driver_trigger_pg0(ioc,
2025             MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
2026
2027         return rc;
2028 }
2029
2030 /**
2031  * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
2032  * @ioc: per adapter object
2033  * @mpi_reply: reply mf payload returned from firmware
2034  * @config_page: contents of the config page
2035  * Context: sleep.
2036  *
2037  * Returns 0 for success, non-zero for failure.
2038  */
2039 int
2040 mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2041         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2042 {
2043         Mpi2ConfigRequest_t mpi_request;
2044         int r;
2045
2046         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2047         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2048         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2049         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2050         mpi_request.ExtPageType =
2051             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2052         mpi_request.Header.PageNumber = 2;
2053         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2054         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2055         r = _config_request(ioc, &mpi_request, mpi_reply,
2056             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2057         if (r)
2058                 goto out;
2059
2060         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2061         r = _config_request(ioc, &mpi_request, mpi_reply,
2062             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2063             sizeof(*config_page));
2064  out:
2065         return r;
2066 }
2067
2068 /**
2069  * mpt3sas_config_set_driver_trigger_pg2 - write driver trigger page 2
2070  * @ioc: per adapter object
2071  * @mpi_reply: reply mf payload returned from firmware
2072  * @config_page: contents of the config page
2073  * Context: sleep.
2074  *
2075  * Returns 0 for success, non-zero for failure.
2076  */
2077 static int
2078 _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2079         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
2080 {
2081         Mpi2ConfigRequest_t mpi_request;
2082         int r;
2083
2084         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2085         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2086         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2087         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2088         mpi_request.ExtPageType =
2089             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2090         mpi_request.Header.PageNumber = 2;
2091         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
2092         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2093         r = _config_request(ioc, &mpi_request, mpi_reply,
2094             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2095         if (r)
2096                 goto out;
2097
2098         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2099         _config_request(ioc, &mpi_request, mpi_reply,
2100             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2101             sizeof(*config_page));
2102         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2103         r = _config_request(ioc, &mpi_request, mpi_reply,
2104             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2105             sizeof(*config_page));
2106  out:
2107         return r;
2108 }
2109
2110 /**
2111  * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
2112  * @ioc: per adapter object
2113  * @event_tg: list of Event Triggers
2114  * @set: set ot clear trigger values
2115  * Context: sleep.
2116  *
2117  * Returns 0 for success, non-zero for failure.
2118  */
2119 int
2120 mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
2121         struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
2122 {
2123         Mpi26DriverTriggerPage2_t tg_pg2;
2124         Mpi2ConfigReply_t mpi_reply;
2125         int rc, i, count;
2126         u16 ioc_status;
2127
2128         rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2129             MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
2130         if (rc)
2131                 return rc;
2132
2133         rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2134         if (rc)
2135                 goto out;
2136
2137         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2138             MPI2_IOCSTATUS_MASK;
2139         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2140                 dcprintk(ioc,
2141                     ioc_err(ioc,
2142                     "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2143                     __func__, ioc_status));
2144                 rc = -EFAULT;
2145                 goto out;
2146         }
2147
2148         if (set) {
2149                 count = event_tg->ValidEntries;
2150                 tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
2151                 for (i = 0; i < count; i++) {
2152                         tg_pg2.MPIEventTriggers[i].MPIEventCode =
2153                             cpu_to_le16(
2154                             event_tg->EventTriggerEntry[i].EventValue);
2155                         tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
2156                             cpu_to_le16(
2157                             event_tg->EventTriggerEntry[i].LogEntryQualifier);
2158                 }
2159         } else {
2160                 tg_pg2.NumMPIEventTrigger = 0;
2161                 memset(&tg_pg2.MPIEventTriggers[0], 0,
2162                     NUM_VALID_ENTRIES * sizeof(
2163                     MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY));
2164         }
2165
2166         rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
2167         if (rc)
2168                 goto out;
2169
2170         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2171             MPI2_IOCSTATUS_MASK;
2172         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2173                 dcprintk(ioc,
2174                     ioc_err(ioc,
2175                     "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
2176                     __func__, ioc_status));
2177                 rc = -EFAULT;
2178                 goto out;
2179         }
2180
2181         return 0;
2182
2183 out:
2184         mpt3sas_config_update_driver_trigger_pg0(ioc,
2185             MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
2186
2187         return rc;
2188 }
2189
2190 /**
2191  * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
2192  * @ioc: per adapter object
2193  * @mpi_reply: reply mf payload returned from firmware
2194  * @config_page: contents of the config page
2195  * Context: sleep.
2196  *
2197  * Returns 0 for success, non-zero for failure.
2198  */
2199 int
2200 mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2201         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2202 {
2203         Mpi2ConfigRequest_t mpi_request;
2204         int r;
2205
2206         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2207         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2208         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2209         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2210         mpi_request.ExtPageType =
2211             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2212         mpi_request.Header.PageNumber = 3;
2213         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2214         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2215         r = _config_request(ioc, &mpi_request, mpi_reply,
2216             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2217         if (r)
2218                 goto out;
2219
2220         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2221         r = _config_request(ioc, &mpi_request, mpi_reply,
2222             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2223             sizeof(*config_page));
2224  out:
2225         return r;
2226 }
2227
2228 /**
2229  * mpt3sas_config_set_driver_trigger_pg3 - write driver trigger page 3
2230  * @ioc: per adapter object
2231  * @mpi_reply: reply mf payload returned from firmware
2232  * @config_page: contents of the config page
2233  * Context: sleep.
2234  *
2235  * Returns 0 for success, non-zero for failure.
2236  */
2237 static int
2238 _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2239         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
2240 {
2241         Mpi2ConfigRequest_t mpi_request;
2242         int r;
2243
2244         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2245         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2246         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2247         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2248         mpi_request.ExtPageType =
2249             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2250         mpi_request.Header.PageNumber = 3;
2251         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
2252         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2253         r = _config_request(ioc, &mpi_request, mpi_reply,
2254             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2255         if (r)
2256                 goto out;
2257
2258         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2259         _config_request(ioc, &mpi_request, mpi_reply,
2260             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2261             sizeof(*config_page));
2262         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2263         r = _config_request(ioc, &mpi_request, mpi_reply,
2264             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2265             sizeof(*config_page));
2266  out:
2267         return r;
2268 }
2269
2270 /**
2271  * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
2272  * @ioc: per adapter object
2273  * @scsi_tg: scsi trigger list
2274  * @set: set ot clear trigger values
2275  * Context: sleep.
2276  *
2277  * Returns 0 for success, non-zero for failure.
2278  */
2279 int
2280 mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
2281         struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
2282 {
2283         Mpi26DriverTriggerPage3_t tg_pg3;
2284         Mpi2ConfigReply_t mpi_reply;
2285         int rc, i, count;
2286         u16 ioc_status;
2287
2288         rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2289             MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
2290         if (rc)
2291                 return rc;
2292
2293         rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2294         if (rc)
2295                 goto out;
2296
2297         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2298             MPI2_IOCSTATUS_MASK;
2299         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2300                 dcprintk(ioc,
2301                     ioc_err(ioc,
2302                     "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2303                     __func__, ioc_status));
2304                 return -EFAULT;
2305         }
2306
2307         if (set) {
2308                 count = scsi_tg->ValidEntries;
2309                 tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
2310                 for (i = 0; i < count; i++) {
2311                         tg_pg3.SCSISenseTriggers[i].ASCQ =
2312                             scsi_tg->SCSITriggerEntry[i].ASCQ;
2313                         tg_pg3.SCSISenseTriggers[i].ASC =
2314                             scsi_tg->SCSITriggerEntry[i].ASC;
2315                         tg_pg3.SCSISenseTriggers[i].SenseKey =
2316                             scsi_tg->SCSITriggerEntry[i].SenseKey;
2317                 }
2318         } else {
2319                 tg_pg3.NumSCSISenseTrigger = 0;
2320                 memset(&tg_pg3.SCSISenseTriggers[0], 0,
2321                     NUM_VALID_ENTRIES * sizeof(
2322                     MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY));
2323         }
2324
2325         rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
2326         if (rc)
2327                 goto out;
2328
2329         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2330             MPI2_IOCSTATUS_MASK;
2331         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2332                 dcprintk(ioc,
2333                     ioc_err(ioc,
2334                     "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
2335                      __func__, ioc_status));
2336                 return -EFAULT;
2337         }
2338
2339         return 0;
2340 out:
2341         mpt3sas_config_update_driver_trigger_pg0(ioc,
2342             MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
2343
2344         return rc;
2345 }
2346
2347 /**
2348  * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
2349  * @ioc: per adapter object
2350  * @mpi_reply: reply mf payload returned from firmware
2351  * @config_page: contents of the config page
2352  * Context: sleep.
2353  *
2354  * Returns 0 for success, non-zero for failure.
2355  */
2356 int
2357 mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2358         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2359 {
2360         Mpi2ConfigRequest_t mpi_request;
2361         int r;
2362
2363         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2364         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2365         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2366         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2367         mpi_request.ExtPageType =
2368             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2369         mpi_request.Header.PageNumber = 4;
2370         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2371         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2372         r = _config_request(ioc, &mpi_request, mpi_reply,
2373             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2374         if (r)
2375                 goto out;
2376
2377         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2378         r = _config_request(ioc, &mpi_request, mpi_reply,
2379             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2380             sizeof(*config_page));
2381  out:
2382         return r;
2383 }
2384
2385 /**
2386  * mpt3sas_config_set_driver_trigger_pg4 - write driver trigger page 4
2387  * @ioc: per adapter object
2388  * @mpi_reply: reply mf payload returned from firmware
2389  * @config_page: contents of the config page
2390  * Context: sleep.
2391  *
2392  * Returns 0 for success, non-zero for failure.
2393  */
2394 static int
2395 _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2396         Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
2397 {
2398         Mpi2ConfigRequest_t mpi_request;
2399         int r;
2400
2401         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2402         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2403         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2404         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2405         mpi_request.ExtPageType =
2406             MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
2407         mpi_request.Header.PageNumber = 4;
2408         mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
2409         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2410         r = _config_request(ioc, &mpi_request, mpi_reply,
2411             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2412         if (r)
2413                 goto out;
2414
2415         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2416         _config_request(ioc, &mpi_request, mpi_reply,
2417             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2418             sizeof(*config_page));
2419         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
2420         r = _config_request(ioc, &mpi_request, mpi_reply,
2421             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2422             sizeof(*config_page));
2423  out:
2424         return r;
2425 }
2426
2427 /**
2428  * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
2429  * @ioc: per adapter object
2430  * @mpi_tg: mpi trigger list
2431  * @set: set ot clear trigger values
2432  * Context: sleep.
2433  *
2434  * Returns 0 for success, non-zero for failure.
2435  */
2436 int
2437 mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
2438         struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
2439 {
2440         Mpi26DriverTriggerPage4_t tg_pg4;
2441         Mpi2ConfigReply_t mpi_reply;
2442         int rc, i, count;
2443         u16 ioc_status;
2444
2445         rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
2446             MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
2447         if (rc)
2448                 return rc;
2449
2450         rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2451         if (rc)
2452                 goto out;
2453
2454         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2455             MPI2_IOCSTATUS_MASK;
2456         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2457                 dcprintk(ioc,
2458                     ioc_err(ioc,
2459                     "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2460                     __func__, ioc_status));
2461                 rc = -EFAULT;
2462                 goto out;
2463         }
2464
2465         if (set) {
2466                 count = mpi_tg->ValidEntries;
2467                 tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
2468                 for (i = 0; i < count; i++) {
2469                         tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
2470                             cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
2471                         tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
2472                             cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
2473                 }
2474         } else {
2475                 tg_pg4.NumIOCStatusLogInfoTrigger = 0;
2476                 memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
2477                     NUM_VALID_ENTRIES * sizeof(
2478                     MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY));
2479         }
2480
2481         rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
2482         if (rc)
2483                 goto out;
2484
2485         ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2486             MPI2_IOCSTATUS_MASK;
2487         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
2488                 dcprintk(ioc,
2489                     ioc_err(ioc,
2490                     "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
2491                     __func__, ioc_status));
2492                 rc = -EFAULT;
2493                 goto out;
2494         }
2495
2496         return 0;
2497
2498 out:
2499         mpt3sas_config_update_driver_trigger_pg0(ioc,
2500             MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
2501
2502         return rc;
2503 }
2504
2505 /**
2506  * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
2507  * raid components
2508  * @ioc: per adapter object
2509  * @pd_handle: phys disk handle
2510  * @volume_handle: volume handle
2511  * Context: sleep.
2512  *
2513  * Return: 0 for success, non-zero for failure.
2514  */
2515 int
2516 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
2517         u16 *volume_handle)
2518 {
2519         Mpi2RaidConfigurationPage0_t *config_page = NULL;
2520         Mpi2ConfigRequest_t mpi_request;
2521         Mpi2ConfigReply_t mpi_reply;
2522         int r, i, config_page_sz;
2523         u16 ioc_status;
2524         int config_num;
2525         u16 element_type;
2526         u16 phys_disk_dev_handle;
2527
2528         *volume_handle = 0;
2529         memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
2530         mpi_request.Function = MPI2_FUNCTION_CONFIG;
2531         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
2532         mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
2533         mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
2534         mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
2535         mpi_request.Header.PageNumber = 0;
2536         ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
2537         r = _config_request(ioc, &mpi_request, &mpi_reply,
2538             MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
2539         if (r)
2540                 goto out;
2541
2542         mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
2543         config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
2544         config_page = kmalloc(config_page_sz, GFP_KERNEL);
2545         if (!config_page) {
2546                 r = -1;
2547                 goto out;
2548         }
2549
2550         config_num = 0xff;
2551         while (1) {
2552                 mpi_request.PageAddress = cpu_to_le32(config_num +
2553                     MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
2554                 r = _config_request(ioc, &mpi_request, &mpi_reply,
2555                     MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
2556                     config_page_sz);
2557                 if (r)
2558                         goto out;
2559                 r = -1;
2560                 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
2561                     MPI2_IOCSTATUS_MASK;
2562                 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
2563                         goto out;
2564                 for (i = 0; i < config_page->NumElements; i++) {
2565                         element_type = le16_to_cpu(config_page->
2566                             ConfigElement[i].ElementFlags) &
2567                             MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
2568                         if (element_type ==
2569                             MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
2570                             element_type ==
2571                             MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
2572                                 phys_disk_dev_handle =
2573                                     le16_to_cpu(config_page->ConfigElement[i].
2574                                     PhysDiskDevHandle);
2575                                 if (phys_disk_dev_handle == pd_handle) {
2576                                         *volume_handle =
2577                                             le16_to_cpu(config_page->
2578                                             ConfigElement[i].VolDevHandle);
2579                                         r = 0;
2580                                         goto out;
2581                                 }
2582                         } else if (element_type ==
2583                             MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
2584                                 *volume_handle = 0;
2585                                 r = 0;
2586                                 goto out;
2587                         }
2588                 }
2589                 config_num = config_page->ConfigNum;
2590         }
2591  out:
2592         kfree(config_page);
2593         return r;
2594 }
2595
2596 /**
2597  * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
2598  * @ioc: per adapter object
2599  * @volume_handle: volume handle
2600  * @wwid: volume wwid
2601  * Context: sleep.
2602  *
2603  * Return: 0 for success, non-zero for failure.
2604  */
2605 int
2606 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
2607         u64 *wwid)
2608 {
2609         Mpi2ConfigReply_t mpi_reply;
2610         Mpi2RaidVolPage1_t raid_vol_pg1;
2611
2612         *wwid = 0;
2613         if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
2614             &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
2615             volume_handle))) {
2616                 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
2617                 return 0;
2618         } else
2619                 return -1;
2620 }