i2c: gpio: fault-injector: refactor incomplete transfer
[linux/fpc-iii.git] / drivers / scsi / mpt3sas / mpt3sas_config.c
blobe87c76a832f64ca8ff1b002369df95cf4c609cab
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 * Returns 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 * Returns 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 * Returns 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 pr_err(MPT3SAS_FMT "%s: timeout\n",
410 ioc->name, __func__);
411 _debug_dump_mf(mpi_request,
412 sizeof(Mpi2ConfigRequest_t)/4);
413 retry_count++;
414 if (ioc->config_cmds.smid == smid)
415 mpt3sas_base_free_smid(ioc, smid);
416 if ((ioc->shost_recovery) || (ioc->config_cmds.status &
417 MPT3_CMD_RESET) || ioc->pci_error_recovery)
418 goto retry_config;
419 issue_host_reset = 1;
420 r = -EFAULT;
421 goto free_mem;
424 if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
425 memcpy(mpi_reply, ioc->config_cmds.reply,
426 sizeof(Mpi2ConfigReply_t));
428 /* Reply Frame Sanity Checks to workaround FW issues */
429 if ((mpi_request->Header.PageType & 0xF) !=
430 (mpi_reply->Header.PageType & 0xF)) {
431 _debug_dump_mf(mpi_request, ioc->request_sz/4);
432 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
433 panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \
434 " mpi_reply mismatch: Requested PageType(0x%02x)" \
435 " Reply PageType(0x%02x)\n", \
436 ioc->name, __func__,
437 (mpi_request->Header.PageType & 0xF),
438 (mpi_reply->Header.PageType & 0xF));
441 if (((mpi_request->Header.PageType & 0xF) ==
442 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
443 mpi_request->ExtPageType != mpi_reply->ExtPageType) {
444 _debug_dump_mf(mpi_request, ioc->request_sz/4);
445 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
446 panic(KERN_WARNING MPT3SAS_FMT "%s: Firmware BUG:" \
447 " mpi_reply mismatch: Requested ExtPageType(0x%02x)"
448 " Reply ExtPageType(0x%02x)\n",
449 ioc->name, __func__, mpi_request->ExtPageType,
450 mpi_reply->ExtPageType);
452 ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
453 & MPI2_IOCSTATUS_MASK;
456 if (retry_count)
457 pr_info(MPT3SAS_FMT "%s: retry (%d) completed!!\n", \
458 ioc->name, __func__, retry_count);
460 if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
461 config_page && mpi_request->Action ==
462 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
463 u8 *p = (u8 *)mem.page;
465 /* Config Page Sanity Checks to workaround FW issues */
466 if (p) {
467 if ((mpi_request->Header.PageType & 0xF) !=
468 (p[3] & 0xF)) {
469 _debug_dump_mf(mpi_request, ioc->request_sz/4);
470 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
471 _debug_dump_config(p, min_t(u16, mem.sz,
472 config_page_sz)/4);
473 panic(KERN_WARNING MPT3SAS_FMT
474 "%s: Firmware BUG:" \
475 " config page mismatch:"
476 " Requested PageType(0x%02x)"
477 " Reply PageType(0x%02x)\n",
478 ioc->name, __func__,
479 (mpi_request->Header.PageType & 0xF),
480 (p[3] & 0xF));
483 if (((mpi_request->Header.PageType & 0xF) ==
484 MPI2_CONFIG_PAGETYPE_EXTENDED) &&
485 (mpi_request->ExtPageType != p[6])) {
486 _debug_dump_mf(mpi_request, ioc->request_sz/4);
487 _debug_dump_reply(mpi_reply, ioc->request_sz/4);
488 _debug_dump_config(p, min_t(u16, mem.sz,
489 config_page_sz)/4);
490 panic(KERN_WARNING MPT3SAS_FMT
491 "%s: Firmware BUG:" \
492 " config page mismatch:"
493 " Requested ExtPageType(0x%02x)"
494 " Reply ExtPageType(0x%02x)\n",
495 ioc->name, __func__,
496 mpi_request->ExtPageType, p[6]);
499 memcpy(config_page, mem.page, min_t(u16, mem.sz,
500 config_page_sz));
503 free_mem:
504 if (config_page)
505 _config_free_config_dma_memory(ioc, &mem);
506 out:
507 ioc->config_cmds.status = MPT3_CMD_NOT_USED;
508 mutex_unlock(&ioc->config_cmds.mutex);
510 if (issue_host_reset)
511 mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
512 return r;
516 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
517 * @ioc: per adapter object
518 * @mpi_reply: reply mf payload returned from firmware
519 * @config_page: contents of the config page
520 * Context: sleep.
522 * Returns 0 for success, non-zero for failure.
525 mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
526 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
528 Mpi2ConfigRequest_t mpi_request;
529 int r;
531 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
532 mpi_request.Function = MPI2_FUNCTION_CONFIG;
533 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
534 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
535 mpi_request.Header.PageNumber = 0;
536 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
537 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
538 r = _config_request(ioc, &mpi_request, mpi_reply,
539 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
540 if (r)
541 goto out;
543 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
544 r = _config_request(ioc, &mpi_request, mpi_reply,
545 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
546 sizeof(*config_page));
547 out:
548 return r;
552 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
553 * @ioc: per adapter object
554 * @mpi_reply: reply mf payload returned from firmware
555 * @config_page: contents of the config page
556 * @sz: size of buffer passed in config_page
557 * Context: sleep.
559 * Returns 0 for success, non-zero for failure.
562 mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
563 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
564 u16 sz)
566 Mpi2ConfigRequest_t mpi_request;
567 int r;
569 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
570 mpi_request.Function = MPI2_FUNCTION_CONFIG;
571 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
572 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
573 mpi_request.Header.PageNumber = 7;
574 mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
575 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
576 r = _config_request(ioc, &mpi_request, mpi_reply,
577 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
578 if (r)
579 goto out;
581 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
582 r = _config_request(ioc, &mpi_request, mpi_reply,
583 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
584 sz);
585 out:
586 return r;
590 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
591 * @ioc: per adapter object
592 * @mpi_reply: reply mf payload returned from firmware
593 * @config_page: contents of the config page
594 * Context: sleep.
596 * Returns 0 for success, non-zero for failure.
599 mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
600 Mpi2ConfigReply_t *mpi_reply,
601 struct Mpi2ManufacturingPage10_t *config_page)
603 Mpi2ConfigRequest_t mpi_request;
604 int r;
606 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
607 mpi_request.Function = MPI2_FUNCTION_CONFIG;
608 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
609 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
610 mpi_request.Header.PageNumber = 10;
611 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
612 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
613 r = _config_request(ioc, &mpi_request, mpi_reply,
614 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
615 if (r)
616 goto out;
618 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
619 r = _config_request(ioc, &mpi_request, mpi_reply,
620 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
621 sizeof(*config_page));
622 out:
623 return r;
627 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
628 * @ioc: per adapter object
629 * @mpi_reply: reply mf payload returned from firmware
630 * @config_page: contents of the config page
631 * Context: sleep.
633 * Returns 0 for success, non-zero for failure.
636 mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
637 Mpi2ConfigReply_t *mpi_reply,
638 struct Mpi2ManufacturingPage11_t *config_page)
640 Mpi2ConfigRequest_t mpi_request;
641 int r;
643 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
644 mpi_request.Function = MPI2_FUNCTION_CONFIG;
645 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
646 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
647 mpi_request.Header.PageNumber = 11;
648 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
649 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
650 r = _config_request(ioc, &mpi_request, mpi_reply,
651 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
652 if (r)
653 goto out;
655 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
656 r = _config_request(ioc, &mpi_request, mpi_reply,
657 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
658 sizeof(*config_page));
659 out:
660 return r;
664 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
665 * @ioc: per adapter object
666 * @mpi_reply: reply mf payload returned from firmware
667 * @config_page: contents of the config page
668 * Context: sleep.
670 * Returns 0 for success, non-zero for failure.
673 mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
674 Mpi2ConfigReply_t *mpi_reply,
675 struct Mpi2ManufacturingPage11_t *config_page)
677 Mpi2ConfigRequest_t mpi_request;
678 int r;
680 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
681 mpi_request.Function = MPI2_FUNCTION_CONFIG;
682 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
683 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
684 mpi_request.Header.PageNumber = 11;
685 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
686 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
687 r = _config_request(ioc, &mpi_request, mpi_reply,
688 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
689 if (r)
690 goto out;
692 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
693 r = _config_request(ioc, &mpi_request, mpi_reply,
694 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
695 sizeof(*config_page));
696 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
697 r = _config_request(ioc, &mpi_request, mpi_reply,
698 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
699 sizeof(*config_page));
700 out:
701 return r;
705 * mpt3sas_config_get_bios_pg2 - obtain bios page 2
706 * @ioc: per adapter object
707 * @mpi_reply: reply mf payload returned from firmware
708 * @config_page: contents of the config page
709 * Context: sleep.
711 * Returns 0 for success, non-zero for failure.
714 mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
715 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
717 Mpi2ConfigRequest_t mpi_request;
718 int r;
720 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
721 mpi_request.Function = MPI2_FUNCTION_CONFIG;
722 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
723 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
724 mpi_request.Header.PageNumber = 2;
725 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
726 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
727 r = _config_request(ioc, &mpi_request, mpi_reply,
728 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
729 if (r)
730 goto out;
732 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
733 r = _config_request(ioc, &mpi_request, mpi_reply,
734 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
735 sizeof(*config_page));
736 out:
737 return r;
741 * mpt3sas_config_get_bios_pg3 - obtain bios page 3
742 * @ioc: per adapter object
743 * @mpi_reply: reply mf payload returned from firmware
744 * @config_page: contents of the config page
745 * Context: sleep.
747 * Returns 0 for success, non-zero for failure.
750 mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
751 *mpi_reply, Mpi2BiosPage3_t *config_page)
753 Mpi2ConfigRequest_t mpi_request;
754 int r;
756 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
757 mpi_request.Function = MPI2_FUNCTION_CONFIG;
758 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
759 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
760 mpi_request.Header.PageNumber = 3;
761 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
762 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
763 r = _config_request(ioc, &mpi_request, mpi_reply,
764 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
765 if (r)
766 goto out;
768 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
769 r = _config_request(ioc, &mpi_request, mpi_reply,
770 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
771 sizeof(*config_page));
772 out:
773 return r;
777 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
778 * @ioc: per adapter object
779 * @mpi_reply: reply mf payload returned from firmware
780 * @config_page: contents of the config page
781 * Context: sleep.
783 * Returns 0 for success, non-zero for failure.
786 mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
787 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
789 Mpi2ConfigRequest_t mpi_request;
790 int r;
792 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
793 mpi_request.Function = MPI2_FUNCTION_CONFIG;
794 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
795 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
796 mpi_request.Header.PageNumber = 0;
797 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
798 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
799 r = _config_request(ioc, &mpi_request, mpi_reply,
800 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
801 if (r)
802 goto out;
804 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
805 r = _config_request(ioc, &mpi_request, mpi_reply,
806 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
807 sizeof(*config_page));
808 out:
809 return r;
813 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
814 * @ioc: per adapter object
815 * @mpi_reply: reply mf payload returned from firmware
816 * @config_page: contents of the config page
817 * Context: sleep.
819 * Returns 0 for success, non-zero for failure.
822 mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
823 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
825 Mpi2ConfigRequest_t mpi_request;
826 int r;
828 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
829 mpi_request.Function = MPI2_FUNCTION_CONFIG;
830 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
831 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
832 mpi_request.Header.PageNumber = 1;
833 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
834 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
835 r = _config_request(ioc, &mpi_request, mpi_reply,
836 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
837 if (r)
838 goto out;
840 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
841 r = _config_request(ioc, &mpi_request, mpi_reply,
842 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
843 sizeof(*config_page));
844 out:
845 return r;
849 * mpt3sas_config_set_iounit_pg1 - set iounit page 1
850 * @ioc: per adapter object
851 * @mpi_reply: reply mf payload returned from firmware
852 * @config_page: contents of the config page
853 * Context: sleep.
855 * Returns 0 for success, non-zero for failure.
858 mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
859 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
861 Mpi2ConfigRequest_t mpi_request;
862 int r;
864 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
865 mpi_request.Function = MPI2_FUNCTION_CONFIG;
866 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
867 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
868 mpi_request.Header.PageNumber = 1;
869 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
870 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
871 r = _config_request(ioc, &mpi_request, mpi_reply,
872 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
873 if (r)
874 goto out;
876 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
877 r = _config_request(ioc, &mpi_request, mpi_reply,
878 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
879 sizeof(*config_page));
880 out:
881 return r;
885 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
886 * @ioc: per adapter object
887 * @mpi_reply: reply mf payload returned from firmware
888 * @config_page: contents of the config page
889 * @sz: size of buffer passed in config_page
890 * Context: sleep.
892 * Returns 0 for success, non-zero for failure.
895 mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
896 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
898 Mpi2ConfigRequest_t mpi_request;
899 int r;
901 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
902 mpi_request.Function = MPI2_FUNCTION_CONFIG;
903 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
904 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
905 mpi_request.Header.PageNumber = 3;
906 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
907 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
908 r = _config_request(ioc, &mpi_request, mpi_reply,
909 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
910 if (r)
911 goto out;
913 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
914 r = _config_request(ioc, &mpi_request, mpi_reply,
915 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
916 out:
917 return r;
921 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
922 * @ioc: per adapter object
923 * @mpi_reply: reply mf payload returned from firmware
924 * @config_page: contents of the config page
925 * Context: sleep.
927 * Returns 0 for success, non-zero for failure.
930 mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
931 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
933 Mpi2ConfigRequest_t mpi_request;
934 int r;
936 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
937 mpi_request.Function = MPI2_FUNCTION_CONFIG;
938 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
939 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
940 mpi_request.Header.PageNumber = 8;
941 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
942 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
943 r = _config_request(ioc, &mpi_request, mpi_reply,
944 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
945 if (r)
946 goto out;
948 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
949 r = _config_request(ioc, &mpi_request, mpi_reply,
950 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
951 sizeof(*config_page));
952 out:
953 return r;
957 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
958 * @ioc: per adapter object
959 * @mpi_reply: reply mf payload returned from firmware
960 * @config_page: contents of the config page
961 * Context: sleep.
963 * Returns 0 for success, non-zero for failure.
966 mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
967 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
969 Mpi2ConfigRequest_t mpi_request;
970 int r;
972 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
973 mpi_request.Function = MPI2_FUNCTION_CONFIG;
974 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
975 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
976 mpi_request.Header.PageNumber = 8;
977 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
978 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
979 r = _config_request(ioc, &mpi_request, mpi_reply,
980 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
981 if (r)
982 goto out;
984 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
985 r = _config_request(ioc, &mpi_request, mpi_reply,
986 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
987 sizeof(*config_page));
988 out:
989 return r;
993 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
994 * @ioc: per adapter object
995 * @mpi_reply: reply mf payload returned from firmware
996 * @config_page: contents of the config page
997 * @form: GET_NEXT_HANDLE or HANDLE
998 * @handle: device handle
999 * Context: sleep.
1001 * Returns 0 for success, non-zero for failure.
1004 mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1005 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
1006 u32 form, u32 handle)
1008 Mpi2ConfigRequest_t mpi_request;
1009 int r;
1011 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1012 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1013 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1014 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1015 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1016 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
1017 mpi_request.Header.PageNumber = 0;
1018 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1019 r = _config_request(ioc, &mpi_request, mpi_reply,
1020 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1021 if (r)
1022 goto out;
1024 mpi_request.PageAddress = cpu_to_le32(form | handle);
1025 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1026 r = _config_request(ioc, &mpi_request, mpi_reply,
1027 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1028 sizeof(*config_page));
1029 out:
1030 return r;
1034 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
1035 * @ioc: per adapter object
1036 * @mpi_reply: reply mf payload returned from firmware
1037 * @config_page: contents of the config page
1038 * @form: GET_NEXT_HANDLE or HANDLE
1039 * @handle: device handle
1040 * Context: sleep.
1042 * Returns 0 for success, non-zero for failure.
1045 mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
1046 Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
1047 u32 form, u32 handle)
1049 Mpi2ConfigRequest_t mpi_request;
1050 int r;
1052 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1053 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1054 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1055 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1056 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1057 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
1058 mpi_request.Header.PageNumber = 1;
1059 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1060 r = _config_request(ioc, &mpi_request, mpi_reply,
1061 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1062 if (r)
1063 goto out;
1065 mpi_request.PageAddress = cpu_to_le32(form | handle);
1066 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1067 r = _config_request(ioc, &mpi_request, mpi_reply,
1068 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1069 sizeof(*config_page));
1070 out:
1071 return r;
1075 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
1076 * @ioc: per adapter object
1077 * @mpi_reply: reply mf payload returned from firmware
1078 * @config_page: contents of the config page
1079 * @form: GET_NEXT_HANDLE or HANDLE
1080 * @handle: device handle
1081 * Context: sleep.
1083 * Returns 0 for success, non-zero for failure.
1086 mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
1087 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
1088 u32 form, u32 handle)
1090 Mpi2ConfigRequest_t mpi_request;
1091 int r;
1093 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1094 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1095 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1096 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1097 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1098 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
1099 mpi_request.Header.PageNumber = 0;
1100 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1101 r = _config_request(ioc, &mpi_request, mpi_reply,
1102 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1103 if (r)
1104 goto out;
1106 mpi_request.PageAddress = cpu_to_le32(form | handle);
1107 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1108 r = _config_request(ioc, &mpi_request, mpi_reply,
1109 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1110 sizeof(*config_page));
1111 out:
1112 return r;
1116 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
1117 * @ioc: per adapter object
1118 * @mpi_reply: reply mf payload returned from firmware
1119 * @config_page: contents of the config page
1120 * @form: GET_NEXT_HANDLE or HANDLE
1121 * @handle: device handle
1122 * Context: sleep.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
1128 Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
1129 u32 form, u32 handle)
1131 Mpi2ConfigRequest_t mpi_request;
1132 int r;
1134 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1135 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1136 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1137 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1138 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1139 mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
1140 mpi_request.Header.PageNumber = 2;
1141 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1142 r = _config_request(ioc, &mpi_request, mpi_reply,
1143 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1144 if (r)
1145 goto out;
1147 mpi_request.PageAddress = cpu_to_le32(form | handle);
1148 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1149 r = _config_request(ioc, &mpi_request, mpi_reply,
1150 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1151 sizeof(*config_page));
1152 out:
1153 return r;
1157 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
1158 * @ioc: per adapter object
1159 * @num_phys: pointer returned with the number of phys
1160 * Context: sleep.
1162 * Returns 0 for success, non-zero for failure.
1165 mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
1167 Mpi2ConfigRequest_t mpi_request;
1168 int r;
1169 u16 ioc_status;
1170 Mpi2ConfigReply_t mpi_reply;
1171 Mpi2SasIOUnitPage0_t config_page;
1173 *num_phys = 0;
1174 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1175 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1176 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1177 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1178 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1179 mpi_request.Header.PageNumber = 0;
1180 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1181 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1182 r = _config_request(ioc, &mpi_request, &mpi_reply,
1183 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1184 if (r)
1185 goto out;
1187 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1188 r = _config_request(ioc, &mpi_request, &mpi_reply,
1189 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1190 sizeof(Mpi2SasIOUnitPage0_t));
1191 if (!r) {
1192 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1193 MPI2_IOCSTATUS_MASK;
1194 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1195 *num_phys = config_page.NumPhys;
1197 out:
1198 return r;
1202 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
1203 * @ioc: per adapter object
1204 * @mpi_reply: reply mf payload returned from firmware
1205 * @config_page: contents of the config page
1206 * @sz: size of buffer passed in config_page
1207 * Context: sleep.
1209 * Calling function should call config_get_number_hba_phys prior to
1210 * this function, so enough memory is allocated for config_page.
1212 * Returns 0 for success, non-zero for failure.
1215 mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
1216 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
1217 u16 sz)
1219 Mpi2ConfigRequest_t mpi_request;
1220 int r;
1222 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1223 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1224 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1225 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1226 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1227 mpi_request.Header.PageNumber = 0;
1228 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1229 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1230 r = _config_request(ioc, &mpi_request, mpi_reply,
1231 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1232 if (r)
1233 goto out;
1235 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1236 r = _config_request(ioc, &mpi_request, mpi_reply,
1237 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1238 out:
1239 return r;
1243 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
1244 * @ioc: per adapter object
1245 * @mpi_reply: reply mf payload returned from firmware
1246 * @config_page: contents of the config page
1247 * @sz: size of buffer passed in config_page
1248 * Context: sleep.
1250 * Calling function should call config_get_number_hba_phys prior to
1251 * this function, so enough memory is allocated for config_page.
1253 * Returns 0 for success, non-zero for failure.
1256 mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1257 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1258 u16 sz)
1260 Mpi2ConfigRequest_t mpi_request;
1261 int r;
1263 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1264 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1265 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1266 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1267 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1268 mpi_request.Header.PageNumber = 1;
1269 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1270 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1271 r = _config_request(ioc, &mpi_request, mpi_reply,
1272 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1273 if (r)
1274 goto out;
1276 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1277 r = _config_request(ioc, &mpi_request, mpi_reply,
1278 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1279 out:
1280 return r;
1284 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1285 * @ioc: per adapter object
1286 * @mpi_reply: reply mf payload returned from firmware
1287 * @config_page: contents of the config page
1288 * @sz: size of buffer passed in config_page
1289 * Context: sleep.
1291 * Calling function should call config_get_number_hba_phys prior to
1292 * this function, so enough memory is allocated for config_page.
1294 * Returns 0 for success, non-zero for failure.
1297 mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
1298 Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
1299 u16 sz)
1301 Mpi2ConfigRequest_t mpi_request;
1302 int r;
1304 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1305 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1306 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1307 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1308 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1309 mpi_request.Header.PageNumber = 1;
1310 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
1311 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1312 r = _config_request(ioc, &mpi_request, mpi_reply,
1313 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1314 if (r)
1315 goto out;
1317 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
1318 _config_request(ioc, &mpi_request, mpi_reply,
1319 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1320 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
1321 r = _config_request(ioc, &mpi_request, mpi_reply,
1322 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1323 out:
1324 return r;
1328 * mpt3sas_config_get_expander_pg0 - obtain expander page 0
1329 * @ioc: per adapter object
1330 * @mpi_reply: reply mf payload returned from firmware
1331 * @config_page: contents of the config page
1332 * @form: GET_NEXT_HANDLE or HANDLE
1333 * @handle: expander handle
1334 * Context: sleep.
1336 * Returns 0 for success, non-zero for failure.
1339 mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1340 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1342 Mpi2ConfigRequest_t mpi_request;
1343 int r;
1345 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1346 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1347 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1348 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1349 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1350 mpi_request.Header.PageNumber = 0;
1351 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1352 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1353 r = _config_request(ioc, &mpi_request, mpi_reply,
1354 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1355 if (r)
1356 goto out;
1358 mpi_request.PageAddress = cpu_to_le32(form | handle);
1359 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1360 r = _config_request(ioc, &mpi_request, mpi_reply,
1361 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1362 sizeof(*config_page));
1363 out:
1364 return r;
1368 * mpt3sas_config_get_expander_pg1 - obtain expander page 1
1369 * @ioc: per adapter object
1370 * @mpi_reply: reply mf payload returned from firmware
1371 * @config_page: contents of the config page
1372 * @phy_number: phy number
1373 * @handle: expander handle
1374 * Context: sleep.
1376 * Returns 0 for success, non-zero for failure.
1379 mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1380 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1381 u16 handle)
1383 Mpi2ConfigRequest_t mpi_request;
1384 int r;
1386 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1387 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1388 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1389 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1390 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1391 mpi_request.Header.PageNumber = 1;
1392 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1393 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1394 r = _config_request(ioc, &mpi_request, mpi_reply,
1395 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1396 if (r)
1397 goto out;
1399 mpi_request.PageAddress =
1400 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1401 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1402 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1403 r = _config_request(ioc, &mpi_request, mpi_reply,
1404 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1405 sizeof(*config_page));
1406 out:
1407 return r;
1411 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
1412 * @ioc: per adapter object
1413 * @mpi_reply: reply mf payload returned from firmware
1414 * @config_page: contents of the config page
1415 * @form: GET_NEXT_HANDLE or HANDLE
1416 * @handle: expander handle
1417 * Context: sleep.
1419 * Returns 0 for success, non-zero for failure.
1422 mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1423 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1425 Mpi2ConfigRequest_t mpi_request;
1426 int r;
1428 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1429 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1430 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1431 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1432 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1433 mpi_request.Header.PageNumber = 0;
1434 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1435 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1436 r = _config_request(ioc, &mpi_request, mpi_reply,
1437 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1438 if (r)
1439 goto out;
1441 mpi_request.PageAddress = cpu_to_le32(form | handle);
1442 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1443 r = _config_request(ioc, &mpi_request, mpi_reply,
1444 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1445 sizeof(*config_page));
1446 out:
1447 return r;
1451 * mpt3sas_config_get_phy_pg0 - obtain phy page 0
1452 * @ioc: per adapter object
1453 * @mpi_reply: reply mf payload returned from firmware
1454 * @config_page: contents of the config page
1455 * @phy_number: phy number
1456 * Context: sleep.
1458 * Returns 0 for success, non-zero for failure.
1461 mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1462 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1464 Mpi2ConfigRequest_t mpi_request;
1465 int r;
1467 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1468 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1469 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1470 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1471 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1472 mpi_request.Header.PageNumber = 0;
1473 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1474 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1475 r = _config_request(ioc, &mpi_request, mpi_reply,
1476 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1477 if (r)
1478 goto out;
1480 mpi_request.PageAddress =
1481 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1482 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1483 r = _config_request(ioc, &mpi_request, mpi_reply,
1484 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1485 sizeof(*config_page));
1486 out:
1487 return r;
1491 * mpt3sas_config_get_phy_pg1 - obtain phy page 1
1492 * @ioc: per adapter object
1493 * @mpi_reply: reply mf payload returned from firmware
1494 * @config_page: contents of the config page
1495 * @phy_number: phy number
1496 * Context: sleep.
1498 * Returns 0 for success, non-zero for failure.
1501 mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1502 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1504 Mpi2ConfigRequest_t mpi_request;
1505 int r;
1507 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1508 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1509 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1510 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1511 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1512 mpi_request.Header.PageNumber = 1;
1513 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1514 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1515 r = _config_request(ioc, &mpi_request, mpi_reply,
1516 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1517 if (r)
1518 goto out;
1520 mpi_request.PageAddress =
1521 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1522 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1523 r = _config_request(ioc, &mpi_request, mpi_reply,
1524 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1525 sizeof(*config_page));
1526 out:
1527 return r;
1531 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1532 * @ioc: per adapter object
1533 * @mpi_reply: reply mf payload returned from firmware
1534 * @config_page: contents of the config page
1535 * @form: GET_NEXT_HANDLE or HANDLE
1536 * @handle: volume handle
1537 * Context: sleep.
1539 * Returns 0 for success, non-zero for failure.
1542 mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
1543 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1544 u32 handle)
1546 Mpi2ConfigRequest_t mpi_request;
1547 int r;
1549 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1550 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1551 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1552 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1553 mpi_request.Header.PageNumber = 1;
1554 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1555 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1556 r = _config_request(ioc, &mpi_request, mpi_reply,
1557 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1558 if (r)
1559 goto out;
1561 mpi_request.PageAddress = cpu_to_le32(form | handle);
1562 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1563 r = _config_request(ioc, &mpi_request, mpi_reply,
1564 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1565 sizeof(*config_page));
1566 out:
1567 return r;
1571 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
1572 * @ioc: per adapter object
1573 * @handle: volume handle
1574 * @num_pds: returns pds count
1575 * Context: sleep.
1577 * Returns 0 for success, non-zero for failure.
1580 mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
1581 u8 *num_pds)
1583 Mpi2ConfigRequest_t mpi_request;
1584 Mpi2RaidVolPage0_t config_page;
1585 Mpi2ConfigReply_t mpi_reply;
1586 int r;
1587 u16 ioc_status;
1589 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1590 *num_pds = 0;
1591 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1592 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1593 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1594 mpi_request.Header.PageNumber = 0;
1595 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1596 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1597 r = _config_request(ioc, &mpi_request, &mpi_reply,
1598 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1599 if (r)
1600 goto out;
1602 mpi_request.PageAddress =
1603 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1604 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1605 r = _config_request(ioc, &mpi_request, &mpi_reply,
1606 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
1607 sizeof(Mpi2RaidVolPage0_t));
1608 if (!r) {
1609 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1610 MPI2_IOCSTATUS_MASK;
1611 if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
1612 *num_pds = config_page.NumPhysDisks;
1615 out:
1616 return r;
1620 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1621 * @ioc: per adapter object
1622 * @mpi_reply: reply mf payload returned from firmware
1623 * @config_page: contents of the config page
1624 * @form: GET_NEXT_HANDLE or HANDLE
1625 * @handle: volume handle
1626 * @sz: size of buffer passed in config_page
1627 * Context: sleep.
1629 * Returns 0 for success, non-zero for failure.
1632 mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
1633 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1634 u32 handle, u16 sz)
1636 Mpi2ConfigRequest_t mpi_request;
1637 int r;
1639 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1640 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1641 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1642 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1643 mpi_request.Header.PageNumber = 0;
1644 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1645 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1646 r = _config_request(ioc, &mpi_request, mpi_reply,
1647 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1648 if (r)
1649 goto out;
1651 mpi_request.PageAddress = cpu_to_le32(form | handle);
1652 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1653 r = _config_request(ioc, &mpi_request, mpi_reply,
1654 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
1655 out:
1656 return r;
1660 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1661 * @ioc: per adapter object
1662 * @mpi_reply: reply mf payload returned from firmware
1663 * @config_page: contents of the config page
1664 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1665 * @form_specific: specific to the form
1666 * Context: sleep.
1668 * Returns 0 for success, non-zero for failure.
1671 mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1672 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1673 u32 form_specific)
1675 Mpi2ConfigRequest_t mpi_request;
1676 int r;
1678 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1679 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1680 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1681 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1682 mpi_request.Header.PageNumber = 0;
1683 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1684 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1685 r = _config_request(ioc, &mpi_request, mpi_reply,
1686 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1687 if (r)
1688 goto out;
1690 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1691 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1692 r = _config_request(ioc, &mpi_request, mpi_reply,
1693 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1694 sizeof(*config_page));
1695 out:
1696 return r;
1700 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
1701 * raid components
1702 * @ioc: per adapter object
1703 * @pd_handle: phys disk handle
1704 * @volume_handle: volume handle
1705 * Context: sleep.
1707 * Returns 0 for success, non-zero for failure.
1710 mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
1711 u16 *volume_handle)
1713 Mpi2RaidConfigurationPage0_t *config_page = NULL;
1714 Mpi2ConfigRequest_t mpi_request;
1715 Mpi2ConfigReply_t mpi_reply;
1716 int r, i, config_page_sz;
1717 u16 ioc_status;
1718 int config_num;
1719 u16 element_type;
1720 u16 phys_disk_dev_handle;
1722 *volume_handle = 0;
1723 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1724 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1725 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1726 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1727 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1728 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1729 mpi_request.Header.PageNumber = 0;
1730 ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
1731 r = _config_request(ioc, &mpi_request, &mpi_reply,
1732 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
1733 if (r)
1734 goto out;
1736 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1737 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
1738 config_page = kmalloc(config_page_sz, GFP_KERNEL);
1739 if (!config_page) {
1740 r = -1;
1741 goto out;
1744 config_num = 0xff;
1745 while (1) {
1746 mpi_request.PageAddress = cpu_to_le32(config_num +
1747 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
1748 r = _config_request(ioc, &mpi_request, &mpi_reply,
1749 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1750 config_page_sz);
1751 if (r)
1752 goto out;
1753 r = -1;
1754 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1755 MPI2_IOCSTATUS_MASK;
1756 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1757 goto out;
1758 for (i = 0; i < config_page->NumElements; i++) {
1759 element_type = le16_to_cpu(config_page->
1760 ConfigElement[i].ElementFlags) &
1761 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
1762 if (element_type ==
1763 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
1764 element_type ==
1765 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
1766 phys_disk_dev_handle =
1767 le16_to_cpu(config_page->ConfigElement[i].
1768 PhysDiskDevHandle);
1769 if (phys_disk_dev_handle == pd_handle) {
1770 *volume_handle =
1771 le16_to_cpu(config_page->
1772 ConfigElement[i].VolDevHandle);
1773 r = 0;
1774 goto out;
1776 } else if (element_type ==
1777 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
1778 *volume_handle = 0;
1779 r = 0;
1780 goto out;
1783 config_num = config_page->ConfigNum;
1785 out:
1786 kfree(config_page);
1787 return r;
1791 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
1792 * @ioc: per adapter object
1793 * @volume_handle: volume handle
1794 * @wwid: volume wwid
1795 * Context: sleep.
1797 * Returns 0 for success, non-zero for failure.
1800 mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
1801 u64 *wwid)
1803 Mpi2ConfigReply_t mpi_reply;
1804 Mpi2RaidVolPage1_t raid_vol_pg1;
1806 *wwid = 0;
1807 if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1808 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1809 volume_handle))) {
1810 *wwid = le64_to_cpu(raid_vol_pg1.WWID);
1811 return 0;
1812 } else
1813 return -1;