2 * Copyright (c) 2011-2015 LSI Corp.
3 * Copyright (c) 2013-2016 Avago Technologies
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 /* TODO Move headers to mprvar */
34 #include <sys/types.h>
35 #include <sys/param.h>
37 #include <sys/mutex.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/kthread.h>
42 #include <sys/taskqueue.h>
44 #include <sys/endian.h>
45 #include <sys/sysctl.h>
46 #include <sys/eventhandler.h>
48 #include <machine/bus.h>
49 #include <machine/resource.h>
50 #include <dev/mpr/mpi/mpi2_type.h>
51 #include <dev/mpr/mpi/mpi2.h>
52 #include <dev/mpr/mpi/mpi2_ioc.h>
53 #include <dev/mpr/mpi/mpi2_sas.h>
54 #include <dev/mpr/mpi/mpi2_pci.h>
55 #include <dev/mpr/mpi/mpi2_cnfg.h>
56 #include <dev/mpr/mpi/mpi2_init.h>
57 #include <dev/mpr/mpi/mpi2_tool.h>
58 #include <dev/mpr/mpr_ioctl.h>
59 #include <dev/mpr/mprvar.h>
62 * mpr_config_get_ioc_pg8 - obtain ioc page 8
63 * @sc: per adapter object
64 * @mpi_reply: reply mf payload returned from firmware
65 * @config_page: contents of the config page
68 * Returns 0 for success, non-zero for failure.
71 mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
72 Mpi2IOCPage8_t *config_page)
74 MPI2_CONFIG_REQUEST *request;
75 MPI2_CONFIG_REPLY *reply;
76 struct mpr_command *cm;
77 MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
81 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
83 if ((cm = mpr_alloc_command(sc)) == NULL) {
84 printf("%s: command alloc failed @ line %d\n", __func__,
89 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
90 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
91 request->Function = MPI2_FUNCTION_CONFIG;
92 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
93 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
94 request->Header.PageNumber = 8;
95 request->Header.PageLength = request->Header.PageVersion = 0;
96 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
98 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
100 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
101 if (error || (reply == NULL)) {
104 * If the request returns an error then we need to do a diag
107 printf("%s: request for header completed with error %d",
112 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
113 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
114 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
117 * If the request returns an error then we need to do a diag
120 printf("%s: header read with error; iocstatus = 0x%x\n",
121 __func__, ioc_status);
125 /* We have to do free and alloc for the reply-free and reply-post
126 * counters to match - Need to review the reply FIFO handling.
128 mpr_free_command(sc, cm);
130 if ((cm = mpr_alloc_command(sc)) == NULL) {
131 printf("%s: command alloc failed @ line %d\n", __func__,
136 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
137 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
138 request->Function = MPI2_FUNCTION_CONFIG;
139 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
140 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
141 request->Header.PageNumber = 8;
142 request->Header.PageVersion = mpi_reply->Header.PageVersion;
143 request->Header.PageLength = mpi_reply->Header.PageLength;
144 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
145 cm->cm_sge = &request->PageBufferSGE;
146 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
147 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
148 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
149 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
151 printf("%s: page alloc failed\n", __func__);
157 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
159 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
160 if (error || (reply == NULL)) {
163 * If the request returns an error then we need to do a diag
166 printf("%s: request for page completed with error %d",
171 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
172 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
173 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
176 * If the request returns an error then we need to do a diag
179 printf("%s: page read with error; iocstatus = 0x%x\n",
180 __func__, ioc_status);
184 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
189 mpr_free_command(sc, cm);
194 * mpr_config_get_iounit_pg8 - obtain iounit page 8
195 * @sc: per adapter object
196 * @mpi_reply: reply mf payload returned from firmware
197 * @config_page: contents of the config page
200 * Returns 0 for success, non-zero for failure.
203 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
204 Mpi2IOUnitPage8_t *config_page)
206 MPI2_CONFIG_REQUEST *request;
207 MPI2_CONFIG_REPLY *reply;
208 struct mpr_command *cm;
209 MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
213 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
215 if ((cm = mpr_alloc_command(sc)) == NULL) {
216 printf("%s: command alloc failed @ line %d\n", __func__,
221 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
222 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
223 request->Function = MPI2_FUNCTION_CONFIG;
224 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
225 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
226 request->Header.PageNumber = 8;
227 request->Header.PageLength = request->Header.PageVersion = 0;
228 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
230 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
232 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
233 if (error || (reply == NULL)) {
236 * If the request returns an error then we need to do a diag
239 printf("%s: request for header completed with error %d",
244 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
245 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
246 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
249 * If the request returns an error then we need to do a diag
252 printf("%s: header read with error; iocstatus = 0x%x\n",
253 __func__, ioc_status);
257 /* We have to do free and alloc for the reply-free and reply-post
258 * counters to match - Need to review the reply FIFO handling.
260 mpr_free_command(sc, cm);
262 if ((cm = mpr_alloc_command(sc)) == NULL) {
263 printf("%s: command alloc failed @ line %d\n", __func__,
268 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
269 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
270 request->Function = MPI2_FUNCTION_CONFIG;
271 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
272 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
273 request->Header.PageNumber = 8;
274 request->Header.PageVersion = mpi_reply->Header.PageVersion;
275 request->Header.PageLength = mpi_reply->Header.PageLength;
276 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
277 cm->cm_sge = &request->PageBufferSGE;
278 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
279 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
280 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
281 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
283 printf("%s: page alloc failed\n", __func__);
289 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
291 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
292 if (error || (reply == NULL)) {
295 * If the request returns an error then we need to do a diag
298 printf("%s: request for page completed with error %d",
303 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
304 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
305 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
308 * If the request returns an error then we need to do a diag
311 printf("%s: page read with error; iocstatus = 0x%x\n",
312 __func__, ioc_status);
316 bcopy(page, config_page, MIN(cm->cm_length,
317 (sizeof(Mpi2IOUnitPage8_t))));
322 mpr_free_command(sc, cm);
327 * mpr_base_static_config_pages - static start of day config pages.
328 * @sc: per adapter object
333 mpr_base_static_config_pages(struct mpr_softc *sc)
335 Mpi2ConfigReply_t mpi_reply;
339 while (mpr_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) {
342 /* We need to Handle this situation */
348 while (mpr_config_get_iounit_pg8(sc, &mpi_reply, &sc->iounit_pg8)) {
351 /* We need to Handle this situation */
359 * mpr_config_get_dpm_pg0 - obtain driver persistent mapping page0
360 * @sc: per adapter object
361 * @mpi_reply: reply mf payload returned from firmware
362 * @config_page: contents of the config page
363 * @sz: size of buffer passed in config_page
366 * Returns 0 for success, non-zero for failure.
369 mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
370 Mpi2DriverMappingPage0_t *config_page, u16 sz)
372 MPI2_CONFIG_REQUEST *request;
373 MPI2_CONFIG_REPLY *reply;
374 struct mpr_command *cm;
375 Mpi2DriverMappingPage0_t *page = NULL;
379 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
381 memset(config_page, 0, sz);
382 if ((cm = mpr_alloc_command(sc)) == NULL) {
383 printf("%s: command alloc failed @ line %d\n", __func__,
388 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
389 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
390 request->Function = MPI2_FUNCTION_CONFIG;
391 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
392 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
393 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
394 request->Header.PageNumber = 0;
395 request->ExtPageLength = request->Header.PageVersion = 0;
396 request->PageAddress = sc->max_dpm_entries <<
397 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
398 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
400 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
402 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
403 if (error || (reply == NULL)) {
406 * If the request returns an error then we need to do a diag
409 printf("%s: request for header completed with error %d",
414 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
415 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
416 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
419 * If the request returns an error then we need to do a diag
422 printf("%s: header read with error; iocstatus = 0x%x\n",
423 __func__, ioc_status);
427 /* We have to do free and alloc for the reply-free and reply-post
428 * counters to match - Need to review the reply FIFO handling.
430 mpr_free_command(sc, cm);
432 if ((cm = mpr_alloc_command(sc)) == NULL) {
433 printf("%s: command alloc failed @ line %d\n", __func__,
438 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
439 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
440 request->Function = MPI2_FUNCTION_CONFIG;
441 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
442 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
443 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
444 request->Header.PageNumber = 0;
445 request->Header.PageVersion = mpi_reply->Header.PageVersion;
446 request->PageAddress = sc->max_dpm_entries <<
447 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
448 request->ExtPageLength = mpi_reply->ExtPageLength;
449 cm->cm_length = le16toh(request->ExtPageLength) * 4;
450 cm->cm_sge = &request->PageBufferSGE;
451 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
452 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
453 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
454 page = malloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
456 printf("%s: page alloc failed\n", __func__);
461 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
463 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
464 if (error || (reply == NULL)) {
467 * If the request returns an error then we need to do a diag
470 printf("%s: request for page completed with error %d",
475 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
476 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
477 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
480 * If the request returns an error then we need to do a diag
483 printf("%s: page read with error; iocstatus = 0x%x\n",
484 __func__, ioc_status);
488 bcopy(page, config_page, MIN(cm->cm_length, sz));
492 mpr_free_command(sc, cm);
497 * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
498 * @sc: per adapter object
499 * @mpi_reply: reply mf payload returned from firmware
500 * @config_page: contents of the config page
501 * @entry_idx: entry index in DPM Page0 to be modified
504 * Returns 0 for success, non-zero for failure.
507 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
508 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
510 MPI2_CONFIG_REQUEST *request;
511 MPI2_CONFIG_REPLY *reply;
512 struct mpr_command *cm;
513 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
517 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
519 if ((cm = mpr_alloc_command(sc)) == NULL) {
520 printf("%s: command alloc failed @ line %d\n", __func__,
525 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
526 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
527 request->Function = MPI2_FUNCTION_CONFIG;
528 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
529 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
530 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
531 request->Header.PageNumber = 0;
532 request->ExtPageLength = request->Header.PageVersion = 0;
533 /* We can remove below two lines ????*/
534 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
535 request->PageAddress |= htole16(entry_idx);
536 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
538 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
540 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
541 if (error || (reply == NULL)) {
544 * If the request returns an error then we need to do a diag
547 printf("%s: request for header completed with error %d",
552 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
553 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
554 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
557 * If the request returns an error then we need to do a diag
560 printf("%s: header read with error; iocstatus = 0x%x\n",
561 __func__, ioc_status);
565 /* We have to do free and alloc for the reply-free and reply-post
566 * counters to match - Need to review the reply FIFO handling.
568 mpr_free_command(sc, cm);
570 if ((cm = mpr_alloc_command(sc)) == NULL) {
571 printf("%s: command alloc failed @ line %d\n", __func__,
576 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
577 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
578 request->Function = MPI2_FUNCTION_CONFIG;
579 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
580 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
581 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
582 request->Header.PageNumber = 0;
583 request->Header.PageVersion = mpi_reply->Header.PageVersion;
584 request->ExtPageLength = mpi_reply->ExtPageLength;
585 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
586 request->PageAddress |= htole16(entry_idx);
587 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
588 cm->cm_sge = &request->PageBufferSGE;
589 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
590 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
591 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
592 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
594 printf("%s: page alloc failed\n", __func__);
598 bcopy(config_page, page, MIN(cm->cm_length,
599 (sizeof(Mpi2DriverMappingPage0_t))));
601 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
603 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
604 if (error || (reply == NULL)) {
607 * If the request returns an error then we need to do a diag
610 printf("%s: request to write page completed with error %d",
615 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
616 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
617 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
620 * If the request returns an error then we need to do a diag
623 printf("%s: page written with error; iocstatus = 0x%x\n",
624 __func__, ioc_status);
631 mpr_free_command(sc, cm);
636 * mpr_config_get_sas_device_pg0 - obtain sas device page 0
637 * @sc: per adapter object
638 * @mpi_reply: reply mf payload returned from firmware
639 * @config_page: contents of the config page
640 * @form: GET_NEXT_HANDLE or HANDLE
641 * @handle: device handle
644 * Returns 0 for success, non-zero for failure.
647 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
648 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
650 MPI2_CONFIG_REQUEST *request;
651 MPI2_CONFIG_REPLY *reply;
652 struct mpr_command *cm;
653 Mpi2SasDevicePage0_t *page = NULL;
657 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
659 if ((cm = mpr_alloc_command(sc)) == NULL) {
660 printf("%s: command alloc failed @ line %d\n", __func__,
665 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
666 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
667 request->Function = MPI2_FUNCTION_CONFIG;
668 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
669 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
670 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
671 request->Header.PageNumber = 0;
672 request->ExtPageLength = request->Header.PageVersion = 0;
673 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
675 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
677 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
678 if (error || (reply == NULL)) {
681 * If the request returns an error then we need to do a diag
684 printf("%s: request for header completed with error %d",
689 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
690 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
691 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
694 * If the request returns an error then we need to do a diag
697 printf("%s: header read with error; iocstatus = 0x%x\n",
698 __func__, ioc_status);
702 /* We have to do free and alloc for the reply-free and reply-post
703 * counters to match - Need to review the reply FIFO handling.
705 mpr_free_command(sc, cm);
707 if ((cm = mpr_alloc_command(sc)) == NULL) {
708 printf("%s: command alloc failed @ line %d\n", __func__,
713 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
714 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
715 request->Function = MPI2_FUNCTION_CONFIG;
716 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
717 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
718 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
719 request->Header.PageNumber = 0;
720 request->Header.PageVersion = mpi_reply->Header.PageVersion;
721 request->ExtPageLength = mpi_reply->ExtPageLength;
722 request->PageAddress = htole32(form | handle);
723 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
724 cm->cm_sge = &request->PageBufferSGE;
725 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
726 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
727 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
728 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
730 printf("%s: page alloc failed\n", __func__);
736 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
738 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
739 if (error || (reply == NULL)) {
742 * If the request returns an error then we need to do a diag
745 printf("%s: request for page completed with error %d",
750 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
751 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
752 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
755 * If the request returns an error then we need to do a diag
758 printf("%s: page read with error; iocstatus = 0x%x\n",
759 __func__, ioc_status);
763 bcopy(page, config_page, MIN(cm->cm_length,
764 sizeof(Mpi2SasDevicePage0_t)));
768 mpr_free_command(sc, cm);
773 * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
774 * @sc: per adapter object
775 * @mpi_reply: reply mf payload returned from firmware
776 * @config_page: contents of the config page
777 * @form: GET_NEXT_HANDLE or HANDLE
778 * @handle: device handle
781 * Returns 0 for success, non-zero for failure.
784 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
785 *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
787 MPI2_CONFIG_REQUEST *request;
788 MPI2_CONFIG_REPLY *reply;
789 struct mpr_command *cm;
790 Mpi26PCIeDevicePage0_t *page = NULL;
794 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
796 if ((cm = mpr_alloc_command(sc)) == NULL) {
797 printf("%s: command alloc failed @ line %d\n", __func__,
802 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
803 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
804 request->Function = MPI2_FUNCTION_CONFIG;
805 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
806 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
807 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
808 request->Header.PageNumber = 0;
809 request->ExtPageLength = request->Header.PageVersion = 0;
810 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
812 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
814 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
815 if (error || (reply == NULL)) {
818 * If the request returns an error then we need to do a diag
821 printf("%s: request for header completed with error %d",
826 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
827 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
828 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
831 * If the request returns an error then we need to do a diag
834 printf("%s: header read with error; iocstatus = 0x%x\n",
835 __func__, ioc_status);
839 /* We have to do free and alloc for the reply-free and reply-post
840 * counters to match - Need to review the reply FIFO handling.
842 mpr_free_command(sc, cm);
844 if ((cm = mpr_alloc_command(sc)) == NULL) {
845 printf("%s: command alloc failed @ line %d\n", __func__,
850 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
851 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
852 request->Function = MPI2_FUNCTION_CONFIG;
853 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
854 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
855 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
856 request->Header.PageNumber = 0;
857 request->Header.PageVersion = mpi_reply->Header.PageVersion;
858 request->ExtPageLength = mpi_reply->ExtPageLength;
859 request->PageAddress = htole32(form | handle);
860 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
861 cm->cm_sge = &request->PageBufferSGE;
862 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
863 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
864 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
865 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
867 printf("%s: page alloc failed\n", __func__);
873 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
875 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
876 if (error || (reply == NULL)) {
879 * If the request returns an error then we need to do a diag
882 printf("%s: request for page completed with error %d",
887 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
888 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
889 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
892 * If the request returns an error then we need to do a diag
895 printf("%s: page read with error; iocstatus = 0x%x\n",
896 __func__, ioc_status);
900 bcopy(page, config_page, MIN(cm->cm_length,
901 sizeof(Mpi26PCIeDevicePage0_t)));
905 mpr_free_command(sc, cm);
910 * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
911 * @sc: per adapter object
912 * @mpi_reply: reply mf payload returned from firmware
913 * @config_page: contents of the config page
914 * @form: GET_NEXT_HANDLE or HANDLE
915 * @handle: device handle
918 * Returns 0 for success, non-zero for failure.
921 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
922 *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
924 MPI2_CONFIG_REQUEST *request;
925 MPI2_CONFIG_REPLY *reply;
926 struct mpr_command *cm;
927 Mpi26PCIeDevicePage2_t *page = NULL;
931 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
933 if ((cm = mpr_alloc_command(sc)) == NULL) {
934 printf("%s: command alloc failed @ line %d\n", __func__,
939 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
940 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
941 request->Function = MPI2_FUNCTION_CONFIG;
942 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
943 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
944 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
945 request->Header.PageNumber = 2;
946 request->ExtPageLength = request->Header.PageVersion = 0;
947 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
949 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
951 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
952 if (error || (reply == NULL)) {
955 * If the request returns an error then we need to do a diag
958 printf("%s: request for header completed with error %d",
963 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
964 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
965 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
968 * If the request returns an error then we need to do a diag
971 printf("%s: header read with error; iocstatus = 0x%x\n",
972 __func__, ioc_status);
976 /* We have to do free and alloc for the reply-free and reply-post
977 * counters to match - Need to review the reply FIFO handling.
979 mpr_free_command(sc, cm);
981 if ((cm = mpr_alloc_command(sc)) == NULL) {
982 printf("%s: command alloc failed @ line %d\n", __func__,
987 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
988 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
989 request->Function = MPI2_FUNCTION_CONFIG;
990 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
991 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
992 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
993 request->Header.PageNumber = 2;
994 request->Header.PageVersion = mpi_reply->Header.PageVersion;
995 request->ExtPageLength = mpi_reply->ExtPageLength;
996 request->PageAddress = htole32(form | handle);
997 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
998 cm->cm_sge = &request->PageBufferSGE;
999 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1000 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1001 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1002 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1004 printf("%s: page alloc failed\n", __func__);
1010 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1012 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1013 if (error || (reply == NULL)) {
1016 * If the request returns an error then we need to do a diag
1019 printf("%s: request for page completed with error %d",
1024 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1025 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1026 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1029 * If the request returns an error then we need to do a diag
1032 printf("%s: page read with error; iocstatus = 0x%x\n",
1033 __func__, ioc_status);
1037 bcopy(page, config_page, MIN(cm->cm_length,
1038 sizeof(Mpi26PCIeDevicePage2_t)));
1042 mpr_free_command(sc, cm);
1047 * mpr_config_get_bios_pg3 - obtain BIOS page 3
1048 * @sc: per adapter object
1049 * @mpi_reply: reply mf payload returned from firmware
1050 * @config_page: contents of the config page
1053 * Returns 0 for success, non-zero for failure.
1056 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1057 Mpi2BiosPage3_t *config_page)
1059 MPI2_CONFIG_REQUEST *request;
1060 MPI2_CONFIG_REPLY *reply;
1061 struct mpr_command *cm;
1062 Mpi2BiosPage3_t *page = NULL;
1066 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1068 if ((cm = mpr_alloc_command(sc)) == NULL) {
1069 printf("%s: command alloc failed @ line %d\n", __func__,
1074 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1075 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1076 request->Function = MPI2_FUNCTION_CONFIG;
1077 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1078 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1079 request->Header.PageNumber = 3;
1080 request->Header.PageLength = request->Header.PageVersion = 0;
1081 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1083 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1085 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1086 if (error || (reply == NULL)) {
1089 * If the request returns an error then we need to do a diag
1092 printf("%s: request for header completed with error %d",
1097 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1098 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1099 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1102 * If the request returns an error then we need to do a diag
1105 printf("%s: header read with error; iocstatus = 0x%x\n",
1106 __func__, ioc_status);
1110 /* We have to do free and alloc for the reply-free and reply-post
1111 * counters to match - Need to review the reply FIFO handling.
1113 mpr_free_command(sc, cm);
1115 if ((cm = mpr_alloc_command(sc)) == NULL) {
1116 printf("%s: command alloc failed @ line %d\n", __func__,
1121 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1122 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1123 request->Function = MPI2_FUNCTION_CONFIG;
1124 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1125 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1126 request->Header.PageNumber = 3;
1127 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1128 request->Header.PageLength = mpi_reply->Header.PageLength;
1129 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1130 cm->cm_sge = &request->PageBufferSGE;
1131 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1132 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1133 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1134 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1136 printf("%s: page alloc failed\n", __func__);
1142 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1144 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1145 if (error || (reply == NULL)) {
1148 * If the request returns an error then we need to do a diag
1151 printf("%s: request for page completed with error %d",
1156 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1157 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1158 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1161 * If the request returns an error then we need to do a diag
1164 printf("%s: page read with error; iocstatus = 0x%x\n",
1165 __func__, ioc_status);
1169 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
1173 mpr_free_command(sc, cm);
1178 * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
1179 * @sc: per adapter object
1180 * @mpi_reply: reply mf payload returned from firmware
1181 * @config_page: contents of the config page
1182 * @page_address: form and handle value used to get page
1185 * Returns 0 for success, non-zero for failure.
1188 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
1189 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
1191 MPI2_CONFIG_REQUEST *request;
1192 MPI2_CONFIG_REPLY *reply = NULL;
1193 struct mpr_command *cm;
1194 Mpi2RaidVolPage0_t *page = NULL;
1198 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1200 if ((cm = mpr_alloc_command(sc)) == NULL) {
1201 printf("%s: command alloc failed @ line %d\n", __func__,
1206 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1207 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1208 request->Function = MPI2_FUNCTION_CONFIG;
1209 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1210 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1211 request->Header.PageNumber = 0;
1212 request->Header.PageLength = request->Header.PageVersion = 0;
1213 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1217 * This page must be polled because the IOC isn't ready yet when this
1220 error = mpr_request_polled(sc, &cm);
1222 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1223 if (error || (reply == NULL)) {
1225 /* If the poll returns error then we need to do diag reset */
1226 printf("%s: poll for header completed with error %d",
1231 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1232 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1233 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1235 /* If the poll returns error then we need to do diag reset */
1236 printf("%s: header read with error; iocstatus = 0x%x\n",
1237 __func__, ioc_status);
1241 /* We have to do free and alloc for the reply-free and reply-post
1242 * counters to match - Need to review the reply FIFO handling.
1244 mpr_free_command(sc, cm);
1246 if ((cm = mpr_alloc_command(sc)) == NULL) {
1247 printf("%s: command alloc failed @ line %d\n", __func__,
1252 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1253 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1254 request->Function = MPI2_FUNCTION_CONFIG;
1255 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1256 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1257 request->Header.PageNumber = 0;
1258 request->Header.PageLength = mpi_reply->Header.PageLength;
1259 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1260 request->PageAddress = page_address;
1261 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1262 cm->cm_sge = &request->PageBufferSGE;
1263 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1264 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1265 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1266 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1268 printf("%s: page alloc failed\n", __func__);
1275 * This page must be polled because the IOC isn't ready yet when this
1278 error = mpr_request_polled(sc, &cm);
1280 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1281 if (error || (reply == NULL)) {
1283 /* If the poll returns error then we need to do diag reset */
1284 printf("%s: poll for page completed with error %d",
1289 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1290 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1291 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1293 /* If the poll returns error then we need to do diag reset */
1294 printf("%s: page read with error; iocstatus = 0x%x\n",
1295 __func__, ioc_status);
1299 bcopy(page, config_page, cm->cm_length);
1303 mpr_free_command(sc, cm);
1308 * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
1309 * @sc: per adapter object
1310 * @mpi_reply: reply mf payload returned from firmware
1311 * @config_page: contents of the config page
1312 * @form: GET_NEXT_HANDLE or HANDLE
1313 * @handle: volume handle
1316 * Returns 0 for success, non-zero for failure.
1319 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
1320 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
1322 MPI2_CONFIG_REQUEST *request;
1323 MPI2_CONFIG_REPLY *reply;
1324 struct mpr_command *cm;
1325 Mpi2RaidVolPage1_t *page = NULL;
1329 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1331 if ((cm = mpr_alloc_command(sc)) == NULL) {
1332 printf("%s: command alloc failed @ line %d\n", __func__,
1337 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1338 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1339 request->Function = MPI2_FUNCTION_CONFIG;
1340 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1341 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1342 request->Header.PageNumber = 1;
1343 request->Header.PageLength = request->Header.PageVersion = 0;
1344 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1346 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1348 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1349 if (error || (reply == NULL)) {
1352 * If the request returns an error then we need to do a diag
1355 printf("%s: request for header completed with error %d",
1360 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1361 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1362 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1365 * If the request returns an error then we need to do a diag
1368 printf("%s: header read with error; iocstatus = 0x%x\n",
1369 __func__, ioc_status);
1373 /* We have to do free and alloc for the reply-free and reply-post
1374 * counters to match - Need to review the reply FIFO handling.
1376 mpr_free_command(sc, cm);
1378 if ((cm = mpr_alloc_command(sc)) == NULL) {
1379 printf("%s: command alloc failed @ line %d\n", __func__,
1384 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1385 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1386 request->Function = MPI2_FUNCTION_CONFIG;
1387 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1388 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1389 request->Header.PageNumber = 1;
1390 request->Header.PageLength = mpi_reply->Header.PageLength;
1391 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1392 request->PageAddress = htole32(form | handle);
1393 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1394 cm->cm_sge = &request->PageBufferSGE;
1395 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1396 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1397 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1398 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1400 printf("%s: page alloc failed\n", __func__);
1406 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1408 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1409 if (error || (reply == NULL)) {
1412 * If the request returns an error then we need to do a diag
1415 printf("%s: request for page completed with error %d",
1420 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1421 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1422 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1425 * If the request returns an error then we need to do a diag
1428 printf("%s: page read with error; iocstatus = 0x%x\n",
1429 __func__, ioc_status);
1433 bcopy(page, config_page, MIN(cm->cm_length,
1434 sizeof(Mpi2RaidVolPage1_t)));
1438 mpr_free_command(sc, cm);
1443 * mpr_config_get_volume_wwid - returns wwid given the volume handle
1444 * @sc: per adapter object
1445 * @volume_handle: volume handle
1446 * @wwid: volume wwid
1449 * Returns 0 for success, non-zero for failure.
1452 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
1454 Mpi2ConfigReply_t mpi_reply;
1455 Mpi2RaidVolPage1_t raid_vol_pg1;
1458 if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
1459 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
1460 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
1461 raid_vol_pg1.WWID.Low);
1468 * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
1469 * @sc: per adapter object
1470 * @mpi_reply: reply mf payload returned from firmware
1471 * @config_page: contents of the config page
1472 * @page_address: form and handle value used to get page
1475 * Returns 0 for success, non-zero for failure.
1478 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1479 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
1481 MPI2_CONFIG_REQUEST *request;
1482 MPI2_CONFIG_REPLY *reply = NULL;
1483 struct mpr_command *cm;
1484 Mpi2RaidPhysDiskPage0_t *page = NULL;
1488 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1490 if ((cm = mpr_alloc_command(sc)) == NULL) {
1491 printf("%s: command alloc failed @ line %d\n", __func__,
1496 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1497 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1498 request->Function = MPI2_FUNCTION_CONFIG;
1499 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1500 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1501 request->Header.PageNumber = 0;
1502 request->Header.PageLength = request->Header.PageVersion = 0;
1503 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1507 * This page must be polled because the IOC isn't ready yet when this
1510 error = mpr_request_polled(sc, &cm);
1512 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1513 if (error || (reply == NULL)) {
1515 /* If the poll returns error then we need to do diag reset */
1516 printf("%s: poll for header completed with error %d",
1521 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1522 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1523 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1525 /* If the poll returns error then we need to do diag reset */
1526 printf("%s: header read with error; iocstatus = 0x%x\n",
1527 __func__, ioc_status);
1531 /* We have to do free and alloc for the reply-free and reply-post
1532 * counters to match - Need to review the reply FIFO handling.
1534 mpr_free_command(sc, cm);
1536 if ((cm = mpr_alloc_command(sc)) == NULL) {
1537 printf("%s: command alloc failed @ line %d\n", __func__,
1542 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1543 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1544 request->Function = MPI2_FUNCTION_CONFIG;
1545 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1546 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1547 request->Header.PageNumber = 0;
1548 request->Header.PageLength = mpi_reply->Header.PageLength;
1549 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1550 request->PageAddress = page_address;
1551 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1552 cm->cm_sge = &request->PageBufferSGE;
1553 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1554 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1555 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1556 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1558 printf("%s: page alloc failed\n", __func__);
1565 * This page must be polled because the IOC isn't ready yet when this
1568 error = mpr_request_polled(sc, &cm);
1570 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1571 if (error || (reply == NULL)) {
1573 /* If the poll returns error then we need to do diag reset */
1574 printf("%s: poll for page completed with error %d",
1579 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1580 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1581 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1583 /* If the poll returns error then we need to do diag reset */
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(Mpi2RaidPhysDiskPage0_t)));
1594 mpr_free_command(sc, cm);