treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / scsi / mpt3sas / mpt3sas_config.c
blob62ddf53ab3aea1b742d5a1373ce48202411d9ba3
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 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;
169 break;
172 if (!desc)
173 return;
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);
180 if (!mpi_reply)
181 return;
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));
190 * _config_alloc_config_dma_memory - obtain physical memory
191 * @ioc: per adapter object
192 * @mem: struct config_request
194 * A wrapper for obtaining dma-able memory for config page request.
196 * Return: 0 for success, non-zero for failure.
198 static int
199 _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
200 struct config_request *mem)
202 int r = 0;
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;
212 } else { /* use tmp buffer if less than 512 bytes */
213 mem->page = ioc->config_page;
214 mem->page_dma = ioc->config_page_dma;
216 ioc->config_vaddr = mem->page;
217 return r;
221 * _config_free_config_dma_memory - wrapper to free the memory
222 * @ioc: per adapter object
223 * @mem: struct config_request
225 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
227 * Return: 0 for success, non-zero for failure.
229 static void
230 _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
231 struct config_request *mem)
233 if (mem->sz > ioc->config_page_sz)
234 dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
235 mem->page_dma);
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.
246 * The callback handler when using _config_request.
248 * Return: 1 meaning mf should be freed from _base_interrupt
249 * 0 means the mf is freed from this function.
252 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
253 u32 reply)
255 MPI2DefaultReply_t *mpi_reply;
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);
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;
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
286 * A generic API for config page requests to firmware.
288 * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
289 * this API.
291 * The callback index is set inside `ioc->config_cb_idx.
293 * Return: 0 for success, non-zero for failure.
295 static int
296 _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
297 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
298 void *config_page, u16 config_page_sz)
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 u8 issue_reset = 0;
308 mutex_lock(&ioc->config_cmds.mutex);
309 if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
310 ioc_err(ioc, "%s: config_cmd in use\n", __func__);
311 mutex_unlock(&ioc->config_cmds.mutex);
312 return -EAGAIN;
315 retry_count = 0;
316 memset(&mem, 0, sizeof(struct config_request));
318 mpi_request->VF_ID = 0; /* TODO */
319 mpi_request->VP_ID = 0;
321 if (config_page) {
322 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
323 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
324 mpi_request->Header.PageType = mpi_reply->Header.PageType;
325 mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
326 mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
327 mpi_request->ExtPageType = mpi_reply->ExtPageType;
328 if (mpi_request->Header.PageLength)
329 mem.sz = mpi_request->Header.PageLength * 4;
330 else
331 mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
332 r = _config_alloc_config_dma_memory(ioc, &mem);
333 if (r != 0)
334 goto out;
335 if (mpi_request->Action ==
336 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
337 mpi_request->Action ==
338 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
339 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
340 MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
341 mem.page_dma);
342 memcpy(mem.page, config_page, min_t(u16, mem.sz,
343 config_page_sz));
344 } else {
345 memset(config_page, 0, config_page_sz);
346 ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
347 MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
348 memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
352 retry_config:
353 if (retry_count) {
354 if (retry_count > 2) { /* attempt only 2 retries */
355 r = -EFAULT;
356 goto free_mem;
358 ioc_info(ioc, "%s: attempting retry (%d)\n",
359 __func__, retry_count);
362 r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
363 if (r)
364 goto free_mem;
366 smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
367 if (!smid) {
368 ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
369 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
370 r = -EAGAIN;
371 goto free_mem;
374 r = 0;
375 memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
376 ioc->config_cmds.status = MPT3_CMD_PENDING;
377 config_request = mpt3sas_base_get_msg_frame(ioc, smid);
378 ioc->config_cmds.smid = smid;
379 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
380 if (ioc->logging_level & MPT_DEBUG_CONFIG)
381 _config_display_some_debug(ioc, smid, "config_request", NULL);
382 init_completion(&ioc->config_cmds.done);
383 ioc->put_smid_default(ioc, smid);
384 wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
385 if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
386 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
387 _config_display_some_debug(ioc,
388 smid, "config_request", NULL);
389 mpt3sas_check_cmd_timeout(ioc,
390 ioc->config_cmds.status, mpi_request,
391 sizeof(Mpi2ConfigRequest_t)/4, issue_reset);
392 retry_count++;
393 if (ioc->config_cmds.smid == smid)
394 mpt3sas_base_free_smid(ioc, smid);
395 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
396 MPT3_CMD_RESET) || ioc->pci_error_recovery)
397 goto retry_config;
398 issue_host_reset = 1;
399 r = -EFAULT;
400 goto free_mem;
403 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
404 memcpy(mpi_reply, ioc->config_cmds.reply,
405 sizeof(Mpi2ConfigReply_t));
407 /* Reply Frame Sanity Checks to workaround FW issues */
408 if ((mpi_request->Header.PageType & 0xF) !=
409 (mpi_reply->Header.PageType & 0xF)) {
410 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
411 _config_display_some_debug(ioc,
412 smid, "config_request", NULL);
413 _debug_dump_mf(mpi_request, ioc->request_sz/4);
414 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
415 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
416 ioc->name, __func__,
417 mpi_request->Header.PageType & 0xF,
418 mpi_reply->Header.PageType & 0xF);
421 if (((mpi_request->Header.PageType & 0xF) ==
422 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
423 mpi_request->ExtPageType != mpi_reply->ExtPageType) {
424 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
425 _config_display_some_debug(ioc,
426 smid, "config_request", NULL);
427 _debug_dump_mf(mpi_request, ioc->request_sz/4);
428 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
429 panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
430 ioc->name, __func__,
431 mpi_request->ExtPageType,
432 mpi_reply->ExtPageType);
434 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
435 & MPI2_IOCSTATUS_MASK;
438 if (retry_count)
439 ioc_info(ioc, "%s: retry (%d) completed!!\n",
440 __func__, retry_count);
442 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
443 config_page && mpi_request->Action ==
444 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
445 u8 *p = (u8 *)mem.page;
447 /* Config Page Sanity Checks to workaround FW issues */
448 if (p) {
449 if ((mpi_request->Header.PageType & 0xF) !=
450 (p[3] & 0xF)) {
451 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
452 _config_display_some_debug(ioc,
453 smid, "config_request", NULL);
454 _debug_dump_mf(mpi_request, ioc->request_sz/4);
455 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
456 _debug_dump_config(p, min_t(u16, mem.sz,
457 config_page_sz)/4);
458 panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
459 ioc->name, __func__,
460 mpi_request->Header.PageType & 0xF,
461 p[3] & 0xF);
464 if (((mpi_request->Header.PageType & 0xF) ==
465 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
466 (mpi_request->ExtPageType != p[6])) {
467 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
468 _config_display_some_debug(ioc,
469 smid, "config_request", NULL);
470 _debug_dump_mf(mpi_request, ioc->request_sz/4);
471 _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
472 _debug_dump_config(p, min_t(u16, mem.sz,
473 config_page_sz)/4);
474 panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
475 ioc->name, __func__,
476 mpi_request->ExtPageType, p[6]);
479 memcpy(config_page, mem.page, min_t(u16, mem.sz,
480 config_page_sz));
483 free_mem:
484 if (config_page)
485 _config_free_config_dma_memory(ioc, &mem);
486 out:
487 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
488 mutex_unlock(&ioc->config_cmds.mutex);
490 if (issue_host_reset)
491 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
492 return r;
496 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
497 * @ioc: per adapter object
498 * @mpi_reply: reply mf payload returned from firmware
499 * @config_page: contents of the config page
500 * Context: sleep.
502 * Return: 0 for success, non-zero for failure.
505 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
506 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
508 Mpi2ConfigRequest_t mpi_request;
509 int r;
511 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
512 mpi_request.Function = MPI2_FUNCTION_CONFIG;
513 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
514 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
515 mpi_request.Header.PageNumber = 0;
516 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
517 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
518 r = _config_request(ioc, &mpi_request, mpi_reply,
519 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
520 if (r)
521 goto out;
523 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
524 r = _config_request(ioc, &mpi_request, mpi_reply,
525 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
526 sizeof(*config_page));
527 out:
528 return r;
532 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
533 * @ioc: per adapter object
534 * @mpi_reply: reply mf payload returned from firmware
535 * @config_page: contents of the config page
536 * @sz: size of buffer passed in config_page
537 * Context: sleep.
539 * Return: 0 for success, non-zero for failure.
542 mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
543 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
544 u16 sz)
546 Mpi2ConfigRequest_t mpi_request;
547 int r;
549 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
550 mpi_request.Function = MPI2_FUNCTION_CONFIG;
551 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
552 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
553 mpi_request.Header.PageNumber = 7;
554 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
555 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
556 r = _config_request(ioc, &mpi_request, mpi_reply,
557 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
558 if (r)
559 goto out;
561 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
562 r = _config_request(ioc, &mpi_request, mpi_reply,
563 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
564 sz);
565 out:
566 return r;
570 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
571 * @ioc: per adapter object
572 * @mpi_reply: reply mf payload returned from firmware
573 * @config_page: contents of the config page
574 * Context: sleep.
576 * Return: 0 for success, non-zero for failure.
579 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
580 Mpi2ConfigReply_t *mpi_reply,
581 struct Mpi2ManufacturingPage10_t *config_page)
583 Mpi2ConfigRequest_t mpi_request;
584 int r;
586 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
587 mpi_request.Function = MPI2_FUNCTION_CONFIG;
588 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
589 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
590 mpi_request.Header.PageNumber = 10;
591 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
592 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
593 r = _config_request(ioc, &mpi_request, mpi_reply,
594 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
595 if (r)
596 goto out;
598 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
599 r = _config_request(ioc, &mpi_request, mpi_reply,
600 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
601 sizeof(*config_page));
602 out:
603 return r;
607 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
608 * @ioc: per adapter object
609 * @mpi_reply: reply mf payload returned from firmware
610 * @config_page: contents of the config page
611 * Context: sleep.
613 * Return: 0 for success, non-zero for failure.
616 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
617 Mpi2ConfigReply_t *mpi_reply,
618 struct Mpi2ManufacturingPage11_t *config_page)
620 Mpi2ConfigRequest_t mpi_request;
621 int r;
623 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
624 mpi_request.Function = MPI2_FUNCTION_CONFIG;
625 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
626 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
627 mpi_request.Header.PageNumber = 11;
628 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
629 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
630 r = _config_request(ioc, &mpi_request, mpi_reply,
631 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
632 if (r)
633 goto out;
635 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
636 r = _config_request(ioc, &mpi_request, mpi_reply,
637 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
638 sizeof(*config_page));
639 out:
640 return r;
644 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
645 * @ioc: per adapter object
646 * @mpi_reply: reply mf payload returned from firmware
647 * @config_page: contents of the config page
648 * Context: sleep.
650 * Return: 0 for success, non-zero for failure.
653 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
654 Mpi2ConfigReply_t *mpi_reply,
655 struct Mpi2ManufacturingPage11_t *config_page)
657 Mpi2ConfigRequest_t mpi_request;
658 int r;
660 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
661 mpi_request.Function = MPI2_FUNCTION_CONFIG;
662 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
663 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
664 mpi_request.Header.PageNumber = 11;
665 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
666 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
667 r = _config_request(ioc, &mpi_request, mpi_reply,
668 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
669 if (r)
670 goto out;
672 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
673 r = _config_request(ioc, &mpi_request, mpi_reply,
674 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
675 sizeof(*config_page));
676 out:
677 return r;
681 * mpt3sas_config_get_bios_pg2 - obtain bios page 2
682 * @ioc: per adapter object
683 * @mpi_reply: reply mf payload returned from firmware
684 * @config_page: contents of the config page
685 * Context: sleep.
687 * Return: 0 for success, non-zero for failure.
690 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
691 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
693 Mpi2ConfigRequest_t mpi_request;
694 int r;
696 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
697 mpi_request.Function = MPI2_FUNCTION_CONFIG;
698 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
699 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
700 mpi_request.Header.PageNumber = 2;
701 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
702 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
703 r = _config_request(ioc, &mpi_request, mpi_reply,
704 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
705 if (r)
706 goto out;
708 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
709 r = _config_request(ioc, &mpi_request, mpi_reply,
710 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
711 sizeof(*config_page));
712 out:
713 return r;
717 * mpt3sas_config_get_bios_pg3 - obtain bios page 3
718 * @ioc: per adapter object
719 * @mpi_reply: reply mf payload returned from firmware
720 * @config_page: contents of the config page
721 * Context: sleep.
723 * Return: 0 for success, non-zero for failure.
726 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
727 *mpi_reply, Mpi2BiosPage3_t *config_page)
729 Mpi2ConfigRequest_t mpi_request;
730 int r;
732 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
733 mpi_request.Function = MPI2_FUNCTION_CONFIG;
734 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
735 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
736 mpi_request.Header.PageNumber = 3;
737 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
738 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
739 r = _config_request(ioc, &mpi_request, mpi_reply,
740 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
741 if (r)
742 goto out;
744 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
745 r = _config_request(ioc, &mpi_request, mpi_reply,
746 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
747 sizeof(*config_page));
748 out:
749 return r;
753 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
754 * @ioc: per adapter object
755 * @mpi_reply: reply mf payload returned from firmware
756 * @config_page: contents of the config page
757 * Context: sleep.
759 * Return: 0 for success, non-zero for failure.
762 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
763 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
765 Mpi2ConfigRequest_t mpi_request;
766 int r;
768 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
769 mpi_request.Function = MPI2_FUNCTION_CONFIG;
770 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
771 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
772 mpi_request.Header.PageNumber = 0;
773 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
774 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
775 r = _config_request(ioc, &mpi_request, mpi_reply,
776 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
777 if (r)
778 goto out;
780 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
781 r = _config_request(ioc, &mpi_request, mpi_reply,
782 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
783 sizeof(*config_page));
784 out:
785 return r;
789 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
790 * @ioc: per adapter object
791 * @mpi_reply: reply mf payload returned from firmware
792 * @config_page: contents of the config page
793 * Context: sleep.
795 * Return: 0 for success, non-zero for failure.
798 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
799 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
801 Mpi2ConfigRequest_t mpi_request;
802 int r;
804 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
805 mpi_request.Function = MPI2_FUNCTION_CONFIG;
806 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
807 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
808 mpi_request.Header.PageNumber = 1;
809 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
810 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
811 r = _config_request(ioc, &mpi_request, mpi_reply,
812 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
813 if (r)
814 goto out;
816 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
817 r = _config_request(ioc, &mpi_request, mpi_reply,
818 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
819 sizeof(*config_page));
820 out:
821 return r;
825 * mpt3sas_config_set_iounit_pg1 - set iounit page 1
826 * @ioc: per adapter object
827 * @mpi_reply: reply mf payload returned from firmware
828 * @config_page: contents of the config page
829 * Context: sleep.
831 * Return: 0 for success, non-zero for failure.
834 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
835 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
837 Mpi2ConfigRequest_t mpi_request;
838 int r;
840 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
841 mpi_request.Function = MPI2_FUNCTION_CONFIG;
842 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
843 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
844 mpi_request.Header.PageNumber = 1;
845 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
846 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
847 r = _config_request(ioc, &mpi_request, mpi_reply,
848 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
849 if (r)
850 goto out;
852 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
853 r = _config_request(ioc, &mpi_request, mpi_reply,
854 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
855 sizeof(*config_page));
856 out:
857 return r;
861 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
862 * @ioc: per adapter object
863 * @mpi_reply: reply mf payload returned from firmware
864 * @config_page: contents of the config page
865 * @sz: size of buffer passed in config_page
866 * Context: sleep.
868 * Return: 0 for success, non-zero for failure.
871 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
872 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
874 Mpi2ConfigRequest_t mpi_request;
875 int r;
877 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
878 mpi_request.Function = MPI2_FUNCTION_CONFIG;
879 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
880 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
881 mpi_request.Header.PageNumber = 3;
882 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
883 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
884 r = _config_request(ioc, &mpi_request, mpi_reply,
885 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
886 if (r)
887 goto out;
889 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
890 r = _config_request(ioc, &mpi_request, mpi_reply,
891 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
892 out:
893 return r;
897 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
898 * @ioc: per adapter object
899 * @mpi_reply: reply mf payload returned from firmware
900 * @config_page: contents of the config page
901 * Context: sleep.
903 * Return: 0 for success, non-zero for failure.
906 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
907 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
909 Mpi2ConfigRequest_t mpi_request;
910 int r;
912 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
913 mpi_request.Function = MPI2_FUNCTION_CONFIG;
914 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
915 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
916 mpi_request.Header.PageNumber = 8;
917 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
918 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
919 r = _config_request(ioc, &mpi_request, mpi_reply,
920 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
921 if (r)
922 goto out;
924 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
925 r = _config_request(ioc, &mpi_request, mpi_reply,
926 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
927 sizeof(*config_page));
928 out:
929 return r;
933 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
934 * @ioc: per adapter object
935 * @mpi_reply: reply mf payload returned from firmware
936 * @config_page: contents of the config page
937 * Context: sleep.
939 * Return: 0 for success, non-zero for failure.
942 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
943 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
945 Mpi2ConfigRequest_t mpi_request;
946 int r;
948 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
949 mpi_request.Function = MPI2_FUNCTION_CONFIG;
950 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
951 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
952 mpi_request.Header.PageNumber = 8;
953 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
954 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
955 r = _config_request(ioc, &mpi_request, mpi_reply,
956 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
957 if (r)
958 goto out;
960 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
961 r = _config_request(ioc, &mpi_request, mpi_reply,
962 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
963 sizeof(*config_page));
964 out:
965 return r;
968 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
969 * @ioc: per adapter object
970 * @mpi_reply: reply mf payload returned from firmware
971 * @config_page: contents of the config page
972 * Context: sleep.
974 * Return: 0 for success, non-zero for failure.
977 mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
978 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
980 Mpi2ConfigRequest_t mpi_request;
981 int r;
983 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
984 mpi_request.Function = MPI2_FUNCTION_CONFIG;
985 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
986 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
987 mpi_request.Header.PageNumber = 1;
988 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
989 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
990 r = _config_request(ioc, &mpi_request, mpi_reply,
991 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
992 if (r)
993 goto out;
995 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
996 r = _config_request(ioc, &mpi_request, mpi_reply,
997 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
998 sizeof(*config_page));
999 out:
1000 return r;
1004 * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
1005 * @ioc: per adapter object
1006 * @mpi_reply: reply mf payload returned from firmware
1007 * @config_page: contents of the config page
1008 * Context: sleep.
1010 * Return: 0 for success, non-zero for failure.
1013 mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
1014 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
1016 Mpi2ConfigRequest_t mpi_request;
1017 int r;
1019 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1020 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1021 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1022 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
1023 mpi_request.Header.PageNumber = 1;
1024 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
1025 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1026 r = _config_request(ioc, &mpi_request, mpi_reply,
1027 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1028 if (r)
1029 goto out;
1031 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1032 r = _config_request(ioc, &mpi_request, mpi_reply,
1033 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1034 sizeof(*config_page));
1035 out:
1036 return r;
1040 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
1041 * @ioc: per adapter object
1042 * @mpi_reply: reply mf payload returned from firmware
1043 * @config_page: contents of the config page
1044 * @form: GET_NEXT_HANDLE or HANDLE
1045 * @handle: device handle
1046 * Context: sleep.
1048 * Return: 0 for success, non-zero for failure.
1051 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1052 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1053 u32 form, u32 handle)
1055 Mpi2ConfigRequest_t mpi_request;
1056 int r;
1058 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1059 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1060 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1061 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1062 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1063 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1064 mpi_request.Header.PageNumber = 0;
1065 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1066 r = _config_request(ioc, &mpi_request, mpi_reply,
1067 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1068 if (r)
1069 goto out;
1071 mpi_request.PageAddress = cpu_to_le32(form | handle);
1072 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1073 r = _config_request(ioc, &mpi_request, mpi_reply,
1074 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1075 sizeof(*config_page));
1076 out:
1077 return r;
1081 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1082 * @ioc: per adapter object
1083 * @mpi_reply: reply mf payload returned from firmware
1084 * @config_page: contents of the config page
1085 * @form: GET_NEXT_HANDLE or HANDLE
1086 * @handle: device handle
1087 * Context: sleep.
1089 * Return: 0 for success, non-zero for failure.
1092 mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1093 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1094 u32 form, u32 handle)
1096 Mpi2ConfigRequest_t mpi_request;
1097 int r;
1099 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1100 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1101 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1102 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1103 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1104 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1105 mpi_request.Header.PageNumber = 1;
1106 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1107 r = _config_request(ioc, &mpi_request, mpi_reply,
1108 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1109 if (r)
1110 goto out;
1112 mpi_request.PageAddress = cpu_to_le32(form | handle);
1113 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1114 r = _config_request(ioc, &mpi_request, mpi_reply,
1115 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1116 sizeof(*config_page));
1117 out:
1118 return r;
1122 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1123 * @ioc: per adapter object
1124 * @mpi_reply: reply mf payload returned from firmware
1125 * @config_page: contents of the config page
1126 * @form: GET_NEXT_HANDLE or HANDLE
1127 * @handle: device handle
1128 * Context: sleep.
1130 * Return: 0 for success, non-zero for failure.
1133 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1134 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1135 u32 form, u32 handle)
1137 Mpi2ConfigRequest_t mpi_request;
1138 int r;
1140 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1141 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1142 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1143 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1144 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1145 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1146 mpi_request.Header.PageNumber = 0;
1147 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1148 r = _config_request(ioc, &mpi_request, mpi_reply,
1149 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1150 if (r)
1151 goto out;
1153 mpi_request.PageAddress = cpu_to_le32(form | handle);
1154 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1155 r = _config_request(ioc, &mpi_request, mpi_reply,
1156 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1157 sizeof(*config_page));
1158 out:
1159 return r;
1163 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1164 * @ioc: per adapter object
1165 * @mpi_reply: reply mf payload returned from firmware
1166 * @config_page: contents of the config page
1167 * @form: GET_NEXT_HANDLE or HANDLE
1168 * @handle: device handle
1169 * Context: sleep.
1171 * Return: 0 for success, non-zero for failure.
1174 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1175 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1176 u32 form, u32 handle)
1178 Mpi2ConfigRequest_t mpi_request;
1179 int r;
1181 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1182 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1183 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1184 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1185 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1186 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1187 mpi_request.Header.PageNumber = 2;
1188 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1189 r = _config_request(ioc, &mpi_request, mpi_reply,
1190 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1191 if (r)
1192 goto out;
1194 mpi_request.PageAddress = cpu_to_le32(form | handle);
1195 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1196 r = _config_request(ioc, &mpi_request, mpi_reply,
1197 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1198 sizeof(*config_page));
1199 out:
1200 return r;
1204 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1205 * @ioc: per adapter object
1206 * @num_phys: pointer returned with the number of phys
1207 * Context: sleep.
1209 * Return: 0 for success, non-zero for failure.
1212 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1214 Mpi2ConfigRequest_t mpi_request;
1215 int r;
1216 u16 ioc_status;
1217 Mpi2ConfigReply_t mpi_reply;
1218 Mpi2SasIOUnitPage0_t config_page;
1220 *num_phys = 0;
1221 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1222 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1223 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1224 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1225 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1226 mpi_request.Header.PageNumber = 0;
1227 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1228 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1229 r = _config_request(ioc, &mpi_request, &mpi_reply,
1230 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1231 if (r)
1232 goto out;
1234 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1235 r = _config_request(ioc, &mpi_request, &mpi_reply,
1236 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1237 sizeof(Mpi2SasIOUnitPage0_t));
1238 if (!r) {
1239 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1240 MPI2_IOCSTATUS_MASK;
1241 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1242 *num_phys = config_page.NumPhys;
1244 out:
1245 return r;
1249 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1250 * @ioc: per adapter object
1251 * @mpi_reply: reply mf payload returned from firmware
1252 * @config_page: contents of the config page
1253 * @sz: size of buffer passed in config_page
1254 * Context: sleep.
1256 * Calling function should call config_get_number_hba_phys prior to
1257 * this function, so enough memory is allocated for config_page.
1259 * Return: 0 for success, non-zero for failure.
1262 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1263 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1264 u16 sz)
1266 Mpi2ConfigRequest_t mpi_request;
1267 int r;
1269 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1270 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1271 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1272 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1273 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1274 mpi_request.Header.PageNumber = 0;
1275 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1276 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1277 r = _config_request(ioc, &mpi_request, mpi_reply,
1278 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1279 if (r)
1280 goto out;
1282 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1283 r = _config_request(ioc, &mpi_request, mpi_reply,
1284 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1285 out:
1286 return r;
1290 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1291 * @ioc: per adapter object
1292 * @mpi_reply: reply mf payload returned from firmware
1293 * @config_page: contents of the config page
1294 * @sz: size of buffer passed in config_page
1295 * Context: sleep.
1297 * Calling function should call config_get_number_hba_phys prior to
1298 * this function, so enough memory is allocated for config_page.
1300 * Return: 0 for success, non-zero for failure.
1303 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1304 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1305 u16 sz)
1307 Mpi2ConfigRequest_t mpi_request;
1308 int r;
1310 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1311 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1312 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1313 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1314 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1315 mpi_request.Header.PageNumber = 1;
1316 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1317 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1318 r = _config_request(ioc, &mpi_request, mpi_reply,
1319 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1320 if (r)
1321 goto out;
1323 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1324 r = _config_request(ioc, &mpi_request, mpi_reply,
1325 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1326 out:
1327 return r;
1331 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1332 * @ioc: per adapter object
1333 * @mpi_reply: reply mf payload returned from firmware
1334 * @config_page: contents of the config page
1335 * @sz: size of buffer passed in config_page
1336 * Context: sleep.
1338 * Calling function should call config_get_number_hba_phys prior to
1339 * this function, so enough memory is allocated for config_page.
1341 * Return: 0 for success, non-zero for failure.
1344 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1345 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1346 u16 sz)
1348 Mpi2ConfigRequest_t mpi_request;
1349 int r;
1351 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1352 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1353 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1354 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1355 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1356 mpi_request.Header.PageNumber = 1;
1357 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1358 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1359 r = _config_request(ioc, &mpi_request, mpi_reply,
1360 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1361 if (r)
1362 goto out;
1364 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1365 _config_request(ioc, &mpi_request, mpi_reply,
1366 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1367 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1368 r = _config_request(ioc, &mpi_request, mpi_reply,
1369 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1370 out:
1371 return r;
1375 * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1376 * @ioc: per adapter object
1377 * @mpi_reply: reply mf payload returned from firmware
1378 * @config_page: contents of the config page
1379 * @form: GET_NEXT_HANDLE or HANDLE
1380 * @handle: expander handle
1381 * Context: sleep.
1383 * Return: 0 for success, non-zero for failure.
1386 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1387 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1389 Mpi2ConfigRequest_t mpi_request;
1390 int r;
1392 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1393 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1394 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1395 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1396 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1397 mpi_request.Header.PageNumber = 0;
1398 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1399 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1400 r = _config_request(ioc, &mpi_request, mpi_reply,
1401 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1402 if (r)
1403 goto out;
1405 mpi_request.PageAddress = cpu_to_le32(form | handle);
1406 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1407 r = _config_request(ioc, &mpi_request, mpi_reply,
1408 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1409 sizeof(*config_page));
1410 out:
1411 return r;
1415 * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1416 * @ioc: per adapter object
1417 * @mpi_reply: reply mf payload returned from firmware
1418 * @config_page: contents of the config page
1419 * @phy_number: phy number
1420 * @handle: expander handle
1421 * Context: sleep.
1423 * Return: 0 for success, non-zero for failure.
1426 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1427 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1428 u16 handle)
1430 Mpi2ConfigRequest_t mpi_request;
1431 int r;
1433 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1434 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1435 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1436 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1437 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1438 mpi_request.Header.PageNumber = 1;
1439 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1440 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1441 r = _config_request(ioc, &mpi_request, mpi_reply,
1442 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1443 if (r)
1444 goto out;
1446 mpi_request.PageAddress =
1447 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1448 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1449 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1450 r = _config_request(ioc, &mpi_request, mpi_reply,
1451 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1452 sizeof(*config_page));
1453 out:
1454 return r;
1458 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1459 * @ioc: per adapter object
1460 * @mpi_reply: reply mf payload returned from firmware
1461 * @config_page: contents of the config page
1462 * @form: GET_NEXT_HANDLE or HANDLE
1463 * @handle: expander handle
1464 * Context: sleep.
1466 * Return: 0 for success, non-zero for failure.
1469 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1470 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1472 Mpi2ConfigRequest_t mpi_request;
1473 int r;
1475 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1476 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1477 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1478 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1479 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1480 mpi_request.Header.PageNumber = 0;
1481 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1482 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1483 r = _config_request(ioc, &mpi_request, mpi_reply,
1484 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1485 if (r)
1486 goto out;
1488 mpi_request.PageAddress = cpu_to_le32(form | handle);
1489 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1490 r = _config_request(ioc, &mpi_request, mpi_reply,
1491 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1492 sizeof(*config_page));
1493 out:
1494 return r;
1498 * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1499 * @ioc: per adapter object
1500 * @mpi_reply: reply mf payload returned from firmware
1501 * @config_page: contents of the config page
1502 * @phy_number: phy number
1503 * Context: sleep.
1505 * Return: 0 for success, non-zero for failure.
1508 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1509 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1511 Mpi2ConfigRequest_t mpi_request;
1512 int r;
1514 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1515 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1516 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1517 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1518 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1519 mpi_request.Header.PageNumber = 0;
1520 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1521 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1522 r = _config_request(ioc, &mpi_request, mpi_reply,
1523 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1524 if (r)
1525 goto out;
1527 mpi_request.PageAddress =
1528 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1529 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1530 r = _config_request(ioc, &mpi_request, mpi_reply,
1531 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1532 sizeof(*config_page));
1533 out:
1534 return r;
1538 * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1539 * @ioc: per adapter object
1540 * @mpi_reply: reply mf payload returned from firmware
1541 * @config_page: contents of the config page
1542 * @phy_number: phy number
1543 * Context: sleep.
1545 * Return: 0 for success, non-zero for failure.
1548 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1549 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1551 Mpi2ConfigRequest_t mpi_request;
1552 int r;
1554 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1555 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1556 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1557 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1558 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1559 mpi_request.Header.PageNumber = 1;
1560 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1561 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1562 r = _config_request(ioc, &mpi_request, mpi_reply,
1563 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1564 if (r)
1565 goto out;
1567 mpi_request.PageAddress =
1568 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1569 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1570 r = _config_request(ioc, &mpi_request, mpi_reply,
1571 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1572 sizeof(*config_page));
1573 out:
1574 return r;
1578 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1579 * @ioc: per adapter object
1580 * @mpi_reply: reply mf payload returned from firmware
1581 * @config_page: contents of the config page
1582 * @form: GET_NEXT_HANDLE or HANDLE
1583 * @handle: volume handle
1584 * Context: sleep.
1586 * Return: 0 for success, non-zero for failure.
1589 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1590 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1591 u32 handle)
1593 Mpi2ConfigRequest_t mpi_request;
1594 int r;
1596 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1597 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1598 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1599 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1600 mpi_request.Header.PageNumber = 1;
1601 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1602 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1603 r = _config_request(ioc, &mpi_request, mpi_reply,
1604 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1605 if (r)
1606 goto out;
1608 mpi_request.PageAddress = cpu_to_le32(form | handle);
1609 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1610 r = _config_request(ioc, &mpi_request, mpi_reply,
1611 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1612 sizeof(*config_page));
1613 out:
1614 return r;
1618 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1619 * @ioc: per adapter object
1620 * @handle: volume handle
1621 * @num_pds: returns pds count
1622 * Context: sleep.
1624 * Return: 0 for success, non-zero for failure.
1627 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1628 u8 *num_pds)
1630 Mpi2ConfigRequest_t mpi_request;
1631 Mpi2RaidVolPage0_t config_page;
1632 Mpi2ConfigReply_t mpi_reply;
1633 int r;
1634 u16 ioc_status;
1636 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1637 *num_pds = 0;
1638 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1639 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1640 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1641 mpi_request.Header.PageNumber = 0;
1642 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1643 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1644 r = _config_request(ioc, &mpi_request, &mpi_reply,
1645 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1646 if (r)
1647 goto out;
1649 mpi_request.PageAddress =
1650 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1651 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1652 r = _config_request(ioc, &mpi_request, &mpi_reply,
1653 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1654 sizeof(Mpi2RaidVolPage0_t));
1655 if (!r) {
1656 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1657 MPI2_IOCSTATUS_MASK;
1658 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1659 *num_pds = config_page.NumPhysDisks;
1662 out:
1663 return r;
1667 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1668 * @ioc: per adapter object
1669 * @mpi_reply: reply mf payload returned from firmware
1670 * @config_page: contents of the config page
1671 * @form: GET_NEXT_HANDLE or HANDLE
1672 * @handle: volume handle
1673 * @sz: size of buffer passed in config_page
1674 * Context: sleep.
1676 * Return: 0 for success, non-zero for failure.
1679 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1680 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1681 u32 handle, u16 sz)
1683 Mpi2ConfigRequest_t mpi_request;
1684 int r;
1686 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1687 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1688 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1689 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1690 mpi_request.Header.PageNumber = 0;
1691 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1692 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1693 r = _config_request(ioc, &mpi_request, mpi_reply,
1694 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1695 if (r)
1696 goto out;
1698 mpi_request.PageAddress = cpu_to_le32(form | handle);
1699 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1700 r = _config_request(ioc, &mpi_request, mpi_reply,
1701 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1702 out:
1703 return r;
1707 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1708 * @ioc: per adapter object
1709 * @mpi_reply: reply mf payload returned from firmware
1710 * @config_page: contents of the config page
1711 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1712 * @form_specific: specific to the form
1713 * Context: sleep.
1715 * Return: 0 for success, non-zero for failure.
1718 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1719 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1720 u32 form_specific)
1722 Mpi2ConfigRequest_t mpi_request;
1723 int r;
1725 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1726 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1727 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1728 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1729 mpi_request.Header.PageNumber = 0;
1730 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1731 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1732 r = _config_request(ioc, &mpi_request, mpi_reply,
1733 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1734 if (r)
1735 goto out;
1737 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1738 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1739 r = _config_request(ioc, &mpi_request, mpi_reply,
1740 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1741 sizeof(*config_page));
1742 out:
1743 return r;
1747 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
1748 * raid components
1749 * @ioc: per adapter object
1750 * @pd_handle: phys disk handle
1751 * @volume_handle: volume handle
1752 * Context: sleep.
1754 * Return: 0 for success, non-zero for failure.
1757 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
1758 u16 *volume_handle)
1760 Mpi2RaidConfigurationPage0_t *config_page = NULL;
1761 Mpi2ConfigRequest_t mpi_request;
1762 Mpi2ConfigReply_t mpi_reply;
1763 int r, i, config_page_sz;
1764 u16 ioc_status;
1765 int config_num;
1766 u16 element_type;
1767 u16 phys_disk_dev_handle;
1769 *volume_handle = 0;
1770 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1771 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1772 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1773 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1774 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1775 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1776 mpi_request.Header.PageNumber = 0;
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;
1783 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1784 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
1785 config_page = kmalloc(config_page_sz, GFP_KERNEL);
1786 if (!config_page) {
1787 r = -1;
1788 goto out;
1791 config_num = 0xff;
1792 while (1) {
1793 mpi_request.PageAddress = cpu_to_le32(config_num +
1794 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
1795 r = _config_request(ioc, &mpi_request, &mpi_reply,
1796 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1797 config_page_sz);
1798 if (r)
1799 goto out;
1800 r = -1;
1801 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1802 MPI2_IOCSTATUS_MASK;
1803 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1804 goto out;
1805 for (i = 0; i < config_page->NumElements; i++) {
1806 element_type = le16_to_cpu(config_page->
1807 ConfigElement[i].ElementFlags) &
1808 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
1809 if (element_type ==
1810 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
1811 element_type ==
1812 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
1813 phys_disk_dev_handle =
1814 le16_to_cpu(config_page->ConfigElement[i].
1815 PhysDiskDevHandle);
1816 if (phys_disk_dev_handle == pd_handle) {
1817 *volume_handle =
1818 le16_to_cpu(config_page->
1819 ConfigElement[i].VolDevHandle);
1820 r = 0;
1821 goto out;
1823 } else if (element_type ==
1824 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
1825 *volume_handle = 0;
1826 r = 0;
1827 goto out;
1830 config_num = config_page->ConfigNum;
1832 out:
1833 kfree(config_page);
1834 return r;
1838 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
1839 * @ioc: per adapter object
1840 * @volume_handle: volume handle
1841 * @wwid: volume wwid
1842 * Context: sleep.
1844 * Return: 0 for success, non-zero for failure.
1847 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
1848 u64 *wwid)
1850 Mpi2ConfigReply_t mpi_reply;
1851 Mpi2RaidVolPage1_t raid_vol_pg1;
1853 *wwid = 0;
1854 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1855 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1856 volume_handle))) {
1857 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
1858 return 0;
1859 } else
1860 return -1;