Index: sys/amd64/conf/NOTES =================================================================== --- sys/amd64/conf/NOTES +++ sys/amd64/conf/NOTES @@ -416,10 +416,6 @@ device aac device aacp # SCSI Passthrough interface (optional, CAM required) -# -# Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families -device aacraid # Container interface, CAM required - # # Highpoint RocketRAID 27xx. device hpt27xx Index: sys/conf/NOTES =================================================================== --- sys/conf/NOTES +++ sys/conf/NOTES @@ -1490,6 +1490,8 @@ # # SCSI host adapters: # +# aacraid: Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming +# families. Container interface, CAM required. # ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/ # 19160x/29160x, aic7770/aic78xx # ahd: Adaptec 29320/39320 Controllers. @@ -1512,6 +1514,7 @@ # 53C876, 53C885, 53C895, 53C895A, 53C896, 53C897, 53C1510D, # 53C1010-33, 53C1010-66. +device aacraid device ahc device ahd device esp Index: sys/conf/files.powerpc =================================================================== --- sys/conf/files.powerpc +++ sys/conf/files.powerpc @@ -16,6 +16,7 @@ cddl/dev/fbt/powerpc/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb +dev/aacraid/aacraid_endian.c optional aacraid dev/adb/adb_bus.c optional adb dev/adb/adb_kbd.c optional adb dev/adb/adb_mouse.c optional adb Index: sys/dev/aacraid/aacraid.c =================================================================== --- sys/dev/aacraid/aacraid.c +++ sys/dev/aacraid/aacraid.c @@ -69,6 +69,7 @@ #include #include #include +#include #ifndef FILTER_HANDLED #define FILTER_HANDLED 0x02 @@ -386,7 +387,7 @@ AAC_FIBSTATE_ASYNC | AAC_FIBSTATE_FAST_RESPONSE; fib->Header.Command = SendHostTime; - *(uint32_t *)fib->data = tv.tv_sec; + *(uint32_t *)fib->data = htole32(tv.tv_sec); aacraid_map_command_sg(cm, NULL, 0, 0); aacraid_release_command(cm); @@ -446,6 +447,7 @@ mi->Command = VM_NameServe; mi->MntType = FT_FILESYS; mi->MntCount = cid; + aac_mntinfo_tole(mi); if (sync_fib) { if (aac_sync_fib(sc, ContainerCommand, 0, fib, @@ -476,6 +478,7 @@ } } bcopy(&fib->data[0], mir, sizeof(struct aac_mntinforesp)); + aac_mntinforesp_toh(mir); /* UID */ *uid = cid; @@ -490,10 +493,12 @@ ccfg->Command = VM_ContainerConfig; ccfg->CTCommand.command = CT_CID_TO_32BITS_UID; ccfg->CTCommand.param[0] = cid; + aac_cnt_config_tole(ccfg); if (sync_fib) { rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK && mir->MntTable[0].VolType != CT_PASSTHRU) @@ -512,6 +517,7 @@ AAC_FIBSTATE_FAST_RESPONSE; fib->Header.Command = ContainerCommand; rval = aacraid_wait_command(cm); + aac_cnt_config_toh(ccfg); if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK && mir->MntTable[0].VolType != CT_PASSTHRU) @@ -804,8 +810,8 @@ cc = (struct aac_close_command *)&fib->data[0]; bzero(cc, sizeof(struct aac_close_command)); - cc->Command = VM_CloseAll; - cc->ContainerId = 0xfffffffe; + cc->Command = htole32(VM_CloseAll); + cc->ContainerId = htole32(0xfffffffe); if (aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_close_command))) printf("FAILED.\n"); @@ -905,6 +911,8 @@ cm = sc->aac_sync_cm; aac_unmap_command(cm); cm->cm_flags |= AAC_CMD_COMPLETED; + aac_fib_header_toh(&cm->cm_fib->Header); + /* is there a completion handler? */ if (cm->cm_complete != NULL) { cm->cm_complete(cm); @@ -931,7 +939,8 @@ for (;;) { isFastResponse = isAif = noMoreAif = 0; /* remove toggle bit (31) */ - handle = (sc->aac_common->ac_host_rrq[index] & 0x7fffffff); + handle = (le32toh(sc->aac_common->ac_host_rrq[index]) & + 0x7fffffff); /* check fast response bit (30) */ if (handle & 0x40000000) isFastResponse = 1; @@ -944,6 +953,7 @@ cm = sc->aac_commands + (handle - 1); fib = cm->cm_fib; + aac_fib_header_toh(&fib->Header); sc->aac_rrq_outstanding[vector_no]--; if (isAif) { noMoreAif = (fib->Header.XferState & AAC_FIBSTATE_NOMOREAIF) ? 1:0; @@ -954,7 +964,7 @@ } else { if (isFastResponse) { fib->Header.XferState |= AAC_FIBSTATE_DONEADAP; - *((u_int32_t *)(fib->data)) = ST_OK; + *((u_int32_t *)(fib->data)) = htole32(ST_OK); cm->cm_flags |= AAC_CMD_FASTRESP; } aac_remove_busy(cm); @@ -1342,6 +1352,10 @@ raw->flags |= RIO2_SGL_CONFORMANT; } + for (i = 0; i < nseg; i++) + aac_sge_ieee1212_tole(sg + i); + aac_raw_io2_tole(raw); + /* update the FIB size for the s/g count */ fib->Header.Size += nseg * sizeof(struct aac_sge_ieee1212); @@ -1349,33 +1363,37 @@ } else if (fib->Header.Command == RawIo) { struct aac_sg_tableraw *sg; sg = (struct aac_sg_tableraw *)cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr; sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len; sg->SgEntryRaw[i].Next = 0; sg->SgEntryRaw[i].Prev = 0; sg->SgEntryRaw[i].Flags = 0; + aac_sg_entryraw_tole(&sg->SgEntryRaw[i]); } + aac_raw_io_tole((struct aac_raw_io *)&fib->data[0]); /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw); } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { struct aac_sg_table *sg; sg = cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntry[i].SgAddress = segs[i].ds_addr; sg->SgEntry[i].SgByteCount = segs[i].ds_len; + aac_sg_entry_tole(&sg->SgEntry[i]); } /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entry); } else { struct aac_sg_table64 *sg; sg = (struct aac_sg_table64 *)cm->cm_sgtable; - sg->SgCount = nseg; + sg->SgCount = htole32(nseg); for (i = 0; i < nseg; i++) { sg->SgEntry64[i].SgAddress = segs[i].ds_addr; sg->SgEntry64[i].SgByteCount = segs[i].ds_len; + aac_sg_entry64_tole(&sg->SgEntry64[i]); } /* update the FIB size for the s/g count */ fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); @@ -1405,11 +1423,13 @@ cm->cm_flags |= AAC_CMD_MAPPED; if (cm->cm_flags & AAC_CMD_WAIT) { + aac_fib_header_tole(&fib->Header); aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, NULL, NULL); } else if (sc->flags & AAC_FLAGS_SYNC_MODE) { u_int32_t wait = 0; sc->aac_sync_cm = cm; + aac_fib_header_tole(&fib->Header); aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, &wait, NULL); } else { @@ -1788,6 +1808,8 @@ ip->MaxIoSize = sc->aac_max_sectors << 9; ip->MaxFibSize = sc->aac_max_fib_size; + aac_adapter_init_tole(ip); + /* * Do controller-type-specific initialisation */ @@ -1996,18 +2018,24 @@ ccfg->CTCommand.command = CT_GET_CONFIG_STATUS; ccfg->CTCommand.param[CNT_SIZE] = sizeof(struct aac_cf_status_hdr); + aac_cnt_config_tole(ccfg); rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); + cf_shdr = (struct aac_cf_status_hdr *)ccfg->CTCommand.data; if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK) { - if (cf_shdr->action <= CFACT_PAUSE) { + if (le32toh(cf_shdr->action) <= CFACT_PAUSE) { bzero(ccfg, sizeof (*ccfg) - CT_PACKET_SIZE); ccfg->Command = VM_ContainerConfig; ccfg->CTCommand.command = CT_COMMIT_CONFIG; + aac_cnt_config_tole(ccfg); rval = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_cnt_config)); + aac_cnt_config_toh(ccfg); + if (rval == 0 && ccfg->Command == ST_OK && ccfg->CTCommand.param[0] == CT_OK) { /* successful completion */ @@ -2087,6 +2115,8 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, struct aac_fib *fib, u_int16_t datasize) { + uint32_t ReceiverFibAddress; + fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); mtx_assert(&sc->aac_io_lock, MA_OWNED); @@ -2105,18 +2135,22 @@ fib->Header.Size = sizeof(struct aac_fib_header) + datasize; fib->Header.SenderSize = sizeof(struct aac_fib); fib->Header.SenderFibAddress = 0; /* Not needed */ - fib->Header.u.ReceiverFibAddress = sc->aac_common_busaddr + + ReceiverFibAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_sync_fib); + fib->Header.u.ReceiverFibAddress = ReceiverFibAddress; + aac_fib_header_tole(&fib->Header); /* * Give the FIB to the controller, wait for a response. */ if (aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, - fib->Header.u.ReceiverFibAddress, 0, 0, 0, NULL, NULL)) { + ReceiverFibAddress, 0, 0, 0, NULL, NULL)) { fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error"); + aac_fib_header_toh(&fib->Header); return(EIO); } + aac_fib_header_toh(&fib->Header); return (0); } @@ -2407,10 +2441,13 @@ pFibX->Handle = cm->cm_fib->Header.Handle; pFibX->HostAddress = cm->cm_fibphys; pFibX->Size = cm->cm_fib->Header.Size; + aac_fib_xporthdr_tole(pFibX); address = cm->cm_fibphys - sizeof(struct aac_fib_xporthdr); high_addr = (u_int32_t)(address >> 32); } + aac_fib_header_tole(&cm->cm_fib->Header); + if (fibsize > 31) fibsize = 31; aac_enqueue_busy(cm); @@ -2468,8 +2505,8 @@ supp_info = ((struct aac_supplement_adapter_info *)&fib->data[0]); adapter_type = (char *)supp_info->AdapterTypeText; - sc->aac_feature_bits = supp_info->FeatureBits; - sc->aac_support_opt2 = supp_info->SupportedOptions2; + sc->aac_feature_bits = le32toh(supp_info->FeatureBits); + sc->aac_support_opt2 = le32toh(supp_info->SupportedOptions2); } } device_printf(sc->aac_dev, "%s, aacraid driver %d.%d.%d-%d\n", @@ -2487,6 +2524,7 @@ /* save the kernel revision structure for later use */ info = (struct aac_adapter_info *)&fib->data[0]; + aac_adapter_info_toh(info); sc->aac_revision = info->KernelRevision; if (bootverbose) { @@ -2720,6 +2758,18 @@ /* * Send a FIB supplied from userspace + * + * Currently, sending a FIB from userspace in BE hosts is not supported. + * There are several things that need to be considered in order to + * support this, such as: + * - At least the FIB data part from userspace should already be in LE, + * or else the kernel would need to know all FIB types to be able to + * correctly convert it to BE. + * - SG tables are converted to BE by aacraid_map_command_sg(). This + * conversion should be supressed if the FIB comes from userspace. + * - aacraid_wait_command() calls functions that convert the FIB header + * to LE. But if the header is already in LE, the conversion should not + * be performed. */ static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) @@ -2961,6 +3011,8 @@ ScsiPortCommandU64 : ScsiPortCommand; cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; + aac_srb_tole(srbcmd); + /* send command */ if (transfer_data) { bus_dmamap_load(cm->cm_passthr_dmat, @@ -2978,7 +3030,7 @@ mtx_unlock(&sc->aac_io_lock); /* copy data */ - if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) { + if (transfer_data && (le32toh(srbcmd->flags) & AAC_SRB_FLAGS_DATA_IN)) { if ((error = copyout(cm->cm_data, (void *)(uintptr_t)srb_sg_address, cm->cm_datalen)) != 0) @@ -2989,6 +3041,7 @@ } /* status */ + aac_srb_response_toh((struct aac_srb_response *)fib->data); error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response)); out: @@ -3039,7 +3092,7 @@ /* set AIF marker */ fib->Header.Handle = 0x00800000; fib->Header.Command = AifRequest; - ((struct aac_aif_command *)fib->data)->command = AifReqEvent; + ((struct aac_aif_command *)fib->data)->command = htole32(AifReqEvent); aacraid_map_command_sg(cm, NULL, 0, 0); } @@ -3080,9 +3133,9 @@ aacraid_print_aif(sc, aif); /* Is it an event that we should care about? */ - switch (aif->command) { + switch (le32toh(aif->command)) { case AifCmdEventNotify: - switch (aif->data.EN.type) { + switch (le32toh(aif->data.EN.type)) { case AifEnAddContainer: case AifEnDeleteContainer: /* @@ -3174,10 +3227,10 @@ break; case AifEnEnclosureManagement: - switch (aif->data.EN.data.EEE.eventType) { + switch (le32toh(aif->data.EN.data.EEE.eventType)) { case AIF_EM_DRIVE_INSERTION: case AIF_EM_DRIVE_REMOVAL: - channel = aif->data.EN.data.EEE.unitID; + channel = le32toh(aif->data.EN.data.EEE.unitID); if (sc->cam_rescan_cb != NULL) sc->cam_rescan_cb(sc, ((channel>>24) & 0xF) + 1, @@ -3189,7 +3242,7 @@ case AifEnAddJBOD: case AifEnDeleteJBOD: case AifRawDeviceRemove: - channel = aif->data.EN.data.ECE.container; + channel = le32toh(aif->data.EN.data.ECE.container); if (sc->cam_rescan_cb != NULL) sc->cam_rescan_cb(sc, ((channel>>24) & 0xF) + 1, AAC_CAM_TARGET_WILDCARD); @@ -3209,6 +3262,8 @@ if (next == 0) sc->aifq_filled = 1; bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib)); + /* Make aifq's FIB header and data LE */ + aac_fib_header_tole(&sc->aac_aifq[current].Header); /* modify AIF contexts */ if (sc->aifq_filled) { for (ctx = sc->fibctx; ctx; ctx = ctx->next) { @@ -3602,6 +3657,7 @@ c_cmd->cmd = CT_GET_SCSI_METHOD; c_cmd->param = 0; + aac_ctcfg_tole(c_cmd); error = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_ctcfg)); if (error) { @@ -3613,6 +3669,7 @@ } c_resp = (struct aac_ctcfg_resp *)&fib->data[0]; + aac_ctcfg_resp_toh(c_resp); if (c_resp->Status != ST_OK) { device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n", c_resp->Status); @@ -3632,6 +3689,7 @@ vmi->ObjId = 0; vmi->IoctlCmd = GetBusInfo; + aac_vmioctl_tole(vmi); error = aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_vmi_businf_resp)); if (error) { @@ -3643,6 +3701,7 @@ } vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0]; + aac_vmi_businf_resp_toh(vmi_resp); if (vmi_resp->Status != ST_OK) { device_printf(sc->aac_dev, "VM_Ioctl returned %d\n", vmi_resp->Status); @@ -3814,6 +3873,7 @@ pc->Min = 1; pc->NoRescan = 1; + aac_pause_command_tole(pc); (void) aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof (struct aac_pause_command)); aac_release_sync_fib(sc); Index: sys/dev/aacraid/aacraid_cam.c =================================================================== --- sys/dev/aacraid/aacraid_cam.c +++ sys/dev/aacraid/aacraid_cam.c @@ -69,6 +69,7 @@ #include #include #include +#include #ifndef CAM_NEW_TRAN_CODE #define CAM_NEW_TRAN_CODE 1 @@ -417,6 +418,7 @@ if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE2) { struct aac_raw_io2 *raw; + /* NOTE: LE conversion handled at aacraid_map_command_sg() */ raw = (struct aac_raw_io2 *)&fib->data[0]; bzero(raw, sizeof(struct aac_raw_io2)); fib->Header.Command = RawIo2; @@ -432,6 +434,7 @@ raw->flags = RIO2_IO_TYPE_WRITE | RIO2_SG_FORMAT_IEEE1212; } else if (sc->flags & AAC_FLAGS_RAW_IO) { struct aac_raw_io *raw; + /* NOTE: LE conversion handled at aacraid_map_command_sg() */ raw = (struct aac_raw_io *)&fib->data[0]; bzero(raw, sizeof(struct aac_raw_io)); fib->Header.Command = RawIo; @@ -452,6 +455,7 @@ br->ContainerId = ccb->ccb_h.target_id; br->BlockNumber = blockno; br->ByteCount = cm->cm_datalen; + aac_blockread_tole(br); fib->Header.Size += sizeof(struct aac_blockread); cm->cm_sgtable = &br->SgMap; } else { @@ -462,6 +466,7 @@ bw->BlockNumber = blockno; bw->ByteCount = cm->cm_datalen; bw->Stable = CUNSTABLE; + aac_blockwrite_tole(bw); fib->Header.Size += sizeof(struct aac_blockwrite); cm->cm_sgtable = &bw->SgMap; } @@ -476,6 +481,7 @@ br->BlockNumber = blockno; br->Pad = 0; br->Flags = 0; + aac_blockread64_tole(br); fib->Header.Size += sizeof(struct aac_blockread64); cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; } else { @@ -487,6 +493,7 @@ bw->BlockNumber = blockno; bw->Pad = 0; bw->Flags = 0; + aac_blockwrite64_tole(bw); fib->Header.Size += sizeof(struct aac_blockwrite64); cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; } @@ -656,9 +663,10 @@ AAC_PM_DRIVERSUP_STOP_UNIT); ccfg->CTCommand.param[1] = co->co_mntobj.ObjectId; ccfg->CTCommand.param[2] = 0; /* 1 - immediate */ + aac_cnt_config_tole(ccfg); if (aacraid_wait_command(cm) != 0 || - *(u_int32_t *)&fib->data[0] != 0) { + le32toh(*(u_int32_t *)&fib->data[0]) != 0) { printf("Power Management: Error start/stop container %d\n", co->co_mntobj.ObjectId); } @@ -930,6 +938,7 @@ srb->lun = ccb->ccb_h.target_lun; srb->timeout = ccb->ccb_h.timeout; /* XXX */ srb->retry_limit = 0; + aac_srb_tole(srb); cm->cm_complete = aac_cam_complete; cm->cm_ccb = ccb; @@ -1119,7 +1128,7 @@ fwprintf(cm->cm_sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); ccb = cm->cm_ccb; - status = ((u_int32_t *)cm->cm_fib->data)[0]; + status = le32toh(((u_int32_t *)cm->cm_fib->data)[0]); if (cm->cm_flags & AAC_CMD_RESET) { ccb->ccb_h.status = CAM_SCSI_BUS_RESET; @@ -1146,6 +1155,7 @@ fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); ccb = cm->cm_ccb; srbr = (struct aac_srb_response *)&cm->cm_fib->data[0]; + aac_srb_response_toh(srbr); if (cm->cm_flags & AAC_CMD_FASTRESP) { /* fast response */ @@ -1297,6 +1307,7 @@ rbc = (struct aac_resetbus *)&vmi->IoctlBuf[0]; rbc->BusNumber = camsc->inf->BusNumber - 1; + aac_vmioctl_tole(vmi); if (aacraid_wait_command(cm) != 0) { device_printf(sc->aac_dev,"Error sending ResetBus command\n"); Index: sys/dev/aacraid/aacraid_endian.h =================================================================== --- /dev/null +++ sys/dev/aacraid/aacraid_endian.h @@ -0,0 +1,114 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +#ifndef AACRAID_ENDIAN_H +#define AACRAID_ENDIAN_H + +#include + +#if _BYTE_ORDER == _LITTLE_ENDIAN + +/* On Little-Endian (LE) hosts, make all FIB data conversion functions empty. */ + +/* Convert from Little-Endian to host order (TOH) */ +#define aac_fib_header_toh(ptr) +#define aac_adapter_info_toh(ptr) +#define aac_container_creation_toh(ptr) +#define aac_mntobj_toh(ptr) +#define aac_mntinforesp_toh(ptr) +#define aac_fsa_ctm_toh(ptr) +#define aac_cnt_config_toh(ptr) +#define aac_ctcfg_resp_toh(ptr) +#define aac_getbusinf_toh(ptr) +#define aac_vmi_businf_resp_toh(ptr) +#define aac_srb_response_toh(ptr) + +/* Convert from host order to Little-Endian (TOLE) */ +#define aac_adapter_init_tole(ptr) +#define aac_fib_header_tole(ptr) +#define aac_mntinfo_tole(ptr) +#define aac_fsa_ctm_tole(ptr) +#define aac_cnt_config_tole(ptr) +#define aac_raw_io_tole(ptr) +#define aac_raw_io2_tole(ptr) +#define aac_fib_xporthdr_tole(ptr) +#define aac_ctcfg_tole(ptr) +#define aac_vmioctl_tole(ptr) +#define aac_pause_command_tole(ptr) +#define aac_srb_tole(ptr) +#define aac_sge_ieee1212_tole(ptr) +#define aac_sg_entryraw_tole(ptr) +#define aac_sg_entry_tole(ptr) +#define aac_sg_entry64_tole(ptr) +#define aac_blockread_tole(ptr) +#define aac_blockwrite_tole(ptr) +#define aac_blockread64_tole(ptr) +#define aac_blockwrite64_tole(ptr) + + +#else /* _BYTE_ORDER != _LITTLE_ENDIAN */ + +/* Convert from Little-Endian to host order (TOH) */ +void aac_fib_header_toh(struct aac_fib_header *ptr); +void aac_adapter_info_toh(struct aac_adapter_info *ptr); +void aac_container_creation_toh(struct aac_container_creation *ptr); +void aac_mntobj_toh(struct aac_mntobj *ptr); +void aac_mntinforesp_toh(struct aac_mntinforesp *ptr); +void aac_fsa_ctm_toh(struct aac_fsa_ctm *ptr); +void aac_cnt_config_toh(struct aac_cnt_config *ptr); +void aac_ctcfg_resp_toh(struct aac_ctcfg_resp *ptr); +void aac_getbusinf_toh(struct aac_getbusinf *ptr); +void aac_vmi_businf_resp_toh(struct aac_vmi_businf_resp *ptr); +void aac_srb_response_toh(struct aac_srb_response *ptr); + +/* Convert from host order to Little-Endian (TOLE) */ +void aac_adapter_init_tole(struct aac_adapter_init *ptr); +void aac_fib_header_tole(struct aac_fib_header *ptr); +void aac_mntinfo_tole(struct aac_mntinfo *ptr); +void aac_fsa_ctm_tole(struct aac_fsa_ctm *ptr); +void aac_cnt_config_tole(struct aac_cnt_config *ptr); +void aac_raw_io_tole(struct aac_raw_io *ptr); +void aac_raw_io2_tole(struct aac_raw_io2 *ptr); +void aac_fib_xporthdr_tole(struct aac_fib_xporthdr *ptr); +void aac_ctcfg_tole(struct aac_ctcfg *ptr); +void aac_vmioctl_tole(struct aac_vmioctl *ptr); +void aac_pause_command_tole(struct aac_pause_command *ptr); +void aac_srb_tole(struct aac_srb *ptr); +void aac_sge_ieee1212_tole(struct aac_sge_ieee1212 *ptr); +void aac_sg_entryraw_tole(struct aac_sg_entryraw *ptr); +void aac_sg_entry_tole(struct aac_sg_entry *ptr); +void aac_sg_entry64_tole(struct aac_sg_entry64 *ptr); +void aac_blockread_tole(struct aac_blockread *ptr); +void aac_blockwrite_tole(struct aac_blockwrite *ptr); +void aac_blockread64_tole(struct aac_blockread64 *ptr); +void aac_blockwrite64_tole(struct aac_blockwrite64 *ptr); + +#endif + +#endif Index: sys/dev/aacraid/aacraid_endian.c =================================================================== --- /dev/null +++ sys/dev/aacraid/aacraid_endian.c @@ -0,0 +1,389 @@ +/*- + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#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 Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -748,6 +748,7 @@ .endif .if ${MACHINE_CPUARCH} == "powerpc" +_aacraid= aacraid _agp= agp _an= an _cardbus= cardbus Index: sys/modules/aacraid/Makefile =================================================================== --- sys/modules/aacraid/Makefile +++ sys/modules/aacraid/Makefile @@ -8,6 +8,9 @@ KMOD= aacraid SRCS= aacraid.c aacraid_pci.c aacraid_cam.c +.if ${MACHINE_CPUARCH} == "powerpc" +SRCS+=aacraid_endian.c +.endif SRCS+= opt_scsi.h opt_cam.h opt_aacraid.h SRCS+= device_if.h bus_if.h pci_if.h Index: sys/powerpc/conf/GENERIC64 =================================================================== --- sys/powerpc/conf/GENERIC64 +++ sys/powerpc/conf/GENERIC64 @@ -136,6 +136,7 @@ device nvd # expose NVMe namespaces as disks, depends on nvme # SCSI Controllers +device aacraid # Adaptec by PMC RAID device ahc # AHA2940 and onboard AIC7xxx devices options AHC_ALLOW_MEMIO # Attempt to use memory mapped I/O device isp # Qlogic family