git: a027f2ab422c - stable/12 - mprutil: add big endian support

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Wed, 01 Dec 2021 18:59:04 UTC
The branch stable/12 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=a027f2ab422c12f3f7bf9d1a519ada6b2b881e8a

commit a027f2ab422c12f3f7bf9d1a519ada6b2b881e8a
Author:     Alfredo Dal'Ava Junior <alfredo@FreeBSD.org>
AuthorDate: 2021-04-17 01:01:38 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2021-12-01 18:24:28 +0000

    mprutil: add big endian support
    
    This fix mprutil on big endian platforms, as follow up of D25785.
    
    Flash operations are still not working, such as MPI2_FUNCTION_FW_UPLOAD
    failing due to timeout.
    
    Firmware version used during tests: 16.00.01.00
    
    Submitted by:   Andre Fernando da Silva <andre.silva@eldorado.org.br>
    Reviewed by:    luporl, Sreekanth Reddy <sreekanth.reddy@broadcom.com> (by e-mail)
    Sponsored by:   Eldorado Research Institute (eldorado.org.br)
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D26040
    
    (cherry picked from commit fc9780fd41e7b29db04e9cb843cb5034b88ae662)
---
 usr.sbin/mpsutil/mps_cmd.c   | 61 +++++++++++++++++++++++++++++++++++---------
 usr.sbin/mpsutil/mps_flash.c |  9 ++++---
 usr.sbin/mpsutil/mps_show.c  | 59 +++++++++++++++++++++---------------------
 usr.sbin/mpsutil/mps_slot.c  |  4 ++-
 usr.sbin/mpsutil/mpsutil.8   |  3 +++
 5 files changed, 90 insertions(+), 46 deletions(-)

diff --git a/usr.sbin/mpsutil/mps_cmd.c b/usr.sbin/mpsutil/mps_cmd.c
index edde180bf99d..51a0e77822d9 100644
--- a/usr.sbin/mpsutil/mps_cmd.c
+++ b/usr.sbin/mpsutil/mps_cmd.c
@@ -47,6 +47,7 @@ __RCSID("$FreeBSD$");
 #endif
 #include <sys/sysctl.h>
 #include <sys/uio.h>
+#include <sys/endian.h>
 
 #include <err.h>
 #include <fcntl.h>
@@ -245,6 +246,8 @@ struct mprs_btdh_mapping {
         uint16_t        Reserved;
 };
 
+static void adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts);
+
 const char *
 mps_ioc_status(U16 IOCStatus)
 {
@@ -300,7 +303,7 @@ mps_set_slot_status(int fd, U16 handle, U16 slot, U32 status)
 	    NULL, 0, NULL, 0, 30) != 0)
 		return (errno);
 
-	if (!IOC_STATUS_SUCCESS(reply.IOCStatus))
+	if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus)))
 		return (EIO);
 	return (0);
 }
@@ -323,7 +326,7 @@ mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
 	    NULL, 0, NULL, 0, 30))
 		return (errno);
 
-	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+	if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus))) {
 		if (IOCStatus != NULL)
 			*IOCStatus = reply.IOCStatus;
 		return (EIO);
@@ -346,15 +349,15 @@ mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber, U32 PageA
 	req.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
 	req.ExtPageType = ExtPageType;
 	req.Header.PageNumber = PageNumber;
-	req.PageAddress = PageAddress;
+	req.PageAddress = htole32(PageAddress);
 
 	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
 	    NULL, 0, NULL, 0, 30))
 		return (errno);
 
-	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+	if (!IOC_STATUS_SUCCESS(le16toh(reply.IOCStatus))) {
 		if (IOCStatus != NULL)
-			*IOCStatus = reply.IOCStatus;
+			*IOCStatus = le16toh(reply.IOCStatus);
 		return (EIO);
 	}
 	if ((header == NULL) || (ExtPageLength == NULL))
@@ -385,7 +388,7 @@ mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
 	bzero(&req, sizeof(req));
 	req.Function = MPI2_FUNCTION_CONFIG;
 	req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	req.PageAddress = PageAddress;
+	req.PageAddress = htole32(PageAddress);
 	req.Header = header;
 	if (req.Header.PageLength == 0)
 		req.Header.PageLength = 4;
@@ -399,6 +402,7 @@ mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
 		errno = error;
 		return (NULL);
 	}
+	reply.IOCStatus = le16toh(reply.IOCStatus);
 	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
 		if (IOCStatus != NULL)
 			*IOCStatus = reply.IOCStatus;
@@ -436,14 +440,14 @@ mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
 	bzero(&req, sizeof(req));
 	req.Function = MPI2_FUNCTION_CONFIG;
 	req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	req.PageAddress = PageAddress;
+	req.PageAddress = htole32(PageAddress);
 	req.Header = header;
 	if (pagelen == 0)
-		pagelen = 4;
+		pagelen = htole16(4);
 	req.ExtPageLength = pagelen;
 	req.ExtPageType = ExtPageType;
 
-	len = pagelen * 4;
+	len = le16toh(pagelen) * 4;
 	buf = malloc(len);
 	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
 	    buf, len, NULL, 0, 30)) {
@@ -452,6 +456,7 @@ mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
 		errno = error;
 		return (NULL);
 	}
+	reply.IOCStatus = le16toh(reply.IOCStatus);
 	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
 		if (IOCStatus != NULL)
 			*IOCStatus = reply.IOCStatus;
@@ -475,7 +480,7 @@ mps_firmware_send(int fd, unsigned char *fw, uint32_t len, bool bios)
 	bzero(&reply, sizeof(reply));
 	req.Function = MPI2_FUNCTION_FW_DOWNLOAD;
 	req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW;
-	req.TotalImageSize = len;
+	req.TotalImageSize = htole32(len);
 	req.MsgFlags = MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
 
 	if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
@@ -506,7 +511,7 @@ mps_firmware_get(int fd, unsigned char **firmware, bool bios)
 		return (-1);
 	}
 
-	size = reply.ActualImageSize;
+	size = le32toh(reply.ActualImageSize);
 	*firmware = calloc(size, sizeof(unsigned char));
 	if (*firmware == NULL) {
 		warn("calloc");
@@ -575,6 +580,7 @@ mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
 		errno = error;
 		return (NULL);
 	}
+	req.ioc_status = le16toh(req.ioc_status);
 	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
 		if (IOCStatus != NULL)
 			*IOCStatus = req.ioc_status;
@@ -602,9 +608,10 @@ mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
 	req.header.PageVersion = PageVersion;
 	req.header.PageNumber = PageNumber;
 	req.header.ExtPageType = ExtPageType;
-	req.page_address = PageAddress;
+	req.page_address = htole32(PageAddress);
 	if (ioctl(fd, MPSIO_READ_EXT_CFG_HEADER, &req) < 0)
 		return (NULL);
+	req.ioc_status = le16toh(req.ioc_status);
 	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
 		if (IOCStatus != NULL)
 			*IOCStatus = req.ioc_status;
@@ -624,6 +631,7 @@ mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
 		errno = error;
 		return (NULL);
 	}
+	req.ioc_status = le16toh(req.ioc_status);
 	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
 		if (IOCStatus != NULL)
 			*IOCStatus = req.ioc_status;
@@ -752,6 +760,35 @@ mps_get_iocfacts(int fd)
 		errno = EINVAL;
 		return (NULL);
 	}
+	adjust_iocfacts_endianness(facts);
 	return (facts);
 }
 
+static void
+adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts)
+{
+	facts->MsgVersion = le16toh(facts->MsgVersion);
+	facts->HeaderVersion = le16toh(facts->HeaderVersion);
+	facts->Reserved1 = le16toh(facts->Reserved1);
+	facts->IOCExceptions = le16toh(facts->IOCExceptions);
+	facts->IOCStatus = le16toh(facts->IOCStatus);
+	facts->IOCLogInfo = le32toh(facts->IOCLogInfo);
+	facts->RequestCredit = le16toh(facts->RequestCredit);
+	facts->ProductID = le16toh(facts->ProductID);
+	facts->IOCCapabilities = le32toh(facts->IOCCapabilities);
+	facts->IOCRequestFrameSize =
+	    le16toh(facts->IOCRequestFrameSize);
+	facts->FWVersion.Word = le32toh(facts->FWVersion.Word);
+	facts->MaxInitiators = le16toh(facts->MaxInitiators);
+	facts->MaxTargets = le16toh(facts->MaxTargets);
+	facts->MaxSasExpanders = le16toh(facts->MaxSasExpanders);
+	facts->MaxEnclosures = le16toh(facts->MaxEnclosures);
+	facts->ProtocolFlags = le16toh(facts->ProtocolFlags);
+	facts->HighPriorityCredit = le16toh(facts->HighPriorityCredit);
+	facts->MaxReplyDescriptorPostQueueDepth =
+	    le16toh(facts->MaxReplyDescriptorPostQueueDepth);
+	facts->MaxDevHandle = le16toh(facts->MaxDevHandle);
+	facts->MaxPersistentEntries =
+	    le16toh(facts->MaxPersistentEntries);
+	facts->MinDevHandle = le16toh(facts->MinDevHandle);
+}
diff --git a/usr.sbin/mpsutil/mps_flash.c b/usr.sbin/mpsutil/mps_flash.c
index 22beaae79bb0..a0cc4a877b7d 100644
--- a/usr.sbin/mpsutil/mps_flash.c
+++ b/usr.sbin/mpsutil/mps_flash.c
@@ -29,6 +29,7 @@ __RCSID("$FreeBSD$");
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/mman.h>
+#include <sys/endian.h>
 
 #include <errno.h>
 #include <err.h>
@@ -203,21 +204,21 @@ flash_update(int argc, char **argv)
 		}
 	} else {
 		fwheader = (MPI2_FW_IMAGE_HEADER *)mem;
-		if (fwheader->VendorID != MPI2_MFGPAGE_VENDORID_LSI) {
+		if (le16toh(fwheader->VendorID) != MPI2_MFGPAGE_VENDORID_LSI) {
 			warnx("Invalid firmware:");
 			warnx("  Expected Vendor ID: %04x",
 			    MPI2_MFGPAGE_VENDORID_LSI);
-			warnx("  Image Vendor ID: %04x", fwheader->VendorID);
+			warnx("  Image Vendor ID: %04x", le16toh(fwheader->VendorID));
 			munmap(mem, st.st_size);
 			close(fd);
 			free(facts);
 			return (1);
 		}
 
-		if (fwheader->ProductID != facts->ProductID) {
+		if (le16toh(fwheader->ProductID) != facts->ProductID) {
 			warnx("Invalid image:");
 			warnx("  Expected Product ID: %04x", facts->ProductID);
-			warnx("  Image Product ID: %04x", fwheader->ProductID);
+			warnx("  Image Product ID: %04x", le16toh(fwheader->ProductID));
 			munmap(mem, st.st_size);
 			close(fd);
 			free(facts);
diff --git a/usr.sbin/mpsutil/mps_show.c b/usr.sbin/mpsutil/mps_show.c
index 814b22ab6f69..3985b3558a90 100644
--- a/usr.sbin/mpsutil/mps_show.c
+++ b/usr.sbin/mpsutil/mps_show.c
@@ -36,6 +36,7 @@ __RCSID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/errno.h>
+#include <sys/endian.h>
 #include <err.h>
 #include <libutil.h>
 #include <stdio.h>
@@ -111,7 +112,7 @@ show_adapter(int ac, char **av)
 		warn("Failed to get BIOS page 3 info");
 		return (error);
 	}
-	v = bios3->BiosVersion;
+	v = le32toh(bios3->BiosVersion);
 	printf("    BIOS Revision: %d.%02d.%02d.%02d\n",
 	    ((v & 0xff000000) >> 24), ((v &0xff0000) >> 16),
 	    ((v & 0xff00) >> 8), (v & 0xff));
@@ -206,12 +207,12 @@ show_adapter(int ac, char **av)
 
 		minspeed = get_device_speed(phy1->MaxMinLinkRate);
 		maxspeed = get_device_speed(phy1->MaxMinLinkRate >> 4);
-		type = get_device_type(phy0->ControllerPhyDeviceInfo);
+		type = get_device_type(le32toh(phy0->ControllerPhyDeviceInfo));
 
-		if (phy0->AttachedDevHandle != 0) {
-			snprintf(devhandle, 5, "%04x", phy0->AttachedDevHandle);
+		if (le16toh(phy0->AttachedDevHandle) != 0) {
+			snprintf(devhandle, 5, "%04x", le16toh(phy0->AttachedDevHandle));
 			snprintf(ctrlhandle, 5, "%04x",
-			    phy0->ControllerDevHandle);
+			    le16toh(phy0->ControllerDevHandle));
 			speed = get_device_speed(phy0->NegotiatedLinkRate);
 		} else {
 			snprintf(devhandle, 5, "    ");
@@ -545,7 +546,7 @@ show_devices(int ac, char **av)
 			close(fd);
 			return (error);
 		}
-		handle = device->DevHandle;
+		handle = le16toh(device->DevHandle);
 
 		if (device->ParentDevHandle == 0x0) {
 			free(device);
@@ -564,7 +565,7 @@ show_devices(int ac, char **av)
 		else
 			snprintf(bt, sizeof(bt), "%02d   %02d", bus, target);
 
-		type = get_device_type(device->DeviceInfo);
+		type = get_device_type(le32toh(device->DeviceInfo));
 
 		if (device->PhyNum < nphys) {
 			phydata = &sas0->PhyData[device->PhyNum];
@@ -576,7 +577,7 @@ show_devices(int ac, char **av)
 			    MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
 			    (device->PhyNum <<
 			    MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
-			    device->ParentDevHandle, &IOCStatus);
+			    le16toh(device->ParentDevHandle), &IOCStatus);
 			if (exp1 == NULL) {
 				if (IOCStatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
 					error = errno;
@@ -595,19 +596,19 @@ show_devices(int ac, char **av)
 			speed = " ";
 
 		if (device->EnclosureHandle != 0) {
-			snprintf(enchandle, 5, "%04x", device->EnclosureHandle);
-			snprintf(slot, 3, "%02d", device->Slot);
+			snprintf(enchandle, 5, "%04x", le16toh(device->EnclosureHandle));
+			snprintf(slot, 3, "%02d", le16toh(device->Slot));
 		} else {
 			snprintf(enchandle, 5, "    ");
 			snprintf(slot, 3, "  ");
 		}
 		printf("%-10s", bt);
-		snprintf(buf, sizeof(buf), "%08x%08x", device->SASAddress.High,
-		    device->SASAddress.Low);
+		snprintf(buf, sizeof(buf), "%08x%08x", le32toh(device->SASAddress.High),
+		    le32toh(device->SASAddress.Low));
 		printf("%-17s", buf);
-		snprintf(buf, sizeof(buf), "%04x", device->DevHandle);
+		snprintf(buf, sizeof(buf), "%04x", le16toh(device->DevHandle));
 		printf("%-8s", buf);
-		snprintf(buf, sizeof(buf), "%04x", device->ParentDevHandle);
+		snprintf(buf, sizeof(buf), "%04x", le16toh(device->ParentDevHandle));
 		printf("%-10s", buf);
 		printf("%-14s%-6s%-5s%-6s%d\n", type, speed,
 		    enchandle, slot, device->MaxPortConnections);
@@ -651,16 +652,16 @@ show_enclosures(int ac, char **av)
 			close(fd);
 			return (error);
 		}
-		type = get_enc_type(enc->Flags, &issep);
+		type = get_enc_type(le16toh(enc->Flags), &issep);
 		if (issep == 0)
 			snprintf(sepstr, 5, "    ");
 		else
-			snprintf(sepstr, 5, "%04x", enc->SEPDevHandle);
+			snprintf(sepstr, 5, "%04x", le16toh(enc->SEPDevHandle));
 		printf("  %.2d    %08x%08x    %s       %04x     %s\n",
-		    enc->NumSlots, enc->EnclosureLogicalID.High,
-		    enc->EnclosureLogicalID.Low, sepstr, enc->EnclosureHandle,
+		    le16toh(enc->NumSlots), le32toh(enc->EnclosureLogicalID.High),
+		    le32toh(enc->EnclosureLogicalID.Low), sepstr, le16toh(enc->EnclosureHandle),
 		    type);
-		handle = enc->EnclosureHandle;
+		handle = le16toh(enc->EnclosureHandle);
 		free(enc);
 	}
 	printf("\n");
@@ -704,19 +705,19 @@ show_expanders(int ac, char **av)
 		}
 
 		nphys = exp0->NumPhys;
-		handle = exp0->DevHandle;
+		handle = le16toh(exp0->DevHandle);
 
 		if (exp0->EnclosureHandle == 0x00)
 			snprintf(enchandle, 5, "    ");
 		else
-			snprintf(enchandle, 5, "%04d", exp0->EnclosureHandle);
+			snprintf(enchandle, 5, "%04d", le16toh(exp0->EnclosureHandle));
 		if (exp0->ParentDevHandle == 0x0)
 			snprintf(parent, 5, "    ");
 		else
-			snprintf(parent, 5, "%04x", exp0->ParentDevHandle);
+			snprintf(parent, 5, "%04x", le16toh(exp0->ParentDevHandle));
 		printf("  %02d    %08x%08x    %04x       %s     %s       %d\n",
-		    exp0->NumPhys, exp0->SASAddress.High, exp0->SASAddress.Low,
-		    exp0->DevHandle, parent, enchandle, exp0->SASLevel);
+		    exp0->NumPhys, le32toh(exp0->SASAddress.High), le32toh(exp0->SASAddress.Low),
+		    le16toh(exp0->DevHandle), parent, enchandle, exp0->SASLevel);
 
 		printf("\n");
 		printf("     Phy  RemotePhy  DevHandle  Speed   Min    Max    Device\n");
@@ -733,8 +734,8 @@ show_expanders(int ac, char **av)
 					warn("Error retrieving expander pg 1");
 				continue;
 			}
-			type = get_device_type(exp1->AttachedDeviceInfo);
-			if ((exp1->AttachedDeviceInfo &0x7) == 0) {
+			type = get_device_type(le32toh(exp1->AttachedDeviceInfo));
+			if ((le32toh(exp1->AttachedDeviceInfo) &0x7) == 0) {
 				speed = "     ";
 				snprintf(rphy, 3, "  ");
 				snprintf(rhandle, 5, "     ");
@@ -744,7 +745,7 @@ show_expanders(int ac, char **av)
 				snprintf(rphy, 3, "%02d",
 				    exp1->AttachedPhyIdentifier);
 				snprintf(rhandle, 5, "%04x",
-				    exp1->AttachedDevHandle);
+				    le16toh(exp1->AttachedDevHandle));
 			}
 			min = get_device_speed(exp1->HwLinkRate);
 			max = get_device_speed(exp1->HwLinkRate >> 4);
@@ -787,7 +788,7 @@ show_cfgpage(int ac, char **av)
 
 	switch (ac) {
 	case 4:
-		addr = (uint32_t)strtoul(av[3], NULL, 0);
+		addr = htole32((uint32_t)strtoul(av[3], NULL, 0));
 	case 3:
 		num = (uint8_t)strtoul(av[2], NULL, 0);
 	case 2:
@@ -814,7 +815,7 @@ show_cfgpage(int ac, char **av)
 
 	if (page >= 0x10) {
 		ehdr = data;
-		len = ehdr->ExtPageLength * 4;
+		len = le16toh(ehdr->ExtPageLength) * 4;
 		page = ehdr->ExtPageType;
 		attrs = ehdr->PageType >> 4;
 	} else {
diff --git a/usr.sbin/mpsutil/mps_slot.c b/usr.sbin/mpsutil/mps_slot.c
index 1879d699067a..bb4a7324c461 100644
--- a/usr.sbin/mpsutil/mps_slot.c
+++ b/usr.sbin/mpsutil/mps_slot.c
@@ -31,6 +31,7 @@ __RCSID("$FreeBSD$");
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/mman.h>
+#include <sys/endian.h>
 
 #include <errno.h>
 #include <err.h>
@@ -99,7 +100,8 @@ slot_set(int argc, char **argv)
 		return (error);
 	}
 
-	if (mps_set_slot_status(fd, handle, slot, status) != 0) {
+	if (mps_set_slot_status(fd, htole16(handle), htole16(slot),
+	    htole32(status)) != 0) {
 		warnx("Failed to set status");
 		close(fd);
 		return (1);
diff --git a/usr.sbin/mpsutil/mpsutil.8 b/usr.sbin/mpsutil/mpsutil.8
index 7bd6728d49de..e7c2fda8f84e 100644
--- a/usr.sbin/mpsutil/mpsutil.8
+++ b/usr.sbin/mpsutil/mpsutil.8
@@ -169,3 +169,6 @@ The
 .Nm
 utility first appeared in
 .Fx 11.0 .
+.Sh TODO
+Flash operations (save/update) are not supported on big-endian architectures.
+.Pp