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
This commit is contained in:
Alfredo Dal'Ava Junior 2021-04-16 22:01:38 -03:00
parent 561d34d705
commit fc9780fd41
5 changed files with 90 additions and 46 deletions

View File

@ -41,6 +41,7 @@ __RCSID("$FreeBSD$");
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
#include <sys/endian.h>
#include <err.h>
#include <fcntl.h>
@ -241,6 +242,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)
{
@ -296,7 +299,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);
}
@ -319,7 +322,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);
@ -342,15 +345,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))
@ -381,7 +384,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;
@ -395,6 +398,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;
@ -432,14 +436,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)) {
@ -448,6 +452,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;
@ -471,7 +476,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),
@ -502,7 +507,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");
@ -571,6 +576,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;
@ -598,9 +604,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;
@ -620,6 +627,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;
@ -761,6 +769,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);
}

View File

@ -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);

View File

@ -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>
@ -105,7 +106,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));
@ -172,12 +173,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, " ");
@ -520,7 +521,7 @@ show_devices(int ac, char **av)
close(fd);
return (error);
}
handle = device->DevHandle;
handle = le16toh(device->DevHandle);
if (device->ParentDevHandle == 0x0) {
free(device);
@ -539,7 +540,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];
@ -551,7 +552,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;
@ -570,19 +571,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);
@ -626,16 +627,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");
@ -679,19 +680,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");
@ -708,8 +709,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, " ");
@ -719,7 +720,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);
@ -762,7 +763,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:
@ -789,7 +790,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 {

View File

@ -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);

View File

@ -163,3 +163,6 @@ The
.Nm
utility first appeared in
.Fx 11.0 .
.Sh TODO
Flash operations (save/update) are not supported on big-endian architectures.
.Pp