2 * This module provides common API for accessing firmware configuration pages
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2008 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
23 * solely responsible for determining the appropriateness of using and
24 * distributing the Program and assumes all risks associated with its
25 * exercise of rights under this Agreement, including but not limited to
26 * the risks and costs of program errors, damage to or loss of data,
27 * programs or equipment, and unavailability or interruption of operations.
29 * DISCLAIMER OF LIABILITY
30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
38 * You should have received a copy of the GNU General Public License
39 * along with this program; if not, write to the Free Software
40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
44 #include <linux/version.h>
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 "mpt2sas_base.h"
57 /* local definitions */
59 /* Timeout for config page request (in seconds) */
60 #define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
62 /* Common sgl flags for READING a config page. */
63 #define MPT2_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 MPT2_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)
74 * struct config_request - obtain dma memory via routine
75 * @config_page_sz: size
76 * @config_page: virt pointer
77 * @config_page_dma: phys pointer
80 struct config_request{
83 dma_addr_t config_page_dma;
86 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
88 * _config_display_some_debug - debug routine
89 * @ioc: per adapter object
90 * @smid: system request message index
91 * @calling_function_name: string pass from calling function
92 * @mpi_reply: reply message frame
95 * Function for displaying debug info helpfull when debugging issues
99 _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
100 char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
102 Mpi2ConfigRequest_t *mpi_request;
105 if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
108 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
109 switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
110 case MPI2_CONFIG_PAGETYPE_IO_UNIT:
113 case MPI2_CONFIG_PAGETYPE_IOC:
116 case MPI2_CONFIG_PAGETYPE_BIOS:
119 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
120 desc = "raid_volume";
122 case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
123 desc = "manufaucturing";
125 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
128 case MPI2_CONFIG_PAGETYPE_EXTENDED:
129 switch (mpi_request->ExtPageType) {
130 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
131 desc = "sas_io_unit";
133 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
134 desc = "sas_expander";
136 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
139 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
142 case MPI2_CONFIG_EXTPAGETYPE_LOG:
145 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
148 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
149 desc = "raid_config";
151 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
152 desc = "driver_mappping";
161 printk(MPT2SAS_DEBUG_FMT "%s: %s(%d), action(%d), form(0x%08x), "
162 "smid(%d)\n", ioc->name, calling_function_name, desc,
163 mpi_request->Header.PageNumber, mpi_request->Action,
164 le32_to_cpu(mpi_request->PageAddress), smid);
169 if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
170 printk(MPT2SAS_DEBUG_FMT
171 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
172 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
173 le32_to_cpu(mpi_reply->IOCLogInfo));
178 * mpt2sas_config_done - config page completion routine
179 * @ioc: per adapter object
180 * @smid: system request message index
181 * @VF_ID: virtual function id
182 * @reply: reply message frame(lower 32bit addr)
185 * The callback handler when using _config_request.
190 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
192 MPI2DefaultReply_t *mpi_reply;
194 if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
196 if (ioc->config_cmds.smid != smid)
198 ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
199 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
201 ioc->config_cmds.status |= MPT2_CMD_REPLY_VALID;
202 memcpy(ioc->config_cmds.reply, mpi_reply,
203 mpi_reply->MsgLength*4);
205 ioc->config_cmds.status &= ~MPT2_CMD_PENDING;
206 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
207 _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
209 complete(&ioc->config_cmds.done);
213 * _config_request - main routine for sending config page requests
214 * @ioc: per adapter object
215 * @mpi_request: request message frame
216 * @mpi_reply: reply mf payload returned from firmware
217 * @timeout: timeout in seconds
218 * Context: sleep, the calling function needs to acquire the config_cmds.mutex
220 * A generic API for config page requests to firmware.
222 * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
225 * The callback index is set inside `ioc->config_cb_idx.
227 * Returns 0 for success, non-zero for failure.
230 _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
231 *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout)
235 unsigned long timeleft;
236 Mpi2ConfigRequest_t *config_request;
239 u8 issue_host_reset = 0;
240 u16 wait_state_count;
242 mutex_lock(&ioc->config_cmds.mutex);
243 if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
244 printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
245 ioc->name, __func__);
246 mutex_unlock(&ioc->config_cmds.mutex);
253 if (retry_count > 2) /* attempt only 2 retries */
255 printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
256 ioc->name, __func__, retry_count);
258 wait_state_count = 0;
259 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
260 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
261 if (wait_state_count++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT) {
262 printk(MPT2SAS_ERR_FMT
263 "%s: failed due to ioc not operational\n",
264 ioc->name, __func__);
269 ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
270 printk(MPT2SAS_INFO_FMT "%s: waiting for "
271 "operational state(count=%d)\n", ioc->name,
272 __func__, wait_state_count);
274 if (wait_state_count)
275 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
276 ioc->name, __func__);
278 smid = mpt2sas_base_get_smid(ioc, ioc->config_cb_idx);
280 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
281 ioc->name, __func__);
287 memset(mpi_reply, 0, sizeof(Mpi2ConfigReply_t));
288 ioc->config_cmds.status = MPT2_CMD_PENDING;
289 config_request = mpt2sas_base_get_msg_frame(ioc, smid);
290 ioc->config_cmds.smid = smid;
291 memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
292 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
293 _config_display_some_debug(ioc, smid, "config_request", NULL);
295 mpt2sas_base_put_smid_default(ioc, smid, config_request->VF_ID);
296 timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
298 if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
299 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
300 ioc->name, __func__);
301 _debug_dump_mf(mpi_request,
302 sizeof(Mpi2ConfigRequest_t)/4);
304 if (ioc->config_cmds.smid == smid)
305 mpt2sas_base_free_smid(ioc, smid);
306 if ((ioc->shost_recovery) ||
307 (ioc->config_cmds.status & MPT2_CMD_RESET))
309 issue_host_reset = 1;
313 if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
314 memcpy(mpi_reply, ioc->config_cmds.reply,
315 sizeof(Mpi2ConfigReply_t));
317 printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
318 ioc->name, __func__);
320 ioc->config_cmds.status = MPT2_CMD_NOT_USED;
321 mutex_unlock(&ioc->config_cmds.mutex);
322 if (issue_host_reset)
323 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
329 * _config_alloc_config_dma_memory - obtain physical memory
330 * @ioc: per adapter object
331 * @mem: struct config_request
333 * A wrapper for obtaining dma-able memory for config page request.
335 * Returns 0 for success, non-zero for failure.
338 _config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
339 struct config_request *mem)
343 mem->config_page = pci_alloc_consistent(ioc->pdev, mem->config_page_sz,
344 &mem->config_page_dma);
345 if (!mem->config_page)
351 * _config_free_config_dma_memory - wrapper to free the memory
352 * @ioc: per adapter object
353 * @mem: struct config_request
355 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
357 * Returns 0 for success, non-zero for failure.
360 _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
361 struct config_request *mem)
363 pci_free_consistent(ioc->pdev, mem->config_page_sz, mem->config_page,
364 mem->config_page_dma);
368 * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
369 * @ioc: per adapter object
370 * @mpi_reply: reply mf payload returned from firmware
371 * @config_page: contents of the config page
374 * Returns 0 for success, non-zero for failure.
377 mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
378 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
380 Mpi2ConfigRequest_t mpi_request;
382 struct config_request mem;
384 memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
385 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
386 mpi_request.Function = MPI2_FUNCTION_CONFIG;
387 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
388 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
389 mpi_request.Header.PageNumber = 0;
390 mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
391 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
392 r = _config_request(ioc, &mpi_request, mpi_reply,
393 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
397 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
398 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
399 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
400 mpi_request.Header.PageType = mpi_reply->Header.PageType;
401 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
402 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
403 if (mem.config_page_sz > ioc->config_page_sz) {
404 r = _config_alloc_config_dma_memory(ioc, &mem);
408 mem.config_page_dma = ioc->config_page_dma;
409 mem.config_page = ioc->config_page;
411 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
412 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
413 mem.config_page_dma);
414 r = _config_request(ioc, &mpi_request, mpi_reply,
415 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
417 memcpy(config_page, mem.config_page,
418 min_t(u16, mem.config_page_sz,
419 sizeof(Mpi2ManufacturingPage0_t)));
421 if (mem.config_page_sz > ioc->config_page_sz)
422 _config_free_config_dma_memory(ioc, &mem);
429 * mpt2sas_config_get_bios_pg2 - obtain bios page 2
430 * @ioc: per adapter object
431 * @mpi_reply: reply mf payload returned from firmware
432 * @config_page: contents of the config page
435 * Returns 0 for success, non-zero for failure.
438 mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
439 Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
441 Mpi2ConfigRequest_t mpi_request;
443 struct config_request mem;
445 memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
446 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
447 mpi_request.Function = MPI2_FUNCTION_CONFIG;
448 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
449 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
450 mpi_request.Header.PageNumber = 2;
451 mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
452 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
453 r = _config_request(ioc, &mpi_request, mpi_reply,
454 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
458 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
459 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
460 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
461 mpi_request.Header.PageType = mpi_reply->Header.PageType;
462 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
463 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
464 if (mem.config_page_sz > ioc->config_page_sz) {
465 r = _config_alloc_config_dma_memory(ioc, &mem);
469 mem.config_page_dma = ioc->config_page_dma;
470 mem.config_page = ioc->config_page;
472 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
473 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
474 mem.config_page_dma);
475 r = _config_request(ioc, &mpi_request, mpi_reply,
476 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
478 memcpy(config_page, mem.config_page,
479 min_t(u16, mem.config_page_sz,
480 sizeof(Mpi2BiosPage2_t)));
482 if (mem.config_page_sz > ioc->config_page_sz)
483 _config_free_config_dma_memory(ioc, &mem);
490 * mpt2sas_config_get_bios_pg3 - obtain bios page 3
491 * @ioc: per adapter object
492 * @mpi_reply: reply mf payload returned from firmware
493 * @config_page: contents of the config page
496 * Returns 0 for success, non-zero for failure.
499 mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
500 *mpi_reply, Mpi2BiosPage3_t *config_page)
502 Mpi2ConfigRequest_t mpi_request;
504 struct config_request mem;
506 memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
507 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
508 mpi_request.Function = MPI2_FUNCTION_CONFIG;
509 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
510 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
511 mpi_request.Header.PageNumber = 3;
512 mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
513 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
514 r = _config_request(ioc, &mpi_request, mpi_reply,
515 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
519 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
520 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
521 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
522 mpi_request.Header.PageType = mpi_reply->Header.PageType;
523 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
524 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
525 if (mem.config_page_sz > ioc->config_page_sz) {
526 r = _config_alloc_config_dma_memory(ioc, &mem);
530 mem.config_page_dma = ioc->config_page_dma;
531 mem.config_page = ioc->config_page;
533 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
534 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
535 mem.config_page_dma);
536 r = _config_request(ioc, &mpi_request, mpi_reply,
537 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
539 memcpy(config_page, mem.config_page,
540 min_t(u16, mem.config_page_sz,
541 sizeof(Mpi2BiosPage3_t)));
543 if (mem.config_page_sz > ioc->config_page_sz)
544 _config_free_config_dma_memory(ioc, &mem);
551 * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
552 * @ioc: per adapter object
553 * @mpi_reply: reply mf payload returned from firmware
554 * @config_page: contents of the config page
557 * Returns 0 for success, non-zero for failure.
560 mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
561 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
563 Mpi2ConfigRequest_t mpi_request;
565 struct config_request mem;
567 memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
568 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
569 mpi_request.Function = MPI2_FUNCTION_CONFIG;
570 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
571 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
572 mpi_request.Header.PageNumber = 0;
573 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
574 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
575 r = _config_request(ioc, &mpi_request, mpi_reply,
576 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
580 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
581 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
582 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
583 mpi_request.Header.PageType = mpi_reply->Header.PageType;
584 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
585 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
586 if (mem.config_page_sz > ioc->config_page_sz) {
587 r = _config_alloc_config_dma_memory(ioc, &mem);
591 mem.config_page_dma = ioc->config_page_dma;
592 mem.config_page = ioc->config_page;
594 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
595 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
596 mem.config_page_dma);
597 r = _config_request(ioc, &mpi_request, mpi_reply,
598 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
600 memcpy(config_page, mem.config_page,
601 min_t(u16, mem.config_page_sz,
602 sizeof(Mpi2IOUnitPage0_t)));
604 if (mem.config_page_sz > ioc->config_page_sz)
605 _config_free_config_dma_memory(ioc, &mem);
612 * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
613 * @ioc: per adapter object
614 * @mpi_reply: reply mf payload returned from firmware
615 * @config_page: contents of the config page
618 * Returns 0 for success, non-zero for failure.
621 mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
622 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
624 Mpi2ConfigRequest_t mpi_request;
626 struct config_request mem;
628 memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
629 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
630 mpi_request.Function = MPI2_FUNCTION_CONFIG;
631 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
632 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
633 mpi_request.Header.PageNumber = 1;
634 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
635 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
636 r = _config_request(ioc, &mpi_request, mpi_reply,
637 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
641 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
642 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
643 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
644 mpi_request.Header.PageType = mpi_reply->Header.PageType;
645 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
646 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
647 if (mem.config_page_sz > ioc->config_page_sz) {
648 r = _config_alloc_config_dma_memory(ioc, &mem);
652 mem.config_page_dma = ioc->config_page_dma;
653 mem.config_page = ioc->config_page;
655 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
656 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
657 mem.config_page_dma);
658 r = _config_request(ioc, &mpi_request, mpi_reply,
659 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
661 memcpy(config_page, mem.config_page,
662 min_t(u16, mem.config_page_sz,
663 sizeof(Mpi2IOUnitPage1_t)));
665 if (mem.config_page_sz > ioc->config_page_sz)
666 _config_free_config_dma_memory(ioc, &mem);
673 * mpt2sas_config_set_iounit_pg1 - set iounit page 1
674 * @ioc: per adapter object
675 * @mpi_reply: reply mf payload returned from firmware
676 * @config_page: contents of the config page
679 * Returns 0 for success, non-zero for failure.
682 mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
683 Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t config_page)
685 Mpi2ConfigRequest_t mpi_request;
687 struct config_request mem;
689 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
690 mpi_request.Function = MPI2_FUNCTION_CONFIG;
691 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
692 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
693 mpi_request.Header.PageNumber = 1;
694 mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
695 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
696 r = _config_request(ioc, &mpi_request, mpi_reply,
697 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
701 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
702 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
703 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
704 mpi_request.Header.PageType = mpi_reply->Header.PageType;
705 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
706 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
707 if (mem.config_page_sz > ioc->config_page_sz) {
708 r = _config_alloc_config_dma_memory(ioc, &mem);
712 mem.config_page_dma = ioc->config_page_dma;
713 mem.config_page = ioc->config_page;
716 memset(mem.config_page, 0, mem.config_page_sz);
717 memcpy(mem.config_page, &config_page,
718 sizeof(Mpi2IOUnitPage1_t));
720 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
721 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.config_page_sz,
722 mem.config_page_dma);
723 r = _config_request(ioc, &mpi_request, mpi_reply,
724 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
726 if (mem.config_page_sz > ioc->config_page_sz)
727 _config_free_config_dma_memory(ioc, &mem);
734 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
735 * @ioc: per adapter object
736 * @mpi_reply: reply mf payload returned from firmware
737 * @config_page: contents of the config page
740 * Returns 0 for success, non-zero for failure.
743 mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
744 Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
746 Mpi2ConfigRequest_t mpi_request;
748 struct config_request mem;
750 memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
751 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
752 mpi_request.Function = MPI2_FUNCTION_CONFIG;
753 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
754 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
755 mpi_request.Header.PageNumber = 8;
756 mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
757 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
758 r = _config_request(ioc, &mpi_request, mpi_reply,
759 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
763 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
764 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
765 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
766 mpi_request.Header.PageType = mpi_reply->Header.PageType;
767 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
768 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
769 if (mem.config_page_sz > ioc->config_page_sz) {
770 r = _config_alloc_config_dma_memory(ioc, &mem);
774 mem.config_page_dma = ioc->config_page_dma;
775 mem.config_page = ioc->config_page;
777 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
778 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
779 mem.config_page_dma);
780 r = _config_request(ioc, &mpi_request, mpi_reply,
781 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
783 memcpy(config_page, mem.config_page,
784 min_t(u16, mem.config_page_sz,
785 sizeof(Mpi2IOCPage8_t)));
787 if (mem.config_page_sz > ioc->config_page_sz)
788 _config_free_config_dma_memory(ioc, &mem);
795 * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
796 * @ioc: per adapter object
797 * @mpi_reply: reply mf payload returned from firmware
798 * @config_page: contents of the config page
799 * @form: GET_NEXT_HANDLE or HANDLE
800 * @handle: device handle
803 * Returns 0 for success, non-zero for failure.
806 mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
807 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u32 handle)
809 Mpi2ConfigRequest_t mpi_request;
811 struct config_request mem;
813 memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
814 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
815 mpi_request.Function = MPI2_FUNCTION_CONFIG;
816 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
817 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
818 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
819 mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
820 mpi_request.Header.PageNumber = 0;
821 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
822 r = _config_request(ioc, &mpi_request, mpi_reply,
823 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
827 mpi_request.PageAddress = cpu_to_le32(form | handle);
828 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
829 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
830 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
831 mpi_request.Header.PageType = mpi_reply->Header.PageType;
832 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
833 mpi_request.ExtPageType = mpi_reply->ExtPageType;
834 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
835 if (mem.config_page_sz > ioc->config_page_sz) {
836 r = _config_alloc_config_dma_memory(ioc, &mem);
840 mem.config_page_dma = ioc->config_page_dma;
841 mem.config_page = ioc->config_page;
843 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
844 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
845 mem.config_page_dma);
846 r = _config_request(ioc, &mpi_request, mpi_reply,
847 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
849 memcpy(config_page, mem.config_page,
850 min_t(u16, mem.config_page_sz,
851 sizeof(Mpi2SasDevicePage0_t)));
853 if (mem.config_page_sz > ioc->config_page_sz)
854 _config_free_config_dma_memory(ioc, &mem);
861 * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
862 * @ioc: per adapter object
863 * @mpi_reply: reply mf payload returned from firmware
864 * @config_page: contents of the config page
865 * @form: GET_NEXT_HANDLE or HANDLE
866 * @handle: device handle
869 * Returns 0 for success, non-zero for failure.
872 mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
873 *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle)
875 Mpi2ConfigRequest_t mpi_request;
877 struct config_request mem;
879 memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
880 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
881 mpi_request.Function = MPI2_FUNCTION_CONFIG;
882 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
883 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
884 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
885 mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
886 mpi_request.Header.PageNumber = 1;
887 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
888 r = _config_request(ioc, &mpi_request, mpi_reply,
889 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
893 mpi_request.PageAddress = cpu_to_le32(form | handle);
894 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
895 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
896 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
897 mpi_request.Header.PageType = mpi_reply->Header.PageType;
898 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
899 mpi_request.ExtPageType = mpi_reply->ExtPageType;
900 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
901 if (mem.config_page_sz > ioc->config_page_sz) {
902 r = _config_alloc_config_dma_memory(ioc, &mem);
906 mem.config_page_dma = ioc->config_page_dma;
907 mem.config_page = ioc->config_page;
909 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
910 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
911 mem.config_page_dma);
912 r = _config_request(ioc, &mpi_request, mpi_reply,
913 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
915 memcpy(config_page, mem.config_page,
916 min_t(u16, mem.config_page_sz,
917 sizeof(Mpi2SasDevicePage1_t)));
919 if (mem.config_page_sz > ioc->config_page_sz)
920 _config_free_config_dma_memory(ioc, &mem);
927 * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
928 * @ioc: per adapter object
929 * @num_phys: pointer returned with the number of phys
932 * Returns 0 for success, non-zero for failure.
935 mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
937 Mpi2ConfigRequest_t mpi_request;
939 struct config_request mem;
941 Mpi2ConfigReply_t mpi_reply;
942 Mpi2SasIOUnitPage0_t config_page;
944 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
945 mpi_request.Function = MPI2_FUNCTION_CONFIG;
946 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
947 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
948 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
949 mpi_request.Header.PageNumber = 0;
950 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
951 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
952 r = _config_request(ioc, &mpi_request, &mpi_reply,
953 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
957 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
958 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
959 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
960 mpi_request.Header.PageType = mpi_reply.Header.PageType;
961 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
962 mpi_request.ExtPageType = mpi_reply.ExtPageType;
963 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
964 if (mem.config_page_sz > ioc->config_page_sz) {
965 r = _config_alloc_config_dma_memory(ioc, &mem);
969 mem.config_page_dma = ioc->config_page_dma;
970 mem.config_page = ioc->config_page;
972 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
973 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
974 mem.config_page_dma);
975 r = _config_request(ioc, &mpi_request, &mpi_reply,
976 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
978 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
980 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
981 memcpy(&config_page, mem.config_page,
982 min_t(u16, mem.config_page_sz,
983 sizeof(Mpi2SasIOUnitPage0_t)));
984 *num_phys = config_page.NumPhys;
988 if (mem.config_page_sz > ioc->config_page_sz)
989 _config_free_config_dma_memory(ioc, &mem);
996 * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
997 * @ioc: per adapter object
998 * @mpi_reply: reply mf payload returned from firmware
999 * @config_page: contents of the config page
1000 * @sz: size of buffer passed in config_page
1003 * Calling function should call config_get_number_hba_phys prior to
1004 * this function, so enough memory is allocated for config_page.
1006 * Returns 0 for success, non-zero for failure.
1009 mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1010 *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz)
1012 Mpi2ConfigRequest_t mpi_request;
1014 struct config_request mem;
1015 memset(config_page, 0, sz);
1016 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1017 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1018 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1019 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1020 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1021 mpi_request.Header.PageNumber = 0;
1022 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1023 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1024 r = _config_request(ioc, &mpi_request, mpi_reply,
1025 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1029 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1030 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1031 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1032 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1033 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1034 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1035 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1036 if (mem.config_page_sz > ioc->config_page_sz) {
1037 r = _config_alloc_config_dma_memory(ioc, &mem);
1041 mem.config_page_dma = ioc->config_page_dma;
1042 mem.config_page = ioc->config_page;
1044 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1045 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1046 mem.config_page_dma);
1047 r = _config_request(ioc, &mpi_request, mpi_reply,
1048 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1050 memcpy(config_page, mem.config_page,
1051 min_t(u16, sz, mem.config_page_sz));
1053 if (mem.config_page_sz > ioc->config_page_sz)
1054 _config_free_config_dma_memory(ioc, &mem);
1061 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0
1062 * @ioc: per adapter object
1063 * @mpi_reply: reply mf payload returned from firmware
1064 * @config_page: contents of the config page
1065 * @sz: size of buffer passed in config_page
1068 * Calling function should call config_get_number_hba_phys prior to
1069 * this function, so enough memory is allocated for config_page.
1071 * Returns 0 for success, non-zero for failure.
1074 mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1075 *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz)
1077 Mpi2ConfigRequest_t mpi_request;
1079 struct config_request mem;
1081 memset(config_page, 0, sz);
1082 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1083 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1084 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1085 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1086 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1087 mpi_request.Header.PageNumber = 1;
1088 mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
1089 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1090 r = _config_request(ioc, &mpi_request, mpi_reply,
1091 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1095 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1096 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1097 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1098 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1099 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1100 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1101 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1102 if (mem.config_page_sz > ioc->config_page_sz) {
1103 r = _config_alloc_config_dma_memory(ioc, &mem);
1107 mem.config_page_dma = ioc->config_page_dma;
1108 mem.config_page = ioc->config_page;
1110 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1111 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1112 mem.config_page_dma);
1113 r = _config_request(ioc, &mpi_request, mpi_reply,
1114 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1116 memcpy(config_page, mem.config_page,
1117 min_t(u16, sz, mem.config_page_sz));
1119 if (mem.config_page_sz > ioc->config_page_sz)
1120 _config_free_config_dma_memory(ioc, &mem);
1127 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
1128 * @ioc: per adapter object
1129 * @mpi_reply: reply mf payload returned from firmware
1130 * @config_page: contents of the config page
1131 * @form: GET_NEXT_HANDLE or HANDLE
1132 * @handle: expander handle
1135 * Returns 0 for success, non-zero for failure.
1138 mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1139 *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
1141 Mpi2ConfigRequest_t mpi_request;
1143 struct config_request mem;
1145 memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
1146 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1147 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1148 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1149 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1150 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1151 mpi_request.Header.PageNumber = 0;
1152 mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
1153 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1154 r = _config_request(ioc, &mpi_request, mpi_reply,
1155 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1159 mpi_request.PageAddress = cpu_to_le32(form | handle);
1160 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1161 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1162 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1163 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1164 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1165 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1166 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1167 if (mem.config_page_sz > ioc->config_page_sz) {
1168 r = _config_alloc_config_dma_memory(ioc, &mem);
1172 mem.config_page_dma = ioc->config_page_dma;
1173 mem.config_page = ioc->config_page;
1175 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1176 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1177 mem.config_page_dma);
1178 r = _config_request(ioc, &mpi_request, mpi_reply,
1179 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1181 memcpy(config_page, mem.config_page,
1182 min_t(u16, mem.config_page_sz,
1183 sizeof(Mpi2ExpanderPage0_t)));
1185 if (mem.config_page_sz > ioc->config_page_sz)
1186 _config_free_config_dma_memory(ioc, &mem);
1193 * mpt2sas_config_get_expander_pg1 - obtain expander page 1
1194 * @ioc: per adapter object
1195 * @mpi_reply: reply mf payload returned from firmware
1196 * @config_page: contents of the config page
1197 * @phy_number: phy number
1198 * @handle: expander handle
1201 * Returns 0 for success, non-zero for failure.
1204 mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1205 *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
1208 Mpi2ConfigRequest_t mpi_request;
1210 struct config_request mem;
1212 memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
1213 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1214 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1215 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1216 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1217 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1218 mpi_request.Header.PageNumber = 1;
1219 mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
1220 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1221 r = _config_request(ioc, &mpi_request, mpi_reply,
1222 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1226 mpi_request.PageAddress =
1227 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
1228 (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
1229 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1230 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1231 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1232 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1233 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1234 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1235 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1236 if (mem.config_page_sz > ioc->config_page_sz) {
1237 r = _config_alloc_config_dma_memory(ioc, &mem);
1241 mem.config_page_dma = ioc->config_page_dma;
1242 mem.config_page = ioc->config_page;
1244 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1245 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1246 mem.config_page_dma);
1247 r = _config_request(ioc, &mpi_request, mpi_reply,
1248 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1250 memcpy(config_page, mem.config_page,
1251 min_t(u16, mem.config_page_sz,
1252 sizeof(Mpi2ExpanderPage1_t)));
1254 if (mem.config_page_sz > ioc->config_page_sz)
1255 _config_free_config_dma_memory(ioc, &mem);
1262 * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
1263 * @ioc: per adapter object
1264 * @mpi_reply: reply mf payload returned from firmware
1265 * @config_page: contents of the config page
1266 * @form: GET_NEXT_HANDLE or HANDLE
1267 * @handle: expander handle
1270 * Returns 0 for success, non-zero for failure.
1273 mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1274 *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
1276 Mpi2ConfigRequest_t mpi_request;
1278 struct config_request mem;
1280 memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
1281 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1282 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1283 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1284 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1285 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
1286 mpi_request.Header.PageNumber = 0;
1287 mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
1288 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1289 r = _config_request(ioc, &mpi_request, mpi_reply,
1290 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1294 mpi_request.PageAddress = cpu_to_le32(form | handle);
1295 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1296 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1297 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1298 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1299 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1300 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1301 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1302 if (mem.config_page_sz > ioc->config_page_sz) {
1303 r = _config_alloc_config_dma_memory(ioc, &mem);
1307 mem.config_page_dma = ioc->config_page_dma;
1308 mem.config_page = ioc->config_page;
1310 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1311 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1312 mem.config_page_dma);
1313 r = _config_request(ioc, &mpi_request, mpi_reply,
1314 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1316 memcpy(config_page, mem.config_page,
1317 min_t(u16, mem.config_page_sz,
1318 sizeof(Mpi2SasEnclosurePage0_t)));
1320 if (mem.config_page_sz > ioc->config_page_sz)
1321 _config_free_config_dma_memory(ioc, &mem);
1328 * mpt2sas_config_get_phy_pg0 - obtain phy 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 * @phy_number: phy number
1335 * Returns 0 for success, non-zero for failure.
1338 mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1339 *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
1341 Mpi2ConfigRequest_t mpi_request;
1343 struct config_request mem;
1345 memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
1346 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1347 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1348 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1349 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1350 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1351 mpi_request.Header.PageNumber = 0;
1352 mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
1353 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1354 r = _config_request(ioc, &mpi_request, mpi_reply,
1355 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1359 mpi_request.PageAddress =
1360 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1361 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1362 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1363 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1364 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1365 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1366 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1367 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1368 if (mem.config_page_sz > ioc->config_page_sz) {
1369 r = _config_alloc_config_dma_memory(ioc, &mem);
1373 mem.config_page_dma = ioc->config_page_dma;
1374 mem.config_page = ioc->config_page;
1376 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1377 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1378 mem.config_page_dma);
1379 r = _config_request(ioc, &mpi_request, mpi_reply,
1380 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1382 memcpy(config_page, mem.config_page,
1383 min_t(u16, mem.config_page_sz,
1384 sizeof(Mpi2SasPhyPage0_t)));
1386 if (mem.config_page_sz > ioc->config_page_sz)
1387 _config_free_config_dma_memory(ioc, &mem);
1394 * mpt2sas_config_get_phy_pg1 - obtain phy page 1
1395 * @ioc: per adapter object
1396 * @mpi_reply: reply mf payload returned from firmware
1397 * @config_page: contents of the config page
1398 * @phy_number: phy number
1401 * Returns 0 for success, non-zero for failure.
1404 mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1405 *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
1407 Mpi2ConfigRequest_t mpi_request;
1409 struct config_request mem;
1411 memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
1412 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1413 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1414 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1415 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1416 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
1417 mpi_request.Header.PageNumber = 1;
1418 mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
1419 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1420 r = _config_request(ioc, &mpi_request, mpi_reply,
1421 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1425 mpi_request.PageAddress =
1426 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
1427 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1428 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1429 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1430 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1431 mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
1432 mpi_request.ExtPageType = mpi_reply->ExtPageType;
1433 mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
1434 if (mem.config_page_sz > ioc->config_page_sz) {
1435 r = _config_alloc_config_dma_memory(ioc, &mem);
1439 mem.config_page_dma = ioc->config_page_dma;
1440 mem.config_page = ioc->config_page;
1442 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1443 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1444 mem.config_page_dma);
1445 r = _config_request(ioc, &mpi_request, mpi_reply,
1446 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1448 memcpy(config_page, mem.config_page,
1449 min_t(u16, mem.config_page_sz,
1450 sizeof(Mpi2SasPhyPage1_t)));
1452 if (mem.config_page_sz > ioc->config_page_sz)
1453 _config_free_config_dma_memory(ioc, &mem);
1460 * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1461 * @ioc: per adapter object
1462 * @mpi_reply: reply mf payload returned from firmware
1463 * @config_page: contents of the config page
1464 * @form: GET_NEXT_HANDLE or HANDLE
1465 * @handle: volume handle
1468 * Returns 0 for success, non-zero for failure.
1471 mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
1472 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
1475 Mpi2ConfigRequest_t mpi_request;
1477 struct config_request mem;
1479 memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
1480 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1481 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1482 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1483 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1484 mpi_request.Header.PageNumber = 1;
1485 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
1486 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1487 r = _config_request(ioc, &mpi_request, mpi_reply,
1488 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1492 mpi_request.PageAddress = cpu_to_le32(form | handle);
1493 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1494 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1495 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1496 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1497 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1498 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1499 if (mem.config_page_sz > ioc->config_page_sz) {
1500 r = _config_alloc_config_dma_memory(ioc, &mem);
1504 mem.config_page_dma = ioc->config_page_dma;
1505 mem.config_page = ioc->config_page;
1507 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1508 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1509 mem.config_page_dma);
1510 r = _config_request(ioc, &mpi_request, mpi_reply,
1511 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1513 memcpy(config_page, mem.config_page,
1514 min_t(u16, mem.config_page_sz,
1515 sizeof(Mpi2RaidVolPage1_t)));
1517 if (mem.config_page_sz > ioc->config_page_sz)
1518 _config_free_config_dma_memory(ioc, &mem);
1525 * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
1526 * @ioc: per adapter object
1527 * @handle: volume handle
1528 * @num_pds: returns pds count
1531 * Returns 0 for success, non-zero for failure.
1534 mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
1537 Mpi2ConfigRequest_t mpi_request;
1538 Mpi2RaidVolPage0_t *config_page;
1539 Mpi2ConfigReply_t mpi_reply;
1541 struct config_request mem;
1544 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1546 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1547 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1548 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1549 mpi_request.Header.PageNumber = 0;
1550 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1551 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1552 r = _config_request(ioc, &mpi_request, &mpi_reply,
1553 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1557 mpi_request.PageAddress =
1558 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
1559 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1560 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1561 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1562 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1563 mpi_request.Header.PageLength = mpi_reply.Header.PageLength;
1564 mem.config_page_sz = le16_to_cpu(mpi_reply.Header.PageLength) * 4;
1565 if (mem.config_page_sz > ioc->config_page_sz) {
1566 r = _config_alloc_config_dma_memory(ioc, &mem);
1570 mem.config_page_dma = ioc->config_page_dma;
1571 mem.config_page = ioc->config_page;
1573 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1574 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1575 mem.config_page_dma);
1576 r = _config_request(ioc, &mpi_request, &mpi_reply,
1577 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1579 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1580 MPI2_IOCSTATUS_MASK;
1581 if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
1582 config_page = mem.config_page;
1583 *num_pds = config_page->NumPhysDisks;
1587 if (mem.config_page_sz > ioc->config_page_sz)
1588 _config_free_config_dma_memory(ioc, &mem);
1595 * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1596 * @ioc: per adapter object
1597 * @mpi_reply: reply mf payload returned from firmware
1598 * @config_page: contents of the config page
1599 * @form: GET_NEXT_HANDLE or HANDLE
1600 * @handle: volume handle
1601 * @sz: size of buffer passed in config_page
1604 * Returns 0 for success, non-zero for failure.
1607 mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
1608 Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
1611 Mpi2ConfigRequest_t mpi_request;
1613 struct config_request mem;
1615 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1616 memset(config_page, 0, sz);
1617 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1618 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1619 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1620 mpi_request.Header.PageNumber = 0;
1621 mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
1622 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1623 r = _config_request(ioc, &mpi_request, mpi_reply,
1624 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1628 mpi_request.PageAddress = cpu_to_le32(form | handle);
1629 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1630 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1631 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1632 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1633 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1634 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1635 if (mem.config_page_sz > ioc->config_page_sz) {
1636 r = _config_alloc_config_dma_memory(ioc, &mem);
1640 mem.config_page_dma = ioc->config_page_dma;
1641 mem.config_page = ioc->config_page;
1643 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1644 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1645 mem.config_page_dma);
1646 r = _config_request(ioc, &mpi_request, mpi_reply,
1647 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1649 memcpy(config_page, mem.config_page,
1650 min_t(u16, sz, mem.config_page_sz));
1652 if (mem.config_page_sz > ioc->config_page_sz)
1653 _config_free_config_dma_memory(ioc, &mem);
1660 * mpt2sas_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
1668 * Returns 0 for success, non-zero for failure.
1671 mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
1672 *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
1675 Mpi2ConfigRequest_t mpi_request;
1677 struct config_request mem;
1679 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1680 memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
1681 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1682 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1683 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1684 mpi_request.Header.PageNumber = 0;
1685 mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
1686 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1687 r = _config_request(ioc, &mpi_request, mpi_reply,
1688 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1692 mpi_request.PageAddress = cpu_to_le32(form | form_specific);
1693 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1694 mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
1695 mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
1696 mpi_request.Header.PageType = mpi_reply->Header.PageType;
1697 mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
1698 mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
1699 if (mem.config_page_sz > ioc->config_page_sz) {
1700 r = _config_alloc_config_dma_memory(ioc, &mem);
1704 mem.config_page_dma = ioc->config_page_dma;
1705 mem.config_page = ioc->config_page;
1707 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1708 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1709 mem.config_page_dma);
1710 r = _config_request(ioc, &mpi_request, mpi_reply,
1711 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1713 memcpy(config_page, mem.config_page,
1714 min_t(u16, mem.config_page_sz,
1715 sizeof(Mpi2RaidPhysDiskPage0_t)));
1717 if (mem.config_page_sz > ioc->config_page_sz)
1718 _config_free_config_dma_memory(ioc, &mem);
1725 * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
1726 * @ioc: per adapter object
1727 * @pd_handle: phys disk handle
1728 * @volume_handle: volume handle
1731 * Returns 0 for success, non-zero for failure.
1734 mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1737 Mpi2RaidConfigurationPage0_t *config_page;
1738 Mpi2ConfigRequest_t mpi_request;
1739 Mpi2ConfigReply_t mpi_reply;
1741 struct config_request mem;
1745 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
1746 mpi_request.Function = MPI2_FUNCTION_CONFIG;
1747 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1748 mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1749 mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
1750 mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
1751 mpi_request.Header.PageNumber = 0;
1752 mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
1753 r = _config_request(ioc, &mpi_request, &mpi_reply,
1754 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1758 mpi_request.PageAddress =
1759 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
1760 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1761 mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
1762 mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
1763 mpi_request.Header.PageType = mpi_reply.Header.PageType;
1764 mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
1765 mpi_request.ExtPageType = mpi_reply.ExtPageType;
1766 mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
1767 if (mem.config_page_sz > ioc->config_page_sz) {
1768 r = _config_alloc_config_dma_memory(ioc, &mem);
1772 mem.config_page_dma = ioc->config_page_dma;
1773 mem.config_page = ioc->config_page;
1775 ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
1776 MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
1777 mem.config_page_dma);
1778 r = _config_request(ioc, &mpi_request, &mpi_reply,
1779 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
1784 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
1785 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1787 config_page = mem.config_page;
1788 for (i = 0; i < config_page->NumElements; i++) {
1789 if ((config_page->ConfigElement[i].ElementFlags &
1790 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
1791 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
1793 if (config_page->ConfigElement[i].PhysDiskDevHandle ==
1795 *volume_handle = le16_to_cpu(config_page->
1796 ConfigElement[i].VolDevHandle);
1803 if (mem.config_page_sz > ioc->config_page_sz)
1804 _config_free_config_dma_memory(ioc, &mem);
1811 * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
1812 * @ioc: per adapter object
1813 * @volume_handle: volume handle
1814 * @wwid: volume wwid
1817 * Returns 0 for success, non-zero for failure.
1820 mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
1823 Mpi2ConfigReply_t mpi_reply;
1824 Mpi2RaidVolPage1_t raid_vol_pg1;
1827 if (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1828 &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
1830 *wwid = le64_to_cpu(raid_vol_pg1.WWID);