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