129b76e53SScott Long /*-
23e891891SBaptiste Daroussin * Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
33e891891SBaptiste Daroussin *
4883bb7e9SScott Long * Copyright (c) 2015 Netflix, Inc.
5883bb7e9SScott Long * Written by: Scott Long <scottl@freebsd.org>
6883bb7e9SScott Long *
729b76e53SScott Long * Copyright (c) 2008 Yahoo!, Inc.
829b76e53SScott Long * All rights reserved.
929b76e53SScott Long * Written by: John Baldwin <jhb@FreeBSD.org>
1029b76e53SScott Long *
1129b76e53SScott Long * Redistribution and use in source and binary forms, with or without
1229b76e53SScott Long * modification, are permitted provided that the following conditions
1329b76e53SScott Long * are met:
1429b76e53SScott Long * 1. Redistributions of source code must retain the above copyright
1529b76e53SScott Long * notice, this list of conditions and the following disclaimer.
1629b76e53SScott Long * 2. Redistributions in binary form must reproduce the above copyright
1729b76e53SScott Long * notice, this list of conditions and the following disclaimer in the
1829b76e53SScott Long * documentation and/or other materials provided with the distribution.
1929b76e53SScott Long * 3. Neither the name of the author nor the names of any co-contributors
2029b76e53SScott Long * may be used to endorse or promote products derived from this software
2129b76e53SScott Long * without specific prior written permission.
2229b76e53SScott Long *
2329b76e53SScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2429b76e53SScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2529b76e53SScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2629b76e53SScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2729b76e53SScott Long * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2829b76e53SScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2929b76e53SScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3029b76e53SScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3129b76e53SScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3229b76e53SScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3329b76e53SScott Long * SUCH DAMAGE.
3429b76e53SScott Long */
3529b76e53SScott Long
3629b76e53SScott Long #include <sys/param.h>
3729b76e53SScott Long #include <sys/errno.h>
3829b76e53SScott Long #include <sys/ioctl.h>
3929b76e53SScott Long #include <sys/sysctl.h>
4029b76e53SScott Long #include <sys/uio.h>
41fc9780fdSAlfredo Dal'Ava Junior #include <sys/endian.h>
4229b76e53SScott Long
4329b76e53SScott Long #include <err.h>
4429b76e53SScott Long #include <fcntl.h>
4529b76e53SScott Long #include <stdio.h>
4629b76e53SScott Long #include <stdlib.h>
4729b76e53SScott Long #include <string.h>
4829b76e53SScott Long #include <unistd.h>
4929b76e53SScott Long
5029b76e53SScott Long #include "mpsutil.h"
5139e2d6bcSScott Long #include <dev/mps/mps_ioctl.h>
5239e2d6bcSScott Long #include <dev/mpr/mpr_ioctl.h>
5329b76e53SScott Long
5429b76e53SScott Long #ifndef USE_MPT_IOCTLS
5529b76e53SScott Long #define USE_MPT_IOCTLS
5629b76e53SScott Long #endif
5729b76e53SScott Long
5829b76e53SScott Long static const char *mps_ioc_status_codes[] = {
5929b76e53SScott Long "Success", /* 0x0000 */
6029b76e53SScott Long "Invalid function",
6129b76e53SScott Long "Busy",
6229b76e53SScott Long "Invalid scatter-gather list",
6329b76e53SScott Long "Internal error",
6429b76e53SScott Long "Reserved",
6529b76e53SScott Long "Insufficient resources",
6629b76e53SScott Long "Invalid field",
6729b76e53SScott Long "Invalid state", /* 0x0008 */
6829b76e53SScott Long "Operation state not supported",
6929b76e53SScott Long NULL,
7029b76e53SScott Long NULL,
7129b76e53SScott Long NULL,
7229b76e53SScott Long NULL,
7329b76e53SScott Long NULL,
7429b76e53SScott Long NULL,
7529b76e53SScott Long NULL, /* 0x0010 */
7629b76e53SScott Long NULL,
7729b76e53SScott Long NULL,
7829b76e53SScott Long NULL,
7929b76e53SScott Long NULL,
8029b76e53SScott Long NULL,
8129b76e53SScott Long NULL,
8229b76e53SScott Long NULL,
8329b76e53SScott Long NULL, /* 0x0018 */
8429b76e53SScott Long NULL,
8529b76e53SScott Long NULL,
8629b76e53SScott Long NULL,
8729b76e53SScott Long NULL,
8829b76e53SScott Long NULL,
8929b76e53SScott Long NULL,
9029b76e53SScott Long NULL,
9129b76e53SScott Long "Invalid configuration action", /* 0x0020 */
9229b76e53SScott Long "Invalid configuration type",
9329b76e53SScott Long "Invalid configuration page",
9429b76e53SScott Long "Invalid configuration data",
9529b76e53SScott Long "No configuration defaults",
9629b76e53SScott Long "Unable to commit configuration change",
9729b76e53SScott Long NULL,
9829b76e53SScott Long NULL,
9929b76e53SScott Long NULL, /* 0x0028 */
10029b76e53SScott Long NULL,
10129b76e53SScott Long NULL,
10229b76e53SScott Long NULL,
10329b76e53SScott Long NULL,
10429b76e53SScott Long NULL,
10529b76e53SScott Long NULL,
10629b76e53SScott Long NULL,
10729b76e53SScott Long NULL, /* 0x0030 */
10829b76e53SScott Long NULL,
10929b76e53SScott Long NULL,
11029b76e53SScott Long NULL,
11129b76e53SScott Long NULL,
11229b76e53SScott Long NULL,
11329b76e53SScott Long NULL,
11429b76e53SScott Long NULL,
11529b76e53SScott Long NULL, /* 0x0038 */
11629b76e53SScott Long NULL,
11729b76e53SScott Long NULL,
11829b76e53SScott Long NULL,
11929b76e53SScott Long NULL,
12029b76e53SScott Long NULL,
12129b76e53SScott Long NULL,
12229b76e53SScott Long NULL,
12329b76e53SScott Long "Recovered SCSI error", /* 0x0040 */
12429b76e53SScott Long "Invalid SCSI bus",
12529b76e53SScott Long "Invalid SCSI target ID",
12629b76e53SScott Long "SCSI device not there",
12729b76e53SScott Long "SCSI data overrun",
12829b76e53SScott Long "SCSI data underrun",
12929b76e53SScott Long "SCSI I/O error",
13029b76e53SScott Long "SCSI protocol error",
13129b76e53SScott Long "SCSI task terminated", /* 0x0048 */
13229b76e53SScott Long "SCSI residual mismatch",
13329b76e53SScott Long "SCSI task management failed",
13429b76e53SScott Long "SCSI I/O controller terminated",
13529b76e53SScott Long "SCSI external controller terminated",
13629b76e53SScott Long "EEDP guard error",
13729b76e53SScott Long "EEDP reference tag error",
13829b76e53SScott Long "EEDP application tag error",
13929b76e53SScott Long NULL, /* 0x0050 */
14029b76e53SScott Long NULL,
14129b76e53SScott Long NULL,
14229b76e53SScott Long NULL,
14329b76e53SScott Long NULL,
14429b76e53SScott Long NULL,
14529b76e53SScott Long NULL,
14629b76e53SScott Long NULL,
14729b76e53SScott Long NULL, /* 0x0058 */
14829b76e53SScott Long NULL,
14929b76e53SScott Long NULL,
15029b76e53SScott Long NULL,
15129b76e53SScott Long NULL,
15229b76e53SScott Long NULL,
15329b76e53SScott Long NULL,
15429b76e53SScott Long NULL,
15529b76e53SScott Long "SCSI target priority I/O", /* 0x0060 */
15629b76e53SScott Long "Invalid SCSI target port",
15729b76e53SScott Long "Invalid SCSI target I/O index",
15829b76e53SScott Long "SCSI target aborted",
15929b76e53SScott Long "No connection retryable",
16029b76e53SScott Long "No connection",
16129b76e53SScott Long "FC aborted",
16229b76e53SScott Long "Invalid FC receive ID",
16329b76e53SScott Long "FC did invalid", /* 0x0068 */
16429b76e53SScott Long "FC node logged out",
16529b76e53SScott Long "Transfer count mismatch",
16629b76e53SScott Long "STS data not set",
16729b76e53SScott Long "FC exchange canceled",
16829b76e53SScott Long "Data offset error",
16929b76e53SScott Long "Too much write data",
17029b76e53SScott Long "IU too short",
17129b76e53SScott Long "ACK NAK timeout", /* 0x0070 */
17229b76e53SScott Long "NAK received",
17329b76e53SScott Long NULL,
17429b76e53SScott Long NULL,
17529b76e53SScott Long NULL,
17629b76e53SScott Long NULL,
17729b76e53SScott Long NULL,
17829b76e53SScott Long NULL,
17929b76e53SScott Long NULL, /* 0x0078 */
18029b76e53SScott Long NULL,
18129b76e53SScott Long NULL,
18229b76e53SScott Long NULL,
18329b76e53SScott Long NULL,
18429b76e53SScott Long NULL,
18529b76e53SScott Long NULL,
18629b76e53SScott Long NULL,
18729b76e53SScott Long "LAN device not found", /* 0x0080 */
18829b76e53SScott Long "LAN device failure",
18929b76e53SScott Long "LAN transmit error",
19029b76e53SScott Long "LAN transmit aborted",
19129b76e53SScott Long "LAN receive error",
19229b76e53SScott Long "LAN receive aborted",
19329b76e53SScott Long "LAN partial packet",
19429b76e53SScott Long "LAN canceled",
19529b76e53SScott Long NULL, /* 0x0088 */
19629b76e53SScott Long NULL,
19729b76e53SScott Long NULL,
19829b76e53SScott Long NULL,
19929b76e53SScott Long NULL,
20029b76e53SScott Long NULL,
20129b76e53SScott Long NULL,
20229b76e53SScott Long NULL,
20329b76e53SScott Long "SAS SMP request failed", /* 0x0090 */
20429b76e53SScott Long "SAS SMP data overrun",
20529b76e53SScott Long NULL,
20629b76e53SScott Long NULL,
20729b76e53SScott Long NULL,
20829b76e53SScott Long NULL,
20929b76e53SScott Long NULL,
21029b76e53SScott Long NULL,
21129b76e53SScott Long "Inband aborted", /* 0x0098 */
21229b76e53SScott Long "No inband connection",
21329b76e53SScott Long NULL,
21429b76e53SScott Long NULL,
21529b76e53SScott Long NULL,
21629b76e53SScott Long NULL,
21729b76e53SScott Long NULL,
21829b76e53SScott Long NULL,
21929b76e53SScott Long "Diagnostic released", /* 0x00A0 */
22029b76e53SScott Long };
22129b76e53SScott Long
2225a92b271SBaptiste Daroussin struct mprs_pass_thru {
2235a92b271SBaptiste Daroussin uint64_t PtrRequest;
2245a92b271SBaptiste Daroussin uint64_t PtrReply;
2255a92b271SBaptiste Daroussin uint64_t PtrData;
2265a92b271SBaptiste Daroussin uint32_t RequestSize;
2275a92b271SBaptiste Daroussin uint32_t ReplySize;
2285a92b271SBaptiste Daroussin uint32_t DataSize;
2295a92b271SBaptiste Daroussin uint32_t DataDirection;
2305a92b271SBaptiste Daroussin uint64_t PtrDataOut;
2315a92b271SBaptiste Daroussin uint32_t DataOutSize;
2325a92b271SBaptiste Daroussin uint32_t Timeout;
2335a92b271SBaptiste Daroussin };
2345a92b271SBaptiste Daroussin
2355a92b271SBaptiste Daroussin struct mprs_btdh_mapping {
2365a92b271SBaptiste Daroussin uint16_t TargetID;
2375a92b271SBaptiste Daroussin uint16_t Bus;
2385a92b271SBaptiste Daroussin uint16_t DevHandle;
2395a92b271SBaptiste Daroussin uint16_t Reserved;
2405a92b271SBaptiste Daroussin };
2415a92b271SBaptiste Daroussin
242fc9780fdSAlfredo Dal'Ava Junior static void adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts);
243fc9780fdSAlfredo Dal'Ava Junior
24429b76e53SScott Long const char *
mps_ioc_status(U16 IOCStatus)24529b76e53SScott Long mps_ioc_status(U16 IOCStatus)
24629b76e53SScott Long {
24729b76e53SScott Long static char buffer[16];
24829b76e53SScott Long
24929b76e53SScott Long IOCStatus &= MPI2_IOCSTATUS_MASK;
25029b76e53SScott Long if (IOCStatus < sizeof(mps_ioc_status_codes) / sizeof(char *) &&
25129b76e53SScott Long mps_ioc_status_codes[IOCStatus] != NULL)
25229b76e53SScott Long return (mps_ioc_status_codes[IOCStatus]);
25329b76e53SScott Long snprintf(buffer, sizeof(buffer), "Status: 0x%04x", IOCStatus);
25429b76e53SScott Long return (buffer);
25529b76e53SScott Long }
25629b76e53SScott Long
25729b76e53SScott Long #ifdef USE_MPT_IOCTLS
25829b76e53SScott Long int
mps_map_btdh(int fd,uint16_t * devhandle,uint16_t * bus,uint16_t * target)25929b76e53SScott Long mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus, uint16_t *target)
26029b76e53SScott Long {
26129b76e53SScott Long int error;
2625a92b271SBaptiste Daroussin struct mprs_btdh_mapping map;
26329b76e53SScott Long
26429b76e53SScott Long map.Bus = *bus;
26529b76e53SScott Long map.TargetID = *target;
26629b76e53SScott Long map.DevHandle = *devhandle;
26729b76e53SScott Long
26829b76e53SScott Long if ((error = ioctl(fd, MPTIOCTL_BTDH_MAPPING, &map)) != 0) {
26929b76e53SScott Long error = errno;
27029b76e53SScott Long warn("Failed to map bus/target/device");
27129b76e53SScott Long return (error);
27229b76e53SScott Long }
27329b76e53SScott Long
27429b76e53SScott Long *bus = map.Bus;
27529b76e53SScott Long *target = map.TargetID;
27629b76e53SScott Long *devhandle = map.DevHandle;
27729b76e53SScott Long
27829b76e53SScott Long return (0);
27929b76e53SScott Long }
28029b76e53SScott Long
28129b76e53SScott Long int
mps_set_slot_status(int fd,U16 handle,U16 slot,U32 status)282c2a13d6fSAndriy Gapon mps_set_slot_status(int fd, U16 handle, U16 slot, U32 status)
283c2a13d6fSAndriy Gapon {
284c2a13d6fSAndriy Gapon MPI2_SEP_REQUEST req;
285c2a13d6fSAndriy Gapon MPI2_SEP_REPLY reply;
286c2a13d6fSAndriy Gapon
287c2a13d6fSAndriy Gapon bzero(&req, sizeof(req));
288c2a13d6fSAndriy Gapon req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
289c2a13d6fSAndriy Gapon req.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
290c2a13d6fSAndriy Gapon req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
291c2a13d6fSAndriy Gapon req.EnclosureHandle = handle;
292c2a13d6fSAndriy Gapon req.Slot = slot;
293c2a13d6fSAndriy Gapon req.SlotStatus = status;
294c2a13d6fSAndriy Gapon
295c2a13d6fSAndriy Gapon if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
296c2a13d6fSAndriy Gapon NULL, 0, NULL, 0, 30) != 0)
297c2a13d6fSAndriy Gapon return (errno);
298c2a13d6fSAndriy Gapon
299fc9780fdSAlfredo Dal'Ava Junior if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus)))
300c2a13d6fSAndriy Gapon return (EIO);
301c2a13d6fSAndriy Gapon return (0);
302c2a13d6fSAndriy Gapon }
303c2a13d6fSAndriy Gapon
304c2a13d6fSAndriy Gapon int
mps_read_config_page_header(int fd,U8 PageType,U8 PageNumber,U32 PageAddress,MPI2_CONFIG_PAGE_HEADER * header,U16 * IOCStatus)30529b76e53SScott Long mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
30629b76e53SScott Long MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus)
30729b76e53SScott Long {
30829b76e53SScott Long MPI2_CONFIG_REQUEST req;
30929b76e53SScott Long MPI2_CONFIG_REPLY reply;
31029b76e53SScott Long
31129b76e53SScott Long bzero(&req, sizeof(req));
31229b76e53SScott Long req.Function = MPI2_FUNCTION_CONFIG;
31329b76e53SScott Long req.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
31429b76e53SScott Long req.Header.PageType = PageType;
31529b76e53SScott Long req.Header.PageNumber = PageNumber;
31629b76e53SScott Long req.PageAddress = PageAddress;
31729b76e53SScott Long
31829b76e53SScott Long if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
31929b76e53SScott Long NULL, 0, NULL, 0, 30))
32029b76e53SScott Long return (errno);
32129b76e53SScott Long
322fc9780fdSAlfredo Dal'Ava Junior if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus))) {
32329b76e53SScott Long if (IOCStatus != NULL)
32429b76e53SScott Long *IOCStatus = reply.IOCStatus;
32529b76e53SScott Long return (EIO);
32629b76e53SScott Long }
32729b76e53SScott Long if (header == NULL)
32829b76e53SScott Long return (EINVAL);
32929b76e53SScott Long *header = reply.Header;
33029b76e53SScott Long return (0);
33129b76e53SScott Long }
33229b76e53SScott Long
33329b76e53SScott Long int
mps_read_ext_config_page_header(int fd,U8 ExtPageType,U8 PageNumber,U32 PageAddress,MPI2_CONFIG_PAGE_HEADER * header,U16 * ExtPageLength,U16 * IOCStatus)33429b76e53SScott Long mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber, U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *ExtPageLength, U16 *IOCStatus)
33529b76e53SScott Long {
33629b76e53SScott Long MPI2_CONFIG_REQUEST req;
33729b76e53SScott Long MPI2_CONFIG_REPLY reply;
33829b76e53SScott Long
33929b76e53SScott Long bzero(&req, sizeof(req));
34029b76e53SScott Long req.Function = MPI2_FUNCTION_CONFIG;
34129b76e53SScott Long req.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
34229b76e53SScott Long req.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
34329b76e53SScott Long req.ExtPageType = ExtPageType;
34429b76e53SScott Long req.Header.PageNumber = PageNumber;
345fc9780fdSAlfredo Dal'Ava Junior req.PageAddress = htole32(PageAddress);
34629b76e53SScott Long
34729b76e53SScott Long if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
34829b76e53SScott Long NULL, 0, NULL, 0, 30))
34929b76e53SScott Long return (errno);
35029b76e53SScott Long
351fc9780fdSAlfredo Dal'Ava Junior if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus))) {
35229b76e53SScott Long if (IOCStatus != NULL)
353fc9780fdSAlfredo Dal'Ava Junior *IOCStatus = le16toh(reply.IOCStatus);
35429b76e53SScott Long return (EIO);
35529b76e53SScott Long }
35629b76e53SScott Long if ((header == NULL) || (ExtPageLength == NULL))
35729b76e53SScott Long return (EINVAL);
35829b76e53SScott Long *header = reply.Header;
35929b76e53SScott Long *ExtPageLength = reply.ExtPageLength;
36029b76e53SScott Long return (0);
36129b76e53SScott Long }
36229b76e53SScott Long
36329b76e53SScott Long void *
mps_read_config_page(int fd,U8 PageType,U8 PageNumber,U32 PageAddress,U16 * IOCStatus)36429b76e53SScott Long mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
36529b76e53SScott Long U16 *IOCStatus)
36629b76e53SScott Long {
36729b76e53SScott Long MPI2_CONFIG_REQUEST req;
36829b76e53SScott Long MPI2_CONFIG_PAGE_HEADER header;
36929b76e53SScott Long MPI2_CONFIG_REPLY reply;
37029b76e53SScott Long void *buf;
37129b76e53SScott Long int error, len;
37229b76e53SScott Long
37329b76e53SScott Long bzero(&header, sizeof(header));
37429b76e53SScott Long error = mps_read_config_page_header(fd, PageType, PageNumber,
37529b76e53SScott Long PageAddress, &header, IOCStatus);
37629b76e53SScott Long if (error) {
37729b76e53SScott Long errno = error;
37829b76e53SScott Long return (NULL);
37929b76e53SScott Long }
38029b76e53SScott Long
38129b76e53SScott Long bzero(&req, sizeof(req));
38229b76e53SScott Long req.Function = MPI2_FUNCTION_CONFIG;
38329b76e53SScott Long req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
384fc9780fdSAlfredo Dal'Ava Junior req.PageAddress = htole32(PageAddress);
38529b76e53SScott Long req.Header = header;
38699cc4d51SScott Long if (req.Header.PageLength == 0)
38729b76e53SScott Long req.Header.PageLength = 4;
38829b76e53SScott Long
38929b76e53SScott Long len = req.Header.PageLength * 4;
39029b76e53SScott Long buf = malloc(len);
39129b76e53SScott Long if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
39229b76e53SScott Long buf, len, NULL, 0, 30)) {
39329b76e53SScott Long error = errno;
39429b76e53SScott Long free(buf);
39529b76e53SScott Long errno = error;
39629b76e53SScott Long return (NULL);
39729b76e53SScott Long }
398fc9780fdSAlfredo Dal'Ava Junior reply.IOCStatus = le16toh(reply.IOCStatus);
39929b76e53SScott Long if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
40029b76e53SScott Long if (IOCStatus != NULL)
40129b76e53SScott Long *IOCStatus = reply.IOCStatus;
40229b76e53SScott Long else
40329b76e53SScott Long warnx("Reading config page failed: 0x%x %s",
40429b76e53SScott Long reply.IOCStatus, mps_ioc_status(reply.IOCStatus));
40529b76e53SScott Long free(buf);
40629b76e53SScott Long errno = EIO;
40729b76e53SScott Long return (NULL);
40829b76e53SScott Long }
40929b76e53SScott Long return (buf);
41029b76e53SScott Long }
41129b76e53SScott Long
41229b76e53SScott Long void *
mps_read_extended_config_page(int fd,U8 ExtPageType,U8 PageVersion,U8 PageNumber,U32 PageAddress,U16 * IOCStatus)41329b76e53SScott Long mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
41429b76e53SScott Long U8 PageNumber, U32 PageAddress, U16 *IOCStatus)
41529b76e53SScott Long {
41629b76e53SScott Long MPI2_CONFIG_REQUEST req;
41729b76e53SScott Long MPI2_CONFIG_PAGE_HEADER header;
41829b76e53SScott Long MPI2_CONFIG_REPLY reply;
41929b76e53SScott Long U16 pagelen;
42029b76e53SScott Long void *buf;
42129b76e53SScott Long int error, len;
42229b76e53SScott Long
42329b76e53SScott Long if (IOCStatus != NULL)
42429b76e53SScott Long *IOCStatus = MPI2_IOCSTATUS_SUCCESS;
42529b76e53SScott Long bzero(&header, sizeof(header));
42629b76e53SScott Long error = mps_read_ext_config_page_header(fd, ExtPageType, PageNumber,
42729b76e53SScott Long PageAddress, &header, &pagelen, IOCStatus);
42829b76e53SScott Long if (error) {
42929b76e53SScott Long errno = error;
43029b76e53SScott Long return (NULL);
43129b76e53SScott Long }
43229b76e53SScott Long
43329b76e53SScott Long bzero(&req, sizeof(req));
43429b76e53SScott Long req.Function = MPI2_FUNCTION_CONFIG;
43529b76e53SScott Long req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
436fc9780fdSAlfredo Dal'Ava Junior req.PageAddress = htole32(PageAddress);
43729b76e53SScott Long req.Header = header;
43829b76e53SScott Long if (pagelen == 0)
439fc9780fdSAlfredo Dal'Ava Junior pagelen = htole16(4);
44029b76e53SScott Long req.ExtPageLength = pagelen;
44129b76e53SScott Long req.ExtPageType = ExtPageType;
44229b76e53SScott Long
443fc9780fdSAlfredo Dal'Ava Junior len = le16toh(pagelen) * 4;
44429b76e53SScott Long buf = malloc(len);
44529b76e53SScott Long if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
44629b76e53SScott Long buf, len, NULL, 0, 30)) {
44729b76e53SScott Long error = errno;
44829b76e53SScott Long free(buf);
44929b76e53SScott Long errno = error;
45029b76e53SScott Long return (NULL);
45129b76e53SScott Long }
452fc9780fdSAlfredo Dal'Ava Junior reply.IOCStatus = le16toh(reply.IOCStatus);
45329b76e53SScott Long if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
45429b76e53SScott Long if (IOCStatus != NULL)
45529b76e53SScott Long *IOCStatus = reply.IOCStatus;
45629b76e53SScott Long else
45729b76e53SScott Long warnx("Reading extended config page failed: %s",
45829b76e53SScott Long mps_ioc_status(reply.IOCStatus));
45929b76e53SScott Long free(buf);
46029b76e53SScott Long errno = EIO;
46129b76e53SScott Long return (NULL);
46229b76e53SScott Long }
46329b76e53SScott Long return (buf);
46429b76e53SScott Long }
46529b76e53SScott Long
4663e891891SBaptiste Daroussin int
mps_firmware_send(int fd,unsigned char * fw,uint32_t len,bool bios)4673e891891SBaptiste Daroussin mps_firmware_send(int fd, unsigned char *fw, uint32_t len, bool bios)
4683e891891SBaptiste Daroussin {
4693e891891SBaptiste Daroussin MPI2_FW_DOWNLOAD_REQUEST req;
4703e891891SBaptiste Daroussin MPI2_FW_DOWNLOAD_REPLY reply;
4713e891891SBaptiste Daroussin
4723e891891SBaptiste Daroussin bzero(&req, sizeof(req));
4733e891891SBaptiste Daroussin bzero(&reply, sizeof(reply));
4743e891891SBaptiste Daroussin req.Function = MPI2_FUNCTION_FW_DOWNLOAD;
4753e891891SBaptiste Daroussin req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW;
476fc9780fdSAlfredo Dal'Ava Junior req.TotalImageSize = htole32(len);
4773e891891SBaptiste Daroussin req.MsgFlags = MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
4783e891891SBaptiste Daroussin
4793e891891SBaptiste Daroussin if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
4803e891891SBaptiste Daroussin fw, len, 0)) {
4813e891891SBaptiste Daroussin return (-1);
4823e891891SBaptiste Daroussin }
4833e891891SBaptiste Daroussin return (0);
4843e891891SBaptiste Daroussin }
4853e891891SBaptiste Daroussin
4863e891891SBaptiste Daroussin int
mps_firmware_get(int fd,unsigned char ** firmware,bool bios)4873e891891SBaptiste Daroussin mps_firmware_get(int fd, unsigned char **firmware, bool bios)
4883e891891SBaptiste Daroussin {
4893e891891SBaptiste Daroussin MPI2_FW_UPLOAD_REQUEST req;
4903e891891SBaptiste Daroussin MPI2_FW_UPLOAD_REPLY reply;
4913e891891SBaptiste Daroussin int size;
4923e891891SBaptiste Daroussin
4933e891891SBaptiste Daroussin *firmware = NULL;
4943e891891SBaptiste Daroussin bzero(&req, sizeof(req));
4953e891891SBaptiste Daroussin bzero(&reply, sizeof(reply));
4963e891891SBaptiste Daroussin req.Function = MPI2_FUNCTION_FW_UPLOAD;
4973e891891SBaptiste Daroussin req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW;
4983e891891SBaptiste Daroussin
4993e891891SBaptiste Daroussin if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
5003e891891SBaptiste Daroussin NULL, 0, 0)) {
5013e891891SBaptiste Daroussin return (-1);
5023e891891SBaptiste Daroussin }
5033e891891SBaptiste Daroussin if (reply.ActualImageSize == 0) {
5043e891891SBaptiste Daroussin return (-1);
5053e891891SBaptiste Daroussin }
5063e891891SBaptiste Daroussin
507fc9780fdSAlfredo Dal'Ava Junior size = le32toh(reply.ActualImageSize);
5084b6fa244SPedro F. Giffuni *firmware = calloc(size, sizeof(unsigned char));
5093e891891SBaptiste Daroussin if (*firmware == NULL) {
5103e891891SBaptiste Daroussin warn("calloc");
5113e891891SBaptiste Daroussin return (-1);
5123e891891SBaptiste Daroussin }
5133e891891SBaptiste Daroussin if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
5143e891891SBaptiste Daroussin *firmware, size, 0)) {
5153e891891SBaptiste Daroussin free(*firmware);
5163e891891SBaptiste Daroussin return (-1);
5173e891891SBaptiste Daroussin }
5183e891891SBaptiste Daroussin
5193e891891SBaptiste Daroussin return (size);
5203e891891SBaptiste Daroussin }
5213e891891SBaptiste Daroussin
52229b76e53SScott Long #else
52329b76e53SScott Long
52429b76e53SScott Long int
mps_read_config_page_header(int fd,U8 PageType,U8 PageNumber,U32 PageAddress,MPI2_CONFIG_PAGE_HEADER * header,U16 * IOCStatus)52529b76e53SScott Long mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
52629b76e53SScott Long MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus)
52729b76e53SScott Long {
52829b76e53SScott Long struct mps_cfg_page_req req;
52929b76e53SScott Long
53029b76e53SScott Long if (IOCStatus != NULL)
53129b76e53SScott Long *IOCStatus = MPI2_IOCSTATUS_SUCCESS;
53229b76e53SScott Long if (header == NULL)
53329b76e53SScott Long return (EINVAL);
53429b76e53SScott Long bzero(&req, sizeof(req));
53529b76e53SScott Long req.header.PageType = PageType;
53629b76e53SScott Long req.header.PageNumber = PageNumber;
53729b76e53SScott Long req.page_address = PageAddress;
53829b76e53SScott Long if (ioctl(fd, MPSIO_READ_CFG_HEADER, &req) < 0)
53929b76e53SScott Long return (errno);
54029b76e53SScott Long if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
54129b76e53SScott Long if (IOCStatus != NULL)
54229b76e53SScott Long *IOCStatus = req.ioc_status;
54329b76e53SScott Long return (EIO);
54429b76e53SScott Long }
54529b76e53SScott Long bcopy(&req.header, header, sizeof(*header));
54629b76e53SScott Long return (0);
54729b76e53SScott Long }
54829b76e53SScott Long
54929b76e53SScott Long void *
mps_read_config_page(int fd,U8 PageType,U8 PageNumber,U32 PageAddress,U16 * IOCStatus)55029b76e53SScott Long mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
55129b76e53SScott Long U16 *IOCStatus)
55229b76e53SScott Long {
55329b76e53SScott Long struct mps_cfg_page_req req;
55429b76e53SScott Long void *buf;
55529b76e53SScott Long int error;
55629b76e53SScott Long
55729b76e53SScott Long error = mps_read_config_page_header(fd, PageType, PageNumber,
55829b76e53SScott Long PageAddress, &req.header, IOCStatus);
55929b76e53SScott Long if (error) {
56029b76e53SScott Long errno = error;
56129b76e53SScott Long return (NULL);
56229b76e53SScott Long }
56329b76e53SScott Long
56429b76e53SScott Long if (req.header.PageLength == 0)
56529b76e53SScott Long req.header.PageLength = 4;
56629b76e53SScott Long req.len = req.header.PageLength * 4;
56729b76e53SScott Long buf = malloc(req.len);
56829b76e53SScott Long req.buf = buf;
56929b76e53SScott Long bcopy(&req.header, buf, sizeof(req.header));
57029b76e53SScott Long if (ioctl(fd, MPSIO_READ_CFG_PAGE, &req) < 0) {
57129b76e53SScott Long error = errno;
57229b76e53SScott Long free(buf);
57329b76e53SScott Long errno = error;
57429b76e53SScott Long return (NULL);
57529b76e53SScott Long }
576fc9780fdSAlfredo Dal'Ava Junior req.ioc_status = le16toh(req.ioc_status);
57729b76e53SScott Long if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
57829b76e53SScott Long if (IOCStatus != NULL)
57929b76e53SScott Long *IOCStatus = req.ioc_status;
58029b76e53SScott Long else
58129b76e53SScott Long warnx("Reading config page failed: 0x%x %s",
58229b76e53SScott Long req.ioc_status, mps_ioc_status(req.ioc_status));
58329b76e53SScott Long free(buf);
58429b76e53SScott Long errno = EIO;
58529b76e53SScott Long return (NULL);
58629b76e53SScott Long }
58729b76e53SScott Long return (buf);
58829b76e53SScott Long }
58929b76e53SScott Long
59029b76e53SScott Long void *
mps_read_extended_config_page(int fd,U8 ExtPageType,U8 PageVersion,U8 PageNumber,U32 PageAddress,U16 * IOCStatus)59129b76e53SScott Long mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
59229b76e53SScott Long U8 PageNumber, U32 PageAddress, U16 *IOCStatus)
59329b76e53SScott Long {
59429b76e53SScott Long struct mps_ext_cfg_page_req req;
59529b76e53SScott Long void *buf;
59629b76e53SScott Long int error;
59729b76e53SScott Long
59829b76e53SScott Long if (IOCStatus != NULL)
59929b76e53SScott Long *IOCStatus = MPI2_IOCSTATUS_SUCCESS;
60029b76e53SScott Long bzero(&req, sizeof(req));
60129b76e53SScott Long req.header.PageVersion = PageVersion;
60229b76e53SScott Long req.header.PageNumber = PageNumber;
60329b76e53SScott Long req.header.ExtPageType = ExtPageType;
604fc9780fdSAlfredo Dal'Ava Junior req.page_address = htole32(PageAddress);
60529b76e53SScott Long if (ioctl(fd, MPSIO_READ_EXT_CFG_HEADER, &req) < 0)
60629b76e53SScott Long return (NULL);
607fc9780fdSAlfredo Dal'Ava Junior req.ioc_status = le16toh(req.ioc_status);
60829b76e53SScott Long if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
60929b76e53SScott Long if (IOCStatus != NULL)
61029b76e53SScott Long *IOCStatus = req.ioc_status;
61129b76e53SScott Long else
61229b76e53SScott Long warnx("Reading extended config page header failed: %s",
61329b76e53SScott Long mps_ioc_status(req.ioc_status));
61429b76e53SScott Long errno = EIO;
61529b76e53SScott Long return (NULL);
61629b76e53SScott Long }
61729b76e53SScott Long req.len = req.header.ExtPageLength * 4;
61829b76e53SScott Long buf = malloc(req.len);
61929b76e53SScott Long req.buf = buf;
62029b76e53SScott Long bcopy(&req.header, buf, sizeof(req.header));
62129b76e53SScott Long if (ioctl(fd, MPSIO_READ_EXT_CFG_PAGE, &req) < 0) {
62229b76e53SScott Long error = errno;
62329b76e53SScott Long free(buf);
62429b76e53SScott Long errno = error;
62529b76e53SScott Long return (NULL);
62629b76e53SScott Long }
627fc9780fdSAlfredo Dal'Ava Junior req.ioc_status = le16toh(req.ioc_status);
62829b76e53SScott Long if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
62929b76e53SScott Long if (IOCStatus != NULL)
63029b76e53SScott Long *IOCStatus = req.ioc_status;
63129b76e53SScott Long else
63229b76e53SScott Long warnx("Reading extended config page failed: %s",
63329b76e53SScott Long mps_ioc_status(req.ioc_status));
63429b76e53SScott Long free(buf);
63529b76e53SScott Long errno = EIO;
63629b76e53SScott Long return (NULL);
63729b76e53SScott Long }
63829b76e53SScott Long return (buf);
63929b76e53SScott Long }
64029b76e53SScott Long #endif
64129b76e53SScott Long
64229b76e53SScott Long int
mps_open(int unit)64329b76e53SScott Long mps_open(int unit)
64429b76e53SScott Long {
64529b76e53SScott Long char path[MAXPATHLEN];
64629b76e53SScott Long
64748f31f4fSBaptiste Daroussin snprintf(path, sizeof(path), "/dev/mp%s%d", is_mps ? "s": "r", unit);
64829b76e53SScott Long return (open(path, O_RDWR));
64929b76e53SScott Long }
65029b76e53SScott Long
65129b76e53SScott Long int
mps_user_command(int fd,void * req,uint32_t req_len,void * reply,uint32_t reply_len,void * buffer,int len,uint32_t flags)65229b76e53SScott Long mps_user_command(int fd, void *req, uint32_t req_len, void *reply,
65329b76e53SScott Long uint32_t reply_len, void *buffer, int len, uint32_t flags)
65429b76e53SScott Long {
65529b76e53SScott Long struct mps_usr_command cmd;
65629b76e53SScott Long
65729b76e53SScott Long bzero(&cmd, sizeof(struct mps_usr_command));
65829b76e53SScott Long cmd.req = req;
65929b76e53SScott Long cmd.req_len = req_len;
66029b76e53SScott Long cmd.rpl = reply;
66129b76e53SScott Long cmd.rpl_len = reply_len;
66229b76e53SScott Long cmd.buf = buffer;
66329b76e53SScott Long cmd.len = len;
66429b76e53SScott Long cmd.flags = flags;
66529b76e53SScott Long
6665a92b271SBaptiste Daroussin if (ioctl(fd, is_mps ? MPSIO_MPS_COMMAND : MPRIO_MPR_COMMAND, &cmd) < 0)
66729b76e53SScott Long return (errno);
66829b76e53SScott Long return (0);
66929b76e53SScott Long }
67029b76e53SScott Long
67129b76e53SScott Long int
mps_pass_command(int fd,void * req,uint32_t req_len,void * reply,uint32_t reply_len,void * data_in,uint32_t datain_len,void * data_out,uint32_t dataout_len,uint32_t timeout)67229b76e53SScott Long mps_pass_command(int fd, void *req, uint32_t req_len, void *reply,
67329b76e53SScott Long uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out,
67429b76e53SScott Long uint32_t dataout_len, uint32_t timeout)
67529b76e53SScott Long {
6765a92b271SBaptiste Daroussin struct mprs_pass_thru pass;
67729b76e53SScott Long
678b627cd1cSAlexander Motin bzero(&pass, sizeof(pass));
67929b76e53SScott Long pass.PtrRequest = (uint64_t)(uintptr_t)req;
68029b76e53SScott Long pass.PtrReply = (uint64_t)(uintptr_t)reply;
68129b76e53SScott Long pass.RequestSize = req_len;
68229b76e53SScott Long pass.ReplySize = reply_len;
683b627cd1cSAlexander Motin if (datain_len && dataout_len) {
684b627cd1cSAlexander Motin pass.PtrData = (uint64_t)(uintptr_t)data_in;
685b627cd1cSAlexander Motin pass.PtrDataOut = (uint64_t)(uintptr_t)data_out;
68629b76e53SScott Long pass.DataSize = datain_len;
68729b76e53SScott Long pass.DataOutSize = dataout_len;
6885a92b271SBaptiste Daroussin if (is_mps) {
68929b76e53SScott Long pass.DataDirection = MPS_PASS_THRU_DIRECTION_BOTH;
6905a92b271SBaptiste Daroussin } else {
6915a92b271SBaptiste Daroussin pass.DataDirection = MPR_PASS_THRU_DIRECTION_BOTH;
6925a92b271SBaptiste Daroussin }
6935a92b271SBaptiste Daroussin } else if (datain_len) {
694b627cd1cSAlexander Motin pass.PtrData = (uint64_t)(uintptr_t)data_in;
695b627cd1cSAlexander Motin pass.DataSize = datain_len;
6965a92b271SBaptiste Daroussin if (is_mps) {
69729b76e53SScott Long pass.DataDirection = MPS_PASS_THRU_DIRECTION_READ;
6985a92b271SBaptiste Daroussin } else {
6995a92b271SBaptiste Daroussin pass.DataDirection = MPR_PASS_THRU_DIRECTION_READ;
7005a92b271SBaptiste Daroussin }
7015a92b271SBaptiste Daroussin } else if (dataout_len) {
702b627cd1cSAlexander Motin pass.PtrData = (uint64_t)(uintptr_t)data_out;
703b627cd1cSAlexander Motin pass.DataSize = dataout_len;
7045a92b271SBaptiste Daroussin if (is_mps) {
70529b76e53SScott Long pass.DataDirection = MPS_PASS_THRU_DIRECTION_WRITE;
7065a92b271SBaptiste Daroussin } else {
7075a92b271SBaptiste Daroussin pass.DataDirection = MPR_PASS_THRU_DIRECTION_WRITE;
7085a92b271SBaptiste Daroussin }
7095a92b271SBaptiste Daroussin } else {
7105a92b271SBaptiste Daroussin if (is_mps) {
71129b76e53SScott Long pass.DataDirection = MPS_PASS_THRU_DIRECTION_NONE;
7125a92b271SBaptiste Daroussin } else {
7135a92b271SBaptiste Daroussin pass.DataDirection = MPR_PASS_THRU_DIRECTION_NONE;
7145a92b271SBaptiste Daroussin }
7155a92b271SBaptiste Daroussin }
71629b76e53SScott Long pass.Timeout = timeout;
71729b76e53SScott Long
71829b76e53SScott Long if (ioctl(fd, MPTIOCTL_PASS_THRU, &pass) < 0)
71929b76e53SScott Long return (errno);
72029b76e53SScott Long return (0);
72129b76e53SScott Long }
72229b76e53SScott Long
7237d154c4dSAlan Somers /* Return the length in bytes of the device's MPI2_IOC_FACTS reply */
7247d154c4dSAlan Somers static size_t
mps_get_ioc_factslen(int fd)7257d154c4dSAlan Somers mps_get_ioc_factslen(int fd)
7267d154c4dSAlan Somers {
7277d154c4dSAlan Somers MPI2_IOC_FACTS_REQUEST req;
7287d154c4dSAlan Somers const size_t factslen = 4;
7297d154c4dSAlan Somers char factsbuf[4] = {0};
7307d154c4dSAlan Somers MPI2_IOC_FACTS_REPLY *facts = (MPI2_IOC_FACTS_REPLY*)factsbuf;
7317d154c4dSAlan Somers int error;
7327d154c4dSAlan Somers
7337d154c4dSAlan Somers bzero(&req, sizeof(req));
7347d154c4dSAlan Somers req.Function = MPI2_FUNCTION_IOC_FACTS;
7357d154c4dSAlan Somers error = mps_pass_command(fd, &req, sizeof(MPI2_IOC_FACTS_REQUEST),
7367d154c4dSAlan Somers factsbuf, factslen, NULL, 0, NULL, 0, 10);
7377d154c4dSAlan Somers
7387d154c4dSAlan Somers if (error)
7397d154c4dSAlan Somers return (0);
7407d154c4dSAlan Somers
7417d154c4dSAlan Somers /* The card's response is measured in dwords */
7427d154c4dSAlan Somers return (facts->MsgLength * 4);
7437d154c4dSAlan Somers }
7447d154c4dSAlan Somers
74529b76e53SScott Long MPI2_IOC_FACTS_REPLY *
mps_get_iocfacts(int fd)74629b76e53SScott Long mps_get_iocfacts(int fd)
74729b76e53SScott Long {
74829b76e53SScott Long MPI2_IOC_FACTS_REPLY *facts;
74929b76e53SScott Long MPI2_IOC_FACTS_REQUEST req;
7507d154c4dSAlan Somers size_t factslen;
75129b76e53SScott Long int error;
75229b76e53SScott Long
7537d154c4dSAlan Somers factslen = mps_get_ioc_factslen(fd);
7547d154c4dSAlan Somers if (factslen == 0)
7557d154c4dSAlan Somers return (NULL);
75669e85eb8SScott Long
75769e85eb8SScott Long facts = malloc(factslen);
75829b76e53SScott Long if (facts == NULL) {
75929b76e53SScott Long errno = ENOMEM;
76029b76e53SScott Long return (NULL);
76129b76e53SScott Long }
76229b76e53SScott Long
7637d154c4dSAlan Somers bzero(&req, sizeof(req));
76429b76e53SScott Long req.Function = MPI2_FUNCTION_IOC_FACTS;
76529b76e53SScott Long
76629b76e53SScott Long #if 1
76729b76e53SScott Long error = mps_pass_command(fd, &req, sizeof(MPI2_IOC_FACTS_REQUEST),
76869e85eb8SScott Long facts, factslen, NULL, 0, NULL, 0, 10);
76929b76e53SScott Long #else
77029b76e53SScott Long error = mps_user_command(fd, &req, sizeof(MPI2_IOC_FACTS_REQUEST),
77169e85eb8SScott Long facts, factslen, NULL, 0, 0);
77229b76e53SScott Long #endif
77329b76e53SScott Long if (error) {
77429b76e53SScott Long free(facts);
77529b76e53SScott Long return (NULL);
77629b76e53SScott Long }
77729b76e53SScott Long
77829b76e53SScott Long if (!IOC_STATUS_SUCCESS(facts->IOCStatus)) {
77929b76e53SScott Long free(facts);
78029b76e53SScott Long errno = EINVAL;
78129b76e53SScott Long return (NULL);
78229b76e53SScott Long }
783fc9780fdSAlfredo Dal'Ava Junior adjust_iocfacts_endianness(facts);
78429b76e53SScott Long return (facts);
78529b76e53SScott Long }
78629b76e53SScott Long
787fc9780fdSAlfredo Dal'Ava Junior static void
adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY * facts)788fc9780fdSAlfredo Dal'Ava Junior adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts)
789fc9780fdSAlfredo Dal'Ava Junior {
790fc9780fdSAlfredo Dal'Ava Junior facts->MsgVersion = le16toh(facts->MsgVersion);
791fc9780fdSAlfredo Dal'Ava Junior facts->HeaderVersion = le16toh(facts->HeaderVersion);
792fc9780fdSAlfredo Dal'Ava Junior facts->Reserved1 = le16toh(facts->Reserved1);
793fc9780fdSAlfredo Dal'Ava Junior facts->IOCExceptions = le16toh(facts->IOCExceptions);
794fc9780fdSAlfredo Dal'Ava Junior facts->IOCStatus = le16toh(facts->IOCStatus);
795fc9780fdSAlfredo Dal'Ava Junior facts->IOCLogInfo = le32toh(facts->IOCLogInfo);
796fc9780fdSAlfredo Dal'Ava Junior facts->RequestCredit = le16toh(facts->RequestCredit);
797fc9780fdSAlfredo Dal'Ava Junior facts->ProductID = le16toh(facts->ProductID);
798fc9780fdSAlfredo Dal'Ava Junior facts->IOCCapabilities = le32toh(facts->IOCCapabilities);
799fc9780fdSAlfredo Dal'Ava Junior facts->IOCRequestFrameSize =
800fc9780fdSAlfredo Dal'Ava Junior le16toh(facts->IOCRequestFrameSize);
801fc9780fdSAlfredo Dal'Ava Junior facts->FWVersion.Word = le32toh(facts->FWVersion.Word);
802fc9780fdSAlfredo Dal'Ava Junior facts->MaxInitiators = le16toh(facts->MaxInitiators);
803fc9780fdSAlfredo Dal'Ava Junior facts->MaxTargets = le16toh(facts->MaxTargets);
804fc9780fdSAlfredo Dal'Ava Junior facts->MaxSasExpanders = le16toh(facts->MaxSasExpanders);
805fc9780fdSAlfredo Dal'Ava Junior facts->MaxEnclosures = le16toh(facts->MaxEnclosures);
806fc9780fdSAlfredo Dal'Ava Junior facts->ProtocolFlags = le16toh(facts->ProtocolFlags);
807fc9780fdSAlfredo Dal'Ava Junior facts->HighPriorityCredit = le16toh(facts->HighPriorityCredit);
808fc9780fdSAlfredo Dal'Ava Junior facts->MaxReplyDescriptorPostQueueDepth =
809fc9780fdSAlfredo Dal'Ava Junior le16toh(facts->MaxReplyDescriptorPostQueueDepth);
810fc9780fdSAlfredo Dal'Ava Junior facts->MaxDevHandle = le16toh(facts->MaxDevHandle);
811fc9780fdSAlfredo Dal'Ava Junior facts->MaxPersistentEntries =
812fc9780fdSAlfredo Dal'Ava Junior le16toh(facts->MaxPersistentEntries);
813fc9780fdSAlfredo Dal'Ava Junior facts->MinDevHandle = le16toh(facts->MinDevHandle);
814fc9780fdSAlfredo Dal'Ava Junior }
815