git: 6cc44223cb67 - stable/12 - mpr: big-endian support

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

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

commit 6cc44223cb6717795afdac4348bbe7e2a968a07d
Author:     Alfredo Dal'Ava Junior <alfredo@FreeBSD.org>
AuthorDate: 2021-03-02 14:05:15 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2021-12-01 18:42:58 +0000

    mpr: big-endian support
    
    This fixes mpr driver on big-endian devices.
    Tested on powerpc64 and powerpc64le targets using a SAS9300-8i card
    (LSISAS3008 pci vendor=0x1000 device=0x0097)
    
    Submitted by:   Andre Fernando da Silva <andre.silva@eldorado.org.br>
    Reviewed by:    luporl, alfredo, Sreekanth Reddy <sreekanth.reddy@broadcom.com> (by email)
    Sponsored by:   Eldorado Research Institute (eldorado.org.br)
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D25785
    
    (cherry picked from commit 71900a794da046ad5322caae2774aed5b3d361b9)
---
 sys/dev/mpr/mpr.c         | 75 ++++++++++++++++++++++++++++++++++-------------
 sys/dev/mpr/mpr_config.c  | 16 +++++-----
 sys/dev/mpr/mpr_mapping.c |  4 +--
 sys/dev/mpr/mpr_sas.c     | 14 +++++----
 sys/dev/mpr/mpr_sas_lsi.c | 21 +++++++------
 sys/dev/mpr/mpr_table.c   | 66 ++++++++++++++++++++---------------------
 sys/dev/mpr/mprvar.h      |  4 +++
 7 files changed, 119 insertions(+), 81 deletions(-)

diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c
index 18300fedec6b..6e52efe0d8a4 100644
--- a/sys/dev/mpr/mpr.c
+++ b/sys/dev/mpr/mpr.c
@@ -111,6 +111,7 @@ static int mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag);
 static int mpr_debug_sysctl(SYSCTL_HANDLER_ARGS);
 static int mpr_dump_reqs(SYSCTL_HANDLER_ARGS);
 static void mpr_parse_debug(struct mpr_softc *sc, char *list);
+static void adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts);
 
 SYSCTL_NODE(_hw, OID_AUTO, mpr, CTLFLAG_RD, 0, "MPR Driver Parameters");
 
@@ -416,7 +417,7 @@ mpr_resize_queues(struct mpr_softc *sc)
 	 * the size of an IEEE Simple SGE.
 	 */
 	if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
-		chain_seg_size = htole16(sc->facts->IOCMaxChainSegmentSize);
+		chain_seg_size = sc->facts->IOCMaxChainSegmentSize;
 		if (chain_seg_size == 0)
 			chain_seg_size = MPR_DEFAULT_CHAIN_SEG_SIZE;
 		sc->chain_frame_size = chain_seg_size *
@@ -1055,15 +1056,21 @@ mpr_request_sync(struct mpr_softc *sc, void *req, MPI2_DEFAULT_REPLY *reply,
 		mpr_dprint(sc, MPR_FAULT, "Timeout reading doorbell 0\n");
 		return (ENXIO);
 	}
+
+	/*
+	 * If in a BE platform, swap bytes using le16toh to not
+	 * disturb 8 bit field neighbors in destination structure
+	 * pointed by data16.
+	 */
 	data16[0] =
-	    mpr_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_DATA_MASK;
+	    le16toh(mpr_regread(sc, MPI2_DOORBELL_OFFSET)) & MPI2_DOORBELL_DATA_MASK;
 	mpr_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0);
 	if (mpr_wait_db_int(sc) != 0) {
 		mpr_dprint(sc, MPR_FAULT, "Timeout reading doorbell 1\n");
 		return (ENXIO);
 	}
 	data16[1] =
-	    mpr_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_DATA_MASK;
+	    le16toh(mpr_regread(sc, MPI2_DOORBELL_OFFSET)) & MPI2_DOORBELL_DATA_MASK;
 	mpr_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0);
 
 	/* Number of 32bit words in the message */
@@ -1088,7 +1095,7 @@ mpr_request_sync(struct mpr_softc *sc, void *req, MPI2_DEFAULT_REPLY *reply,
 			    "Timeout reading doorbell %d\n", i);
 			return (ENXIO);
 		}
-		data16[i] = mpr_regread(sc, MPI2_DOORBELL_OFFSET) &
+		data16[i] = le16toh(mpr_regread(sc, MPI2_DOORBELL_OFFSET)) &
 		    MPI2_DOORBELL_DATA_MASK;
 		mpr_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0);
 	}
@@ -1143,9 +1150,8 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
 		mpr_regwrite(sc, MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET,
 		    rd.u.low);
 	} else {
-		rd.u.low = cm->cm_desc.Words.Low;
-		rd.u.high = cm->cm_desc.Words.High;
-		rd.word = htole64(rd.word);
+		rd.u.low = htole32(cm->cm_desc.Words.Low);
+		rd.u.high = htole32(cm->cm_desc.Words.High);
 		mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET,
 		    rd.u.low);
 		mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET,
@@ -1153,6 +1159,36 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
 	}
 }
 
+/*
+ * Ioc facts are read in 16 bit words and and stored with le16toh,
+ * this takes care of proper U8 fields endianness in
+ * MPI2_IOC_FACTS_REPLY, but we still need to swap back U16 fields.
+ */
+static void
+adjust_iocfacts_endianness(MPI2_IOC_FACTS_REPLY *facts)
+{
+	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->IOCMaxChainSegmentSize = le16toh(facts->IOCMaxChainSegmentSize);
+	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);
+}
+
 /*
  * Just the FACTS, ma'am.
  */
@@ -1174,6 +1210,9 @@ mpr_get_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 	request.Function = MPI2_FUNCTION_IOC_FACTS;
 	error = mpr_request_sync(sc, &request, reply, req_sz, reply_sz, 5);
 
+	adjust_iocfacts_endianness(facts);
+	mpr_dprint(sc, MPR_TRACE, "facts->IOCCapabilities 0x%x\n", facts->IOCCapabilities);
+
 	mpr_dprint(sc, MPR_INIT, "%s exit, error= %d\n", __func__, error);
 	return (error);
 }
@@ -1232,10 +1271,10 @@ mpr_send_iocinit(struct mpr_softc *sc)
 	init.HostPageSize = HOST_PAGE_SIZE_4K;
 
 	error = mpr_request_sync(sc, &init, &reply, req_sz, reply_sz, 5);
-	if ((reply.IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
+	if ((le16toh(reply.IOCStatus) & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
 		error = ENXIO;
 
-	mpr_dprint(sc, MPR_INIT, "IOCInit status= 0x%x\n", reply.IOCStatus);
+	mpr_dprint(sc, MPR_INIT, "IOCInit status= 0x%x\n", le16toh(reply.IOCStatus));
 	mpr_dprint(sc, MPR_INIT, "%s exit\n", __func__);
 	return (error);
 }
@@ -1568,7 +1607,7 @@ mpr_alloc_requests(struct mpr_softc *sc)
 		cm->cm_req_busaddr = sc->req_busaddr + i * sc->reqframesz;
 		cm->cm_sense = &sc->sense_frames[i];
 		cm->cm_sense_busaddr = sc->sense_busaddr + i * MPR_SENSE_LEN;
-		cm->cm_desc.Default.SMID = i;
+		cm->cm_desc.Default.SMID = htole16(i);
 		cm->cm_sc = sc;
 		cm->cm_state = MPR_CM_STATE_BUSY;
 		TAILQ_INIT(&cm->cm_chain_list);
@@ -1691,7 +1730,7 @@ mpr_init_queues(struct mpr_softc *sc)
 	 * Initialize all of the free queue entries.
 	 */
 	for (i = 0; i < sc->fqdepth; i++) {
-		sc->free_queue[i] = sc->reply_busaddr + (i * sc->replyframesz);
+		sc->free_queue[i] = htole32(sc->reply_busaddr + (i * sc->replyframesz));
 	}
 	sc->replyfreeindex = sc->num_replies;
 
@@ -2756,7 +2795,8 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle,
 		bcopy(fullmask, (uint8_t *)&evtreq->EventMasks, 16);
 	}
 #else
-		bcopy(sc->event_mask, (uint8_t *)&evtreq->EventMasks, 16);
+	for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
+		evtreq->EventMasks[i] = htole32(sc->event_mask[i]);
 #endif
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
@@ -2810,7 +2850,8 @@ mpr_reregister_events(struct mpr_softc *sc)
 		bcopy(fullmask, (uint8_t *)&evtreq->EventMasks, 16);
 	}
 #else
-		bcopy(sc->event_mask, (uint8_t *)&evtreq->EventMasks, 16);
+	for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
+		evtreq->EventMasks[i] = htole32(sc->event_mask[i]);
 #endif
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
@@ -3483,8 +3524,6 @@ mpr_push_sge(struct mpr_command *cm, MPI2_SGE_SIMPLE64 *sge, size_t len,
 		/* Endian Safe code */
 		sge_flags = sge->FlagsLength;
 		sge->FlagsLength = htole32(sge_flags);
-		sge->Address.High = htole32(sge->Address.High);	
-		sge->Address.Low = htole32(sge->Address.Low);
 		bcopy(sge, cm->cm_sge, len);
 		cm->cm_sge = (MPI2_SGE_IO_UNION *)((uintptr_t)cm->cm_sge + len);
 	}
@@ -3511,8 +3550,6 @@ mpr_push_sge(struct mpr_command *cm, MPI2_SGE_SIMPLE64 *sge, size_t len,
 	/* Endian Safe code */
 	sge_flags = sge->FlagsLength;
 	sge->FlagsLength = htole32(sge_flags);
-	sge->Address.High = htole32(sge->Address.High);	
-	sge->Address.Low = htole32(sge->Address.Low);
 	bcopy(sge, cm->cm_sge, len);
 	cm->cm_sge = (MPI2_SGE_IO_UNION *)((uintptr_t)cm->cm_sge + len);
 	return (0);
@@ -3571,8 +3608,6 @@ mpr_push_ieee_sge(struct mpr_command *cm, void *sgep, int segsleft)
 			/* Endian Safe code */
 			sge_length = sge->Length;
 			sge->Length = htole32(sge_length);
-			sge->Address.High = htole32(sge->Address.High);	
-			sge->Address.Low = htole32(sge->Address.Low);
 			bcopy(sgep, cm->cm_sge, ieee_sge_size);
 			cm->cm_sge =
 			    (MPI25_SGE_IO_UNION *)((uintptr_t)cm->cm_sge +
@@ -3590,8 +3625,6 @@ mpr_push_ieee_sge(struct mpr_command *cm, void *sgep, int segsleft)
 	/* Endian Safe code */
 	sge_length = sge->Length;
 	sge->Length = htole32(sge_length);
-	sge->Address.High = htole32(sge->Address.High);	
-	sge->Address.Low = htole32(sge->Address.Low);
 	bcopy(sgep, cm->cm_sge, ieee_sge_size);
 	cm->cm_sge = (MPI25_SGE_IO_UNION *)((uintptr_t)cm->cm_sge +
 	    ieee_sge_size);
diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c
index 80c8a189b433..96b6031a534b 100644
--- a/sys/dev/mpr/mpr_config.c
+++ b/sys/dev/mpr/mpr_config.c
@@ -142,7 +142,7 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->Header.PageNumber = 8;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->Header.PageLength = mpi_reply->Header.PageLength;
-	cm->cm_length =  le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -274,7 +274,7 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->Header.PageNumber = 8;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->Header.PageLength = mpi_reply->Header.PageLength;
-	cm->cm_length =  le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -406,7 +406,7 @@ mpr_config_get_man_pg11(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->Header.PageNumber = 11;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->Header.PageLength = mpi_reply->Header.PageLength;
-	cm->cm_length =  le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -602,7 +602,7 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->PageAddress = sc->max_dpm_entries <<
 	    MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
 	request->ExtPageLength = mpi_reply->ExtPageLength;
-	cm->cm_length =  le16toh(request->ExtPageLength) * 4;
+	cm->cm_length = le16toh(request->ExtPageLength) * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -1282,7 +1282,7 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->Header.PageNumber = 3;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->Header.PageLength = mpi_reply->Header.PageLength;
-	cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -1414,7 +1414,7 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
 	request->Header.PageLength = mpi_reply->Header.PageLength;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->PageAddress = page_address;
-	cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -1546,7 +1546,7 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
 	request->Header.PageLength = mpi_reply->Header.PageLength;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->PageAddress = htole32(form | handle);
-	cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
@@ -1704,7 +1704,7 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 	request->Header.PageLength = mpi_reply->Header.PageLength;
 	request->Header.PageVersion = mpi_reply->Header.PageVersion;
 	request->PageAddress = page_address;
-	cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
+	cm->cm_length = mpi_reply->Header.PageLength * 4;
 	cm->cm_sge = &request->PageBufferSGE;
 	cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 	cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
diff --git a/sys/dev/mpr/mpr_mapping.c b/sys/dev/mpr/mpr_mapping.c
index 47d82063c128..9af67b6250f3 100644
--- a/sys/dev/mpr/mpr_mapping.c
+++ b/sys/dev/mpr/mpr_mapping.c
@@ -2572,7 +2572,7 @@ mpr_mapping_initialize(struct mpr_softc *sc)
 	sc->pending_map_events = 0;
 	sc->num_enc_table_entries = 0;
 	sc->num_rsvd_entries = 0;
-	sc->max_dpm_entries = sc->ioc_pg8.MaxPersistentEntries;
+	sc->max_dpm_entries = le16toh(sc->ioc_pg8.MaxPersistentEntries);
 	sc->is_dpm_enable = (sc->max_dpm_entries) ? 1 : 0;
 	sc->track_mapping_events = 0;
 
@@ -2586,7 +2586,7 @@ mpr_mapping_initialize(struct mpr_softc *sc)
 	if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
 		sc->num_rsvd_entries = 1;
 
-	volume_mapping_flags = sc->ioc_pg8.IRVolumeMappingFlags &
+	volume_mapping_flags = le16toh(sc->ioc_pg8.IRVolumeMappingFlags) &
 	    MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
 	if (sc->ir_firmware && (volume_mapping_flags ==
 	    MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING))
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index d3147a7e3f4d..2fb20ebcd9d7 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -2130,7 +2130,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
 		}
 
 		if ((lun != NULL) && (lun->eedp_formatted)) {
-			req->EEDPBlockSize = htole16(lun->eedp_block_size);
+			req->EEDPBlockSize = htole32(lun->eedp_block_size);
 			eedp_flags |= (MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
 			    MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
 			    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD);
@@ -2501,10 +2501,6 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
 	target_id_t target_id;
 
 	MPR_FUNCTRACE(sc);
-	mpr_dprint(sc, MPR_TRACE,
-	    "cm %p SMID %u ccb %p reply %p outstanding %u\n", cm,
-	    cm->cm_desc.Default.SMID, cm->cm_ccb, cm->cm_reply,
-	    cm->cm_targ->outstanding);
 
 	callout_stop(&cm->cm_callout);
 	mtx_assert(&sc->mpr_mtx, MA_OWNED);
@@ -2514,6 +2510,12 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
 	csio = &ccb->csio;
 	target_id = csio->ccb_h.target_id;
 	rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply;
+	mpr_dprint(sc, MPR_TRACE,
+	    "cm %p SMID %u ccb %p reply %p outstanding %u csio->scsi_status 0x%x,"
+	    "csio->dxfer_len 0x%x, csio->msg_le 0x%xn\n", cm,
+	    cm->cm_desc.Default.SMID, cm->cm_ccb, cm->cm_reply,
+	    cm->cm_targ->outstanding, csio->scsi_status,
+	    csio->dxfer_len, csio->msg_len);
 	/*
 	 * XXX KDM if the chain allocation fails, does it matter if we do
 	 * the sync and unload here?  It is simpler to do it in every case,
@@ -3892,7 +3894,7 @@ mprsas_portenable_complete(struct mpr_softc *sc, struct mpr_command *cm)
 	reply = (MPI2_PORT_ENABLE_REPLY *)cm->cm_reply;
 	if (reply == NULL)
 		mpr_dprint(sc, MPR_FAULT, "Portenable NULL reply\n");
-	else if (le16toh(reply->IOCStatus & MPI2_IOCSTATUS_MASK) !=
+	else if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
 	    MPI2_IOCSTATUS_SUCCESS)
 		mpr_dprint(sc, MPR_FAULT, "Portenable failed\n");
 
diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c
index 5e7da7d2e096..7bb72509e67e 100644
--- a/sys/dev/mpr/mpr_sas_lsi.c
+++ b/sys/dev/mpr/mpr_sas_lsi.c
@@ -160,11 +160,11 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
 	}
 
 	bcopy(event->EventData, fw_event->event_data, sz);
-	fw_event->event = event->Event;
-	if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
-	    event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
-	    event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE ||
-	    event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
+	fw_event->event = le16toh(event->Event);
+	if ((fw_event->event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
+	    fw_event->event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
+	    fw_event->event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE ||
+	    fw_event->event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
 	    sc->track_mapping_events)
 		sc->pending_map_events++;
 
@@ -173,9 +173,9 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
 	 * are processed. Increment the startup_refcount and decrement it after
 	 * events are processed.
 	 */
-	if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
-	    event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
-	    event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
+	if ((fw_event->event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
+	    fw_event->event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
+	    fw_event->event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
 	    sc->wait_for_port_enable)
 		mprsas_startup_increment(sc->sassc);
 
@@ -868,9 +868,8 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
 			parent_devinfo = le32toh(parent_config_page.DeviceInfo);
 		}
 	}
-	/* TODO Check proper endianness */
-	sas_address = config_page.SASAddress.High;
-	sas_address = (sas_address << 32) | config_page.SASAddress.Low;
+	sas_address = htole32(config_page.SASAddress.High);
+	sas_address = (sas_address << 32) | htole32(config_page.SASAddress.Low);
 	mpr_dprint(sc, MPR_MAPPING, "Handle 0x%04x SAS Address from SAS device "
 	    "page0 = %jx\n", handle, sas_address);
 
diff --git a/sys/dev/mpr/mpr_table.c b/sys/dev/mpr/mpr_table.c
index a1bddf1a3065..79088fe8204e 100644
--- a/sys/dev/mpr/mpr_table.c
+++ b/sys/dev/mpr/mpr_table.c
@@ -316,7 +316,7 @@ mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 	MPR_PRINTFIELD_START(sc, "PortFacts");
 	MPR_PRINTFIELD(sc, facts, PortNumber, %d);
 	MPR_PRINTFIELD(sc, facts, PortType, 0x%x);
-	MPR_PRINTFIELD(sc, facts, MaxPostedCmdBuffers, %d);
+	MPR_PRINTFIELD_16(sc, facts, MaxPostedCmdBuffers, %d);
 }
 
 void
@@ -324,33 +324,33 @@ mpr_print_evt_generic(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event
 {
 
 	MPR_PRINTFIELD_START(sc, "EventReply");
-	MPR_PRINTFIELD(sc, event, EventDataLength, %d);
+	MPR_PRINTFIELD_16(sc, event, EventDataLength, %d);
 	MPR_PRINTFIELD(sc, event, AckRequired, %d);
 	mpr_print_field(sc, "Event: %s (0x%x)\n",
-	    mpr_describe_table(mpr_event_names, event->Event), event->Event);
-	MPR_PRINTFIELD(sc, event, EventContext, 0x%x);
+	    mpr_describe_table(mpr_event_names, le16toh(event->Event)), le16toh(event->Event));
+	MPR_PRINTFIELD_32(sc, event, EventContext, 0x%x);
 }
 
 void
 mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS Device Page 0");
-	MPR_PRINTFIELD(sc, buf, Slot, %d);
-	MPR_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
+	MPR_PRINTFIELD_16(sc, buf, Slot, %d);
+	MPR_PRINTFIELD_16(sc, buf, EnclosureHandle, 0x%x);
 	mpr_print_field(sc, "SASAddress: 0x%jx\n",
 	    mpr_to_u64(&buf->SASAddress));
-	MPR_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
+	MPR_PRINTFIELD_16(sc, buf, ParentDevHandle, 0x%x);
 	MPR_PRINTFIELD(sc, buf, PhyNum, %d);
 	MPR_PRINTFIELD(sc, buf, AccessStatus, 0x%x);
-	MPR_PRINTFIELD(sc, buf, DevHandle, 0x%x);
+	MPR_PRINTFIELD_16(sc, buf, DevHandle, 0x%x);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
-	mpr_print_field(sc, "DeviceInfo: %b,%s\n", buf->DeviceInfo,
+	mpr_print_field(sc, "DeviceInfo: %b,%s\n", le32toh(buf->DeviceInfo),
 	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
 	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
 	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
 	    mpr_describe_table(mpr_sasdev0_devtype, buf->DeviceInfo & 0x03));
-	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
+	MPR_PRINTFIELD_16(sc, buf, Flags, 0x%x);
 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPR_PRINTFIELD(sc, buf, MaxPortConnections, %d);
 	mpr_print_field(sc, "DeviceName: 0x%jx\n",
@@ -366,7 +366,7 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 	mpr_print_evt_generic(sc, event);
 
-	switch(event->Event) {
+	switch(le16toh(event->Event)) {
 	case MPI2_EVENT_SAS_DISCOVERY:
 	{
 		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
@@ -378,7 +378,7 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 		    mpr_describe_table(mpr_sasdisc_reason, data->ReasonCode));
 		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
 		mpr_print_field(sc, "DiscoveryStatus: %b\n",
-		    data->DiscoveryStatus,  "\20"
+		    le32toh(data->DiscoveryStatus),  "\20"
 		    "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
 		    "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
 		    "\11SmpCrcError" "\12SubSubLink" "\13TableTableLink"
@@ -397,8 +397,8 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
 		    &event->EventData;
-		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
-		MPR_PRINTFIELD(sc, data, ExpanderDevHandle, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, EnclosureHandle, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, ExpanderDevHandle, 0x%x);
 		MPR_PRINTFIELD(sc, data, NumPhys, %d);
 		MPR_PRINTFIELD(sc, data, NumEntries, %d);
 		MPR_PRINTFIELD(sc, data, StartPhyNum, %d);
@@ -411,7 +411,7 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 			phynum = data->StartPhyNum + i;
 			mpr_print_field(sc,
 			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
-			    phy->AttachedDevHandle);
+			    le16toh(phy->AttachedDevHandle));
 			mpr_print_field(sc,
 			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
 			    mpr_describe_table(mpr_linkrate_names,
@@ -428,13 +428,13 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
 		    &event->EventData;
-		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, EnclosureHandle, 0x%x);
 		mpr_print_field(sc, "ReasonCode: %s\n",
 		    mpr_describe_table(mpr_sastopo_exp, data->ReasonCode));
 		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
-		MPR_PRINTFIELD(sc, data, NumSlots, %d);
-		MPR_PRINTFIELD(sc, data, StartSlot, %d);
-		MPR_PRINTFIELD(sc, data, PhyBits, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, NumSlots, %d);
+		MPR_PRINTFIELD_16(sc, data, StartSlot, %d);
+		MPR_PRINTFIELD_32(sc, data, PhyBits, 0x%x);
 		break;
 	}
 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
@@ -443,12 +443,12 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 
 		data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
 		    &event->EventData;
-		MPR_PRINTFIELD(sc, data, TaskTag, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, TaskTag, 0x%x);
 		mpr_print_field(sc, "ReasonCode: %s\n",
 		    mpr_describe_table(mpr_sasdev_reason, data->ReasonCode));
 		MPR_PRINTFIELD(sc, data, ASC, 0x%x);
 		MPR_PRINTFIELD(sc, data, ASCQ, 0x%x);
-		MPR_PRINTFIELD(sc, data, DevHandle, 0x%x);
+		MPR_PRINTFIELD_16(sc, data, DevHandle, 0x%x);
 		mpr_print_field(sc, "SASAddress: 0x%jx\n",
 		    mpr_to_u64(&data->SASAddress));
 		break;
@@ -476,24 +476,24 @@ mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
 	MPR_PRINTFIELD(sc, buf, NumPhys, %d);
 	MPR_PRINTFIELD(sc, buf, Phy, %d);
-	MPR_PRINTFIELD(sc, buf, NumTableEntriesProgrammed, %d);
+	MPR_PRINTFIELD_16(sc, buf, NumTableEntriesProgrammed, %d);
 	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
 	mpr_print_field(sc, "HwLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
-	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
+	MPR_PRINTFIELD_16(sc, buf, AttachedDevHandle, 0x%04x);
 	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
-	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
+	    (le32toh(buf->PhyInfo) >> 16) & 0xf), le32toh(buf->PhyInfo));
 	mpr_print_field(sc, "AttachedDeviceInfo: %b,%s\n",
-	    buf->AttachedDeviceInfo, "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
+	    le32toh(buf->AttachedDeviceInfo), "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
 	    "\7SSPinit" "\10SATAdev" "\11SMPtarg" "\12STPtarg" "\13SSPtarg"
 	    "\14Direct" "\15LSIdev" "\16ATAPIdev" "\17SEPdev",
 	    mpr_describe_table(mpr_sasdev0_devtype,
-	    buf->AttachedDeviceInfo & 0x03));
-	MPR_PRINTFIELD(sc, buf, ExpanderDevHandle, 0x%04x);
+	    le32toh(buf->AttachedDeviceInfo) & 0x03));
+	MPR_PRINTFIELD_16(sc, buf, ExpanderDevHandle, 0x%04x);
 	MPR_PRINTFIELD(sc, buf, ChangeCount, %d);
 	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
@@ -501,10 +501,10 @@ mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 	MPR_PRINTFIELD(sc, buf, PhyIdentifier, %d);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
 	MPR_PRINTFIELD(sc, buf, DiscoveryInfo, 0x%x);
-	MPR_PRINTFIELD(sc, buf, AttachedPhyInfo, 0x%x);
+	MPR_PRINTFIELD_32(sc, buf, AttachedPhyInfo, 0x%x);
 	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
-	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
+	    le32toh(buf->AttachedPhyInfo) & 0xf), le32toh(buf->AttachedPhyInfo));
 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
 	MPR_PRINTFIELD(sc, buf, SelfConfigStatus, 0x%x);
 }
@@ -513,12 +513,12 @@ void
 mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS PHY Page 0");
-	MPR_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
-	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
+	MPR_PRINTFIELD_16(sc, buf, OwnerDevHandle, 0x%04x);
+	MPR_PRINTFIELD_16(sc, buf, AttachedDevHandle, 0x%04x);
 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
 	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
-	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
+	    le32toh(buf->AttachedPhyInfo) & 0xf), le32toh(buf->AttachedPhyInfo));
 	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
@@ -529,7 +529,7 @@ mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
 	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
 	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
 	    mpr_describe_table(mpr_phyinfo_reason_names,
-	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
+	    (le32toh(buf->PhyInfo) >> 16) & 0xf), le32toh(buf->PhyInfo));
 	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
 	    mpr_describe_table(mpr_linkrate_names,
 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h
index 08216ff54d1d..f8e479b2fbc8 100644
--- a/sys/dev/mpr/mprvar.h
+++ b/sys/dev/mpr/mprvar.h
@@ -760,6 +760,10 @@ do {							\
 	mpr_printf((sc), tag "\n")
 #define MPR_PRINTFIELD(sc, facts, attr, fmt)	\
 	mpr_print_field((sc), #attr ": " #fmt "\n", (facts)->attr)
+#define MPR_PRINTFIELD_16(sc, facts, attr, fmt)	\
+	mpr_print_field((sc), #attr ": " #fmt "\n", le16toh((facts)->attr))
+#define MPR_PRINTFIELD_32(sc, facts, attr, fmt)	\
+	mpr_print_field((sc), #attr ": " #fmt "\n", le32toh((facts)->attr))
 
 static __inline void
 mpr_from_u64(uint64_t data, U64 *mpr)