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
29 * $FreeBSD: head/sys/dev/mpr/mpr_config.c 322364 2017-08-10 14:59:17Z ken $
32 /* TODO Move headers to mprvar */
33 #include <sys/types.h>
34 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/kthread.h>
40 #include <sys/taskqueue.h>
42 #include <sys/endian.h>
43 #include <sys/sysctl.h>
44 #include <sys/eventhandler.h>
46 #include <dev/raid/mpr/mpi/mpi2_type.h>
47 #include <dev/raid/mpr/mpi/mpi2.h>
48 #include <dev/raid/mpr/mpi/mpi2_ioc.h>
49 #include <dev/raid/mpr/mpi/mpi2_sas.h>
50 #include <dev/raid/mpr/mpi/mpi2_pci.h>
51 #include <dev/raid/mpr/mpi/mpi2_cnfg.h>
52 #include <dev/raid/mpr/mpi/mpi2_init.h>
53 #include <dev/raid/mpr/mpi/mpi2_tool.h>
54 #include <dev/raid/mpr/mpr_ioctl.h>
55 #include <dev/raid/mpr/mprvar.h>
58 * mpr_config_get_ioc_pg8 - obtain ioc page 8
59 * @sc: per adapter object
60 * @mpi_reply: reply mf payload returned from firmware
61 * @config_page: contents of the config page
64 * Returns 0 for success, non-zero for failure.
67 mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
68 Mpi2IOCPage8_t *config_page)
70 MPI2_CONFIG_REQUEST *request;
71 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
72 struct mpr_command *cm;
73 MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
77 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
79 if ((cm = mpr_alloc_command(sc)) == NULL) {
80 kprintf("%s: command alloc failed @ line %d\n", __func__,
85 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
86 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
87 request->Function = MPI2_FUNCTION_CONFIG;
88 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
89 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
90 request->Header.PageNumber = 8;
91 request->Header.PageLength = request->Header.PageVersion = 0;
92 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
94 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
96 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
97 if (error || (reply == NULL)) {
100 * If the request returns an error then we need to do a diag
103 kprintf("%s: request for header completed with error %d",
108 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
109 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
110 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
113 * If the request returns an error then we need to do a diag
116 kprintf("%s: header read with error; iocstatus = 0x%x\n",
117 __func__, ioc_status);
121 /* We have to do free and alloc for the reply-free and reply-post
122 * counters to match - Need to review the reply FIFO handling.
124 mpr_free_command(sc, cm);
126 if ((cm = mpr_alloc_command(sc)) == NULL) {
127 kprintf("%s: command alloc failed @ line %d\n", __func__,
132 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
133 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
134 request->Function = MPI2_FUNCTION_CONFIG;
135 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
136 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
137 request->Header.PageNumber = 8;
138 request->Header.PageVersion = mpi_reply->Header.PageVersion;
139 request->Header.PageLength = mpi_reply->Header.PageLength;
140 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
141 cm->cm_sge = &request->PageBufferSGE;
142 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
143 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
144 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
145 page = kmalloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
147 kprintf("%s: page alloc failed\n", __func__);
153 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
155 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
156 if (error || (reply == NULL)) {
159 * If the request returns an error then we need to do a diag
162 kprintf("%s: request for page completed with error %d",
167 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
168 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
169 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
172 * If the request returns an error then we need to do a diag
175 kprintf("%s: page read with error; iocstatus = 0x%x\n",
176 __func__, ioc_status);
180 bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
185 mpr_free_command(sc, cm);
190 * mpr_config_get_iounit_pg8 - obtain iounit page 8
191 * @sc: per adapter object
192 * @mpi_reply: reply mf payload returned from firmware
193 * @config_page: contents of the config page
196 * Returns 0 for success, non-zero for failure.
199 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
200 Mpi2IOUnitPage8_t *config_page)
202 MPI2_CONFIG_REQUEST *request;
203 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
204 struct mpr_command *cm;
205 MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
209 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
211 if ((cm = mpr_alloc_command(sc)) == NULL) {
212 kprintf("%s: command alloc failed @ line %d\n", __func__,
217 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
218 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
219 request->Function = MPI2_FUNCTION_CONFIG;
220 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
221 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
222 request->Header.PageNumber = 8;
223 request->Header.PageLength = request->Header.PageVersion = 0;
224 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
226 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
228 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
229 if (error || (reply == NULL)) {
232 * If the request returns an error then we need to do a diag
235 kprintf("%s: request for header completed with error %d",
240 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
241 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
242 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
245 * If the request returns an error then we need to do a diag
248 kprintf("%s: header read with error; iocstatus = 0x%x\n",
249 __func__, ioc_status);
253 /* We have to do free and alloc for the reply-free and reply-post
254 * counters to match - Need to review the reply FIFO handling.
256 mpr_free_command(sc, cm);
258 if ((cm = mpr_alloc_command(sc)) == NULL) {
259 kprintf("%s: command alloc failed @ line %d\n", __func__,
264 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
265 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
266 request->Function = MPI2_FUNCTION_CONFIG;
267 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
268 request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
269 request->Header.PageNumber = 8;
270 request->Header.PageVersion = mpi_reply->Header.PageVersion;
271 request->Header.PageLength = mpi_reply->Header.PageLength;
272 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
273 cm->cm_sge = &request->PageBufferSGE;
274 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
275 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
276 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
277 page = kmalloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
279 kprintf("%s: page alloc failed\n", __func__);
285 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 kprintf("%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 kprintf("%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 = NULL; /* XXX swildner: warning fix */
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 kprintf("%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);
398 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
399 if (error || (reply == NULL)) {
402 * If the request returns an error then we need to do a diag
405 kprintf("%s: request for header completed with error %d",
410 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
411 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
412 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
415 * If the request returns an error then we need to do a diag
418 kprintf("%s: header read with error; iocstatus = 0x%x\n",
419 __func__, ioc_status);
423 /* We have to do free and alloc for the reply-free and reply-post
424 * counters to match - Need to review the reply FIFO handling.
426 mpr_free_command(sc, cm);
428 if ((cm = mpr_alloc_command(sc)) == NULL) {
429 kprintf("%s: command alloc failed @ line %d\n", __func__,
434 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
435 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
436 request->Function = MPI2_FUNCTION_CONFIG;
437 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
438 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
439 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
440 request->Header.PageNumber = 0;
441 request->Header.PageVersion = mpi_reply->Header.PageVersion;
442 request->PageAddress = sc->max_dpm_entries <<
443 MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
444 request->ExtPageLength = mpi_reply->ExtPageLength;
445 cm->cm_length = le16toh(request->ExtPageLength) * 4;
446 cm->cm_sge = &request->PageBufferSGE;
447 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
448 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
449 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
450 page = kmalloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
452 kprintf("%s: page alloc failed\n", __func__);
457 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
459 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
460 if (error || (reply == NULL)) {
463 * If the request returns an error then we need to do a diag
466 kprintf("%s: request for page completed with error %d",
471 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
472 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
473 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
476 * If the request returns an error then we need to do a diag
479 kprintf("%s: page read with error; iocstatus = 0x%x\n",
480 __func__, ioc_status);
484 bcopy(page, config_page, MIN(cm->cm_length, sz));
488 mpr_free_command(sc, cm);
493 * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
494 * @sc: per adapter object
495 * @mpi_reply: reply mf payload returned from firmware
496 * @config_page: contents of the config page
497 * @entry_idx: entry index in DPM Page0 to be modified
500 * Returns 0 for success, non-zero for failure.
503 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
504 Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
506 MPI2_CONFIG_REQUEST *request;
507 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
508 struct mpr_command *cm;
509 MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
513 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
515 if ((cm = mpr_alloc_command(sc)) == NULL) {
516 kprintf("%s: command alloc failed @ line %d\n", __func__,
521 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
522 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
523 request->Function = MPI2_FUNCTION_CONFIG;
524 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
525 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
526 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
527 request->Header.PageNumber = 0;
528 request->ExtPageLength = request->Header.PageVersion = 0;
529 /* We can remove below two lines ????*/
530 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
531 request->PageAddress |= htole16(entry_idx);
532 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
534 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
536 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
537 if (error || (reply == NULL)) {
540 * If the request returns an error then we need to do a diag
543 kprintf("%s: request for header completed with error %d",
548 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
549 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
550 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
553 * If the request returns an error then we need to do a diag
556 kprintf("%s: header read with error; iocstatus = 0x%x\n",
557 __func__, ioc_status);
561 /* We have to do free and alloc for the reply-free and reply-post
562 * counters to match - Need to review the reply FIFO handling.
564 mpr_free_command(sc, cm);
566 if ((cm = mpr_alloc_command(sc)) == NULL) {
567 kprintf("%s: command alloc failed @ line %d\n", __func__,
572 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
573 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
574 request->Function = MPI2_FUNCTION_CONFIG;
575 request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
576 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
577 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
578 request->Header.PageNumber = 0;
579 request->Header.PageVersion = mpi_reply->Header.PageVersion;
580 request->ExtPageLength = mpi_reply->ExtPageLength;
581 request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
582 request->PageAddress |= htole16(entry_idx);
583 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
584 cm->cm_sge = &request->PageBufferSGE;
585 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
586 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
587 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
588 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
590 kprintf("%s: page alloc failed\n", __func__);
594 bcopy(config_page, page, MIN(cm->cm_length,
595 (sizeof(Mpi2DriverMappingPage0_t))));
597 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
599 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
600 if (error || (reply == NULL)) {
603 * If the request returns an error then we need to do a diag
606 kprintf("%s: request to write page completed with error %d",
611 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
612 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
613 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
616 * If the request returns an error then we need to do a diag
619 kprintf("%s: page written with error; iocstatus = 0x%x\n",
620 __func__, ioc_status);
627 mpr_free_command(sc, cm);
632 * mpr_config_get_sas_device_pg0 - obtain sas device page 0
633 * @sc: per adapter object
634 * @mpi_reply: reply mf payload returned from firmware
635 * @config_page: contents of the config page
636 * @form: GET_NEXT_HANDLE or HANDLE
637 * @handle: device handle
640 * Returns 0 for success, non-zero for failure.
643 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
644 *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
646 MPI2_CONFIG_REQUEST *request;
647 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
648 struct mpr_command *cm;
649 Mpi2SasDevicePage0_t *page = NULL;
653 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
655 if ((cm = mpr_alloc_command(sc)) == NULL) {
656 kprintf("%s: command alloc failed @ line %d\n", __func__,
661 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
662 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
663 request->Function = MPI2_FUNCTION_CONFIG;
664 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
665 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
666 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
667 request->Header.PageNumber = 0;
668 request->ExtPageLength = request->Header.PageVersion = 0;
669 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
671 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
673 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
674 if (error || (reply == NULL)) {
677 * If the request returns an error then we need to do a diag
680 kprintf("%s: request for header completed with error %d",
685 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
686 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
687 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
690 * If the request returns an error then we need to do a diag
693 kprintf("%s: header read with error; iocstatus = 0x%x\n",
694 __func__, ioc_status);
698 /* We have to do free and alloc for the reply-free and reply-post
699 * counters to match - Need to review the reply FIFO handling.
701 mpr_free_command(sc, cm);
703 if ((cm = mpr_alloc_command(sc)) == NULL) {
704 kprintf("%s: command alloc failed @ line %d\n", __func__,
709 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
710 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
711 request->Function = MPI2_FUNCTION_CONFIG;
712 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
713 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
714 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
715 request->Header.PageNumber = 0;
716 request->Header.PageVersion = mpi_reply->Header.PageVersion;
717 request->ExtPageLength = mpi_reply->ExtPageLength;
718 request->PageAddress = htole32(form | handle);
719 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
720 cm->cm_sge = &request->PageBufferSGE;
721 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
722 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
723 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
724 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
726 kprintf("%s: page alloc failed\n", __func__);
732 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
734 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
735 if (error || (reply == NULL)) {
738 * If the request returns an error then we need to do a diag
741 kprintf("%s: request for page completed with error %d",
746 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
747 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
748 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
751 * If the request returns an error then we need to do a diag
754 kprintf("%s: page read with error; iocstatus = 0x%x\n",
755 __func__, ioc_status);
759 bcopy(page, config_page, MIN(cm->cm_length,
760 sizeof(Mpi2SasDevicePage0_t)));
764 mpr_free_command(sc, cm);
769 * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
770 * @sc: per adapter object
771 * @mpi_reply: reply mf payload returned from firmware
772 * @config_page: contents of the config page
773 * @form: GET_NEXT_HANDLE or HANDLE
774 * @handle: device handle
777 * Returns 0 for success, non-zero for failure.
780 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
781 *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
783 MPI2_CONFIG_REQUEST *request;
784 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
785 struct mpr_command *cm;
786 Mpi26PCIeDevicePage0_t *page = NULL;
790 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
792 if ((cm = mpr_alloc_command(sc)) == NULL) {
793 kprintf("%s: command alloc failed @ line %d\n", __func__,
798 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
799 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
800 request->Function = MPI2_FUNCTION_CONFIG;
801 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
802 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
803 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
804 request->Header.PageNumber = 0;
805 request->ExtPageLength = request->Header.PageVersion = 0;
806 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
808 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
810 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
811 if (error || (reply == NULL)) {
814 * If the request returns an error then we need to do a diag
817 kprintf("%s: request for header completed with error %d",
822 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
823 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
824 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
827 * If the request returns an error then we need to do a diag
830 kprintf("%s: header read with error; iocstatus = 0x%x\n",
831 __func__, ioc_status);
835 /* We have to do free and alloc for the reply-free and reply-post
836 * counters to match - Need to review the reply FIFO handling.
838 mpr_free_command(sc, cm);
840 if ((cm = mpr_alloc_command(sc)) == NULL) {
841 kprintf("%s: command alloc failed @ line %d\n", __func__,
846 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
847 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
848 request->Function = MPI2_FUNCTION_CONFIG;
849 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
850 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
851 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
852 request->Header.PageNumber = 0;
853 request->Header.PageVersion = mpi_reply->Header.PageVersion;
854 request->ExtPageLength = mpi_reply->ExtPageLength;
855 request->PageAddress = htole32(form | handle);
856 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
857 cm->cm_sge = &request->PageBufferSGE;
858 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
859 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
860 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
861 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
863 kprintf("%s: page alloc failed\n", __func__);
869 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
871 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
872 if (error || (reply == NULL)) {
875 * If the request returns an error then we need to do a diag
878 kprintf("%s: request for page completed with error %d",
883 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
884 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
885 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
888 * If the request returns an error then we need to do a diag
891 kprintf("%s: page read with error; iocstatus = 0x%x\n",
892 __func__, ioc_status);
896 bcopy(page, config_page, MIN(cm->cm_length,
897 sizeof(Mpi26PCIeDevicePage0_t)));
901 mpr_free_command(sc, cm);
906 * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
907 * @sc: per adapter object
908 * @mpi_reply: reply mf payload returned from firmware
909 * @config_page: contents of the config page
910 * @form: GET_NEXT_HANDLE or HANDLE
911 * @handle: device handle
914 * Returns 0 for success, non-zero for failure.
917 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
918 *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
920 MPI2_CONFIG_REQUEST *request;
921 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
922 struct mpr_command *cm;
923 Mpi26PCIeDevicePage2_t *page = NULL;
927 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
929 if ((cm = mpr_alloc_command(sc)) == NULL) {
930 kprintf("%s: command alloc failed @ line %d\n", __func__,
935 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
936 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
937 request->Function = MPI2_FUNCTION_CONFIG;
938 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
939 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
940 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
941 request->Header.PageNumber = 2;
942 request->ExtPageLength = request->Header.PageVersion = 0;
943 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
945 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
947 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
948 if (error || (reply == NULL)) {
951 * If the request returns an error then we need to do a diag
954 kprintf("%s: request for header completed with error %d",
959 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
960 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
961 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
964 * If the request returns an error then we need to do a diag
967 kprintf("%s: header read with error; iocstatus = 0x%x\n",
968 __func__, ioc_status);
972 /* We have to do free and alloc for the reply-free and reply-post
973 * counters to match - Need to review the reply FIFO handling.
975 mpr_free_command(sc, cm);
977 if ((cm = mpr_alloc_command(sc)) == NULL) {
978 kprintf("%s: command alloc failed @ line %d\n", __func__,
983 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
984 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
985 request->Function = MPI2_FUNCTION_CONFIG;
986 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
987 request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
988 request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
989 request->Header.PageNumber = 2;
990 request->Header.PageVersion = mpi_reply->Header.PageVersion;
991 request->ExtPageLength = mpi_reply->ExtPageLength;
992 request->PageAddress = htole32(form | handle);
993 cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
994 cm->cm_sge = &request->PageBufferSGE;
995 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
996 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
997 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
998 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1000 kprintf("%s: page alloc failed\n", __func__);
1006 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1008 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1009 if (error || (reply == NULL)) {
1012 * If the request returns an error then we need to do a diag
1015 kprintf("%s: request for page completed with error %d",
1020 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1021 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1022 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1025 * If the request returns an error then we need to do a diag
1028 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1029 __func__, ioc_status);
1033 bcopy(page, config_page, MIN(cm->cm_length,
1034 sizeof(Mpi26PCIeDevicePage2_t)));
1038 mpr_free_command(sc, cm);
1043 * mpr_config_get_bios_pg3 - obtain BIOS page 3
1044 * @sc: per adapter object
1045 * @mpi_reply: reply mf payload returned from firmware
1046 * @config_page: contents of the config page
1049 * Returns 0 for success, non-zero for failure.
1052 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1053 Mpi2BiosPage3_t *config_page)
1055 MPI2_CONFIG_REQUEST *request;
1056 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
1057 struct mpr_command *cm;
1058 Mpi2BiosPage3_t *page = NULL;
1062 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1064 if ((cm = mpr_alloc_command(sc)) == NULL) {
1065 kprintf("%s: command alloc failed @ line %d\n", __func__,
1070 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1071 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1072 request->Function = MPI2_FUNCTION_CONFIG;
1073 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1074 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1075 request->Header.PageNumber = 3;
1076 request->Header.PageLength = request->Header.PageVersion = 0;
1077 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1079 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1081 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1082 if (error || (reply == NULL)) {
1085 * If the request returns an error then we need to do a diag
1088 kprintf("%s: request for header completed with error %d",
1093 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1094 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1095 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1098 * If the request returns an error then we need to do a diag
1101 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1102 __func__, ioc_status);
1106 /* We have to do free and alloc for the reply-free and reply-post
1107 * counters to match - Need to review the reply FIFO handling.
1109 mpr_free_command(sc, cm);
1111 if ((cm = mpr_alloc_command(sc)) == NULL) {
1112 kprintf("%s: command alloc failed @ line %d\n", __func__,
1117 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1118 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1119 request->Function = MPI2_FUNCTION_CONFIG;
1120 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1121 request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
1122 request->Header.PageNumber = 3;
1123 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1124 request->Header.PageLength = mpi_reply->Header.PageLength;
1125 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1126 cm->cm_sge = &request->PageBufferSGE;
1127 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1128 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1129 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1130 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1132 kprintf("%s: page alloc failed\n", __func__);
1138 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1140 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1141 if (error || (reply == NULL)) {
1144 * If the request returns an error then we need to do a diag
1147 kprintf("%s: request for page completed with error %d",
1152 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1153 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1154 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1157 * If the request returns an error then we need to do a diag
1160 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1161 __func__, ioc_status);
1165 bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
1169 mpr_free_command(sc, cm);
1174 * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
1175 * @sc: per adapter object
1176 * @mpi_reply: reply mf payload returned from firmware
1177 * @config_page: contents of the config page
1178 * @page_address: form and handle value used to get page
1181 * Returns 0 for success, non-zero for failure.
1184 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
1185 *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
1187 MPI2_CONFIG_REQUEST *request;
1188 MPI2_CONFIG_REPLY *reply = NULL;
1189 struct mpr_command *cm;
1190 Mpi2RaidVolPage0_t *page = NULL;
1194 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1196 if ((cm = mpr_alloc_command(sc)) == NULL) {
1197 kprintf("%s: command alloc failed @ line %d\n", __func__,
1202 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1203 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1204 request->Function = MPI2_FUNCTION_CONFIG;
1205 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1206 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1207 request->Header.PageNumber = 0;
1208 request->Header.PageLength = request->Header.PageVersion = 0;
1209 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1213 * This page must be polled because the IOC isn't ready yet when this
1216 error = mpr_request_polled(sc, &cm);
1218 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1219 if (error || (reply == NULL)) {
1221 /* If the poll returns error then we need to do diag reset */
1222 kprintf("%s: poll for header completed with error %d",
1227 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1228 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1229 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1231 /* If the poll returns error then we need to do diag reset */
1232 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1233 __func__, ioc_status);
1237 /* We have to do free and alloc for the reply-free and reply-post
1238 * counters to match - Need to review the reply FIFO handling.
1240 mpr_free_command(sc, cm);
1242 if ((cm = mpr_alloc_command(sc)) == NULL) {
1243 kprintf("%s: command alloc failed @ line %d\n", __func__,
1248 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1249 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1250 request->Function = MPI2_FUNCTION_CONFIG;
1251 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1252 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1253 request->Header.PageNumber = 0;
1254 request->Header.PageLength = mpi_reply->Header.PageLength;
1255 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1256 request->PageAddress = page_address;
1257 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1258 cm->cm_sge = &request->PageBufferSGE;
1259 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1260 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1261 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1262 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1264 kprintf("%s: page alloc failed\n", __func__);
1271 * This page must be polled because the IOC isn't ready yet when this
1274 error = mpr_request_polled(sc, &cm);
1276 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1277 if (error || (reply == NULL)) {
1279 /* If the poll returns error then we need to do diag reset */
1280 kprintf("%s: poll for page completed with error %d",
1285 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1286 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1287 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1289 /* If the poll returns error then we need to do diag reset */
1290 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1291 __func__, ioc_status);
1295 bcopy(page, config_page, cm->cm_length);
1299 mpr_free_command(sc, cm);
1304 * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
1305 * @sc: per adapter object
1306 * @mpi_reply: reply mf payload returned from firmware
1307 * @config_page: contents of the config page
1308 * @form: GET_NEXT_HANDLE or HANDLE
1309 * @handle: volume handle
1312 * Returns 0 for success, non-zero for failure.
1315 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
1316 *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
1318 MPI2_CONFIG_REQUEST *request;
1319 MPI2_CONFIG_REPLY *reply = NULL; /* XXX swildner: warning fix */
1320 struct mpr_command *cm;
1321 Mpi2RaidVolPage1_t *page = NULL;
1325 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1327 if ((cm = mpr_alloc_command(sc)) == NULL) {
1328 kprintf("%s: command alloc failed @ line %d\n", __func__,
1333 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1334 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1335 request->Function = MPI2_FUNCTION_CONFIG;
1336 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1337 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1338 request->Header.PageNumber = 1;
1339 request->Header.PageLength = request->Header.PageVersion = 0;
1340 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1342 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1344 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1345 if (error || (reply == NULL)) {
1348 * If the request returns an error then we need to do a diag
1351 kprintf("%s: request for header completed with error %d",
1356 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1357 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1358 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1361 * If the request returns an error then we need to do a diag
1364 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1365 __func__, ioc_status);
1369 /* We have to do free and alloc for the reply-free and reply-post
1370 * counters to match - Need to review the reply FIFO handling.
1372 mpr_free_command(sc, cm);
1374 if ((cm = mpr_alloc_command(sc)) == NULL) {
1375 kprintf("%s: command alloc failed @ line %d\n", __func__,
1380 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1381 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1382 request->Function = MPI2_FUNCTION_CONFIG;
1383 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1384 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
1385 request->Header.PageNumber = 1;
1386 request->Header.PageLength = mpi_reply->Header.PageLength;
1387 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1388 request->PageAddress = htole32(form | handle);
1389 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1390 cm->cm_sge = &request->PageBufferSGE;
1391 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1392 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1393 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1394 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1396 kprintf("%s: page alloc failed\n", __func__);
1402 error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
1404 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1405 if (error || (reply == NULL)) {
1408 * If the request returns an error then we need to do a diag
1411 kprintf("%s: request for page completed with error %d",
1416 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1417 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1418 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1421 * If the request returns an error then we need to do a diag
1424 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1425 __func__, ioc_status);
1429 bcopy(page, config_page, MIN(cm->cm_length,
1430 sizeof(Mpi2RaidVolPage1_t)));
1434 mpr_free_command(sc, cm);
1439 * mpr_config_get_volume_wwid - returns wwid given the volume handle
1440 * @sc: per adapter object
1441 * @volume_handle: volume handle
1442 * @wwid: volume wwid
1445 * Returns 0 for success, non-zero for failure.
1448 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
1450 Mpi2ConfigReply_t mpi_reply;
1451 Mpi2RaidVolPage1_t raid_vol_pg1;
1454 if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
1455 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
1456 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
1457 raid_vol_pg1.WWID.Low);
1464 * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
1465 * @sc: per adapter object
1466 * @mpi_reply: reply mf payload returned from firmware
1467 * @config_page: contents of the config page
1468 * @page_address: form and handle value used to get page
1471 * Returns 0 for success, non-zero for failure.
1474 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
1475 Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
1477 MPI2_CONFIG_REQUEST *request;
1478 MPI2_CONFIG_REPLY *reply = NULL;
1479 struct mpr_command *cm;
1480 Mpi2RaidPhysDiskPage0_t *page = NULL;
1484 mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
1486 if ((cm = mpr_alloc_command(sc)) == NULL) {
1487 kprintf("%s: command alloc failed @ line %d\n", __func__,
1492 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1493 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1494 request->Function = MPI2_FUNCTION_CONFIG;
1495 request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
1496 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1497 request->Header.PageNumber = 0;
1498 request->Header.PageLength = request->Header.PageVersion = 0;
1499 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1503 * This page must be polled because the IOC isn't ready yet when this
1506 error = mpr_request_polled(sc, &cm);
1508 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1509 if (error || (reply == NULL)) {
1511 /* If the poll returns error then we need to do diag reset */
1512 kprintf("%s: poll for header completed with error %d",
1517 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1518 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1519 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1521 /* If the poll returns error then we need to do diag reset */
1522 kprintf("%s: header read with error; iocstatus = 0x%x\n",
1523 __func__, ioc_status);
1527 /* We have to do free and alloc for the reply-free and reply-post
1528 * counters to match - Need to review the reply FIFO handling.
1530 mpr_free_command(sc, cm);
1532 if ((cm = mpr_alloc_command(sc)) == NULL) {
1533 kprintf("%s: command alloc failed @ line %d\n", __func__,
1538 request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
1539 bzero(request, sizeof(MPI2_CONFIG_REQUEST));
1540 request->Function = MPI2_FUNCTION_CONFIG;
1541 request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1542 request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
1543 request->Header.PageNumber = 0;
1544 request->Header.PageLength = mpi_reply->Header.PageLength;
1545 request->Header.PageVersion = mpi_reply->Header.PageVersion;
1546 request->PageAddress = page_address;
1547 cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
1548 cm->cm_sge = &request->PageBufferSGE;
1549 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
1550 cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
1551 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1552 page = kmalloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
1554 kprintf("%s: page alloc failed\n", __func__);
1561 * This page must be polled because the IOC isn't ready yet when this
1564 error = mpr_request_polled(sc, &cm);
1566 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
1567 if (error || (reply == NULL)) {
1569 /* If the poll returns error then we need to do diag reset */
1570 kprintf("%s: poll for page completed with error %d",
1575 ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
1576 bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
1577 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
1579 /* If the poll returns error then we need to do diag reset */
1580 kprintf("%s: page read with error; iocstatus = 0x%x\n",
1581 __func__, ioc_status);
1585 bcopy(page, config_page, MIN(cm->cm_length,
1586 sizeof(Mpi2RaidPhysDiskPage0_t)));
1590 mpr_free_command(sc, cm);