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);
99 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
100 if (error || (reply == NULL)) {
103 * If the request returns an error then we need to do a diag
106 printf("%s: request for header completed with error %d",
111 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
112 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
113 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
116 * If the request returns an error then we need to do a diag
119 printf("%s: header read with error; iocstatus = 0x%x\n",
120 __func__, ioc_status);
124 /* We have to do free and alloc for the reply-free and reply-post
125 * counters to match - Need to review the reply FIFO handling.
127 mpr_free_command(sc, cm);
129 if ((cm = mpr_alloc_command(sc)) == NULL) {
130 printf("%s: command alloc failed @ line %d\n", __func__,
135 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
136 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
137 request->Function = MPI2_FUNCTION_CONFIG;
138 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
139 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
140 request->Header.PageNumber = 8;
141 request->Header.PageVersion = mpi_reply->Header.PageVersion;
142 request->Header.PageLength = mpi_reply->Header.PageLength;
143 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
144 cm->cm_sge = &request->PageBufferSGE;
145 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
146 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
147 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
148 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
150 printf("%s: page alloc failed\n", __func__);
156 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
157 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
158 if (error || (reply == NULL)) {
161 * If the request returns an error then we need to do a diag
164 printf("%s: request for page completed with error %d",
169 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
170 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
171 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
174 * If the request returns an error then we need to do a diag
177 printf("%s: page read with error; iocstatus = 0x%x\n",
178 __func__, ioc_status);
182 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
187 mpr_free_command(sc, cm);
192 * mpr_config_get_iounit_pg8 - obtain iounit page 8
193 * @sc: per adapter object
194 * @mpi_reply: reply mf payload returned from firmware
195 * @config_page: contents of the config page
198 * Returns 0 for success, non-zero for failure.
201 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
202 Mpi2IOUnitPage8_t *config_page)
204 MPI2_CONFIG_REQUEST *request;
205 MPI2_CONFIG_REPLY *reply;
206 struct mpr_command *cm;
207 MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
211 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
213 if ((cm = mpr_alloc_command(sc)) == NULL) {
214 printf("%s: command alloc failed @ line %d\n", __func__,
219 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
220 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
221 request->Function = MPI2_FUNCTION_CONFIG;
222 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
223 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
224 request->Header.PageNumber = 8;
225 request->Header.PageLength = request->Header.PageVersion = 0;
226 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
228 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
229 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
230 if (error || (reply == NULL)) {
233 * If the request returns an error then we need to do a diag
236 printf("%s: request for header completed with error %d",
241 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
242 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
243 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
246 * If the request returns an error then we need to do a diag
249 printf("%s: header read with error; iocstatus = 0x%x\n",
250 __func__, ioc_status);
254 /* We have to do free and alloc for the reply-free and reply-post
255 * counters to match - Need to review the reply FIFO handling.
257 mpr_free_command(sc, cm);
259 if ((cm = mpr_alloc_command(sc)) == NULL) {
260 printf("%s: command alloc failed @ line %d\n", __func__,
265 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
266 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
267 request->Function = MPI2_FUNCTION_CONFIG;
268 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
269 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
270 request->Header.PageNumber = 8;
271 request->Header.PageVersion = mpi_reply->Header.PageVersion;
272 request->Header.PageLength = mpi_reply->Header.PageLength;
273 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
274 cm->cm_sge = &request->PageBufferSGE;
275 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
276 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
277 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
278 page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
280 printf("%s: page alloc failed\n", __func__);
286 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
287 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
288 if (error || (reply == NULL)) {
291 * If the request returns an error then we need to do a diag
294 printf("%s: request for page completed with error %d",
299 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
300 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
301 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
304 * If the request returns an error then we need to do a diag
307 printf("%s: page read with error; iocstatus = 0x%x\n",
308 __func__, ioc_status);
312 bcopy(page, config_page, MIN(cm->cm_length,
313 (sizeof(Mpi2IOUnitPage8_t))));
318 mpr_free_command(sc, cm);
323 * mpr_base_static_config_pages - static start of day config pages.
324 * @sc: per adapter object
329 mpr_base_static_config_pages(struct mpr_softc *sc)
331 Mpi2ConfigReply_t mpi_reply;
335 while (mpr_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) {
338 /* We need to Handle this situation */
344 while (mpr_config_get_iounit_pg8(sc, &mpi_reply, &sc->iounit_pg8)) {
347 /* We need to Handle this situation */
355 * mpr_config_get_dpm_pg0 - obtain driver persistent mapping page0
356 * @sc: per adapter object
357 * @mpi_reply: reply mf payload returned from firmware
358 * @config_page: contents of the config page
359 * @sz: size of buffer passed in config_page
362 * Returns 0 for success, non-zero for failure.
365 mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
366 Mpi2DriverMappingPage0_t *config_page, u16 sz)
368 MPI2_CONFIG_REQUEST *request;
369 MPI2_CONFIG_REPLY *reply;
370 struct mpr_command *cm;
371 Mpi2DriverMappingPage0_t *page = NULL;
375 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
377 memset(config_page, 0, sz);
378 if ((cm = mpr_alloc_command(sc)) == NULL) {
379 printf("%s: command alloc failed @ line %d\n", __func__,
384 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
385 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
386 request->Function = MPI2_FUNCTION_CONFIG;
387 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
388 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
389 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
390 request->Header.PageNumber = 0;
391 request->ExtPageLength = request->Header.PageVersion = 0;
392 request->PageAddress = sc->max_dpm_entries <<
393 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
394 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
396 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
397 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
398 if (error || (reply == NULL)) {
401 * If the request returns an error then we need to do a diag
404 printf("%s: request for header completed with error %d",
409 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
410 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
411 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
414 * If the request returns an error then we need to do a diag
417 printf("%s: header read with error; iocstatus = 0x%x\n",
418 __func__, ioc_status);
422 /* We have to do free and alloc for the reply-free and reply-post
423 * counters to match - Need to review the reply FIFO handling.
425 mpr_free_command(sc, cm);
427 if ((cm = mpr_alloc_command(sc)) == NULL) {
428 printf("%s: command alloc failed @ line %d\n", __func__,
433 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
434 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
435 request->Function = MPI2_FUNCTION_CONFIG;
436 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
437 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
438 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
439 request->Header.PageNumber = 0;
440 request->Header.PageVersion = mpi_reply->Header.PageVersion;
441 request->PageAddress = sc->max_dpm_entries <<
442 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
443 request->ExtPageLength = mpi_reply->ExtPageLength;
444 cm->cm_length = le16toh(request->ExtPageLength) * 4;
445 cm->cm_sge = &request->PageBufferSGE;
446 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
447 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
448 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
449 page = malloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
451 printf("%s: page alloc failed\n", __func__);
456 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
457 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
458 if (error || (reply == NULL)) {
461 * If the request returns an error then we need to do a diag
464 printf("%s: request for page completed with error %d",
469 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
470 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
471 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
474 * If the request returns an error then we need to do a diag
477 printf("%s: page read with error; iocstatus = 0x%x\n",
478 __func__, ioc_status);
482 bcopy(page, config_page, MIN(cm->cm_length, sz));
486 mpr_free_command(sc, cm);
491 * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
492 * @sc: per adapter object
493 * @mpi_reply: reply mf payload returned from firmware
494 * @config_page: contents of the config page
495 * @entry_idx: entry index in DPM Page0 to be modified
498 * Returns 0 for success, non-zero for failure.
501 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
502 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
504 MPI2_CONFIG_REQUEST *request;
505 MPI2_CONFIG_REPLY *reply;
506 struct mpr_command *cm;
507 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
511 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
513 if ((cm = mpr_alloc_command(sc)) == NULL) {
514 printf("%s: command alloc failed @ line %d\n", __func__,
519 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
520 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
521 request->Function = MPI2_FUNCTION_CONFIG;
522 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
523 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
524 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
525 request->Header.PageNumber = 0;
526 request->ExtPageLength = request->Header.PageVersion = 0;
527 /* We can remove below two lines ????*/
528 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
529 request->PageAddress |= htole16(entry_idx);
530 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
532 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
533 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
534 if (error || (reply == NULL)) {
537 * If the request returns an error then we need to do a diag
540 printf("%s: request for header completed with error %d",
545 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
546 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
547 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
550 * If the request returns an error then we need to do a diag
553 printf("%s: header read with error; iocstatus = 0x%x\n",
554 __func__, ioc_status);
558 /* We have to do free and alloc for the reply-free and reply-post
559 * counters to match - Need to review the reply FIFO handling.
561 mpr_free_command(sc, cm);
563 if ((cm = mpr_alloc_command(sc)) == NULL) {
564 printf("%s: command alloc failed @ line %d\n", __func__,
569 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
570 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
571 request->Function = MPI2_FUNCTION_CONFIG;
572 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
573 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
574 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
575 request->Header.PageNumber = 0;
576 request->Header.PageVersion = mpi_reply->Header.PageVersion;
577 request->ExtPageLength = mpi_reply->ExtPageLength;
578 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
579 request->PageAddress |= htole16(entry_idx);
580 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
581 cm->cm_sge = &request->PageBufferSGE;
582 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
583 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
584 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
585 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
587 printf("%s: page alloc failed\n", __func__);
591 bcopy(config_page, page, MIN(cm->cm_length,
592 (sizeof(Mpi2DriverMappingPage0_t))));
594 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
595 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
596 if (error || (reply == NULL)) {
599 * If the request returns an error then we need to do a diag
602 printf("%s: request to write page completed with error %d",
607 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
608 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
609 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
612 * If the request returns an error then we need to do a diag
615 printf("%s: page written with error; iocstatus = 0x%x\n",
616 __func__, ioc_status);
623 mpr_free_command(sc, cm);
628 * mpr_config_get_sas_device_pg0 - obtain sas device page 0
629 * @sc: per adapter object
630 * @mpi_reply: reply mf payload returned from firmware
631 * @config_page: contents of the config page
632 * @form: GET_NEXT_HANDLE or HANDLE
633 * @handle: device handle
636 * Returns 0 for success, non-zero for failure.
639 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
640 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
642 MPI2_CONFIG_REQUEST *request;
643 MPI2_CONFIG_REPLY *reply;
644 struct mpr_command *cm;
645 Mpi2SasDevicePage0_t *page = NULL;
649 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
651 if ((cm = mpr_alloc_command(sc)) == NULL) {
652 printf("%s: command alloc failed @ line %d\n", __func__,
657 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
658 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
659 request->Function = MPI2_FUNCTION_CONFIG;
660 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
661 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
662 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
663 request->Header.PageNumber = 0;
664 request->ExtPageLength = request->Header.PageVersion = 0;
665 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
667 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
668 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
669 if (error || (reply == NULL)) {
672 * If the request returns an error then we need to do a diag
675 printf("%s: request for header completed with error %d",
680 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
681 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
682 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
685 * If the request returns an error then we need to do a diag
688 printf("%s: header read with error; iocstatus = 0x%x\n",
689 __func__, ioc_status);
693 /* We have to do free and alloc for the reply-free and reply-post
694 * counters to match - Need to review the reply FIFO handling.
696 mpr_free_command(sc, cm);
698 if ((cm = mpr_alloc_command(sc)) == NULL) {
699 printf("%s: command alloc failed @ line %d\n", __func__,
704 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
705 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
706 request->Function = MPI2_FUNCTION_CONFIG;
707 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
708 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
709 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
710 request->Header.PageNumber = 0;
711 request->Header.PageVersion = mpi_reply->Header.PageVersion;
712 request->ExtPageLength = mpi_reply->ExtPageLength;
713 request->PageAddress = htole32(form | handle);
714 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
715 cm->cm_sge = &request->PageBufferSGE;
716 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
717 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
718 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
719 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
721 printf("%s: page alloc failed\n", __func__);
727 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
728 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
729 if (error || (reply == NULL)) {
732 * If the request returns an error then we need to do a diag
735 printf("%s: request for page completed with error %d",
740 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
741 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
742 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
745 * If the request returns an error then we need to do a diag
748 printf("%s: page read with error; iocstatus = 0x%x\n",
749 __func__, ioc_status);
753 bcopy(page, config_page, MIN(cm->cm_length,
754 sizeof(Mpi2SasDevicePage0_t)));
758 mpr_free_command(sc, cm);
763 * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
764 * @sc: per adapter object
765 * @mpi_reply: reply mf payload returned from firmware
766 * @config_page: contents of the config page
767 * @form: GET_NEXT_HANDLE or HANDLE
768 * @handle: device handle
771 * Returns 0 for success, non-zero for failure.
774 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
775 *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
777 MPI2_CONFIG_REQUEST *request;
778 MPI2_CONFIG_REPLY *reply;
779 struct mpr_command *cm;
780 Mpi26PCIeDevicePage0_t *page = NULL;
784 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
786 if ((cm = mpr_alloc_command(sc)) == NULL) {
787 printf("%s: command alloc failed @ line %d\n", __func__,
792 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
793 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
794 request->Function = MPI2_FUNCTION_CONFIG;
795 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
796 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
797 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
798 request->Header.PageNumber = 0;
799 request->ExtPageLength = request->Header.PageVersion = 0;
800 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
802 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
803 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
804 if (error || (reply == NULL)) {
807 * If the request returns an error then we need to do a diag
810 printf("%s: request for header completed with error %d",
815 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
816 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
817 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
820 * If the request returns an error then we need to do a diag
823 printf("%s: header read with error; iocstatus = 0x%x\n",
824 __func__, ioc_status);
828 /* We have to do free and alloc for the reply-free and reply-post
829 * counters to match - Need to review the reply FIFO handling.
831 mpr_free_command(sc, cm);
833 if ((cm = mpr_alloc_command(sc)) == NULL) {
834 printf("%s: command alloc failed @ line %d\n", __func__,
839 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
840 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
841 request->Function = MPI2_FUNCTION_CONFIG;
842 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
843 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
844 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
845 request->Header.PageNumber = 0;
846 request->Header.PageVersion = mpi_reply->Header.PageVersion;
847 request->ExtPageLength = mpi_reply->ExtPageLength;
848 request->PageAddress = htole32(form | handle);
849 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
850 cm->cm_sge = &request->PageBufferSGE;
851 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
852 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
853 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
854 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
856 printf("%s: page alloc failed\n", __func__);
862 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
863 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
864 if (error || (reply == NULL)) {
867 * If the request returns an error then we need to do a diag
870 printf("%s: request for page completed with error %d",
875 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
876 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
877 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
880 * If the request returns an error then we need to do a diag
883 printf("%s: page read with error; iocstatus = 0x%x\n",
884 __func__, ioc_status);
888 bcopy(page, config_page, MIN(cm->cm_length,
889 sizeof(Mpi26PCIeDevicePage0_t)));
893 mpr_free_command(sc, cm);
898 * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
899 * @sc: per adapter object
900 * @mpi_reply: reply mf payload returned from firmware
901 * @config_page: contents of the config page
902 * @form: GET_NEXT_HANDLE or HANDLE
903 * @handle: device handle
906 * Returns 0 for success, non-zero for failure.
909 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
910 *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
912 MPI2_CONFIG_REQUEST *request;
913 MPI2_CONFIG_REPLY *reply;
914 struct mpr_command *cm;
915 Mpi26PCIeDevicePage2_t *page = NULL;
919 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
921 if ((cm = mpr_alloc_command(sc)) == NULL) {
922 printf("%s: command alloc failed @ line %d\n", __func__,
927 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
928 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
929 request->Function = MPI2_FUNCTION_CONFIG;
930 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
931 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
932 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
933 request->Header.PageNumber = 2;
934 request->ExtPageLength = request->Header.PageVersion = 0;
935 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
937 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
938 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
939 if (error || (reply == NULL)) {
942 * If the request returns an error then we need to do a diag
945 printf("%s: request for header completed with error %d",
950 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
951 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
952 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
955 * If the request returns an error then we need to do a diag
958 printf("%s: header read with error; iocstatus = 0x%x\n",
959 __func__, ioc_status);
963 /* We have to do free and alloc for the reply-free and reply-post
964 * counters to match - Need to review the reply FIFO handling.
966 mpr_free_command(sc, cm);
968 if ((cm = mpr_alloc_command(sc)) == NULL) {
969 printf("%s: command alloc failed @ line %d\n", __func__,
974 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
975 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
976 request->Function = MPI2_FUNCTION_CONFIG;
977 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
978 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
979 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
980 request->Header.PageNumber = 2;
981 request->Header.PageVersion = mpi_reply->Header.PageVersion;
982 request->ExtPageLength = mpi_reply->ExtPageLength;
983 request->PageAddress = htole32(form | handle);
984 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
985 cm->cm_sge = &request->PageBufferSGE;
986 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
987 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
988 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
989 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
991 printf("%s: page alloc failed\n", __func__);
997 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
998 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
999 if (error || (reply == NULL)) {
1002 * If the request returns an error then we need to do a diag
1005 printf("%s: request for page completed with error %d",
1010 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1011 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1012 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1015 * If the request returns an error then we need to do a diag
1018 printf("%s: page read with error; iocstatus = 0x%x\n",
1019 __func__, ioc_status);
1023 bcopy(page, config_page, MIN(cm->cm_length,
1024 sizeof(Mpi26PCIeDevicePage2_t)));
1028 mpr_free_command(sc, cm);
1033 * mpr_config_get_bios_pg3 - obtain BIOS page 3
1034 * @sc: per adapter object
1035 * @mpi_reply: reply mf payload returned from firmware
1036 * @config_page: contents of the config page
1039 * Returns 0 for success, non-zero for failure.
1042 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1043 Mpi2BiosPage3_t *config_page)
1045 MPI2_CONFIG_REQUEST *request;
1046 MPI2_CONFIG_REPLY *reply;
1047 struct mpr_command *cm;
1048 Mpi2BiosPage3_t *page = NULL;
1052 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1054 if ((cm = mpr_alloc_command(sc)) == NULL) {
1055 printf("%s: command alloc failed @ line %d\n", __func__,
1060 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1061 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1062 request->Function = MPI2_FUNCTION_CONFIG;
1063 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1064 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1065 request->Header.PageNumber = 3;
1066 request->Header.PageLength = request->Header.PageVersion = 0;
1067 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1069 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
1070 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1071 if (error || (reply == NULL)) {
1074 * If the request returns an error then we need to do a diag
1077 printf("%s: request for header completed with error %d",
1082 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1083 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1084 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1087 * If the request returns an error then we need to do a diag
1090 printf("%s: header read with error; iocstatus = 0x%x\n",
1091 __func__, ioc_status);
1095 /* We have to do free and alloc for the reply-free and reply-post
1096 * counters to match - Need to review the reply FIFO handling.
1098 mpr_free_command(sc, cm);
1100 if ((cm = mpr_alloc_command(sc)) == NULL) {
1101 printf("%s: command alloc failed @ line %d\n", __func__,
1106 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1107 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1108 request->Function = MPI2_FUNCTION_CONFIG;
1109 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1110 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1111 request->Header.PageNumber = 3;
1112 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1113 request->Header.PageLength = mpi_reply->Header.PageLength;
1114 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1115 cm->cm_sge = &request->PageBufferSGE;
1116 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1117 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1118 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1119 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1121 printf("%s: page alloc failed\n", __func__);
1127 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
1128 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1129 if (error || (reply == NULL)) {
1132 * If the request returns an error then we need to do a diag
1135 printf("%s: request for page completed with error %d",
1140 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1141 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1142 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1145 * If the request returns an error then we need to do a diag
1148 printf("%s: page read with error; iocstatus = 0x%x\n",
1149 __func__, ioc_status);
1153 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
1157 mpr_free_command(sc, cm);
1162 * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
1163 * @sc: per adapter object
1164 * @mpi_reply: reply mf payload returned from firmware
1165 * @config_page: contents of the config page
1166 * @page_address: form and handle value used to get page
1169 * Returns 0 for success, non-zero for failure.
1172 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
1173 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
1175 MPI2_CONFIG_REQUEST *request;
1176 MPI2_CONFIG_REPLY *reply;
1177 struct mpr_command *cm;
1178 Mpi2RaidVolPage0_t *page = NULL;
1182 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1184 if ((cm = mpr_alloc_command(sc)) == NULL) {
1185 printf("%s: command alloc failed @ line %d\n", __func__,
1190 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1191 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1192 request->Function = MPI2_FUNCTION_CONFIG;
1193 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1194 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1195 request->Header.PageNumber = 0;
1196 request->Header.PageLength = request->Header.PageVersion = 0;
1197 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1201 * This page must be polled because the IOC isn't ready yet when this
1204 error = mpr_request_polled(sc, cm);
1205 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1206 if (error || (reply == NULL)) {
1208 /* If the poll returns error then we need to do diag reset */
1209 printf("%s: poll for header completed with error %d",
1214 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1215 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1216 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1218 /* If the poll returns error then we need to do diag reset */
1219 printf("%s: header read with error; iocstatus = 0x%x\n",
1220 __func__, ioc_status);
1224 /* We have to do free and alloc for the reply-free and reply-post
1225 * counters to match - Need to review the reply FIFO handling.
1227 mpr_free_command(sc, cm);
1229 if ((cm = mpr_alloc_command(sc)) == NULL) {
1230 printf("%s: command alloc failed @ line %d\n", __func__,
1235 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1236 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1237 request->Function = MPI2_FUNCTION_CONFIG;
1238 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1239 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1240 request->Header.PageNumber = 0;
1241 request->Header.PageLength = mpi_reply->Header.PageLength;
1242 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1243 request->PageAddress = page_address;
1244 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1245 cm->cm_sge = &request->PageBufferSGE;
1246 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1247 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1248 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1249 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1251 printf("%s: page alloc failed\n", __func__);
1258 * This page must be polled because the IOC isn't ready yet when this
1261 error = mpr_request_polled(sc, cm);
1262 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1263 if (error || (reply == NULL)) {
1265 /* If the poll returns error then we need to do diag reset */
1266 printf("%s: poll for page completed with error %d",
1271 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1272 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1273 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1275 /* If the poll returns error then we need to do diag reset */
1276 printf("%s: page read with error; iocstatus = 0x%x\n",
1277 __func__, ioc_status);
1281 bcopy(page, config_page, cm->cm_length);
1285 mpr_free_command(sc, cm);
1290 * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
1291 * @sc: per adapter object
1292 * @mpi_reply: reply mf payload returned from firmware
1293 * @config_page: contents of the config page
1294 * @form: GET_NEXT_HANDLE or HANDLE
1295 * @handle: volume handle
1298 * Returns 0 for success, non-zero for failure.
1301 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
1302 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
1304 MPI2_CONFIG_REQUEST *request;
1305 MPI2_CONFIG_REPLY *reply;
1306 struct mpr_command *cm;
1307 Mpi2RaidVolPage1_t *page = NULL;
1311 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1313 if ((cm = mpr_alloc_command(sc)) == NULL) {
1314 printf("%s: command alloc failed @ line %d\n", __func__,
1319 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1320 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1321 request->Function = MPI2_FUNCTION_CONFIG;
1322 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1323 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1324 request->Header.PageNumber = 1;
1325 request->Header.PageLength = request->Header.PageVersion = 0;
1326 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1328 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
1329 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1330 if (error || (reply == NULL)) {
1333 * If the request returns an error then we need to do a diag
1336 printf("%s: request for header completed with error %d",
1341 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1342 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1343 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1346 * If the request returns an error then we need to do a diag
1349 printf("%s: header read with error; iocstatus = 0x%x\n",
1350 __func__, ioc_status);
1354 /* We have to do free and alloc for the reply-free and reply-post
1355 * counters to match - Need to review the reply FIFO handling.
1357 mpr_free_command(sc, cm);
1359 if ((cm = mpr_alloc_command(sc)) == NULL) {
1360 printf("%s: command alloc failed @ line %d\n", __func__,
1365 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1366 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1367 request->Function = MPI2_FUNCTION_CONFIG;
1368 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1369 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1370 request->Header.PageNumber = 1;
1371 request->Header.PageLength = mpi_reply->Header.PageLength;
1372 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1373 request->PageAddress = htole32(form | handle);
1374 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1375 cm->cm_sge = &request->PageBufferSGE;
1376 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1377 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1378 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1379 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1381 printf("%s: page alloc failed\n", __func__);
1387 error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
1388 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1389 if (error || (reply == NULL)) {
1392 * If the request returns an error then we need to do a diag
1395 printf("%s: request for page completed with error %d",
1400 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1401 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1402 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1405 * If the request returns an error then we need to do a diag
1408 printf("%s: page read with error; iocstatus = 0x%x\n",
1409 __func__, ioc_status);
1413 bcopy(page, config_page, MIN(cm->cm_length,
1414 sizeof(Mpi2RaidVolPage1_t)));
1418 mpr_free_command(sc, cm);
1423 * mpr_config_get_volume_wwid - returns wwid given the volume handle
1424 * @sc: per adapter object
1425 * @volume_handle: volume handle
1426 * @wwid: volume wwid
1429 * Returns 0 for success, non-zero for failure.
1432 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
1434 Mpi2ConfigReply_t mpi_reply;
1435 Mpi2RaidVolPage1_t raid_vol_pg1;
1438 if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
1439 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
1440 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
1441 raid_vol_pg1.WWID.Low);
1448 * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
1449 * @sc: per adapter object
1450 * @mpi_reply: reply mf payload returned from firmware
1451 * @config_page: contents of the config page
1452 * @page_address: form and handle value used to get page
1455 * Returns 0 for success, non-zero for failure.
1458 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1459 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
1461 MPI2_CONFIG_REQUEST *request;
1462 MPI2_CONFIG_REPLY *reply;
1463 struct mpr_command *cm;
1464 Mpi2RaidPhysDiskPage0_t *page = NULL;
1468 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1470 if ((cm = mpr_alloc_command(sc)) == NULL) {
1471 printf("%s: command alloc failed @ line %d\n", __func__,
1476 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1477 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1478 request->Function = MPI2_FUNCTION_CONFIG;
1479 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1480 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1481 request->Header.PageNumber = 0;
1482 request->Header.PageLength = request->Header.PageVersion = 0;
1483 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1487 * This page must be polled because the IOC isn't ready yet when this
1490 error = mpr_request_polled(sc, cm);
1491 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1492 if (error || (reply == NULL)) {
1494 /* If the poll returns error then we need to do diag reset */
1495 printf("%s: poll for header completed with error %d",
1500 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1501 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1502 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1504 /* If the poll returns error then we need to do diag reset */
1505 printf("%s: header read with error; iocstatus = 0x%x\n",
1506 __func__, ioc_status);
1510 /* We have to do free and alloc for the reply-free and reply-post
1511 * counters to match - Need to review the reply FIFO handling.
1513 mpr_free_command(sc, cm);
1515 if ((cm = mpr_alloc_command(sc)) == NULL) {
1516 printf("%s: command alloc failed @ line %d\n", __func__,
1521 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1522 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1523 request->Function = MPI2_FUNCTION_CONFIG;
1524 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1525 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1526 request->Header.PageNumber = 0;
1527 request->Header.PageLength = mpi_reply->Header.PageLength;
1528 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1529 request->PageAddress = page_address;
1530 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1531 cm->cm_sge = &request->PageBufferSGE;
1532 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1533 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1534 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1535 page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1537 printf("%s: page alloc failed\n", __func__);
1544 * This page must be polled because the IOC isn't ready yet when this
1547 error = mpr_request_polled(sc, cm);
1548 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1549 if (error || (reply == NULL)) {
1551 /* If the poll returns error then we need to do diag reset */
1552 printf("%s: poll for page completed with error %d",
1557 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1558 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1559 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1561 /* If the poll returns error then we need to do diag reset */
1562 printf("%s: page read with error; iocstatus = 0x%x\n",
1563 __func__, ioc_status);
1567 bcopy(page, config_page, MIN(cm->cm_length,
1568 sizeof(Mpi2RaidPhysDiskPage0_t)));
1572 mpr_free_command(sc, cm);