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-2010 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>
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_mappping";
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_ioc_pg8 - obtain ioc page 8
688 * @ioc: per adapter object
689 * @mpi_reply: reply mf payload returned from firmware
690 * @config_page: contents of the config page
693 * Returns 0 for success, non-zero for failure.
696 mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER
*ioc
,
697 Mpi2ConfigReply_t
*mpi_reply
, Mpi2IOCPage8_t
*config_page
)
699 Mpi2ConfigRequest_t mpi_request
;
702 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
703 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
704 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
705 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_IOC
;
706 mpi_request
.Header
.PageNumber
= 8;
707 mpi_request
.Header
.PageVersion
= MPI2_IOCPAGE8_PAGEVERSION
;
708 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
709 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
710 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
714 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
715 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
716 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
717 sizeof(*config_page
));
723 * mpt2sas_config_get_sas_device_pg0 - obtain sas device page 0
724 * @ioc: per adapter object
725 * @mpi_reply: reply mf payload returned from firmware
726 * @config_page: contents of the config page
727 * @form: GET_NEXT_HANDLE or HANDLE
728 * @handle: device handle
731 * Returns 0 for success, non-zero for failure.
734 mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
735 *mpi_reply
, Mpi2SasDevicePage0_t
*config_page
, u32 form
, u32 handle
)
737 Mpi2ConfigRequest_t mpi_request
;
740 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
741 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
742 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
743 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
744 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE
;
745 mpi_request
.Header
.PageVersion
= MPI2_SASDEVICE0_PAGEVERSION
;
746 mpi_request
.Header
.PageNumber
= 0;
747 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
748 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
749 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
753 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
754 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
755 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
756 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
757 sizeof(*config_page
));
763 * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1
764 * @ioc: per adapter object
765 * @mpi_reply: reply mf payload returned from firmware
766 * @config_page: contents of the config page
767 * @form: GET_NEXT_HANDLE or HANDLE
768 * @handle: device handle
771 * Returns 0 for success, non-zero for failure.
774 mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
775 *mpi_reply
, Mpi2SasDevicePage1_t
*config_page
, u32 form
, u32 handle
)
777 Mpi2ConfigRequest_t mpi_request
;
780 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
781 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
782 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
783 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
784 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE
;
785 mpi_request
.Header
.PageVersion
= MPI2_SASDEVICE1_PAGEVERSION
;
786 mpi_request
.Header
.PageNumber
= 1;
787 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
788 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
789 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
793 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
794 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
795 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
796 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
797 sizeof(*config_page
));
803 * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host
804 * @ioc: per adapter object
805 * @num_phys: pointer returned with the number of phys
808 * Returns 0 for success, non-zero for failure.
811 mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER
*ioc
, u8
*num_phys
)
813 Mpi2ConfigRequest_t mpi_request
;
816 Mpi2ConfigReply_t mpi_reply
;
817 Mpi2SasIOUnitPage0_t config_page
;
820 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
821 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
822 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
823 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
824 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
825 mpi_request
.Header
.PageNumber
= 0;
826 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE0_PAGEVERSION
;
827 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
828 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
829 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
833 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
834 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
835 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, &config_page
,
836 sizeof(Mpi2SasIOUnitPage0_t
));
838 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
840 if (ioc_status
== MPI2_IOCSTATUS_SUCCESS
)
841 *num_phys
= config_page
.NumPhys
;
848 * mpt2sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
849 * @ioc: per adapter object
850 * @mpi_reply: reply mf payload returned from firmware
851 * @config_page: contents of the config page
852 * @sz: size of buffer passed in config_page
855 * Calling function should call config_get_number_hba_phys prior to
856 * this function, so enough memory is allocated for config_page.
858 * Returns 0 for success, non-zero for failure.
861 mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
862 *mpi_reply
, Mpi2SasIOUnitPage0_t
*config_page
, u16 sz
)
864 Mpi2ConfigRequest_t mpi_request
;
867 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
868 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
869 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
870 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
871 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
872 mpi_request
.Header
.PageNumber
= 0;
873 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE0_PAGEVERSION
;
874 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
875 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
876 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
880 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
881 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
882 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
888 * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
889 * @ioc: per adapter object
890 * @mpi_reply: reply mf payload returned from firmware
891 * @config_page: contents of the config page
892 * @sz: size of buffer passed in config_page
895 * Calling function should call config_get_number_hba_phys prior to
896 * this function, so enough memory is allocated for config_page.
898 * Returns 0 for success, non-zero for failure.
901 mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
902 *mpi_reply
, Mpi2SasIOUnitPage1_t
*config_page
, u16 sz
)
904 Mpi2ConfigRequest_t mpi_request
;
907 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
908 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
909 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
910 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
911 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
912 mpi_request
.Header
.PageNumber
= 1;
913 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE1_PAGEVERSION
;
914 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
915 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
916 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
920 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
921 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
922 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
928 * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1
929 * @ioc: per adapter object
930 * @mpi_reply: reply mf payload returned from firmware
931 * @config_page: contents of the config page
932 * @sz: size of buffer passed in config_page
935 * Calling function should call config_get_number_hba_phys prior to
936 * this function, so enough memory is allocated for config_page.
938 * Returns 0 for success, non-zero for failure.
941 mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
942 *mpi_reply
, Mpi2SasIOUnitPage1_t
*config_page
, u16 sz
)
944 Mpi2ConfigRequest_t mpi_request
;
947 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
948 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
949 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
950 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
951 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
952 mpi_request
.Header
.PageNumber
= 1;
953 mpi_request
.Header
.PageVersion
= MPI2_SASIOUNITPAGE1_PAGEVERSION
;
954 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
955 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
956 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
960 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
961 _config_request(ioc
, &mpi_request
, mpi_reply
,
962 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
963 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
964 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
965 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
971 * mpt2sas_config_get_expander_pg0 - obtain expander page 0
972 * @ioc: per adapter object
973 * @mpi_reply: reply mf payload returned from firmware
974 * @config_page: contents of the config page
975 * @form: GET_NEXT_HANDLE or HANDLE
976 * @handle: expander handle
979 * Returns 0 for success, non-zero for failure.
982 mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
983 *mpi_reply
, Mpi2ExpanderPage0_t
*config_page
, u32 form
, u32 handle
)
985 Mpi2ConfigRequest_t mpi_request
;
988 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
989 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
990 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
991 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
992 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
993 mpi_request
.Header
.PageNumber
= 0;
994 mpi_request
.Header
.PageVersion
= MPI2_SASEXPANDER0_PAGEVERSION
;
995 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
996 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
997 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1001 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1002 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1003 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1004 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1005 sizeof(*config_page
));
1011 * mpt2sas_config_get_expander_pg1 - obtain expander page 1
1012 * @ioc: per adapter object
1013 * @mpi_reply: reply mf payload returned from firmware
1014 * @config_page: contents of the config page
1015 * @phy_number: phy number
1016 * @handle: expander handle
1019 * Returns 0 for success, non-zero for failure.
1022 mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1023 *mpi_reply
, Mpi2ExpanderPage1_t
*config_page
, u32 phy_number
,
1026 Mpi2ConfigRequest_t mpi_request
;
1029 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1030 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1031 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1032 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1033 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER
;
1034 mpi_request
.Header
.PageNumber
= 1;
1035 mpi_request
.Header
.PageVersion
= MPI2_SASEXPANDER1_PAGEVERSION
;
1036 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1037 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1038 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1042 mpi_request
.PageAddress
=
1043 cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM
|
1044 (phy_number
<< MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT
) | handle
);
1045 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1046 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1047 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1048 sizeof(*config_page
));
1054 * mpt2sas_config_get_enclosure_pg0 - obtain enclosure page 0
1055 * @ioc: per adapter object
1056 * @mpi_reply: reply mf payload returned from firmware
1057 * @config_page: contents of the config page
1058 * @form: GET_NEXT_HANDLE or HANDLE
1059 * @handle: expander handle
1062 * Returns 0 for success, non-zero for failure.
1065 mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1066 *mpi_reply
, Mpi2SasEnclosurePage0_t
*config_page
, u32 form
, u32 handle
)
1068 Mpi2ConfigRequest_t mpi_request
;
1071 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1072 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1073 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1074 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1075 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE
;
1076 mpi_request
.Header
.PageNumber
= 0;
1077 mpi_request
.Header
.PageVersion
= MPI2_SASENCLOSURE0_PAGEVERSION
;
1078 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1079 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1080 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1084 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1085 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1086 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1087 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1088 sizeof(*config_page
));
1094 * mpt2sas_config_get_phy_pg0 - obtain phy page 0
1095 * @ioc: per adapter object
1096 * @mpi_reply: reply mf payload returned from firmware
1097 * @config_page: contents of the config page
1098 * @phy_number: phy number
1101 * Returns 0 for success, non-zero for failure.
1104 mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1105 *mpi_reply
, Mpi2SasPhyPage0_t
*config_page
, u32 phy_number
)
1107 Mpi2ConfigRequest_t mpi_request
;
1110 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1111 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1112 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1113 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1114 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_PHY
;
1115 mpi_request
.Header
.PageNumber
= 0;
1116 mpi_request
.Header
.PageVersion
= MPI2_SASPHY0_PAGEVERSION
;
1117 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1118 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1119 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1123 mpi_request
.PageAddress
=
1124 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER
| phy_number
);
1125 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1126 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1127 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1128 sizeof(*config_page
));
1134 * mpt2sas_config_get_phy_pg1 - obtain phy page 1
1135 * @ioc: per adapter object
1136 * @mpi_reply: reply mf payload returned from firmware
1137 * @config_page: contents of the config page
1138 * @phy_number: phy number
1141 * Returns 0 for success, non-zero for failure.
1144 mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1145 *mpi_reply
, Mpi2SasPhyPage1_t
*config_page
, u32 phy_number
)
1147 Mpi2ConfigRequest_t mpi_request
;
1150 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1151 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1152 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1153 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1154 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_SAS_PHY
;
1155 mpi_request
.Header
.PageNumber
= 1;
1156 mpi_request
.Header
.PageVersion
= MPI2_SASPHY1_PAGEVERSION
;
1157 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1158 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1159 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1163 mpi_request
.PageAddress
=
1164 cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER
| phy_number
);
1165 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1166 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1167 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1168 sizeof(*config_page
));
1174 * mpt2sas_config_get_raid_volume_pg1 - obtain raid volume page 1
1175 * @ioc: per adapter object
1176 * @mpi_reply: reply mf payload returned from firmware
1177 * @config_page: contents of the config page
1178 * @form: GET_NEXT_HANDLE or HANDLE
1179 * @handle: volume handle
1182 * Returns 0 for success, non-zero for failure.
1185 mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER
*ioc
,
1186 Mpi2ConfigReply_t
*mpi_reply
, Mpi2RaidVolPage1_t
*config_page
, u32 form
,
1189 Mpi2ConfigRequest_t mpi_request
;
1192 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1193 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1194 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1195 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1196 mpi_request
.Header
.PageNumber
= 1;
1197 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE1_PAGEVERSION
;
1198 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1199 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1200 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1204 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1205 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1206 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1207 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1208 sizeof(*config_page
));
1214 * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume
1215 * @ioc: per adapter object
1216 * @handle: volume handle
1217 * @num_pds: returns pds count
1220 * Returns 0 for success, non-zero for failure.
1223 mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER
*ioc
, u16 handle
,
1226 Mpi2ConfigRequest_t mpi_request
;
1227 Mpi2RaidVolPage0_t config_page
;
1228 Mpi2ConfigReply_t mpi_reply
;
1232 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1234 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1235 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1236 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1237 mpi_request
.Header
.PageNumber
= 0;
1238 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE0_PAGEVERSION
;
1239 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1240 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1241 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1245 mpi_request
.PageAddress
=
1246 cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE
| handle
);
1247 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1248 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1249 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, &config_page
,
1250 sizeof(Mpi2RaidVolPage0_t
));
1252 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) &
1253 MPI2_IOCSTATUS_MASK
;
1254 if (ioc_status
== MPI2_IOCSTATUS_SUCCESS
)
1255 *num_pds
= config_page
.NumPhysDisks
;
1263 * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0
1264 * @ioc: per adapter object
1265 * @mpi_reply: reply mf payload returned from firmware
1266 * @config_page: contents of the config page
1267 * @form: GET_NEXT_HANDLE or HANDLE
1268 * @handle: volume handle
1269 * @sz: size of buffer passed in config_page
1272 * Returns 0 for success, non-zero for failure.
1275 mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER
*ioc
,
1276 Mpi2ConfigReply_t
*mpi_reply
, Mpi2RaidVolPage0_t
*config_page
, u32 form
,
1279 Mpi2ConfigRequest_t mpi_request
;
1282 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1283 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1284 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1285 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_VOLUME
;
1286 mpi_request
.Header
.PageNumber
= 0;
1287 mpi_request
.Header
.PageVersion
= MPI2_RAIDVOLPAGE0_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
, NULL
, 0);
1294 mpi_request
.PageAddress
= cpu_to_le32(form
| handle
);
1295 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1296 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1297 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
, sz
);
1303 * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0
1304 * @ioc: per adapter object
1305 * @mpi_reply: reply mf payload returned from firmware
1306 * @config_page: contents of the config page
1307 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
1308 * @form_specific: specific to the form
1311 * Returns 0 for success, non-zero for failure.
1314 mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER
*ioc
, Mpi2ConfigReply_t
1315 *mpi_reply
, Mpi2RaidPhysDiskPage0_t
*config_page
, u32 form
,
1318 Mpi2ConfigRequest_t mpi_request
;
1321 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1322 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1323 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1324 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK
;
1325 mpi_request
.Header
.PageNumber
= 0;
1326 mpi_request
.Header
.PageVersion
= MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION
;
1327 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1328 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1329 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1333 mpi_request
.PageAddress
= cpu_to_le32(form
| form_specific
);
1334 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1335 r
= _config_request(ioc
, &mpi_request
, mpi_reply
,
1336 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1337 sizeof(*config_page
));
1343 * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components
1344 * @ioc: per adapter object
1345 * @pd_handle: phys disk handle
1346 * @volume_handle: volume handle
1349 * Returns 0 for success, non-zero for failure.
1352 mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER
*ioc
, u16 pd_handle
,
1355 Mpi2RaidConfigurationPage0_t
*config_page
= NULL
;
1356 Mpi2ConfigRequest_t mpi_request
;
1357 Mpi2ConfigReply_t mpi_reply
;
1358 int r
, i
, config_page_sz
;
1362 memset(&mpi_request
, 0, sizeof(Mpi2ConfigRequest_t
));
1363 mpi_request
.Function
= MPI2_FUNCTION_CONFIG
;
1364 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_HEADER
;
1365 mpi_request
.Header
.PageType
= MPI2_CONFIG_PAGETYPE_EXTENDED
;
1366 mpi_request
.ExtPageType
= MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG
;
1367 mpi_request
.Header
.PageVersion
= MPI2_RAIDCONFIG0_PAGEVERSION
;
1368 mpi_request
.Header
.PageNumber
= 0;
1369 mpt2sas_base_build_zero_len_sge(ioc
, &mpi_request
.PageBufferSGE
);
1370 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1371 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, NULL
, 0);
1375 mpi_request
.PageAddress
=
1376 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG
);
1377 mpi_request
.Action
= MPI2_CONFIG_ACTION_PAGE_READ_CURRENT
;
1378 config_page_sz
= (le16_to_cpu(mpi_reply
.ExtPageLength
) * 4);
1379 config_page
= kmalloc(config_page_sz
, GFP_KERNEL
);
1382 r
= _config_request(ioc
, &mpi_request
, &mpi_reply
,
1383 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT
, config_page
,
1389 ioc_status
= le16_to_cpu(mpi_reply
.IOCStatus
) & MPI2_IOCSTATUS_MASK
;
1390 if (ioc_status
!= MPI2_IOCSTATUS_SUCCESS
)
1392 for (i
= 0; i
< config_page
->NumElements
; i
++) {
1393 if ((le16_to_cpu(config_page
->ConfigElement
[i
].ElementFlags
) &
1394 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE
) !=
1395 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT
)
1397 if (le16_to_cpu(config_page
->ConfigElement
[i
].
1398 PhysDiskDevHandle
) == pd_handle
) {
1399 *volume_handle
= le16_to_cpu(config_page
->
1400 ConfigElement
[i
].VolDevHandle
);
1411 * mpt2sas_config_get_volume_wwid - returns wwid given the volume handle
1412 * @ioc: per adapter object
1413 * @volume_handle: volume handle
1414 * @wwid: volume wwid
1417 * Returns 0 for success, non-zero for failure.
1420 mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER
*ioc
, u16 volume_handle
,
1423 Mpi2ConfigReply_t mpi_reply
;
1424 Mpi2RaidVolPage1_t raid_vol_pg1
;
1427 if (!(mpt2sas_config_get_raid_volume_pg1(ioc
, &mpi_reply
,
1428 &raid_vol_pg1
, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE
,
1430 *wwid
= le64_to_cpu(raid_vol_pg1
.WWID
);