Linux 4.19.133
[linux/fpc-iii.git] / drivers / scsi / mpt3sas / mpt3sas_config.c
blob9b01c5a7aebd9df0a1e3e911449e3f688f333860
1 /*
2 * This module provides common API for accessing firmware configuration pages
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)
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.
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.
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.
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
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.
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>
55 #include "mpt3sas_base.h"
57 /* local definitions */
59 /* Timeout for config page request (in seconds) */
60 #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15
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)
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)
73 /**
74 * struct config_request - obtain dma memory via routine
75 * @sz: size
76 * @page: virt pointer
77 * @page_dma: phys pointer
80 struct config_request {
81 u16 sz;
82 void *page;
83 dma_addr_t page_dma;
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.
94 * Function for displaying debug info helpful when debugging issues
95 * in this module.
97 static void
98 _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
99 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
101 Mpi2ConfigRequest_t *mpi_request;
102 char *desc = NULL;
104 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
105 return;
107 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
108 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
109 case MPI2_CONFIG_PAGETYPE_IO_UNIT:
110 desc = "io_unit";
111 break;
112 case MPI2_CONFIG_PAGETYPE_IOC:
113 desc = "ioc";
114 break;
115 case MPI2_CONFIG_PAGETYPE_BIOS:
116 desc = "bios";
117 break;
118 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
119 desc = "raid_volume";
120 break;
121 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
122 desc = "manufaucturing";
123 break;
124 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
125 desc = "physdisk";
126 break;
127 case MPI2_CONFIG_PAGETYPE_EXTENDED:
128 switch (mpi_request->ExtPageType) {
129 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
130 desc = "sas_io_unit";
131 break;
132 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
133 desc = "sas_expander";
134 break;
135 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
136 desc = "sas_device";
137 break;
138 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
139 desc = "sas_phy";
140 break;
141 case MPI2_CONFIG_EXTPAGETYPE_LOG:
142 desc = "log";
143 break;
144 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
145 desc = "enclosure";
146 break;
147 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
148 desc = "raid_config";
149 break;
150 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
151 desc = "driver_mapping";
152 break;
153 case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
154 desc = "sas_port";
155 break;
156 case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
157 desc = "ext_manufacturing";
158 break;
159 case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
160 desc = "pcie_io_unit";
161 break;
162 case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
163 desc = "pcie_switch";
164 break;
165 case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
166 desc = "pcie_device";
167 break;
168 case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
169 desc = "pcie_link";
170 break;
172 break;
175 if (!desc)
176 return;
178 pr_info(MPT3SAS_FMT
179 "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",
180 ioc->name, calling_function_name, desc,
181 mpi_request->Header.PageNumber, mpi_request->Action,
182 le32_to_cpu(mpi_request->PageAddress), smid);
184 if (!mpi_reply)
185 return;
187 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
188 pr_info(MPT3SAS_FMT
189 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
190 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
191 le32_to_cpu(mpi_reply->IOCLogInfo));
195 * _config_alloc_config_dma_memory - obtain physical memory
196 * @ioc: per adapter object
197 * @mem: struct config_request
199 * A wrapper for obtaining dma-able memory for config page request.
201 * Return: 0 for success, non-zero for failure.
203 static int
204 _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
205 struct config_request *mem)
207 int r = 0;
209 if (mem->sz > ioc->config_page_sz) {
210 mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
211 &mem->page_dma, GFP_KERNEL);
212 if (!mem->page) {
213 pr_err(MPT3SAS_FMT
214 "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
215 ioc->name, __func__, mem->sz);
216 r = -ENOMEM;
218 } else { /* use tmp buffer if less than 512 bytes */
219 mem->page = ioc->config_page;
220 mem->page_dma = ioc->config_page_dma;
222 ioc->config_vaddr = mem->page;
223 return r;
227 * _config_free_config_dma_memory - wrapper to free the memory
228 * @ioc: per adapter object
229 * @mem: struct config_request
231 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
233 * Return: 0 for success, non-zero for failure.
235 static void
236 _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
237 struct config_request *mem)
239 if (mem->sz > ioc->config_page_sz)
240 dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
241 mem->page_dma);
245 * mpt3sas_config_done - config page completion routine
246 * @ioc: per adapter object
247 * @smid: system request message index
248 * @msix_index: MSIX table index supplied by the OS
249 * @reply: reply message frame(lower 32bit addr)
250 * Context: none.
252 * The callback handler when using _config_request.
254 * Return: 1 meaning mf should be freed from _base_interrupt
255 * 0 means the mf is freed from this function.
258 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
259 u32 reply)
261 MPI2DefaultReply_t *mpi_reply;
263 if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)
264 return 1;
265 if (ioc->config_cmds.smid != smid)
266 return 1;
267 ioc->config_cmds.status |= MPT3_CMD_COMPLETE;
268 mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
269 if (mpi_reply) {
270 ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;
271 memcpy(ioc->config_cmds.reply, mpi_reply,
272 mpi_reply->MsgLength*4);
274 ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
275 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
276 ioc->config_cmds.smid = USHRT_MAX;
277 complete(&ioc->config_cmds.done);
278 return 1;
282 * _config_request - main routine for sending config page requests
283 * @ioc: per adapter object
284 * @mpi_request: request message frame
285 * @mpi_reply: reply mf payload returned from firmware
286 * @timeout: timeout in seconds
287 * @config_page: contents of the config page
288 * @config_page_sz: size of config page
289 * Context: sleep
291 * A generic API for config page requests to firmware.
293 * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
294 * this API.
296 * The callback index is set inside `ioc->config_cb_idx.
298 * Return: 0 for success, non-zero for failure.
300 static int
301 _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
302 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
303 void *config_page, u16 config_page_sz)
305 u16 smid;
306 u32 ioc_state;
307 Mpi2ConfigRequest_t *config_request;
308 int r;
309 u8 retry_count, issue_host_reset = 0;
310 u16 wait_state_count;
311 struct config_request mem;
312 u32 ioc_status = UINT_MAX;
314 mutex_lock(&ioc->config_cmds.mutex);
315 if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
316 pr_err(MPT3SAS_FMT "%s: config_cmd in use\n",
317 ioc->name, __func__);
318 mutex_unlock(&ioc->config_cmds.mutex);
319 return -EAGAIN;
322 retry_count = 0;
323 memset(&mem, 0, sizeof(struct config_request));
325 mpi_request->VF_ID = 0; /* TODO */
326 mpi_request->VP_ID = 0;
328 if (config_page) {
329 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
330 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
331 mpi_request->Header.PageType = mpi_reply->Header.PageType;
332 mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
333 mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
334 mpi_request->ExtPageType = mpi_reply->ExtPageType;
335 if (mpi_request->Header.PageLength)
336 mem.sz = mpi_request->Header.PageLength * 4;
337 else
338 mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
339 r = _config_alloc_config_dma_memory(ioc, &mem);
340 if (r != 0)
341 goto out;
342 if (mpi_request->Action ==
343 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
344 mpi_request->Action ==
345 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
346 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
347 MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
348 mem.page_dma);
349 memcpy(mem.page, config_page, min_t(u16, mem.sz,
350 config_page_sz));
351 } else {
352 memset(config_page, 0, config_page_sz);
353 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
354 MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
355 memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
359 retry_config:
360 if (retry_count) {
361 if (retry_count > 2) { /* attempt only 2 retries */
362 r = -EFAULT;
363 goto free_mem;
365 pr_info(MPT3SAS_FMT "%s: attempting retry (%d)\n",
366 ioc->name, __func__, retry_count);
368 wait_state_count = 0;
369 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
370 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
371 if (wait_state_count++ == MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT) {
372 pr_err(MPT3SAS_FMT
373 "%s: failed due to ioc not operational\n",
374 ioc->name, __func__);
375 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
376 r = -EFAULT;
377 goto free_mem;
379 ssleep(1);
380 ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
381 pr_info(MPT3SAS_FMT
382 "%s: waiting for operational state(count=%d)\n",
383 ioc->name, __func__, wait_state_count);
385 if (wait_state_count)
386 pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
387 ioc->name, __func__);
389 smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
390 if (!smid) {
391 pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
392 ioc->name, __func__);
393 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
394 r = -EAGAIN;
395 goto free_mem;
398 r = 0;
399 memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
400 ioc->config_cmds.status = MPT3_CMD_PENDING;
401 config_request = mpt3sas_base_get_msg_frame(ioc, smid);
402 ioc->config_cmds.smid = smid;
403 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
404 _config_display_some_debug(ioc, smid, "config_request", NULL);
405 init_completion(&ioc->config_cmds.done);
406 mpt3sas_base_put_smid_default(ioc, smid);
407 wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
408 if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
409 mpt3sas_base_check_cmd_timeout(ioc,
410 ioc->config_cmds.status, mpi_request,
411 sizeof(Mpi2ConfigRequest_t)/4);
412 retry_count++;
413 if (ioc->config_cmds.smid == smid)
414 mpt3sas_base_free_smid(ioc, smid);
415 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
416 MPT3_CMD_RESET) || ioc->pci_error_recovery)
417 goto retry_config;
418 issue_host_reset = 1;
419 r = -EFAULT;
420 goto free_mem;
423 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
424 memcpy(mpi_reply, ioc->config_cmds.reply,
425 sizeof(Mpi2ConfigReply_t));
427 /* Reply Frame Sanity Checks to workaround FW issues */
428 if ((mpi_request->Header.PageType & 0xF) !=
429 (mpi_reply->Header.PageType & 0xF)) {
430 _debug_dump_mf(mpi_request, ioc->request_sz/4);
431 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
432 panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \
433 " mpi_reply mismatch: Requested PageType(0x%02x)" \
434 " Reply PageType(0x%02x)\n", \
435 ioc->name, __func__,
436 (mpi_request->Header.PageType & 0xF),
437 (mpi_reply->Header.PageType & 0xF));
440 if (((mpi_request->Header.PageType & 0xF) ==
441 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
442 mpi_request->ExtPageType != mpi_reply->ExtPageType) {
443 _debug_dump_mf(mpi_request, ioc->request_sz/4);
444 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
445 panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \
446 " mpi_reply mismatch: Requested ExtPageType(0x%02x)"
447 " Reply ExtPageType(0x%02x)\n",
448 ioc->name, __func__, mpi_request->ExtPageType,
449 mpi_reply->ExtPageType);
451 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
452 & MPI2_IOCSTATUS_MASK;
455 if (retry_count)
456 pr_info(MPT3SAS_FMT "%s: retry (%d) completed!!\n", \
457 ioc->name, __func__, retry_count);
459 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
460 config_page && mpi_request->Action ==
461 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
462 u8 *p = (u8 *)mem.page;
464 /* Config Page Sanity Checks to workaround FW issues */
465 if (p) {
466 if ((mpi_request->Header.PageType & 0xF) !=
467 (p[3] & 0xF)) {
468 _debug_dump_mf(mpi_request, ioc->request_sz/4);
469 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
470 _debug_dump_config(p, min_t(u16, mem.sz,
471 config_page_sz)/4);
472 panic(KERN_WARNING MPT3SAS_FMT
473 "%s: Firmware BUG:" \
474 " config page mismatch:"
475 " Requested PageType(0x%02x)"
476 " Reply PageType(0x%02x)\n",
477 ioc->name, __func__,
478 (mpi_request->Header.PageType & 0xF),
479 (p[3] & 0xF));
482 if (((mpi_request->Header.PageType & 0xF) ==
483 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
484 (mpi_request->ExtPageType != p[6])) {
485 _debug_dump_mf(mpi_request, ioc->request_sz/4);
486 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
487 _debug_dump_config(p, min_t(u16, mem.sz,
488 config_page_sz)/4);
489 panic(KERN_WARNING MPT3SAS_FMT
490 "%s: Firmware BUG:" \
491 " config page mismatch:"
492 " Requested ExtPageType(0x%02x)"
493 " Reply ExtPageType(0x%02x)\n",
494 ioc->name, __func__,
495 mpi_request->ExtPageType, p[6]);
498 memcpy(config_page, mem.page, min_t(u16, mem.sz,
499 config_page_sz));
502 free_mem:
503 if (config_page)
504 _config_free_config_dma_memory(ioc, &mem);
505 out:
506 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
507 mutex_unlock(&ioc->config_cmds.mutex);
509 if (issue_host_reset)
510 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
511 return r;
515 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
516 * @ioc: per adapter object
517 * @mpi_reply: reply mf payload returned from firmware
518 * @config_page: contents of the config page
519 * Context: sleep.
521 * Return: 0 for success, non-zero for failure.
524 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
525 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
527 Mpi2ConfigRequest_t mpi_request;
528 int r;
530 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
531 mpi_request.Function = MPI2_FUNCTION_CONFIG;
532 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
533 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
534 mpi_request.Header.PageNumber = 0;
535 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
536 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
537 r = _config_request(ioc, &mpi_request, mpi_reply,
538 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
539 if (r)
540 goto out;
542 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
543 r = _config_request(ioc, &mpi_request, mpi_reply,
544 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
545 sizeof(*config_page));
546 out:
547 return r;
551 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
552 * @ioc: per adapter object
553 * @mpi_reply: reply mf payload returned from firmware
554 * @config_page: contents of the config page
555 * @sz: size of buffer passed in config_page
556 * Context: sleep.
558 * Return: 0 for success, non-zero for failure.
561 mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
562 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
563 u16 sz)
565 Mpi2ConfigRequest_t mpi_request;
566 int r;
568 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
569 mpi_request.Function = MPI2_FUNCTION_CONFIG;
570 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
571 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
572 mpi_request.Header.PageNumber = 7;
573 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
574 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
575 r = _config_request(ioc, &mpi_request, mpi_reply,
576 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
577 if (r)
578 goto out;
580 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
581 r = _config_request(ioc, &mpi_request, mpi_reply,
582 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
583 sz);
584 out:
585 return r;
589 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
590 * @ioc: per adapter object
591 * @mpi_reply: reply mf payload returned from firmware
592 * @config_page: contents of the config page
593 * Context: sleep.
595 * Return: 0 for success, non-zero for failure.
598 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
599 Mpi2ConfigReply_t *mpi_reply,
600 struct Mpi2ManufacturingPage10_t *config_page)
602 Mpi2ConfigRequest_t mpi_request;
603 int r;
605 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
606 mpi_request.Function = MPI2_FUNCTION_CONFIG;
607 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
608 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
609 mpi_request.Header.PageNumber = 10;
610 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
611 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
612 r = _config_request(ioc, &mpi_request, mpi_reply,
613 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
614 if (r)
615 goto out;
617 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
618 r = _config_request(ioc, &mpi_request, mpi_reply,
619 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
620 sizeof(*config_page));
621 out:
622 return r;
626 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
627 * @ioc: per adapter object
628 * @mpi_reply: reply mf payload returned from firmware
629 * @config_page: contents of the config page
630 * Context: sleep.
632 * Return: 0 for success, non-zero for failure.
635 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
636 Mpi2ConfigReply_t *mpi_reply,
637 struct Mpi2ManufacturingPage11_t *config_page)
639 Mpi2ConfigRequest_t mpi_request;
640 int r;
642 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
643 mpi_request.Function = MPI2_FUNCTION_CONFIG;
644 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
645 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
646 mpi_request.Header.PageNumber = 11;
647 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
648 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
649 r = _config_request(ioc, &mpi_request, mpi_reply,
650 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
651 if (r)
652 goto out;
654 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
655 r = _config_request(ioc, &mpi_request, mpi_reply,
656 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
657 sizeof(*config_page));
658 out:
659 return r;
663 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
664 * @ioc: per adapter object
665 * @mpi_reply: reply mf payload returned from firmware
666 * @config_page: contents of the config page
667 * Context: sleep.
669 * Return: 0 for success, non-zero for failure.
672 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
673 Mpi2ConfigReply_t *mpi_reply,
674 struct Mpi2ManufacturingPage11_t *config_page)
676 Mpi2ConfigRequest_t mpi_request;
677 int r;
679 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
680 mpi_request.Function = MPI2_FUNCTION_CONFIG;
681 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
682 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
683 mpi_request.Header.PageNumber = 11;
684 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
685 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
686 r = _config_request(ioc, &mpi_request, mpi_reply,
687 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
688 if (r)
689 goto out;
691 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
692 r = _config_request(ioc, &mpi_request, mpi_reply,
693 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
694 sizeof(*config_page));
695 out:
696 return r;
700 * mpt3sas_config_get_bios_pg2 - obtain bios page 2
701 * @ioc: per adapter object
702 * @mpi_reply: reply mf payload returned from firmware
703 * @config_page: contents of the config page
704 * Context: sleep.
706 * Return: 0 for success, non-zero for failure.
709 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
710 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
712 Mpi2ConfigRequest_t mpi_request;
713 int r;
715 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
716 mpi_request.Function = MPI2_FUNCTION_CONFIG;
717 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
718 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
719 mpi_request.Header.PageNumber = 2;
720 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
721 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
722 r = _config_request(ioc, &mpi_request, mpi_reply,
723 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
724 if (r)
725 goto out;
727 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
728 r = _config_request(ioc, &mpi_request, mpi_reply,
729 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
730 sizeof(*config_page));
731 out:
732 return r;
736 * mpt3sas_config_get_bios_pg3 - obtain bios page 3
737 * @ioc: per adapter object
738 * @mpi_reply: reply mf payload returned from firmware
739 * @config_page: contents of the config page
740 * Context: sleep.
742 * Return: 0 for success, non-zero for failure.
745 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
746 *mpi_reply, Mpi2BiosPage3_t *config_page)
748 Mpi2ConfigRequest_t mpi_request;
749 int r;
751 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
752 mpi_request.Function = MPI2_FUNCTION_CONFIG;
753 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
754 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
755 mpi_request.Header.PageNumber = 3;
756 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
757 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
758 r = _config_request(ioc, &mpi_request, mpi_reply,
759 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
760 if (r)
761 goto out;
763 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
764 r = _config_request(ioc, &mpi_request, mpi_reply,
765 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
766 sizeof(*config_page));
767 out:
768 return r;
772 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
773 * @ioc: per adapter object
774 * @mpi_reply: reply mf payload returned from firmware
775 * @config_page: contents of the config page
776 * Context: sleep.
778 * Return: 0 for success, non-zero for failure.
781 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
782 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
784 Mpi2ConfigRequest_t mpi_request;
785 int r;
787 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
788 mpi_request.Function = MPI2_FUNCTION_CONFIG;
789 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
790 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
791 mpi_request.Header.PageNumber = 0;
792 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
793 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
794 r = _config_request(ioc, &mpi_request, mpi_reply,
795 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
796 if (r)
797 goto out;
799 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
800 r = _config_request(ioc, &mpi_request, mpi_reply,
801 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
802 sizeof(*config_page));
803 out:
804 return r;
808 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
809 * @ioc: per adapter object
810 * @mpi_reply: reply mf payload returned from firmware
811 * @config_page: contents of the config page
812 * Context: sleep.
814 * Return: 0 for success, non-zero for failure.
817 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
818 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
820 Mpi2ConfigRequest_t mpi_request;
821 int r;
823 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
824 mpi_request.Function = MPI2_FUNCTION_CONFIG;
825 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
826 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
827 mpi_request.Header.PageNumber = 1;
828 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
829 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
830 r = _config_request(ioc, &mpi_request, mpi_reply,
831 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
832 if (r)
833 goto out;
835 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
836 r = _config_request(ioc, &mpi_request, mpi_reply,
837 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
838 sizeof(*config_page));
839 out:
840 return r;
844 * mpt3sas_config_set_iounit_pg1 - set iounit page 1
845 * @ioc: per adapter object
846 * @mpi_reply: reply mf payload returned from firmware
847 * @config_page: contents of the config page
848 * Context: sleep.
850 * Return: 0 for success, non-zero for failure.
853 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
854 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
856 Mpi2ConfigRequest_t mpi_request;
857 int r;
859 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
860 mpi_request.Function = MPI2_FUNCTION_CONFIG;
861 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
862 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
863 mpi_request.Header.PageNumber = 1;
864 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
865 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
866 r = _config_request(ioc, &mpi_request, mpi_reply,
867 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
868 if (r)
869 goto out;
871 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
872 r = _config_request(ioc, &mpi_request, mpi_reply,
873 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
874 sizeof(*config_page));
875 out:
876 return r;
880 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
881 * @ioc: per adapter object
882 * @mpi_reply: reply mf payload returned from firmware
883 * @config_page: contents of the config page
884 * @sz: size of buffer passed in config_page
885 * Context: sleep.
887 * Return: 0 for success, non-zero for failure.
890 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
891 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
893 Mpi2ConfigRequest_t mpi_request;
894 int r;
896 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
897 mpi_request.Function = MPI2_FUNCTION_CONFIG;
898 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
899 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
900 mpi_request.Header.PageNumber = 3;
901 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
902 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
903 r = _config_request(ioc, &mpi_request, mpi_reply,
904 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
905 if (r)
906 goto out;
908 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
909 r = _config_request(ioc, &mpi_request, mpi_reply,
910 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
911 out:
912 return r;
916 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
917 * @ioc: per adapter object
918 * @mpi_reply: reply mf payload returned from firmware
919 * @config_page: contents of the config page
920 * Context: sleep.
922 * Return: 0 for success, non-zero for failure.
925 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
926 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
928 Mpi2ConfigRequest_t mpi_request;
929 int r;
931 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
932 mpi_request.Function = MPI2_FUNCTION_CONFIG;
933 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
934 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
935 mpi_request.Header.PageNumber = 8;
936 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
937 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
938 r = _config_request(ioc, &mpi_request, mpi_reply,
939 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
940 if (r)
941 goto out;
943 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
944 r = _config_request(ioc, &mpi_request, mpi_reply,
945 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
946 sizeof(*config_page));
947 out:
948 return r;
952 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
953 * @ioc: per adapter object
954 * @mpi_reply: reply mf payload returned from firmware
955 * @config_page: contents of the config page
956 * Context: sleep.
958 * Return: 0 for success, non-zero for failure.
961 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
962 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
964 Mpi2ConfigRequest_t mpi_request;
965 int r;
967 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
968 mpi_request.Function = MPI2_FUNCTION_CONFIG;
969 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
970 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
971 mpi_request.Header.PageNumber = 8;
972 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
973 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
974 r = _config_request(ioc, &mpi_request, mpi_reply,
975 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
976 if (r)
977 goto out;
979 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
980 r = _config_request(ioc, &mpi_request, mpi_reply,
981 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
982 sizeof(*config_page));
983 out:
984 return r;
988 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
989 * @ioc: per adapter object
990 * @mpi_reply: reply mf payload returned from firmware
991 * @config_page: contents of the config page
992 * @form: GET_NEXT_HANDLE or HANDLE
993 * @handle: device handle
994 * Context: sleep.
996 * Return: 0 for success, non-zero for failure.
999 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1000 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1001 u32 form, u32 handle)
1003 Mpi2ConfigRequest_t mpi_request;
1004 int r;
1006 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1007 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1008 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1009 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1010 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1011 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1012 mpi_request.Header.PageNumber = 0;
1013 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1014 r = _config_request(ioc, &mpi_request, mpi_reply,
1015 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1016 if (r)
1017 goto out;
1019 mpi_request.PageAddress = cpu_to_le32(form | handle);
1020 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1021 r = _config_request(ioc, &mpi_request, mpi_reply,
1022 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1023 sizeof(*config_page));
1024 out:
1025 return r;
1029 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1030 * @ioc: per adapter object
1031 * @mpi_reply: reply mf payload returned from firmware
1032 * @config_page: contents of the config page
1033 * @form: GET_NEXT_HANDLE or HANDLE
1034 * @handle: device handle
1035 * Context: sleep.
1037 * Return: 0 for success, non-zero for failure.
1040 mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1041 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1042 u32 form, u32 handle)
1044 Mpi2ConfigRequest_t mpi_request;
1045 int r;
1047 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1048 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1049 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1050 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1051 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1052 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1053 mpi_request.Header.PageNumber = 1;
1054 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1055 r = _config_request(ioc, &mpi_request, mpi_reply,
1056 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1057 if (r)
1058 goto out;
1060 mpi_request.PageAddress = cpu_to_le32(form | handle);
1061 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1062 r = _config_request(ioc, &mpi_request, mpi_reply,
1063 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1064 sizeof(*config_page));
1065 out:
1066 return r;
1070 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1071 * @ioc: per adapter object
1072 * @mpi_reply: reply mf payload returned from firmware
1073 * @config_page: contents of the config page
1074 * @form: GET_NEXT_HANDLE or HANDLE
1075 * @handle: device handle
1076 * Context: sleep.
1078 * Return: 0 for success, non-zero for failure.
1081 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1082 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1083 u32 form, u32 handle)
1085 Mpi2ConfigRequest_t mpi_request;
1086 int r;
1088 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1089 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1090 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1091 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1092 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1093 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1094 mpi_request.Header.PageNumber = 0;
1095 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1096 r = _config_request(ioc, &mpi_request, mpi_reply,
1097 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1098 if (r)
1099 goto out;
1101 mpi_request.PageAddress = cpu_to_le32(form | handle);
1102 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1103 r = _config_request(ioc, &mpi_request, mpi_reply,
1104 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1105 sizeof(*config_page));
1106 out:
1107 return r;
1111 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1112 * @ioc: per adapter object
1113 * @mpi_reply: reply mf payload returned from firmware
1114 * @config_page: contents of the config page
1115 * @form: GET_NEXT_HANDLE or HANDLE
1116 * @handle: device handle
1117 * Context: sleep.
1119 * Return: 0 for success, non-zero for failure.
1122 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1123 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1124 u32 form, u32 handle)
1126 Mpi2ConfigRequest_t mpi_request;
1127 int r;
1129 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1130 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1131 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1132 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1133 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1134 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1135 mpi_request.Header.PageNumber = 2;
1136 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1137 r = _config_request(ioc, &mpi_request, mpi_reply,
1138 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1139 if (r)
1140 goto out;
1142 mpi_request.PageAddress = cpu_to_le32(form | handle);
1143 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1144 r = _config_request(ioc, &mpi_request, mpi_reply,
1145 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1146 sizeof(*config_page));
1147 out:
1148 return r;
1152 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1153 * @ioc: per adapter object
1154 * @num_phys: pointer returned with the number of phys
1155 * Context: sleep.
1157 * Return: 0 for success, non-zero for failure.
1160 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1162 Mpi2ConfigRequest_t mpi_request;
1163 int r;
1164 u16 ioc_status;
1165 Mpi2ConfigReply_t mpi_reply;
1166 Mpi2SasIOUnitPage0_t config_page;
1168 *num_phys = 0;
1169 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1170 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1171 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1172 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1173 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1174 mpi_request.Header.PageNumber = 0;
1175 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1176 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1177 r = _config_request(ioc, &mpi_request, &mpi_reply,
1178 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1179 if (r)
1180 goto out;
1182 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1183 r = _config_request(ioc, &mpi_request, &mpi_reply,
1184 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1185 sizeof(Mpi2SasIOUnitPage0_t));
1186 if (!r) {
1187 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1188 MPI2_IOCSTATUS_MASK;
1189 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1190 *num_phys = config_page.NumPhys;
1192 out:
1193 return r;
1197 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1198 * @ioc: per adapter object
1199 * @mpi_reply: reply mf payload returned from firmware
1200 * @config_page: contents of the config page
1201 * @sz: size of buffer passed in config_page
1202 * Context: sleep.
1204 * Calling function should call config_get_number_hba_phys prior to
1205 * this function, so enough memory is allocated for config_page.
1207 * Return: 0 for success, non-zero for failure.
1210 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1211 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1212 u16 sz)
1214 Mpi2ConfigRequest_t mpi_request;
1215 int r;
1217 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1218 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1219 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1220 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1221 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1222 mpi_request.Header.PageNumber = 0;
1223 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1224 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1225 r = _config_request(ioc, &mpi_request, mpi_reply,
1226 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1227 if (r)
1228 goto out;
1230 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1231 r = _config_request(ioc, &mpi_request, mpi_reply,
1232 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1233 out:
1234 return r;
1238 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1239 * @ioc: per adapter object
1240 * @mpi_reply: reply mf payload returned from firmware
1241 * @config_page: contents of the config page
1242 * @sz: size of buffer passed in config_page
1243 * Context: sleep.
1245 * Calling function should call config_get_number_hba_phys prior to
1246 * this function, so enough memory is allocated for config_page.
1248 * Return: 0 for success, non-zero for failure.
1251 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1252 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1253 u16 sz)
1255 Mpi2ConfigRequest_t mpi_request;
1256 int r;
1258 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1259 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1260 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1261 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1262 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1263 mpi_request.Header.PageNumber = 1;
1264 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1265 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1266 r = _config_request(ioc, &mpi_request, mpi_reply,
1267 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1268 if (r)
1269 goto out;
1271 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1272 r = _config_request(ioc, &mpi_request, mpi_reply,
1273 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1274 out:
1275 return r;
1279 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1280 * @ioc: per adapter object
1281 * @mpi_reply: reply mf payload returned from firmware
1282 * @config_page: contents of the config page
1283 * @sz: size of buffer passed in config_page
1284 * Context: sleep.
1286 * Calling function should call config_get_number_hba_phys prior to
1287 * this function, so enough memory is allocated for config_page.
1289 * Return: 0 for success, non-zero for failure.
1292 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1293 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1294 u16 sz)
1296 Mpi2ConfigRequest_t mpi_request;
1297 int r;
1299 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1300 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1301 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1302 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1303 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1304 mpi_request.Header.PageNumber = 1;
1305 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1306 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1307 r = _config_request(ioc, &mpi_request, mpi_reply,
1308 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1309 if (r)
1310 goto out;
1312 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1313 _config_request(ioc, &mpi_request, mpi_reply,
1314 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1315 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1316 r = _config_request(ioc, &mpi_request, mpi_reply,
1317 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1318 out:
1319 return r;
1323 * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1324 * @ioc: per adapter object
1325 * @mpi_reply: reply mf payload returned from firmware
1326 * @config_page: contents of the config page
1327 * @form: GET_NEXT_HANDLE or HANDLE
1328 * @handle: expander handle
1329 * Context: sleep.
1331 * Return: 0 for success, non-zero for failure.
1334 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1335 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1337 Mpi2ConfigRequest_t mpi_request;
1338 int r;
1340 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1341 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1342 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1343 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1344 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1345 mpi_request.Header.PageNumber = 0;
1346 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1347 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1348 r = _config_request(ioc, &mpi_request, mpi_reply,
1349 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1350 if (r)
1351 goto out;
1353 mpi_request.PageAddress = cpu_to_le32(form | handle);
1354 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1355 r = _config_request(ioc, &mpi_request, mpi_reply,
1356 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1357 sizeof(*config_page));
1358 out:
1359 return r;
1363 * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1364 * @ioc: per adapter object
1365 * @mpi_reply: reply mf payload returned from firmware
1366 * @config_page: contents of the config page
1367 * @phy_number: phy number
1368 * @handle: expander handle
1369 * Context: sleep.
1371 * Return: 0 for success, non-zero for failure.
1374 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1375 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1376 u16 handle)
1378 Mpi2ConfigRequest_t mpi_request;
1379 int r;
1381 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1382 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1383 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1384 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1385 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1386 mpi_request.Header.PageNumber = 1;
1387 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1388 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1389 r = _config_request(ioc, &mpi_request, mpi_reply,
1390 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1391 if (r)
1392 goto out;
1394 mpi_request.PageAddress =
1395 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1396 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1397 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1398 r = _config_request(ioc, &mpi_request, mpi_reply,
1399 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1400 sizeof(*config_page));
1401 out:
1402 return r;
1406 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1407 * @ioc: per adapter object
1408 * @mpi_reply: reply mf payload returned from firmware
1409 * @config_page: contents of the config page
1410 * @form: GET_NEXT_HANDLE or HANDLE
1411 * @handle: expander handle
1412 * Context: sleep.
1414 * Return: 0 for success, non-zero for failure.
1417 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1418 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1420 Mpi2ConfigRequest_t mpi_request;
1421 int r;
1423 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1424 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1425 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1426 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1427 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1428 mpi_request.Header.PageNumber = 0;
1429 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1430 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1431 r = _config_request(ioc, &mpi_request, mpi_reply,
1432 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1433 if (r)
1434 goto out;
1436 mpi_request.PageAddress = cpu_to_le32(form | handle);
1437 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1438 r = _config_request(ioc, &mpi_request, mpi_reply,
1439 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1440 sizeof(*config_page));
1441 out:
1442 return r;
1446 * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1447 * @ioc: per adapter object
1448 * @mpi_reply: reply mf payload returned from firmware
1449 * @config_page: contents of the config page
1450 * @phy_number: phy number
1451 * Context: sleep.
1453 * Return: 0 for success, non-zero for failure.
1456 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1457 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1459 Mpi2ConfigRequest_t mpi_request;
1460 int r;
1462 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1463 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1464 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1465 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1466 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1467 mpi_request.Header.PageNumber = 0;
1468 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1469 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1470 r = _config_request(ioc, &mpi_request, mpi_reply,
1471 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1472 if (r)
1473 goto out;
1475 mpi_request.PageAddress =
1476 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1477 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1478 r = _config_request(ioc, &mpi_request, mpi_reply,
1479 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1480 sizeof(*config_page));
1481 out:
1482 return r;
1486 * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1487 * @ioc: per adapter object
1488 * @mpi_reply: reply mf payload returned from firmware
1489 * @config_page: contents of the config page
1490 * @phy_number: phy number
1491 * Context: sleep.
1493 * Return: 0 for success, non-zero for failure.
1496 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1497 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1499 Mpi2ConfigRequest_t mpi_request;
1500 int r;
1502 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1503 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1504 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1505 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1506 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1507 mpi_request.Header.PageNumber = 1;
1508 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1509 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1510 r = _config_request(ioc, &mpi_request, mpi_reply,
1511 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1512 if (r)
1513 goto out;
1515 mpi_request.PageAddress =
1516 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1517 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1518 r = _config_request(ioc, &mpi_request, mpi_reply,
1519 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1520 sizeof(*config_page));
1521 out:
1522 return r;
1526 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1527 * @ioc: per adapter object
1528 * @mpi_reply: reply mf payload returned from firmware
1529 * @config_page: contents of the config page
1530 * @form: GET_NEXT_HANDLE or HANDLE
1531 * @handle: volume handle
1532 * Context: sleep.
1534 * Return: 0 for success, non-zero for failure.
1537 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1538 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1539 u32 handle)
1541 Mpi2ConfigRequest_t mpi_request;
1542 int r;
1544 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1545 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1546 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1547 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1548 mpi_request.Header.PageNumber = 1;
1549 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1550 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1551 r = _config_request(ioc, &mpi_request, mpi_reply,
1552 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1553 if (r)
1554 goto out;
1556 mpi_request.PageAddress = cpu_to_le32(form | handle);
1557 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1558 r = _config_request(ioc, &mpi_request, mpi_reply,
1559 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1560 sizeof(*config_page));
1561 out:
1562 return r;
1566 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1567 * @ioc: per adapter object
1568 * @handle: volume handle
1569 * @num_pds: returns pds count
1570 * Context: sleep.
1572 * Return: 0 for success, non-zero for failure.
1575 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1576 u8 *num_pds)
1578 Mpi2ConfigRequest_t mpi_request;
1579 Mpi2RaidVolPage0_t config_page;
1580 Mpi2ConfigReply_t mpi_reply;
1581 int r;
1582 u16 ioc_status;
1584 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1585 *num_pds = 0;
1586 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1587 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1588 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1589 mpi_request.Header.PageNumber = 0;
1590 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1591 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1592 r = _config_request(ioc, &mpi_request, &mpi_reply,
1593 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1594 if (r)
1595 goto out;
1597 mpi_request.PageAddress =
1598 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1599 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1600 r = _config_request(ioc, &mpi_request, &mpi_reply,
1601 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1602 sizeof(Mpi2RaidVolPage0_t));
1603 if (!r) {
1604 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1605 MPI2_IOCSTATUS_MASK;
1606 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1607 *num_pds = config_page.NumPhysDisks;
1610 out:
1611 return r;
1615 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1616 * @ioc: per adapter object
1617 * @mpi_reply: reply mf payload returned from firmware
1618 * @config_page: contents of the config page
1619 * @form: GET_NEXT_HANDLE or HANDLE
1620 * @handle: volume handle
1621 * @sz: size of buffer passed in config_page
1622 * Context: sleep.
1624 * Return: 0 for success, non-zero for failure.
1627 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1628 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1629 u32 handle, u16 sz)
1631 Mpi2ConfigRequest_t mpi_request;
1632 int r;
1634 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1635 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1636 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1637 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1638 mpi_request.Header.PageNumber = 0;
1639 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1640 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1641 r = _config_request(ioc, &mpi_request, mpi_reply,
1642 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1643 if (r)
1644 goto out;
1646 mpi_request.PageAddress = cpu_to_le32(form | handle);
1647 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1648 r = _config_request(ioc, &mpi_request, mpi_reply,
1649 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1650 out:
1651 return r;
1655 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1656 * @ioc: per adapter object
1657 * @mpi_reply: reply mf payload returned from firmware
1658 * @config_page: contents of the config page
1659 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1660 * @form_specific: specific to the form
1661 * Context: sleep.
1663 * Return: 0 for success, non-zero for failure.
1666 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1667 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1668 u32 form_specific)
1670 Mpi2ConfigRequest_t mpi_request;
1671 int r;
1673 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1674 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1675 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1676 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1677 mpi_request.Header.PageNumber = 0;
1678 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1679 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1680 r = _config_request(ioc, &mpi_request, mpi_reply,
1681 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1682 if (r)
1683 goto out;
1685 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1686 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1687 r = _config_request(ioc, &mpi_request, mpi_reply,
1688 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1689 sizeof(*config_page));
1690 out:
1691 return r;
1695 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
1696 * raid components
1697 * @ioc: per adapter object
1698 * @pd_handle: phys disk handle
1699 * @volume_handle: volume handle
1700 * Context: sleep.
1702 * Return: 0 for success, non-zero for failure.
1705 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
1706 u16 *volume_handle)
1708 Mpi2RaidConfigurationPage0_t *config_page = NULL;
1709 Mpi2ConfigRequest_t mpi_request;
1710 Mpi2ConfigReply_t mpi_reply;
1711 int r, i, config_page_sz;
1712 u16 ioc_status;
1713 int config_num;
1714 u16 element_type;
1715 u16 phys_disk_dev_handle;
1717 *volume_handle = 0;
1718 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1719 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1720 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1721 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1722 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1723 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1724 mpi_request.Header.PageNumber = 0;
1725 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1726 r = _config_request(ioc, &mpi_request, &mpi_reply,
1727 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1728 if (r)
1729 goto out;
1731 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1732 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
1733 config_page = kmalloc(config_page_sz, GFP_KERNEL);
1734 if (!config_page) {
1735 r = -1;
1736 goto out;
1739 config_num = 0xff;
1740 while (1) {
1741 mpi_request.PageAddress = cpu_to_le32(config_num +
1742 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
1743 r = _config_request(ioc, &mpi_request, &mpi_reply,
1744 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1745 config_page_sz);
1746 if (r)
1747 goto out;
1748 r = -1;
1749 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1750 MPI2_IOCSTATUS_MASK;
1751 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1752 goto out;
1753 for (i = 0; i < config_page->NumElements; i++) {
1754 element_type = le16_to_cpu(config_page->
1755 ConfigElement[i].ElementFlags) &
1756 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
1757 if (element_type ==
1758 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
1759 element_type ==
1760 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
1761 phys_disk_dev_handle =
1762 le16_to_cpu(config_page->ConfigElement[i].
1763 PhysDiskDevHandle);
1764 if (phys_disk_dev_handle == pd_handle) {
1765 *volume_handle =
1766 le16_to_cpu(config_page->
1767 ConfigElement[i].VolDevHandle);
1768 r = 0;
1769 goto out;
1771 } else if (element_type ==
1772 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
1773 *volume_handle = 0;
1774 r = 0;
1775 goto out;
1778 config_num = config_page->ConfigNum;
1780 out:
1781 kfree(config_page);
1782 return r;
1786 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
1787 * @ioc: per adapter object
1788 * @volume_handle: volume handle
1789 * @wwid: volume wwid
1790 * Context: sleep.
1792 * Return: 0 for success, non-zero for failure.
1795 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
1796 u64 *wwid)
1798 Mpi2ConfigReply_t mpi_reply;
1799 Mpi2RaidVolPage1_t raid_vol_pg1;
1801 *wwid = 0;
1802 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1803 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1804 volume_handle))) {
1805 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
1806 return 0;
1807 } else
1808 return -1;