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-2014 LSI Corporation
6 * Copyright (C) 20013-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.
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,
45 #include <linux/module.h>
46 #include <linux/kernel.h>
47 #include <linux/init.h>
48 #include <linux/errno.h>
49 #include <linux/blkdev.h>
50 #include <linux/sched.h>
51 #include <linux/workqueue.h>
52 #include <linux/delay.h>
53 #include <linux/pci.h>
54 #include <linux/slab.h>
56 #include "mpt2sas_base.h"
58 /* local definitions */
60 /* Timeout for config page request (in seconds) */
61 #define MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT 15
63 /* Common sgl flags for READING a config page. */
64 #define MPT2_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
65 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
66 | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
68 /* Common sgl flags for WRITING a config page. */
69 #define MPT2_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
70 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
71 | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
72 << MPI2_SGE_FLAGS_SHIFT)
75 * struct config_request - obtain dma memory via routine
78 * @page_dma: phys pointer
81 struct config_request
{
87 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
89 * _config_display_some_debug - debug routine
90 * @ioc: per adapter object
91 * @smid: system request message index
92 * @calling_function_name: string pass from calling function
93 * @mpi_reply: reply message frame
96 * Function for displaying debug info helpful when debugging issues
100 _config_display_some_debug(struct MPT2SAS_ADAPTER
*ioc
, u16 smid
,
101 char *calling_function_name
, MPI2DefaultReply_t
*mpi_reply
)
103 Mpi2ConfigRequest_t
*mpi_request
;
106 if (!(ioc
->logging_level
& MPT_DEBUG_CONFIG
))
109 mpi_request
= mpt2sas_base_get_msg_frame(ioc
, smid
);
110 switch (mpi_request
->Header
.PageType
& MPI2_CONFIG_PAGETYPE_MASK
) {
111 case MPI2_CONFIG_PAGETYPE_IO_UNIT
:
114 case MPI2_CONFIG_PAGETYPE_IOC
:
117 case MPI2_CONFIG_PAGETYPE_BIOS
:
120 case MPI2_CONFIG_PAGETYPE_RAID_VOLUME
:
121 desc
= "raid_volume";
123 case MPI2_CONFIG_PAGETYPE_MANUFACTURING
:
124 desc
= "manufaucturing";
126 case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK
:
129 case MPI2_CONFIG_PAGETYPE_EXTENDED
:
130 switch (mpi_request
->ExtPageType
) {
131 case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
:
132 desc
= "sas_io_unit";
134 case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER
:
135 desc
= "sas_expander";
137 case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE
:
140 case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY
:
143 case MPI2_CONFIG_EXTPAGETYPE_LOG
:
146 case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE
:
149 case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG
:
150 desc
= "raid_config";
152 case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING
:
153 desc
= "driver_mapping";
162 printk(MPT2SAS_INFO_FMT
"%s: %s(%d), action(%d), form(0x%08x), "
163 "smid(%d)\n", ioc
->name
, calling_function_name
, desc
,
164 mpi_request
->Header
.PageNumber
, mpi_request
->Action
,
165 le32_to_cpu(mpi_request
->PageAddress
), smid
);
170 if (mpi_reply
->IOCStatus
|| mpi_reply
->IOCLogInfo
)
171 printk(MPT2SAS_INFO_FMT
172 "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
173 ioc
->name
, le16_to_cpu(mpi_reply
->IOCStatus
),
174 le32_to_cpu(mpi_reply
->IOCLogInfo
));
179 * _config_alloc_config_dma_memory - obtain physical memory
180 * @ioc: per adapter object
181 * @mem: struct config_request
183 * A wrapper for obtaining dma-able memory for config page request.
185 * Returns 0 for success, non-zero for failure.
188 _config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER
*ioc
,
189 struct config_request
*mem
)
193 if (mem
->sz
> ioc
->config_page_sz
) {
194 mem
->page
= dma_alloc_coherent(&ioc
->pdev
->dev
, mem
->sz
,
195 &mem
->page_dma
, GFP_KERNEL
);
197 printk(MPT2SAS_ERR_FMT
"%s: dma_alloc_coherent"
198 " failed asking for (%d) bytes!!\n",
199 ioc
->name
, __func__
, mem
->sz
);
202 } else { /* use tmp buffer if less than 512 bytes */
203 mem
->page
= ioc
->config_page
;
204 mem
->page_dma
= ioc
->config_page_dma
;
210 * _config_free_config_dma_memory - wrapper to free the memory
211 * @ioc: per adapter object
212 * @mem: struct config_request
214 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
216 * Returns 0 for success, non-zero for failure.
219 _config_free_config_dma_memory(struct MPT2SAS_ADAPTER
*ioc
,
220 struct config_request
*mem
)
222 if (mem
->sz
> ioc
->config_page_sz
)
223 dma_free_coherent(&ioc
->pdev
->dev
, mem
->sz
, mem
->page
,
228 * mpt2sas_config_done - config page completion routine
229 * @ioc: per adapter object
230 * @smid: system request message index
231 * @msix_index: MSIX table index supplied by the OS
232 * @reply: reply message frame(lower 32bit addr)
235 * The callback handler when using _config_request.
237 * Return 1 meaning mf should be freed from _base_interrupt
238 * 0 means the mf is freed from this function.
241 mpt2sas_config_done(struct MPT2SAS_ADAPTER
*ioc
, u16 smid
, u8 msix_index
,
244 MPI2DefaultReply_t
*mpi_reply
;
246 if (ioc
->config_cmds
.status
== MPT2_CMD_NOT_USED
)
248 if (ioc
->config_cmds
.smid
!= smid
)
250 ioc
->config_cmds
.status
|= MPT2_CMD_COMPLETE
;
251 mpi_reply
= mpt2sas_base_get_reply_virt_addr(ioc
, reply
);
253 ioc
->config_cmds
.status
|= MPT2_CMD_REPLY_VALID
;
254 memcpy(ioc
->config_cmds
.reply
, mpi_reply
,
255 mpi_reply
->MsgLength
*4);
257 ioc
->config_cmds
.status
&= ~MPT2_CMD_PENDING
;
258 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
259 _config_display_some_debug(ioc
, smid
, "config_done", mpi_reply
);
261 ioc
->config_cmds
.smid
= USHRT_MAX
;
262 complete(&ioc
->config_cmds
.done
);
267 * _config_request - main routine for sending config page requests
268 * @ioc: per adapter object
269 * @mpi_request: request message frame
270 * @mpi_reply: reply mf payload returned from firmware
271 * @timeout: timeout in seconds
272 * @config_page: contents of the config page
273 * @config_page_sz: size of config page
276 * A generic API for config page requests to firmware.
278 * The ioc->config_cmds.status flag should be MPT2_CMD_NOT_USED before calling
281 * The callback index is set inside `ioc->config_cb_idx.
283 * Returns 0 for success, non-zero for failure.
286 _config_request(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigRequest_t
287 *mpi_request
, Mpi2ConfigReply_t
*mpi_reply
, int timeout
,
288 void *config_page
, u16 config_page_sz
)
292 unsigned long timeleft
;
293 Mpi2ConfigRequest_t
*config_request
;
295 u8 retry_count
, issue_host_reset
= 0;
296 u16 wait_state_count
;
297 struct config_request mem
;
299 mutex_lock(&ioc
->config_cmds
.mutex
);
300 if (ioc
->config_cmds
.status
!= MPT2_CMD_NOT_USED
) {
301 printk(MPT2SAS_ERR_FMT
"%s: config_cmd in use\n",
302 ioc
->name
, __func__
);
303 mutex_unlock(&ioc
->config_cmds
.mutex
);
308 memset(&mem
, 0, sizeof(struct config_request
));
310 mpi_request
->VF_ID
= 0; /* TODO */
311 mpi_request
->VP_ID
= 0;
314 mpi_request
->Header
.PageVersion
= mpi_reply
->Header
.PageVersion
;
315 mpi_request
->Header
.PageNumber
= mpi_reply
->Header
.PageNumber
;
316 mpi_request
->Header
.PageType
= mpi_reply
->Header
.PageType
;
317 mpi_request
->Header
.PageLength
= mpi_reply
->Header
.PageLength
;
318 mpi_request
->ExtPageLength
= mpi_reply
->ExtPageLength
;
319 mpi_request
->ExtPageType
= mpi_reply
->ExtPageType
;
320 if (mpi_request
->Header
.PageLength
)
321 mem
.sz
= mpi_request
->Header
.PageLength
* 4;
323 mem
.sz
= le16_to_cpu(mpi_reply
->ExtPageLength
) * 4;
324 r
= _config_alloc_config_dma_memory(ioc
, &mem
);
327 if (mpi_request
->Action
==
328 MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT
||
329 mpi_request
->Action
==
330 MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM
) {
331 ioc
->base_add_sg_single(&mpi_request
->PageBufferSGE
,
332 MPT2_CONFIG_COMMON_WRITE_SGLFLAGS
| mem
.sz
,
334 memcpy(mem
.page
, config_page
, min_t(u16
, mem
.sz
,
337 memset(config_page
, 0, config_page_sz
);
338 ioc
->base_add_sg_single(&mpi_request
->PageBufferSGE
,
339 MPT2_CONFIG_COMMON_SGLFLAGS
| mem
.sz
, mem
.page_dma
);
345 if (retry_count
> 2) { /* attempt only 2 retries */
349 printk(MPT2SAS_INFO_FMT
"%s: attempting retry (%d)\n",
350 ioc
->name
, __func__
, retry_count
);
352 wait_state_count
= 0;
353 ioc_state
= mpt2sas_base_get_iocstate(ioc
, 1);
354 while (ioc_state
!= MPI2_IOC_STATE_OPERATIONAL
) {
355 if (wait_state_count
++ == MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
) {
356 printk(MPT2SAS_ERR_FMT
357 "%s: failed due to ioc not operational\n",
358 ioc
->name
, __func__
);
359 ioc
->config_cmds
.status
= MPT2_CMD_NOT_USED
;
364 ioc_state
= mpt2sas_base_get_iocstate(ioc
, 1);
365 printk(MPT2SAS_INFO_FMT
"%s: waiting for "
366 "operational state(count=%d)\n", ioc
->name
,
367 __func__
, wait_state_count
);
369 if (wait_state_count
)
370 printk(MPT2SAS_INFO_FMT
"%s: ioc is operational\n",
371 ioc
->name
, __func__
);
373 smid
= mpt2sas_base_get_smid(ioc
, ioc
->config_cb_idx
);
375 printk(MPT2SAS_ERR_FMT
"%s: failed obtaining a smid\n",
376 ioc
->name
, __func__
);
377 ioc
->config_cmds
.status
= MPT2_CMD_NOT_USED
;
383 memset(mpi_reply
, 0, sizeof(Mpi2ConfigReply_t
));
384 ioc
->config_cmds
.status
= MPT2_CMD_PENDING
;
385 config_request
= mpt2sas_base_get_msg_frame(ioc
, smid
);
386 ioc
->config_cmds
.smid
= smid
;
387 memcpy(config_request
, mpi_request
, sizeof(Mpi2ConfigRequest_t
));
388 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
389 _config_display_some_debug(ioc
, smid
, "config_request", NULL
);
391 init_completion(&ioc
->config_cmds
.done
);
392 mpt2sas_base_put_smid_default(ioc
, smid
);
393 timeleft
= wait_for_completion_timeout(&ioc
->config_cmds
.done
,
395 if (!(ioc
->config_cmds
.status
& MPT2_CMD_COMPLETE
)) {
396 printk(MPT2SAS_ERR_FMT
"%s: timeout\n",
397 ioc
->name
, __func__
);
398 _debug_dump_mf(mpi_request
,
399 sizeof(Mpi2ConfigRequest_t
)/4);
401 if (ioc
->config_cmds
.smid
== smid
)
402 mpt2sas_base_free_smid(ioc
, smid
);
403 if ((ioc
->shost_recovery
) || (ioc
->config_cmds
.status
&
404 MPT2_CMD_RESET
) || ioc
->pci_error_recovery
)
406 issue_host_reset
= 1;
411 if (ioc
->config_cmds
.status
& MPT2_CMD_REPLY_VALID
)
412 memcpy(mpi_reply
, ioc
->config_cmds
.reply
,
413 sizeof(Mpi2ConfigReply_t
));
415 printk(MPT2SAS_INFO_FMT
"%s: retry (%d) completed!!\n",
416 ioc
->name
, __func__
, retry_count
);
417 if (config_page
&& mpi_request
->Action
==
418 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
)
419 memcpy(config_page
, mem
.page
, min_t(u16
, mem
.sz
,
423 _config_free_config_dma_memory(ioc
, &mem
);
425 ioc
->config_cmds
.status
= MPT2_CMD_NOT_USED
;
426 mutex_unlock(&ioc
->config_cmds
.mutex
);
428 if (issue_host_reset
)
429 mpt2sas_base_hard_reset_handler(ioc
, CAN_SLEEP
,
435 * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
436 * @ioc: per adapter object
437 * @mpi_reply: reply mf payload returned from firmware
438 * @config_page: contents of the config page
441 * Returns 0 for success, non-zero for failure.
444 mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER
*ioc
,
445 Mpi2ConfigReply_t
*mpi_reply
, Mpi2ManufacturingPage0_t
*config_page
)
447 Mpi2ConfigRequest_t mpi_request
;
450 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
451 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
452 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
453 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_MANUFACTURING
;
454 mpi_request
.Header
.PageNumber
= 0;
455 mpi_request
.Header
.PageVersion
= MPI2_MANUFACTURING0_PAGEVERSION
;
456 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
457 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
458 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
462 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
463 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
464 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
465 sizeof(*config_page
));
471 * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
472 * @ioc: per adapter object
473 * @mpi_reply: reply mf payload returned from firmware
474 * @config_page: contents of the config page
477 * Returns 0 for success, non-zero for failure.
480 mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER
*ioc
,
481 Mpi2ConfigReply_t
*mpi_reply
, Mpi2ManufacturingPage10_t
*config_page
)
483 Mpi2ConfigRequest_t mpi_request
;
486 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
487 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
488 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
489 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_MANUFACTURING
;
490 mpi_request
.Header
.PageNumber
= 10;
491 mpi_request
.Header
.PageVersion
= MPI2_MANUFACTURING0_PAGEVERSION
;
492 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
493 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
494 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
498 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
499 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
500 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
501 sizeof(*config_page
));
507 * mpt2sas_config_get_bios_pg2 - obtain bios page 2
508 * @ioc: per adapter object
509 * @mpi_reply: reply mf payload returned from firmware
510 * @config_page: contents of the config page
513 * Returns 0 for success, non-zero for failure.
516 mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER
*ioc
,
517 Mpi2ConfigReply_t
*mpi_reply
, Mpi2BiosPage2_t
*config_page
)
519 Mpi2ConfigRequest_t mpi_request
;
522 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
523 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
524 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
525 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_BIOS
;
526 mpi_request
.Header
.PageNumber
= 2;
527 mpi_request
.Header
.PageVersion
= MPI2_BIOSPAGE2_PAGEVERSION
;
528 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
529 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
530 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
534 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
535 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
536 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
537 sizeof(*config_page
));
543 * mpt2sas_config_get_bios_pg3 - obtain bios page 3
544 * @ioc: per adapter object
545 * @mpi_reply: reply mf payload returned from firmware
546 * @config_page: contents of the config page
549 * Returns 0 for success, non-zero for failure.
552 mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
553 *mpi_reply
, Mpi2BiosPage3_t
*config_page
)
555 Mpi2ConfigRequest_t mpi_request
;
558 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
559 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
560 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
561 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_BIOS
;
562 mpi_request
.Header
.PageNumber
= 3;
563 mpi_request
.Header
.PageVersion
= MPI2_BIOSPAGE3_PAGEVERSION
;
564 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
565 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
566 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
570 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
571 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
572 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
573 sizeof(*config_page
));
579 * mpt2sas_config_get_iounit_pg0 - obtain iounit page 0
580 * @ioc: per adapter object
581 * @mpi_reply: reply mf payload returned from firmware
582 * @config_page: contents of the config page
585 * Returns 0 for success, non-zero for failure.
588 mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER
*ioc
,
589 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOUnitPage0_t
*config_page
)
591 Mpi2ConfigRequest_t mpi_request
;
594 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
595 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
596 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
597 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IO_UNIT
;
598 mpi_request
.Header
.PageNumber
= 0;
599 mpi_request
.Header
.PageVersion
= MPI2_IOUNITPAGE0_PAGEVERSION
;
600 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
601 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
602 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
606 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
607 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
608 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
609 sizeof(*config_page
));
615 * mpt2sas_config_get_iounit_pg1 - obtain iounit page 1
616 * @ioc: per adapter object
617 * @mpi_reply: reply mf payload returned from firmware
618 * @config_page: contents of the config page
621 * Returns 0 for success, non-zero for failure.
624 mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
,
625 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOUnitPage1_t
*config_page
)
627 Mpi2ConfigRequest_t mpi_request
;
630 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
631 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
632 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
633 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IO_UNIT
;
634 mpi_request
.Header
.PageNumber
= 1;
635 mpi_request
.Header
.PageVersion
= MPI2_IOUNITPAGE1_PAGEVERSION
;
636 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
637 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
638 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
642 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
643 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
644 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
645 sizeof(*config_page
));
651 * mpt2sas_config_set_iounit_pg1 - set iounit page 1
652 * @ioc: per adapter object
653 * @mpi_reply: reply mf payload returned from firmware
654 * @config_page: contents of the config page
657 * Returns 0 for success, non-zero for failure.
660 mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
,
661 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOUnitPage1_t
*config_page
)
663 Mpi2ConfigRequest_t mpi_request
;
666 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
667 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
668 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
669 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IO_UNIT
;
670 mpi_request
.Header
.PageNumber
= 1;
671 mpi_request
.Header
.PageVersion
= MPI2_IOUNITPAGE1_PAGEVERSION
;
672 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
673 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
674 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
678 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
679 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
680 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
681 sizeof(*config_page
));
687 * mpt2sas_config_get_iounit_pg3 - obtain iounit page 3
688 * @ioc: per adapter object
689 * @mpi_reply: reply mf payload returned from firmware
690 * @config_page: contents of the config page
691 * @sz: size of buffer passed in config_page
694 * Returns 0 for success, non-zero for failure.
697 mpt2sas_config_get_iounit_pg3(struct MPT2SAS_ADAPTER
*ioc
,
698 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOUnitPage3_t
*config_page
, u16 sz
)
700 Mpi2ConfigRequest_t mpi_request
;
703 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
704 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
705 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
706 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IO_UNIT
;
707 mpi_request
.Header
.PageNumber
= 3;
708 mpi_request
.Header
.PageVersion
= MPI2_IOUNITPAGE3_PAGEVERSION
;
709 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
710 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
711 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
715 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
716 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
717 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
723 * mpt2sas_config_get_iounit_pg8 - obtain iounit page 8
724 * @ioc: per adapter object
725 * @mpi_reply: reply mf payload returned from firmware
726 * @config_page: contents of the config page
729 * Returns 0 for success, non-zero for failure.
732 mpt2sas_config_get_iounit_pg8(struct MPT2SAS_ADAPTER
*ioc
,
733 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOUnitPage8_t
*config_page
)
735 Mpi2ConfigRequest_t mpi_request
;
738 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
739 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
740 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
741 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IO_UNIT
;
742 mpi_request
.Header
.PageNumber
= 8;
743 mpi_request
.Header
.PageVersion
= MPI2_IOUNITPAGE8_PAGEVERSION
;
744 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
745 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
746 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
750 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
751 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
752 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
753 sizeof(*config_page
));
759 * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8
760 * @ioc: per adapter object
761 * @mpi_reply: reply mf payload returned from firmware
762 * @config_page: contents of the config page
765 * Returns 0 for success, non-zero for failure.
768 mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER
*ioc
,
769 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOCPage8_t
*config_page
)
771 Mpi2ConfigRequest_t mpi_request
;
774 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
775 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
776 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
777 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IOC
;
778 mpi_request
.Header
.PageNumber
= 8;
779 mpi_request
.Header
.PageVersion
= MPI2_IOCPAGE8_PAGEVERSION
;
780 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
781 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
782 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
786 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
787 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
788 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
789 sizeof(*config_page
));
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
;
812 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
813 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
814 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
815 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
816 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE
;
817 mpi_request
.Header
.PageVersion
= MPI2_SASDEVICE0_PAGEVERSION
;
818 mpi_request
.Header
.PageNumber
= 0;
819 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
820 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
821 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
825 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
826 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
827 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
828 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
829 sizeof(*config_page
));
835 * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
836 * @ioc: per adapter object
837 * @mpi_reply: reply mf payload returned from firmware
838 * @config_page: contents of the config page
839 * @form: GET_NEXT_HANDLE or HANDLE
840 * @handle: device handle
843 * Returns 0 for success, non-zero for failure.
846 mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
847 *mpi_reply
, Mpi2SasDevicePage1_t
*config_page
, u32 form
, u32 handle
)
849 Mpi2ConfigRequest_t mpi_request
;
852 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
853 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
854 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
855 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
856 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE
;
857 mpi_request
.Header
.PageVersion
= MPI2_SASDEVICE1_PAGEVERSION
;
858 mpi_request
.Header
.PageNumber
= 1;
859 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
860 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
861 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
865 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
866 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
867 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
868 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
869 sizeof(*config_page
));
875 * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
876 * @ioc: per adapter object
877 * @num_phys: pointer returned with the number of phys
880 * Returns 0 for success, non-zero for failure.
883 mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER
*ioc
, u8
*num_phys
)
885 Mpi2ConfigRequest_t mpi_request
;
888 Mpi2ConfigReply_t mpi_reply
;
889 Mpi2SasIOUnitPage0_t config_page
;
892 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
893 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
894 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
895 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
896 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
897 mpi_request
.Header
.PageNumber
= 0;
898 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE0_PAGEVERSION
;
899 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
900 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
901 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
905 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
906 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
907 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, &config_page
,
908 sizeof(Mpi2SasIOUnitPage0_t
));
910 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
912 if (ioc_status
== MPI2_IOCSTATUS_SUCCESS
)
913 *num_phys
= config_page
.NumPhys
;
920 * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
921 * @ioc: per adapter object
922 * @mpi_reply: reply mf payload returned from firmware
923 * @config_page: contents of the config page
924 * @sz: size of buffer passed in config_page
927 * Calling function should call config_get_number_hba_phys prior to
928 * this function, so enough memory is allocated for config_page.
930 * Returns 0 for success, non-zero for failure.
933 mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
934 *mpi_reply
, Mpi2SasIOUnitPage0_t
*config_page
, u16 sz
)
936 Mpi2ConfigRequest_t mpi_request
;
939 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
940 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
941 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
942 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
943 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
944 mpi_request
.Header
.PageNumber
= 0;
945 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE0_PAGEVERSION
;
946 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
947 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
948 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
952 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
953 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
954 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
960 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
961 * @ioc: per adapter object
962 * @mpi_reply: reply mf payload returned from firmware
963 * @config_page: contents of the config page
964 * @sz: size of buffer passed in config_page
967 * Calling function should call config_get_number_hba_phys prior to
968 * this function, so enough memory is allocated for config_page.
970 * Returns 0 for success, non-zero for failure.
973 mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
974 *mpi_reply
, Mpi2SasIOUnitPage1_t
*config_page
, u16 sz
)
976 Mpi2ConfigRequest_t mpi_request
;
979 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
980 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
981 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
982 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
983 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
984 mpi_request
.Header
.PageNumber
= 1;
985 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE1_PAGEVERSION
;
986 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
987 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
988 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
992 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
993 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
994 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
1000 * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
1001 * @ioc: per adapter object
1002 * @mpi_reply: reply mf payload returned from firmware
1003 * @config_page: contents of the config page
1004 * @sz: size of buffer passed in config_page
1007 * Calling function should call config_get_number_hba_phys prior to
1008 * this function, so enough memory is allocated for config_page.
1010 * Returns 0 for success, non-zero for failure.
1013 mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1014 *mpi_reply
, Mpi2SasIOUnitPage1_t
*config_page
, u16 sz
)
1016 Mpi2ConfigRequest_t mpi_request
;
1019 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1020 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1021 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1022 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1023 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
1024 mpi_request
.Header
.PageNumber
= 1;
1025 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE1_PAGEVERSION
;
1026 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1027 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1028 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1032 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
1033 _config_request(ioc
, &mpi_request
, mpi_reply
,
1034 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
1035 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
1036 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1037 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
1043 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
1044 * @ioc: per adapter object
1045 * @mpi_reply: reply mf payload returned from firmware
1046 * @config_page: contents of the config page
1047 * @form: GET_NEXT_HANDLE or HANDLE
1048 * @handle: expander handle
1051 * Returns 0 for success, non-zero for failure.
1054 mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1055 *mpi_reply
, Mpi2ExpanderPage0_t
*config_page
, u32 form
, u32 handle
)
1057 Mpi2ConfigRequest_t mpi_request
;
1060 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1061 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1062 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1063 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1064 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
1065 mpi_request
.Header
.PageNumber
= 0;
1066 mpi_request
.Header
.PageVersion
= MPI2_SASEXPANDER0_PAGEVERSION
;
1067 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1068 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1069 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1073 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1074 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1075 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1076 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1077 sizeof(*config_page
));
1083 * mpt2sas_config_get_expander_pg1 - obtain expander page 1
1084 * @ioc: per adapter object
1085 * @mpi_reply: reply mf payload returned from firmware
1086 * @config_page: contents of the config page
1087 * @phy_number: phy number
1088 * @handle: expander handle
1091 * Returns 0 for success, non-zero for failure.
1094 mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1095 *mpi_reply
, Mpi2ExpanderPage1_t
*config_page
, u32 phy_number
,
1098 Mpi2ConfigRequest_t mpi_request
;
1101 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1102 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1103 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1104 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1105 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
1106 mpi_request
.Header
.PageNumber
= 1;
1107 mpi_request
.Header
.PageVersion
= MPI2_SASEXPANDER1_PAGEVERSION
;
1108 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1109 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1110 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1114 mpi_request
.PageAddress
=
1115 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM
|
1116 (phy_number
<< MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT
) | handle
);
1117 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1118 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1119 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1120 sizeof(*config_page
));
1126 * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
1127 * @ioc: per adapter object
1128 * @mpi_reply: reply mf payload returned from firmware
1129 * @config_page: contents of the config page
1130 * @form: GET_NEXT_HANDLE or HANDLE
1131 * @handle: expander handle
1134 * Returns 0 for success, non-zero for failure.
1137 mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1138 *mpi_reply
, Mpi2SasEnclosurePage0_t
*config_page
, u32 form
, u32 handle
)
1140 Mpi2ConfigRequest_t mpi_request
;
1143 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1144 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1145 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1146 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1147 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE
;
1148 mpi_request
.Header
.PageNumber
= 0;
1149 mpi_request
.Header
.PageVersion
= MPI2_SASENCLOSURE0_PAGEVERSION
;
1150 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1151 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1152 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1156 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1157 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1158 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1159 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1160 sizeof(*config_page
));
1166 * mpt2sas_config_get_phy_pg0 - obtain phy page 0
1167 * @ioc: per adapter object
1168 * @mpi_reply: reply mf payload returned from firmware
1169 * @config_page: contents of the config page
1170 * @phy_number: phy number
1173 * Returns 0 for success, non-zero for failure.
1176 mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1177 *mpi_reply
, Mpi2SasPhyPage0_t
*config_page
, u32 phy_number
)
1179 Mpi2ConfigRequest_t mpi_request
;
1182 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1183 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1184 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1185 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1186 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_PHY
;
1187 mpi_request
.Header
.PageNumber
= 0;
1188 mpi_request
.Header
.PageVersion
= MPI2_SASPHY0_PAGEVERSION
;
1189 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1190 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1191 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1195 mpi_request
.PageAddress
=
1196 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER
| phy_number
);
1197 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1198 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1199 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1200 sizeof(*config_page
));
1206 * mpt2sas_config_get_phy_pg1 - obtain phy page 1
1207 * @ioc: per adapter object
1208 * @mpi_reply: reply mf payload returned from firmware
1209 * @config_page: contents of the config page
1210 * @phy_number: phy number
1213 * Returns 0 for success, non-zero for failure.
1216 mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1217 *mpi_reply
, Mpi2SasPhyPage1_t
*config_page
, u32 phy_number
)
1219 Mpi2ConfigRequest_t mpi_request
;
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_PHY
;
1227 mpi_request
.Header
.PageNumber
= 1;
1228 mpi_request
.Header
.PageVersion
= MPI2_SASPHY1_PAGEVERSION
;
1229 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1230 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1231 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1235 mpi_request
.PageAddress
=
1236 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER
| phy_number
);
1237 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1238 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1239 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1240 sizeof(*config_page
));
1246 * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1247 * @ioc: per adapter object
1248 * @mpi_reply: reply mf payload returned from firmware
1249 * @config_page: contents of the config page
1250 * @form: GET_NEXT_HANDLE or HANDLE
1251 * @handle: volume handle
1254 * Returns 0 for success, non-zero for failure.
1257 mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER
*ioc
,
1258 Mpi2ConfigReply_t
*mpi_reply
, Mpi2RaidVolPage1_t
*config_page
, u32 form
,
1261 Mpi2ConfigRequest_t mpi_request
;
1264 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1265 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1266 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1267 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1268 mpi_request
.Header
.PageNumber
= 1;
1269 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE1_PAGEVERSION
;
1270 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1271 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1272 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1276 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1277 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1278 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1279 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1280 sizeof(*config_page
));
1286 * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
1287 * @ioc: per adapter object
1288 * @handle: volume handle
1289 * @num_pds: returns pds count
1292 * Returns 0 for success, non-zero for failure.
1295 mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER
*ioc
, u16 handle
,
1298 Mpi2ConfigRequest_t mpi_request
;
1299 Mpi2RaidVolPage0_t config_page
;
1300 Mpi2ConfigReply_t mpi_reply
;
1304 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1306 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1307 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1308 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1309 mpi_request
.Header
.PageNumber
= 0;
1310 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE0_PAGEVERSION
;
1311 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1312 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1313 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1317 mpi_request
.PageAddress
=
1318 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE
| handle
);
1319 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1320 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1321 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, &config_page
,
1322 sizeof(Mpi2RaidVolPage0_t
));
1324 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1325 MPI2_IOCSTATUS_MASK
;
1326 if (ioc_status
== MPI2_IOCSTATUS_SUCCESS
)
1327 *num_pds
= config_page
.NumPhysDisks
;
1335 * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1336 * @ioc: per adapter object
1337 * @mpi_reply: reply mf payload returned from firmware
1338 * @config_page: contents of the config page
1339 * @form: GET_NEXT_HANDLE or HANDLE
1340 * @handle: volume handle
1341 * @sz: size of buffer passed in config_page
1344 * Returns 0 for success, non-zero for failure.
1347 mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER
*ioc
,
1348 Mpi2ConfigReply_t
*mpi_reply
, Mpi2RaidVolPage0_t
*config_page
, u32 form
,
1351 Mpi2ConfigRequest_t mpi_request
;
1354 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1355 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1356 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1357 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1358 mpi_request
.Header
.PageNumber
= 0;
1359 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE0_PAGEVERSION
;
1360 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1361 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1362 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1366 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1367 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1368 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1369 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
1375 * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1376 * @ioc: per adapter object
1377 * @mpi_reply: reply mf payload returned from firmware
1378 * @config_page: contents of the config page
1379 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1380 * @form_specific: specific to the form
1383 * Returns 0 for success, non-zero for failure.
1386 mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1387 *mpi_reply
, Mpi2RaidPhysDiskPage0_t
*config_page
, u32 form
,
1390 Mpi2ConfigRequest_t mpi_request
;
1393 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1394 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1395 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1396 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK
;
1397 mpi_request
.Header
.PageNumber
= 0;
1398 mpi_request
.Header
.PageVersion
= MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION
;
1399 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1400 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1401 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1405 mpi_request
.PageAddress
= cpu_to_le32(form
| form_specific
);
1406 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1407 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1408 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1409 sizeof(*config_page
));
1415 * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
1416 * @ioc: per adapter object
1417 * @pd_handle: phys disk handle
1418 * @volume_handle: volume handle
1421 * Returns 0 for success, non-zero for failure.
1424 mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER
*ioc
, u16 pd_handle
,
1427 Mpi2RaidConfigurationPage0_t
*config_page
= NULL
;
1428 Mpi2ConfigRequest_t mpi_request
;
1429 Mpi2ConfigReply_t mpi_reply
;
1430 int r
, i
, config_page_sz
;
1434 u16 phys_disk_dev_handle
;
1437 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1438 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1439 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1440 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1441 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG
;
1442 mpi_request
.Header
.PageVersion
= MPI2_RAIDCONFIG0_PAGEVERSION
;
1443 mpi_request
.Header
.PageNumber
= 0;
1444 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1445 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1446 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1450 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1451 config_page_sz
= (le16_to_cpu(mpi_reply
.ExtPageLength
) * 4);
1452 config_page
= kmalloc(config_page_sz
, GFP_KERNEL
);
1459 mpi_request
.PageAddress
= cpu_to_le32(config_num
+
1460 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM
);
1461 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1462 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1467 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1468 MPI2_IOCSTATUS_MASK
;
1469 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
)
1471 for (i
= 0; i
< config_page
->NumElements
; i
++) {
1472 element_type
= le16_to_cpu(config_page
->
1473 ConfigElement
[i
].ElementFlags
) &
1474 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE
;
1476 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT
||
1478 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT
) {
1479 phys_disk_dev_handle
=
1480 le16_to_cpu(config_page
->ConfigElement
[i
].
1482 if (phys_disk_dev_handle
== pd_handle
) {
1484 le16_to_cpu(config_page
->
1485 ConfigElement
[i
].VolDevHandle
);
1489 } else if (element_type
==
1490 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT
) {
1496 config_num
= config_page
->ConfigNum
;
1504 * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
1505 * @ioc: per adapter object
1506 * @volume_handle: volume handle
1507 * @wwid: volume wwid
1510 * Returns 0 for success, non-zero for failure.
1513 mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER
*ioc
, u16 volume_handle
,
1516 Mpi2ConfigReply_t mpi_reply
;
1517 Mpi2RaidVolPage1_t raid_vol_pg1
;
1520 if (!(mpt2sas_config_get_raid_volume_pg1(ioc
, &mpi_reply
,
1521 &raid_vol_pg1
, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE
,
1523 *wwid
= le64_to_cpu(raid_vol_pg1
.WWID
);