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