2 * Copyright (c) 2011-2015 LSI Corp.
3 * Copyright (c) 2013-2016 Avago Technologies
4 * Copyright 2000-2020 Broadcom Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Broadcom Inc. (LSI) MPT-Fusion Host Adapter FreeBSD
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 /* TODO Move headers to mprvar */
35 #include <sys/types.h>
36 #include <sys/param.h>
38 #include <sys/mutex.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/kthread.h>
43 #include <sys/taskqueue.h>
45 #include <sys/endian.h>
46 #include <sys/sysctl.h>
47 #include <sys/eventhandler.h>
49 #include <machine/bus.h>
50 #include <machine/resource.h>
51 #include <dev/mpr/mpi/mpi2_type.h>
52 #include <dev/mpr/mpi/mpi2.h>
53 #include <dev/mpr/mpi/mpi2_ioc.h>
54 #include <dev/mpr/mpi/mpi2_sas.h>
55 #include <dev/mpr/mpi/mpi2_pci.h>
56 #include <dev/mpr/mpi/mpi2_cnfg.h>
57 #include <dev/mpr/mpi/mpi2_init.h>
58 #include <dev/mpr/mpi/mpi2_tool.h>
59 #include <dev/mpr/mpr_ioctl.h>
60 #include <dev/mpr/mprvar.h>
63 * mpr_config_get_ioc_pg8 - obtain ioc page 8
64 * @sc: per adapter object
65 * @mpi_reply: reply mf payload returned from firmware
66 * @config_page: contents of the config page
69 * Returns 0 for success, non-zero for failure.
72 mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
73 Mpi2IOCPage8_t *config_page)
75 MPI2_CONFIG_REQUEST *request;
76 MPI2_CONFIG_REPLY *reply;
77 struct mpr_command *cm;
78 MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
82 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
84 if ((cm = mpr_alloc_command(sc)) == NULL) {
85 printf("%s: command alloc failed @ line %d\n", __func__,
90 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
91 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
92 request->Function = MPI2_FUNCTION_CONFIG;
93 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
94 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
95 request->Header.PageNumber = 8;
96 request->Header.PageLength = request->Header.PageVersion = 0;
97 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
99 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
101 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
102 if (error || (reply == NULL)) {
105 * If the request returns an error then we need to do a diag
108 printf("%s: request for header completed with error %d",
113 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
114 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
115 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
118 * If the request returns an error then we need to do a diag
121 printf("%s: header read with error; iocstatus = 0x%x\n",
122 __func__, ioc_status);
126 /* We have to do free and alloc for the reply-free and reply-post
127 * counters to match - Need to review the reply FIFO handling.
129 mpr_free_command(sc, cm);
131 if ((cm = mpr_alloc_command(sc)) == NULL) {
132 printf("%s: command alloc failed @ line %d\n", __func__,
137 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
138 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
139 request->Function = MPI2_FUNCTION_CONFIG;
140 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
141 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
142 request->Header.PageNumber = 8;
143 request->Header.PageVersion = mpi_reply->Header.PageVersion;
144 request->Header.PageLength = mpi_reply->Header.PageLength;
145 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
146 cm->cm_sge = &request->PageBufferSGE;
147 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
148 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
149 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
150 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
152 printf("%s: page alloc failed\n", __func__);
158 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
160 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
161 if (error || (reply == NULL)) {
164 * If the request returns an error then we need to do a diag
167 printf("%s: request for page completed with error %d",
172 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
173 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
174 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
177 * If the request returns an error then we need to do a diag
180 printf("%s: page read with error; iocstatus = 0x%x\n",
181 __func__, ioc_status);
185 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
190 mpr_free_command(sc, cm);
195 * mpr_config_get_iounit_pg8 - obtain iounit page 8
196 * @sc: per adapter object
197 * @mpi_reply: reply mf payload returned from firmware
198 * @config_page: contents of the config page
201 * Returns 0 for success, non-zero for failure.
204 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
205 Mpi2IOUnitPage8_t *config_page)
207 MPI2_CONFIG_REQUEST *request;
208 MPI2_CONFIG_REPLY *reply;
209 struct mpr_command *cm;
210 MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
214 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
216 if ((cm = mpr_alloc_command(sc)) == NULL) {
217 printf("%s: command alloc failed @ line %d\n", __func__,
222 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
223 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
224 request->Function = MPI2_FUNCTION_CONFIG;
225 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
226 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
227 request->Header.PageNumber = 8;
228 request->Header.PageLength = request->Header.PageVersion = 0;
229 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
231 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
233 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
234 if (error || (reply == NULL)) {
237 * If the request returns an error then we need to do a diag
240 printf("%s: request for header completed with error %d",
245 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
246 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
247 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
250 * If the request returns an error then we need to do a diag
253 printf("%s: header read with error; iocstatus = 0x%x\n",
254 __func__, ioc_status);
258 /* We have to do free and alloc for the reply-free and reply-post
259 * counters to match - Need to review the reply FIFO handling.
261 mpr_free_command(sc, cm);
263 if ((cm = mpr_alloc_command(sc)) == NULL) {
264 printf("%s: command alloc failed @ line %d\n", __func__,
269 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
270 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
271 request->Function = MPI2_FUNCTION_CONFIG;
272 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
273 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
274 request->Header.PageNumber = 8;
275 request->Header.PageVersion = mpi_reply->Header.PageVersion;
276 request->Header.PageLength = mpi_reply->Header.PageLength;
277 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
278 cm->cm_sge = &request->PageBufferSGE;
279 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
280 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
281 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
282 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
284 printf("%s: page alloc failed\n", __func__);
290 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
292 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
293 if (error || (reply == NULL)) {
296 * If the request returns an error then we need to do a diag
299 printf("%s: request for page completed with error %d",
304 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
305 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
306 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
309 * If the request returns an error then we need to do a diag
312 printf("%s: page read with error; iocstatus = 0x%x\n",
313 __func__, ioc_status);
317 bcopy(page, config_page, MIN(cm->cm_length,
318 (sizeof(Mpi2IOUnitPage8_t))));
323 mpr_free_command(sc, cm);
328 * mpr_config_get_man_pg11 - obtain manufacturing page 11
329 * @sc: per adapter object
330 * @mpi_reply: reply mf payload returned from firmware
331 * @config_page: contents of the config page
334 * Returns 0 for success, non-zero for failure.
337 mpr_config_get_man_pg11(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
338 Mpi2ManufacturingPage11_t *config_page)
340 MPI2_CONFIG_REQUEST *request;
341 MPI2_CONFIG_REPLY *reply;
342 struct mpr_command *cm;
343 MPI2_CONFIG_PAGE_MAN_11 *page = NULL;
347 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
349 if ((cm = mpr_alloc_command(sc)) == NULL) {
350 printf("%s: command alloc failed @ line %d\n", __func__,
355 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
356 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
357 request->Function = MPI2_FUNCTION_CONFIG;
358 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
359 request->Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
360 request->Header.PageNumber = 11;
361 request->Header.PageLength = request->Header.PageVersion = 0;
362 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
364 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
365 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
366 if (error || (reply == NULL)) {
369 * If the request returns an error then we need to do a diag
372 printf("%s: request for header completed with error %d",
377 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
378 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
379 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
382 * If the request returns an error then we need to do a diag
385 printf("%s: header read with error; iocstatus = 0x%x\n",
386 __func__, ioc_status);
390 /* We have to do free and alloc for the reply-free and reply-post
391 * counters to match - Need to review the reply FIFO handling.
393 mpr_free_command(sc, cm);
395 if ((cm = mpr_alloc_command(sc)) == NULL) {
396 printf("%s: command alloc failed @ line %d\n", __func__,
401 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
402 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
403 request->Function = MPI2_FUNCTION_CONFIG;
404 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
405 request->Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
406 request->Header.PageNumber = 11;
407 request->Header.PageVersion = mpi_reply->Header.PageVersion;
408 request->Header.PageLength = mpi_reply->Header.PageLength;
409 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
410 cm->cm_sge = &request->PageBufferSGE;
411 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
412 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
413 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
414 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
416 printf("%s: page alloc failed\n", __func__);
422 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
423 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
424 if (error || (reply == NULL)) {
427 * If the request returns an error then we need to do a diag
430 printf("%s: request for page completed with error %d",
435 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
436 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
437 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
440 * If the request returns an error then we need to do a diag
443 printf("%s: page read with error; iocstatus = 0x%x\n",
444 __func__, ioc_status);
448 bcopy(page, config_page, MIN(cm->cm_length,
449 (sizeof(Mpi2ManufacturingPage11_t))));
454 mpr_free_command(sc, cm);
459 * mpr_base_static_config_pages - static start of day config pages.
460 * @sc: per adapter object
465 mpr_base_static_config_pages(struct mpr_softc *sc)
467 Mpi2ConfigReply_t mpi_reply;
468 Mpi2ManufacturingPage11_t man_pg11;
472 while (mpr_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) {
475 /* We need to Handle this situation */
481 while (mpr_config_get_iounit_pg8(sc, &mpi_reply, &sc->iounit_pg8)) {
484 /* We need to Handle this situation */
490 while ((rc = mpr_config_get_man_pg11(sc, &mpi_reply, &man_pg11))) {
493 /* We need to Handle this situation */
500 sc->custom_nvme_tm_handling = (le16toh(man_pg11.AddlFlags2) &
501 MPI2_MAN_PG11_ADDLFLAGS2_CUSTOM_TM_HANDLING_MASK);
502 sc->nvme_abort_timeout = man_pg11.NVMeAbortTO;
504 /* Minimum NVMe Abort timeout value should be 6 seconds &
505 * maximum value should be 60 seconds.
507 if (sc->nvme_abort_timeout < 6)
508 sc->nvme_abort_timeout = 6;
509 if (sc->nvme_abort_timeout > 60)
510 sc->nvme_abort_timeout = 60;
515 * mpr_config_get_dpm_pg0 - obtain driver persistent mapping page0
516 * @sc: per adapter object
517 * @mpi_reply: reply mf payload returned from firmware
518 * @config_page: contents of the config page
519 * @sz: size of buffer passed in config_page
522 * Returns 0 for success, non-zero for failure.
525 mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
526 Mpi2DriverMappingPage0_t *config_page, u16 sz)
528 MPI2_CONFIG_REQUEST *request;
529 MPI2_CONFIG_REPLY *reply;
530 struct mpr_command *cm;
531 Mpi2DriverMappingPage0_t *page = NULL;
535 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
537 memset(config_page, 0, sz);
538 if ((cm = mpr_alloc_command(sc)) == NULL) {
539 printf("%s: command alloc failed @ line %d\n", __func__,
544 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
545 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
546 request->Function = MPI2_FUNCTION_CONFIG;
547 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
548 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
549 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
550 request->Header.PageNumber = 0;
551 request->ExtPageLength = request->Header.PageVersion = 0;
552 request->PageAddress = sc->max_dpm_entries <<
553 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
554 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
556 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
558 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
559 if (error || (reply == NULL)) {
562 * If the request returns an error then we need to do a diag
565 printf("%s: request for header completed with error %d",
570 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
571 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
572 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
575 * If the request returns an error then we need to do a diag
578 printf("%s: header read with error; iocstatus = 0x%x\n",
579 __func__, ioc_status);
583 /* We have to do free and alloc for the reply-free and reply-post
584 * counters to match - Need to review the reply FIFO handling.
586 mpr_free_command(sc, cm);
588 if ((cm = mpr_alloc_command(sc)) == NULL) {
589 printf("%s: command alloc failed @ line %d\n", __func__,
594 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
595 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
596 request->Function = MPI2_FUNCTION_CONFIG;
597 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
598 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
599 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
600 request->Header.PageNumber = 0;
601 request->Header.PageVersion = mpi_reply->Header.PageVersion;
602 request->PageAddress = sc->max_dpm_entries <<
603 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
604 request->ExtPageLength = mpi_reply->ExtPageLength;
605 cm->cm_length = le16toh(request->ExtPageLength) * 4;
606 cm->cm_sge = &request->PageBufferSGE;
607 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
608 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
609 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
610 page = malloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
612 printf("%s: page alloc failed\n", __func__);
617 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
619 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
620 if (error || (reply == NULL)) {
623 * If the request returns an error then we need to do a diag
626 printf("%s: request for page completed with error %d",
631 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
632 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
633 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
636 * If the request returns an error then we need to do a diag
639 printf("%s: page read with error; iocstatus = 0x%x\n",
640 __func__, ioc_status);
644 bcopy(page, config_page, MIN(cm->cm_length, sz));
648 mpr_free_command(sc, cm);
653 * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
654 * @sc: per adapter object
655 * @mpi_reply: reply mf payload returned from firmware
656 * @config_page: contents of the config page
657 * @entry_idx: entry index in DPM Page0 to be modified
660 * Returns 0 for success, non-zero for failure.
663 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
664 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
666 MPI2_CONFIG_REQUEST *request;
667 MPI2_CONFIG_REPLY *reply;
668 struct mpr_command *cm;
669 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
673 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
675 if ((cm = mpr_alloc_command(sc)) == NULL) {
676 printf("%s: command alloc failed @ line %d\n", __func__,
681 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
682 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
683 request->Function = MPI2_FUNCTION_CONFIG;
684 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
685 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
686 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
687 request->Header.PageNumber = 0;
688 request->ExtPageLength = request->Header.PageVersion = 0;
689 /* We can remove below two lines ????*/
690 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
691 request->PageAddress |= htole16(entry_idx);
692 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
694 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
696 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
697 if (error || (reply == NULL)) {
700 * If the request returns an error then we need to do a diag
703 printf("%s: request for header completed with error %d",
708 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
709 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
710 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
713 * If the request returns an error then we need to do a diag
716 printf("%s: header read with error; iocstatus = 0x%x\n",
717 __func__, ioc_status);
721 /* We have to do free and alloc for the reply-free and reply-post
722 * counters to match - Need to review the reply FIFO handling.
724 mpr_free_command(sc, cm);
726 if ((cm = mpr_alloc_command(sc)) == NULL) {
727 printf("%s: command alloc failed @ line %d\n", __func__,
732 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
733 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
734 request->Function = MPI2_FUNCTION_CONFIG;
735 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
736 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
737 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
738 request->Header.PageNumber = 0;
739 request->Header.PageVersion = mpi_reply->Header.PageVersion;
740 request->ExtPageLength = mpi_reply->ExtPageLength;
741 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
742 request->PageAddress |= htole16(entry_idx);
743 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
744 cm->cm_sge = &request->PageBufferSGE;
745 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
746 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
747 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
748 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
750 printf("%s: page alloc failed\n", __func__);
754 bcopy(config_page, page, MIN(cm->cm_length,
755 (sizeof(Mpi2DriverMappingPage0_t))));
757 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
759 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
760 if (error || (reply == NULL)) {
763 * If the request returns an error then we need to do a diag
766 printf("%s: request to write page completed with error %d",
771 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
772 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
773 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
776 * If the request returns an error then we need to do a diag
779 printf("%s: page written with error; iocstatus = 0x%x\n",
780 __func__, ioc_status);
787 mpr_free_command(sc, cm);
792 * mpr_config_get_sas_device_pg0 - obtain sas device page 0
793 * @sc: per adapter object
794 * @mpi_reply: reply mf payload returned from firmware
795 * @config_page: contents of the config page
796 * @form: GET_NEXT_HANDLE or HANDLE
797 * @handle: device handle
800 * Returns 0 for success, non-zero for failure.
803 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
804 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
806 MPI2_CONFIG_REQUEST *request;
807 MPI2_CONFIG_REPLY *reply;
808 struct mpr_command *cm;
809 Mpi2SasDevicePage0_t *page = NULL;
813 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
815 if ((cm = mpr_alloc_command(sc)) == NULL) {
816 printf("%s: command alloc failed @ line %d\n", __func__,
821 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
822 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
823 request->Function = MPI2_FUNCTION_CONFIG;
824 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
825 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
826 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
827 request->Header.PageNumber = 0;
828 request->ExtPageLength = request->Header.PageVersion = 0;
829 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
831 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
833 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
834 if (error || (reply == NULL)) {
837 * If the request returns an error then we need to do a diag
840 printf("%s: request for header completed with error %d",
845 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
846 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
847 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
850 * If the request returns an error then we need to do a diag
853 printf("%s: header read with error; iocstatus = 0x%x\n",
854 __func__, ioc_status);
858 /* We have to do free and alloc for the reply-free and reply-post
859 * counters to match - Need to review the reply FIFO handling.
861 mpr_free_command(sc, cm);
863 if ((cm = mpr_alloc_command(sc)) == NULL) {
864 printf("%s: command alloc failed @ line %d\n", __func__,
869 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
870 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
871 request->Function = MPI2_FUNCTION_CONFIG;
872 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
873 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
874 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
875 request->Header.PageNumber = 0;
876 request->Header.PageVersion = mpi_reply->Header.PageVersion;
877 request->ExtPageLength = mpi_reply->ExtPageLength;
878 request->PageAddress = htole32(form | handle);
879 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
880 cm->cm_sge = &request->PageBufferSGE;
881 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
882 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
883 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
884 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
886 printf("%s: page alloc failed\n", __func__);
892 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
894 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
895 if (error || (reply == NULL)) {
898 * If the request returns an error then we need to do a diag
901 printf("%s: request for page completed with error %d",
906 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
907 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
908 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
911 * If the request returns an error then we need to do a diag
914 printf("%s: page read with error; iocstatus = 0x%x\n",
915 __func__, ioc_status);
919 bcopy(page, config_page, MIN(cm->cm_length,
920 sizeof(Mpi2SasDevicePage0_t)));
924 mpr_free_command(sc, cm);
929 * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
930 * @sc: per adapter object
931 * @mpi_reply: reply mf payload returned from firmware
932 * @config_page: contents of the config page
933 * @form: GET_NEXT_HANDLE or HANDLE
934 * @handle: device handle
937 * Returns 0 for success, non-zero for failure.
940 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
941 *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
943 MPI2_CONFIG_REQUEST *request;
944 MPI2_CONFIG_REPLY *reply;
945 struct mpr_command *cm;
946 Mpi26PCIeDevicePage0_t *page = NULL;
950 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
952 if ((cm = mpr_alloc_command(sc)) == NULL) {
953 printf("%s: command alloc failed @ line %d\n", __func__,
958 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
959 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
960 request->Function = MPI2_FUNCTION_CONFIG;
961 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
962 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
963 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
964 request->Header.PageNumber = 0;
965 request->ExtPageLength = request->Header.PageVersion = 0;
966 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
968 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
970 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
971 if (error || (reply == NULL)) {
974 * If the request returns an error then we need to do a diag
977 printf("%s: request for header completed with error %d",
982 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
983 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
984 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
987 * If the request returns an error then we need to do a diag
990 printf("%s: header read with error; iocstatus = 0x%x\n",
991 __func__, ioc_status);
995 /* We have to do free and alloc for the reply-free and reply-post
996 * counters to match - Need to review the reply FIFO handling.
998 mpr_free_command(sc, cm);
1000 if ((cm = mpr_alloc_command(sc)) == NULL) {
1001 printf("%s: command alloc failed @ line %d\n", __func__,
1006 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1007 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1008 request->Function = MPI2_FUNCTION_CONFIG;
1009 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1010 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1011 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1012 request->Header.PageNumber = 0;
1013 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1014 request->ExtPageLength = mpi_reply->ExtPageLength;
1015 request->PageAddress = htole32(form | handle);
1016 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
1017 cm->cm_sge = &request->PageBufferSGE;
1018 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1019 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1020 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1021 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1023 printf("%s: page alloc failed\n", __func__);
1029 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1031 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1032 if (error || (reply == NULL)) {
1035 * If the request returns an error then we need to do a diag
1038 printf("%s: request for page completed with error %d",
1043 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1044 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1045 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1048 * If the request returns an error then we need to do a diag
1051 printf("%s: page read with error; iocstatus = 0x%x\n",
1052 __func__, ioc_status);
1056 bcopy(page, config_page, MIN(cm->cm_length,
1057 sizeof(Mpi26PCIeDevicePage0_t)));
1061 mpr_free_command(sc, cm);
1066 * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
1067 * @sc: per adapter object
1068 * @mpi_reply: reply mf payload returned from firmware
1069 * @config_page: contents of the config page
1070 * @form: GET_NEXT_HANDLE or HANDLE
1071 * @handle: device handle
1074 * Returns 0 for success, non-zero for failure.
1077 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
1078 *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
1080 MPI2_CONFIG_REQUEST *request;
1081 MPI2_CONFIG_REPLY *reply;
1082 struct mpr_command *cm;
1083 Mpi26PCIeDevicePage2_t *page = NULL;
1087 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1089 if ((cm = mpr_alloc_command(sc)) == NULL) {
1090 printf("%s: command alloc failed @ line %d\n", __func__,
1095 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1096 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1097 request->Function = MPI2_FUNCTION_CONFIG;
1098 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1099 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1100 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1101 request->Header.PageNumber = 2;
1102 request->ExtPageLength = request->Header.PageVersion = 0;
1103 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1105 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1107 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1108 if (error || (reply == NULL)) {
1111 * If the request returns an error then we need to do a diag
1114 printf("%s: request for header completed with error %d",
1119 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1120 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1121 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1124 * If the request returns an error then we need to do a diag
1127 printf("%s: header read with error; iocstatus = 0x%x\n",
1128 __func__, ioc_status);
1132 /* We have to do free and alloc for the reply-free and reply-post
1133 * counters to match - Need to review the reply FIFO handling.
1135 mpr_free_command(sc, cm);
1137 if ((cm = mpr_alloc_command(sc)) == NULL) {
1138 printf("%s: command alloc failed @ line %d\n", __func__,
1143 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1144 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1145 request->Function = MPI2_FUNCTION_CONFIG;
1146 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1147 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
1148 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
1149 request->Header.PageNumber = 2;
1150 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1151 request->ExtPageLength = mpi_reply->ExtPageLength;
1152 request->PageAddress = htole32(form | handle);
1153 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
1154 cm->cm_sge = &request->PageBufferSGE;
1155 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1156 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1157 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1158 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1160 printf("%s: page alloc failed\n", __func__);
1166 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1168 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1169 if (error || (reply == NULL)) {
1172 * If the request returns an error then we need to do a diag
1175 printf("%s: request for page completed with error %d",
1180 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1181 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1182 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1185 * If the request returns an error then we need to do a diag
1188 printf("%s: page read with error; iocstatus = 0x%x\n",
1189 __func__, ioc_status);
1193 bcopy(page, config_page, MIN(cm->cm_length,
1194 sizeof(Mpi26PCIeDevicePage2_t)));
1198 mpr_free_command(sc, cm);
1203 * mpr_config_get_bios_pg3 - obtain BIOS page 3
1204 * @sc: per adapter object
1205 * @mpi_reply: reply mf payload returned from firmware
1206 * @config_page: contents of the config page
1209 * Returns 0 for success, non-zero for failure.
1212 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1213 Mpi2BiosPage3_t *config_page)
1215 MPI2_CONFIG_REQUEST *request;
1216 MPI2_CONFIG_REPLY *reply;
1217 struct mpr_command *cm;
1218 Mpi2BiosPage3_t *page = NULL;
1222 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1224 if ((cm = mpr_alloc_command(sc)) == NULL) {
1225 printf("%s: command alloc failed @ line %d\n", __func__,
1230 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1231 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1232 request->Function = MPI2_FUNCTION_CONFIG;
1233 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1234 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1235 request->Header.PageNumber = 3;
1236 request->Header.PageLength = request->Header.PageVersion = 0;
1237 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1239 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1241 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1242 if (error || (reply == NULL)) {
1245 * If the request returns an error then we need to do a diag
1248 printf("%s: request for header completed with error %d",
1253 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1254 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1255 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1258 * If the request returns an error then we need to do a diag
1261 printf("%s: header read with error; iocstatus = 0x%x\n",
1262 __func__, ioc_status);
1266 /* We have to do free and alloc for the reply-free and reply-post
1267 * counters to match - Need to review the reply FIFO handling.
1269 mpr_free_command(sc, cm);
1271 if ((cm = mpr_alloc_command(sc)) == NULL) {
1272 printf("%s: command alloc failed @ line %d\n", __func__,
1277 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1278 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1279 request->Function = MPI2_FUNCTION_CONFIG;
1280 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1281 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1282 request->Header.PageNumber = 3;
1283 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1284 request->Header.PageLength = mpi_reply->Header.PageLength;
1285 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1286 cm->cm_sge = &request->PageBufferSGE;
1287 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1288 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1289 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1290 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1292 printf("%s: page alloc failed\n", __func__);
1298 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1300 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1301 if (error || (reply == NULL)) {
1304 * If the request returns an error then we need to do a diag
1307 printf("%s: request for page completed with error %d",
1312 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1313 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1314 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1317 * If the request returns an error then we need to do a diag
1320 printf("%s: page read with error; iocstatus = 0x%x\n",
1321 __func__, ioc_status);
1325 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
1329 mpr_free_command(sc, cm);
1334 * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
1335 * @sc: per adapter object
1336 * @mpi_reply: reply mf payload returned from firmware
1337 * @config_page: contents of the config page
1338 * @page_address: form and handle value used to get page
1341 * Returns 0 for success, non-zero for failure.
1344 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
1345 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
1347 MPI2_CONFIG_REQUEST *request;
1348 MPI2_CONFIG_REPLY *reply = NULL;
1349 struct mpr_command *cm;
1350 Mpi2RaidVolPage0_t *page = NULL;
1354 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1356 if ((cm = mpr_alloc_command(sc)) == NULL) {
1357 printf("%s: command alloc failed @ line %d\n", __func__,
1362 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1363 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1364 request->Function = MPI2_FUNCTION_CONFIG;
1365 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1366 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1367 request->Header.PageNumber = 0;
1368 request->Header.PageLength = request->Header.PageVersion = 0;
1369 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1373 * This page must be polled because the IOC isn't ready yet when this
1376 error = mpr_request_polled(sc, &cm);
1378 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1379 if (error || (reply == NULL)) {
1381 /* If the poll returns error then we need to do diag reset */
1382 printf("%s: poll for header completed with error %d",
1387 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1388 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1389 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1391 /* If the poll returns error then we need to do diag reset */
1392 printf("%s: header read with error; iocstatus = 0x%x\n",
1393 __func__, ioc_status);
1397 /* We have to do free and alloc for the reply-free and reply-post
1398 * counters to match - Need to review the reply FIFO handling.
1400 mpr_free_command(sc, cm);
1402 if ((cm = mpr_alloc_command(sc)) == NULL) {
1403 printf("%s: command alloc failed @ line %d\n", __func__,
1408 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1409 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1410 request->Function = MPI2_FUNCTION_CONFIG;
1411 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1412 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1413 request->Header.PageNumber = 0;
1414 request->Header.PageLength = mpi_reply->Header.PageLength;
1415 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1416 request->PageAddress = page_address;
1417 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1418 cm->cm_sge = &request->PageBufferSGE;
1419 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1420 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1421 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1422 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1424 printf("%s: page alloc failed\n", __func__);
1431 * This page must be polled because the IOC isn't ready yet when this
1434 error = mpr_request_polled(sc, &cm);
1436 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1437 if (error || (reply == NULL)) {
1439 /* If the poll returns error then we need to do diag reset */
1440 printf("%s: poll for page completed with error %d",
1445 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1446 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1447 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1449 /* If the poll returns error then we need to do diag reset */
1450 printf("%s: page read with error; iocstatus = 0x%x\n",
1451 __func__, ioc_status);
1455 bcopy(page, config_page, cm->cm_length);
1459 mpr_free_command(sc, cm);
1464 * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
1465 * @sc: per adapter object
1466 * @mpi_reply: reply mf payload returned from firmware
1467 * @config_page: contents of the config page
1468 * @form: GET_NEXT_HANDLE or HANDLE
1469 * @handle: volume handle
1472 * Returns 0 for success, non-zero for failure.
1475 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
1476 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
1478 MPI2_CONFIG_REQUEST *request;
1479 MPI2_CONFIG_REPLY *reply;
1480 struct mpr_command *cm;
1481 Mpi2RaidVolPage1_t *page = NULL;
1485 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1487 if ((cm = mpr_alloc_command(sc)) == NULL) {
1488 printf("%s: command alloc failed @ line %d\n", __func__,
1493 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1494 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1495 request->Function = MPI2_FUNCTION_CONFIG;
1496 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1497 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1498 request->Header.PageNumber = 1;
1499 request->Header.PageLength = request->Header.PageVersion = 0;
1500 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1502 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1504 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1505 if (error || (reply == NULL)) {
1508 * If the request returns an error then we need to do a diag
1511 printf("%s: request for header completed with error %d",
1516 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1517 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1518 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1521 * If the request returns an error then we need to do a diag
1524 printf("%s: header read with error; iocstatus = 0x%x\n",
1525 __func__, ioc_status);
1529 /* We have to do free and alloc for the reply-free and reply-post
1530 * counters to match - Need to review the reply FIFO handling.
1532 mpr_free_command(sc, cm);
1534 if ((cm = mpr_alloc_command(sc)) == NULL) {
1535 printf("%s: command alloc failed @ line %d\n", __func__,
1540 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1541 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1542 request->Function = MPI2_FUNCTION_CONFIG;
1543 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1544 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1545 request->Header.PageNumber = 1;
1546 request->Header.PageLength = mpi_reply->Header.PageLength;
1547 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1548 request->PageAddress = htole32(form | handle);
1549 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1550 cm->cm_sge = &request->PageBufferSGE;
1551 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1552 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1553 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1554 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1556 printf("%s: page alloc failed\n", __func__);
1562 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1564 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1565 if (error || (reply == NULL)) {
1568 * If the request returns an error then we need to do a diag
1571 printf("%s: request for page completed with error %d",
1576 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1577 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1578 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1581 * If the request returns an error then we need to do a diag
1584 printf("%s: page read with error; iocstatus = 0x%x\n",
1585 __func__, ioc_status);
1589 bcopy(page, config_page, MIN(cm->cm_length,
1590 sizeof(Mpi2RaidVolPage1_t)));
1594 mpr_free_command(sc, cm);
1599 * mpr_config_get_volume_wwid - returns wwid given the volume handle
1600 * @sc: per adapter object
1601 * @volume_handle: volume handle
1602 * @wwid: volume wwid
1605 * Returns 0 for success, non-zero for failure.
1608 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
1610 Mpi2ConfigReply_t mpi_reply;
1611 Mpi2RaidVolPage1_t raid_vol_pg1;
1614 if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
1615 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
1616 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
1617 raid_vol_pg1.WWID.Low);
1624 * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
1625 * @sc: per adapter object
1626 * @mpi_reply: reply mf payload returned from firmware
1627 * @config_page: contents of the config page
1628 * @page_address: form and handle value used to get page
1631 * Returns 0 for success, non-zero for failure.
1634 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1635 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
1637 MPI2_CONFIG_REQUEST *request;
1638 MPI2_CONFIG_REPLY *reply = NULL;
1639 struct mpr_command *cm;
1640 Mpi2RaidPhysDiskPage0_t *page = NULL;
1644 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1646 if ((cm = mpr_alloc_command(sc)) == NULL) {
1647 printf("%s: command alloc failed @ line %d\n", __func__,
1652 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1653 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1654 request->Function = MPI2_FUNCTION_CONFIG;
1655 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1656 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1657 request->Header.PageNumber = 0;
1658 request->Header.PageLength = request->Header.PageVersion = 0;
1659 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1663 * This page must be polled because the IOC isn't ready yet when this
1666 error = mpr_request_polled(sc, &cm);
1668 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1669 if (error || (reply == NULL)) {
1671 /* If the poll returns error then we need to do diag reset */
1672 printf("%s: poll for header completed with error %d",
1677 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1678 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1679 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1681 /* If the poll returns error then we need to do diag reset */
1682 printf("%s: header read with error; iocstatus = 0x%x\n",
1683 __func__, ioc_status);
1687 /* We have to do free and alloc for the reply-free and reply-post
1688 * counters to match - Need to review the reply FIFO handling.
1690 mpr_free_command(sc, cm);
1692 if ((cm = mpr_alloc_command(sc)) == NULL) {
1693 printf("%s: command alloc failed @ line %d\n", __func__,
1698 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1699 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1700 request->Function = MPI2_FUNCTION_CONFIG;
1701 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1702 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1703 request->Header.PageNumber = 0;
1704 request->Header.PageLength = mpi_reply->Header.PageLength;
1705 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1706 request->PageAddress = page_address;
1707 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1708 cm->cm_sge = &request->PageBufferSGE;
1709 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1710 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1711 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1712 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1714 printf("%s: page alloc failed\n", __func__);
1721 * This page must be polled because the IOC isn't ready yet when this
1724 error = mpr_request_polled(sc, &cm);
1726 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1727 if (error || (reply == NULL)) {
1729 /* If the poll returns error then we need to do diag reset */
1730 printf("%s: poll for page completed with error %d",
1735 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1736 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1737 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1739 /* If the poll returns error then we need to do diag reset */
1740 printf("%s: page read with error; iocstatus = 0x%x\n",
1741 __func__, ioc_status);
1745 bcopy(page, config_page, MIN(cm->cm_length,
1746 sizeof(Mpi2RaidPhysDiskPage0_t)));
1750 mpr_free_command(sc, cm);