freebsd-dev/sys/dev/aacraid/aacraid_endian.c
Leandro Lupori d8c51c6f74 [aacraid] Port driver to big-endian
Port aacraid driver to big-endian (BE) hosts.

The immediate goal of this change is to make it possible to use the
aacraid driver on PowerPC64 machines that have Adaptec Series 8 SAS
controllers.

Adapters supported by this driver expect FIB contents in little-endian
(LE) byte order. All FIBs have a fixed header part as well as a data
part that depends on the command being issued to the controller.

In this way, on BE hosts, the FIB header and all FIB data structures
used in aacraid.c and aacraid_cam.c need to be converted to LE before
being sent to the adapter and converted to BE when coming from it.

The functions to convert each struct are on aacraid_endian.c.
For little-endian (LE) targets, they are macros that expand
to nothing.
In some cases, when only a few fields of a large structure are used,
the fields are converted inline, by the code using them.

PR:		237463
Reviewed by:	jhibbits
Sponsored by:	Eldorado Research Institute (eldorado.org.br)
Differential Revision:	https://reviews.freebsd.org/D23887
2020-03-05 20:04:41 +00:00

390 lines
8.5 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2019 Leandro Lupori
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
#include <dev/aacraid/aacraid_reg.h>
#include <dev/aacraid/aacraid_endian.h>
#if _BYTE_ORDER != _LITTLE_ENDIAN
#define TOH2(field, bits) field = le##bits##toh(field)
#define TOH(field, bits) TOH2(field, bits)
#define TOLE2(field, bits) field = htole##bits(field)
#define TOLE(field, bits) TOLE2(field, bits)
/* Convert from Little-Endian to host order (TOH) */
void
aac_fib_header_toh(struct aac_fib_header *ptr)
{
TOH(ptr->XferState, 32);
TOH(ptr->Command, 16);
TOH(ptr->Size, 16);
TOH(ptr->SenderSize, 16);
TOH(ptr->SenderFibAddress, 32);
TOH(ptr->u.ReceiverFibAddress, 32);
TOH(ptr->Handle, 32);
TOH(ptr->Previous, 32);
TOH(ptr->Next, 32);
}
void
aac_adapter_info_toh(struct aac_adapter_info *ptr)
{
TOH(ptr->PlatformBase, 32);
TOH(ptr->CpuArchitecture, 32);
TOH(ptr->CpuVariant, 32);
TOH(ptr->ClockSpeed, 32);
TOH(ptr->ExecutionMem, 32);
TOH(ptr->BufferMem, 32);
TOH(ptr->TotalMem, 32);
TOH(ptr->KernelRevision.buildNumber, 32);
TOH(ptr->MonitorRevision.buildNumber, 32);
TOH(ptr->HardwareRevision.buildNumber, 32);
TOH(ptr->BIOSRevision.buildNumber, 32);
TOH(ptr->ClusteringEnabled, 32);
TOH(ptr->ClusterChannelMask, 32);
TOH(ptr->SerialNumber, 64);
TOH(ptr->batteryPlatform, 32);
TOH(ptr->SupportedOptions, 32);
TOH(ptr->OemVariant, 32);
}
void
aac_container_creation_toh(struct aac_container_creation *ptr)
{
u_int32_t *date = (u_int32_t *)ptr + 1;
*date = le32toh(*date);
TOH(ptr->ViaAdapterSerialNumber, 64);
}
void
aac_mntobj_toh(struct aac_mntobj *ptr)
{
TOH(ptr->ObjectId, 32);
aac_container_creation_toh(&ptr->CreateInfo);
TOH(ptr->Capacity, 32);
TOH(ptr->VolType, 32);
TOH(ptr->ObjType, 32);
TOH(ptr->ContentState, 32);
TOH(ptr->ObjExtension.BlockDevice.BlockSize, 32);
TOH(ptr->ObjExtension.BlockDevice.bdLgclPhysMap, 32);
TOH(ptr->AlterEgoId, 32);
TOH(ptr->CapacityHigh, 32);
}
void
aac_mntinforesp_toh(struct aac_mntinforesp *ptr)
{
TOH(ptr->Status, 32);
TOH(ptr->MntType, 32);
TOH(ptr->MntRespCount, 32);
aac_mntobj_toh(&ptr->MntTable[0]);
}
void
aac_fsa_ctm_toh(struct aac_fsa_ctm *ptr)
{
int i;
TOH(ptr->command, 32);
for (i = 0; i < CT_FIB_PARAMS; i++)
TOH(ptr->param[i], 32);
}
void
aac_cnt_config_toh(struct aac_cnt_config *ptr)
{
TOH(ptr->Command, 32);
aac_fsa_ctm_toh(&ptr->CTCommand);
}
void
aac_ctcfg_resp_toh(struct aac_ctcfg_resp *ptr)
{
TOH(ptr->Status, 32);
TOH(ptr->resp, 32);
TOH(ptr->param, 32);
}
void
aac_getbusinf_toh(struct aac_getbusinf *ptr)
{
TOH(ptr->ProbeComplete, 32);
TOH(ptr->BusCount, 32);
TOH(ptr->TargetsPerBus, 32);
}
void
aac_vmi_businf_resp_toh(struct aac_vmi_businf_resp *ptr)
{
TOH(ptr->Status, 32);
TOH(ptr->ObjType, 32);
TOH(ptr->MethId, 32);
TOH(ptr->ObjId, 32);
TOH(ptr->IoctlCmd, 32);
aac_getbusinf_toh(&ptr->BusInf);
}
void
aac_srb_response_toh(struct aac_srb_response *ptr)
{
TOH(ptr->fib_status, 32);
TOH(ptr->srb_status, 32);
TOH(ptr->scsi_status, 32);
TOH(ptr->data_len, 32);
TOH(ptr->sense_len, 32);
}
/* Convert from host order to Little-Endian (TOLE) */
void
aac_adapter_init_tole(struct aac_adapter_init *ptr)
{
TOLE(ptr->InitStructRevision, 32);
TOLE(ptr->NoOfMSIXVectors, 32);
TOLE(ptr->FilesystemRevision, 32);
TOLE(ptr->CommHeaderAddress, 32);
TOLE(ptr->FastIoCommAreaAddress, 32);
TOLE(ptr->AdapterFibsPhysicalAddress, 32);
TOLE(ptr->AdapterFibsVirtualAddress, 32);
TOLE(ptr->AdapterFibsSize, 32);
TOLE(ptr->AdapterFibAlign, 32);
TOLE(ptr->PrintfBufferAddress, 32);
TOLE(ptr->PrintfBufferSize, 32);
TOLE(ptr->HostPhysMemPages, 32);
TOLE(ptr->HostElapsedSeconds, 32);
TOLE(ptr->InitFlags, 32);
TOLE(ptr->MaxIoCommands, 32);
TOLE(ptr->MaxIoSize, 32);
TOLE(ptr->MaxFibSize, 32);
TOLE(ptr->MaxNumAif, 32);
TOLE(ptr->HostRRQ_AddrLow, 32);
TOLE(ptr->HostRRQ_AddrHigh, 32);
}
void
aac_fib_header_tole(struct aac_fib_header *ptr)
{
TOLE(ptr->XferState, 32);
TOLE(ptr->Command, 16);
TOLE(ptr->Size, 16);
TOLE(ptr->SenderSize, 16);
TOLE(ptr->SenderFibAddress, 32);
TOLE(ptr->u.ReceiverFibAddress, 32);
TOLE(ptr->Handle, 32);
TOLE(ptr->Previous, 32);
TOLE(ptr->Next, 32);
}
void
aac_mntinfo_tole(struct aac_mntinfo *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->MntType, 32);
TOLE(ptr->MntCount, 32);
}
void
aac_fsa_ctm_tole(struct aac_fsa_ctm *ptr)
{
int i;
TOLE(ptr->command, 32);
for (i = 0; i < CT_FIB_PARAMS; i++)
TOLE(ptr->param[i], 32);
}
void
aac_cnt_config_tole(struct aac_cnt_config *ptr)
{
TOLE(ptr->Command, 32);
aac_fsa_ctm_tole(&ptr->CTCommand);
}
void
aac_raw_io_tole(struct aac_raw_io *ptr)
{
TOLE(ptr->BlockNumber, 64);
TOLE(ptr->ByteCount, 32);
TOLE(ptr->ContainerId, 16);
TOLE(ptr->Flags, 16);
TOLE(ptr->BpTotal, 16);
TOLE(ptr->BpComplete, 16);
}
void
aac_raw_io2_tole(struct aac_raw_io2 *ptr)
{
TOLE(ptr->strtBlkLow, 32);
TOLE(ptr->strtBlkHigh, 32);
TOLE(ptr->byteCnt, 32);
TOLE(ptr->ldNum, 16);
TOLE(ptr->flags, 16);
TOLE(ptr->sgeFirstSize, 32);
TOLE(ptr->sgeNominalSize, 32);
}
void
aac_fib_xporthdr_tole(struct aac_fib_xporthdr *ptr)
{
TOLE(ptr->HostAddress, 64);
TOLE(ptr->Size, 32);
TOLE(ptr->Handle, 32);
}
void
aac_ctcfg_tole(struct aac_ctcfg *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->cmd, 32);
TOLE(ptr->param, 32);
}
void
aac_vmioctl_tole(struct aac_vmioctl *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->ObjType, 32);
TOLE(ptr->MethId, 32);
TOLE(ptr->ObjId, 32);
TOLE(ptr->IoctlCmd, 32);
TOLE(ptr->IoctlBuf[0], 32);
}
void
aac_pause_command_tole(struct aac_pause_command *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->Type, 32);
TOLE(ptr->Timeout, 32);
TOLE(ptr->Min, 32);
TOLE(ptr->NoRescan, 32);
TOLE(ptr->Parm3, 32);
TOLE(ptr->Parm4, 32);
TOLE(ptr->Count, 32);
}
void
aac_srb_tole(struct aac_srb *ptr)
{
TOLE(ptr->function, 32);
TOLE(ptr->bus, 32);
TOLE(ptr->target, 32);
TOLE(ptr->lun, 32);
TOLE(ptr->timeout, 32);
TOLE(ptr->flags, 32);
TOLE(ptr->data_len, 32);
TOLE(ptr->retry_limit, 32);
TOLE(ptr->cdb_len, 32);
}
void
aac_sge_ieee1212_tole(struct aac_sge_ieee1212 *ptr)
{
TOLE(ptr->addrLow, 32);
TOLE(ptr->addrHigh, 32);
TOLE(ptr->length, 32);
TOLE(ptr->flags, 32);
}
void
aac_sg_entryraw_tole(struct aac_sg_entryraw *ptr)
{
TOLE(ptr->Next, 32);
TOLE(ptr->Prev, 32);
TOLE(ptr->SgAddress, 64);
TOLE(ptr->SgByteCount, 32);
TOLE(ptr->Flags, 32);
}
void
aac_sg_entry_tole(struct aac_sg_entry *ptr)
{
TOLE(ptr->SgAddress, 32);
TOLE(ptr->SgByteCount, 32);
}
void
aac_sg_entry64_tole(struct aac_sg_entry64 *ptr)
{
TOLE(ptr->SgAddress, 64);
TOLE(ptr->SgByteCount, 32);
}
void
aac_blockread_tole(struct aac_blockread *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->ContainerId, 32);
TOLE(ptr->BlockNumber, 32);
TOLE(ptr->ByteCount, 32);
}
void
aac_blockwrite_tole(struct aac_blockwrite *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->ContainerId, 32);
TOLE(ptr->BlockNumber, 32);
TOLE(ptr->ByteCount, 32);
TOLE(ptr->Stable, 32);
}
void
aac_blockread64_tole(struct aac_blockread64 *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->ContainerId, 16);
TOLE(ptr->SectorCount, 16);
TOLE(ptr->BlockNumber, 32);
TOLE(ptr->Pad, 16);
TOLE(ptr->Flags, 16);
}
void
aac_blockwrite64_tole(struct aac_blockwrite64 *ptr)
{
TOLE(ptr->Command, 32);
TOLE(ptr->ContainerId, 16);
TOLE(ptr->SectorCount, 16);
TOLE(ptr->BlockNumber, 32);
TOLE(ptr->Pad, 16);
TOLE(ptr->Flags, 16);
}
#endif