Date: Fri, 14 Dec 2018 08:00:01 +0000 (UTC) From: Kashyap D Desai <kadesai@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r342061 - head/sys/dev/mrsas Message-ID: <201812140800.wBE801vi082890@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kadesai Date: Fri Dec 14 08:00:01 2018 New Revision: 342061 URL: https://svnweb.freebsd.org/changeset/base/342061 Log: This patch will add support for divert bitmap in RAID map. Divert bitmap is supported for SAS3.5 adapters only. Submitted by: Sumit Saxena <sumit.saxena@broadcom.com> Reviewed by: Kashyap Desai <Kashyap.Desai@broadcom.com> Approved by: ken MFC after: 3 days Sponsored by: Broadcom Inc Modified: head/sys/dev/mrsas/mrsas.c head/sys/dev/mrsas/mrsas.h head/sys/dev/mrsas/mrsas_cam.c head/sys/dev/mrsas/mrsas_fp.c Modified: head/sys/dev/mrsas/mrsas.c ============================================================================== --- head/sys/dev/mrsas/mrsas.c Fri Dec 14 07:59:09 2018 (r342060) +++ head/sys/dev/mrsas/mrsas.c Fri Dec 14 08:00:01 2018 (r342061) @@ -1589,8 +1589,8 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M cmd_mpt = sc->mpt_cmd_list[smid - 1]; scsi_io_req = (MRSAS_RAID_SCSI_IO_REQUEST *) cmd_mpt->io_request; - status = scsi_io_req->RaidContext.status; - extStatus = scsi_io_req->RaidContext.exStatus; + status = scsi_io_req->RaidContext.raid_context.status; + extStatus = scsi_io_req->RaidContext.raid_context.exStatus; switch (scsi_io_req->Function) { case MPI2_FUNCTION_SCSI_TASK_MGMT: @@ -1614,8 +1614,8 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M case MRSAS_MPI2_FUNCTION_LD_IO_REQUEST: mrsas_map_mpt_cmd_status(cmd_mpt, status, extStatus); mrsas_cmd_done(sc, cmd_mpt); - scsi_io_req->RaidContext.status = 0; - scsi_io_req->RaidContext.exStatus = 0; + scsi_io_req->RaidContext.raid_context.status = 0; + scsi_io_req->RaidContext.raid_context.exStatus = 0; mrsas_atomic_dec(&sc->fw_outstanding); break; case MRSAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /* MFI command */ @@ -3214,7 +3214,7 @@ mrsas_complete_outstanding_ioctls(struct mrsas_softc * if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) { for (MSIxIndex = 0; MSIxIndex < count; MSIxIndex++) mrsas_complete_mptmfi_passthru(sc, cmd_mfi, - cmd_mpt->io_request->RaidContext.status); + cmd_mpt->io_request->RaidContext.raid_context.status); } } } Modified: head/sys/dev/mrsas/mrsas.h ============================================================================== --- head/sys/dev/mrsas/mrsas.h Fri Dec 14 07:59:09 2018 (r342060) +++ head/sys/dev/mrsas/mrsas.h Fri Dec 14 08:00:01 2018 (r342061) @@ -179,7 +179,54 @@ typedef struct _RAID_CONTEXT { u_int8_t resvd2; /* 0x1F */ } RAID_CONTEXT; +/* + * Raid Context structure which describes ventura MegaRAID specific IO Paramenters + * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames + */ +typedef struct _RAID_CONTEXT_G35 { + u_int16_t Type:4; + u_int16_t nseg:4; + u_int16_t resvd0:8; + u_int16_t timeoutValue; + union { + struct { + u_int16_t reserved:1; + u_int16_t sld:1; + u_int16_t c2f:1; + u_int16_t fwn:1; + u_int16_t sqn:1; + u_int16_t sbs:1; + u_int16_t rw:1; + u_int16_t log:1; + u_int16_t cpuSel:4; + u_int16_t setDivert:4; + } bits; + u_int16_t s; + } routingFlags; + u_int16_t VirtualDiskTgtId; + u_int64_t regLockRowLBA; + u_int32_t regLockLength; + union { + u_int16_t nextLMId; + u_int16_t peerSMID; + } smid; + u_int8_t exStatus; + u_int8_t status; + u_int8_t RAIDFlags; + u_int8_t spanArm; + u_int16_t configSeqNum; + u_int16_t numSGE:12; + u_int16_t reserved:3; + u_int16_t streamDetected:1; + u_int8_t resvd2[2]; +} RAID_CONTEXT_G35; +typedef union _RAID_CONTEXT_UNION { + RAID_CONTEXT raid_context; + RAID_CONTEXT_G35 raid_context_g35; +} RAID_CONTEXT_UNION, *PRAID_CONTEXT_UNION; + + /************************************************************************* * MPI2 Defines ************************************************************************/ @@ -439,7 +486,7 @@ typedef struct _MPI2_RAID_SCSI_IO_REQUEST { u_int8_t LUN[8]; /* 0x34 */ u_int32_t Control; /* 0x3C */ MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */ - RAID_CONTEXT RaidContext; /* 0x60 */ + RAID_CONTEXT_UNION RaidContext; /* 0x60 */ MPI2_SGE_IO_UNION SGL; /* 0x80 */ } MRSAS_RAID_SCSI_IO_REQUEST, MPI2_POINTER PTR_MRSAS_RAID_SCSI_IO_REQUEST, MRSASRaidSCSIIORequest_t, MPI2_POINTER pMRSASRaidSCSIIORequest_t; @@ -754,7 +801,8 @@ typedef struct _MR_LD_RAID { u_int32_t fpReadAcrossStripe:1; u_int32_t fpNonRWCapable:1; u_int32_t tmCapable:1; - u_int32_t reserved4:6; + u_int32_t fpCacheBypassCapable:1; + u_int32_t reserved4:5; } capability; u_int32_t reserved6; u_int64_t size; @@ -1448,6 +1496,7 @@ enum MR_EVT_ARGS { #define MR_RL_FLAGS_GRANT_DESTINATION_CPU1 0x10 #define MR_RL_FLAGS_GRANT_DESTINATION_CUDA 0x80 #define MR_RL_FLAGS_SEQ_NUM_ENABLE 0x8 +#define MR_RL_WRITE_BACK_MODE 0x01 /* * T10 PI defines @@ -1469,8 +1518,12 @@ enum MR_EVT_ARGS { typedef enum MR_RAID_FLAGS_IO_SUB_TYPE { MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0, MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1, -} MR_RAID_FLAGS_IO_SUB_TYPE; - + MR_RAID_FLAGS_IO_SUB_TYPE_RMW_DATA = 2, + MR_RAID_FLAGS_IO_SUB_TYPE_RMW_P = 3, + MR_RAID_FLAGS_IO_SUB_TYPE_RMW_Q = 4, + MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS = 6, + MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT = 7 +} MR_RAID_FLAGS_IO_SUB_TYPE; /* * Request descriptor types */ Modified: head/sys/dev/mrsas/mrsas_cam.c ============================================================================== --- head/sys/dev/mrsas/mrsas_cam.c Fri Dec 14 07:59:09 2018 (r342060) +++ head/sys/dev/mrsas/mrsas_cam.c Fri Dec 14 08:00:01 2018 (r342061) @@ -765,9 +765,9 @@ mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrs device_id = ccb_h->target_id; io_request = cmd->io_request; - io_request->RaidContext.VirtualDiskTgtId = device_id; - io_request->RaidContext.status = 0; - io_request->RaidContext.exStatus = 0; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id; + io_request->RaidContext.raid_context.status = 0; + io_request->RaidContext.raid_context.exStatus = 0; /* just the cdb len, other flags zero, and ORed-in later for FP */ io_request->IoFlags = csio->cdb_len; @@ -783,12 +783,16 @@ mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrs "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge); return (FAIL); } - /* - * numSGE store lower 8 bit of sge_count. numSGEExt store - * higher 8 bit of sge_count - */ - io_request->RaidContext.numSGE = cmd->sge_count; - io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + if (sc->is_ventura) + io_request->RaidContext.raid_context_g35.numSGE = cmd->sge_count; + else { + /* + * numSGE store lower 8 bit of sge_count. numSGEExt store + * higher 8 bit of sge_count + */ + io_request->RaidContext.raid_context.numSGE = cmd->sge_count; + io_request->RaidContext.raid_context.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + } } else { device_printf(sc->mrsas_dev, "Data map/load failed.\n"); @@ -898,10 +902,10 @@ mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mp ld = MR_TargetIdToLdGet(device_id, map_ptr); if ((ld >= MAX_LOGICAL_DRIVES_EXT) || (!sc->fast_path_io)) { - io_request->RaidContext.regLockFlags = 0; + io_request->RaidContext.raid_context.regLockFlags = 0; fp_possible = 0; } else { - if (MR_BuildRaidContext(sc, &io_info, &io_request->RaidContext, map_ptr)) + if (MR_BuildRaidContext(sc, &io_info, &io_request->RaidContext.raid_context, map_ptr)) fp_possible = io_info.fpOkForIo; } @@ -921,16 +925,26 @@ mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mp (MPI2_REQ_DESCRIPT_FLAGS_FP_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); if (sc->mrsas_gen3_ctrl) { - if (io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED) + if (io_request->RaidContext.raid_context.regLockFlags == REGION_TYPE_UNUSED) cmd->request_desc->SCSIIO.RequestFlags = (MRSAS_REQ_DESCRIPT_FLAGS_NO_LOCK << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - io_request->RaidContext.Type = MPI2_TYPE_CUDA; - io_request->RaidContext.nseg = 0x1; + io_request->RaidContext.raid_context.Type = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context.nseg = 0x1; io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH; - io_request->RaidContext.regLockFlags |= + io_request->RaidContext.raid_context.regLockFlags |= (MR_RL_FLAGS_GRANT_DESTINATION_CUDA | MR_RL_FLAGS_SEQ_NUM_ENABLE); + } else if (sc->is_ventura) { + io_request->RaidContext.raid_context_g35.Type = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context_g35.nseg = 0x1; + io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1; + io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH; + if (io_request->RaidContext.raid_context_g35.routingFlags.bits.sld) { + io_request->RaidContext.raid_context_g35.RAIDFlags = + (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } } if ((sc->load_balance_info[device_id].loadBalanceFlag) && (io_info.isRead)) { @@ -939,26 +953,34 @@ mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mp &sc->load_balance_info[device_id], &io_info); cmd->load_balance = MRSAS_LOAD_BALANCE_FLAG; cmd->pd_r1_lb = io_info.pd_after_lb; + if (sc->is_ventura) + io_request->RaidContext.raid_context_g35.spanArm = io_info.span_arm; + else + io_request->RaidContext.raid_context.spanArm = io_info.span_arm; } else cmd->load_balance = 0; cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle; io_request->DevHandle = io_info.devHandle; } else { /* Not FP IO */ - io_request->RaidContext.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec; + io_request->RaidContext.raid_context.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec; cmd->request_desc->SCSIIO.RequestFlags = (MRSAS_REQ_DESCRIPT_FLAGS_LD_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); if (sc->mrsas_gen3_ctrl) { - if (io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED) + if (io_request->RaidContext.raid_context.regLockFlags == REGION_TYPE_UNUSED) cmd->request_desc->SCSIIO.RequestFlags = (MRSAS_REQ_DESCRIPT_FLAGS_NO_LOCK << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - io_request->RaidContext.Type = MPI2_TYPE_CUDA; - io_request->RaidContext.regLockFlags |= + io_request->RaidContext.raid_context.Type = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context.regLockFlags |= (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 | MR_RL_FLAGS_SEQ_NUM_ENABLE); - io_request->RaidContext.nseg = 0x1; + io_request->RaidContext.raid_context.nseg = 0x1; + } else if (sc->is_ventura) { + io_request->RaidContext.raid_context_g35.Type = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1; + io_request->RaidContext.raid_context_g35.nseg = 0x1; } io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST; io_request->DevHandle = device_id; @@ -1001,7 +1023,7 @@ mrsas_build_ldio_nonrw(struct mrsas_softc *sc, struct (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - io_request->RaidContext.VirtualDiskTgtId = device_id; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id; io_request->LUN[1] = ccb_h->target_lun & 0xF; io_request->DataLength = cmd->length; @@ -1011,12 +1033,16 @@ mrsas_build_ldio_nonrw(struct mrsas_softc *sc, struct "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge); return (1); } - /* - * numSGE store lower 8 bit of sge_count. numSGEExt store - * higher 8 bit of sge_count - */ - io_request->RaidContext.numSGE = cmd->sge_count; - io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + if (sc->is_ventura) + io_request->RaidContext.raid_context_g35.numSGE = cmd->sge_count; + else { + /* + * numSGE store lower 8 bit of sge_count. numSGEExt store + * higher 8 bit of sge_count + */ + io_request->RaidContext.raid_context.numSGE = cmd->sge_count; + io_request->RaidContext.raid_context.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + } } else { device_printf(sc->mrsas_dev, "Data map/load failed.\n"); return (1); @@ -1046,11 +1072,11 @@ mrsas_build_syspdio(struct mrsas_softc *sc, struct mrs io_request = cmd->io_request; device_id = ccb_h->target_id; local_map_ptr = sc->ld_drv_map[(sc->map_id & 1)]; - io_request->RaidContext.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD + io_request->RaidContext.raid_context.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT; - io_request->RaidContext.regLockFlags = 0; - io_request->RaidContext.regLockRowLBA = 0; - io_request->RaidContext.regLockLength = 0; + io_request->RaidContext.raid_context.regLockFlags = 0; + io_request->RaidContext.raid_context.regLockRowLBA = 0; + io_request->RaidContext.raid_context.regLockLength = 0; /* If FW supports PD sequence number */ if (sc->use_seqnum_jbod_fp && @@ -1058,25 +1084,28 @@ mrsas_build_syspdio(struct mrsas_softc *sc, struct mrs //printf("Using Drv seq num\n"); pd_sync = (void *)sc->jbodmap_mem[(sc->pd_seq_map_id - 1) & 1]; cmd->tmCapable = pd_sync->seq[device_id].capability.tmCapable; - io_request->RaidContext.VirtualDiskTgtId = device_id + 255; - io_request->RaidContext.configSeqNum = pd_sync->seq[device_id].seqNum; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id + 255; + io_request->RaidContext.raid_context.configSeqNum = pd_sync->seq[device_id].seqNum; io_request->DevHandle = pd_sync->seq[device_id].devHandle; - io_request->RaidContext.regLockFlags |= - (MR_RL_FLAGS_SEQ_NUM_ENABLE | MR_RL_FLAGS_GRANT_DESTINATION_CUDA); - io_request->RaidContext.Type = MPI2_TYPE_CUDA; - io_request->RaidContext.nseg = 0x1; + if (sc->is_ventura) + io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1; + else + io_request->RaidContext.raid_context.regLockFlags |= + (MR_RL_FLAGS_SEQ_NUM_ENABLE | MR_RL_FLAGS_GRANT_DESTINATION_CUDA); + io_request->RaidContext.raid_context.Type = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context.nseg = 0x1; } else if (sc->fast_path_io) { //printf("Using LD RAID map\n"); - io_request->RaidContext.VirtualDiskTgtId = device_id; - io_request->RaidContext.configSeqNum = 0; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id; + io_request->RaidContext.raid_context.configSeqNum = 0; local_map_ptr = sc->ld_drv_map[(sc->map_id & 1)]; io_request->DevHandle = local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; } else { //printf("Using FW PATH\n"); /* Want to send all IO via FW path */ - io_request->RaidContext.VirtualDiskTgtId = device_id; - io_request->RaidContext.configSeqNum = 0; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id; + io_request->RaidContext.raid_context.configSeqNum = 0; io_request->DevHandle = 0xFFFF; } @@ -1090,13 +1119,13 @@ mrsas_build_syspdio(struct mrsas_softc *sc, struct mrs cmd->request_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - io_request->RaidContext.timeoutValue = + io_request->RaidContext.raid_context.timeoutValue = local_map_ptr->raidMap.fpPdIoTimeoutSec; - io_request->RaidContext.VirtualDiskTgtId = device_id; + io_request->RaidContext.raid_context.VirtualDiskTgtId = device_id; } else { /* system pd fast path */ io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; - io_request->RaidContext.timeoutValue = local_map_ptr->raidMap.fpPdIoTimeoutSec; + io_request->RaidContext.raid_context.timeoutValue = local_map_ptr->raidMap.fpPdIoTimeoutSec; /* * NOTE - For system pd RW cmds only IoFlags will be FAST_PATH @@ -1120,12 +1149,16 @@ mrsas_build_syspdio(struct mrsas_softc *sc, struct mrs "max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge); return (1); } - /* - * numSGE store lower 8 bit of sge_count. numSGEExt store - * higher 8 bit of sge_count - */ - io_request->RaidContext.numSGE = cmd->sge_count; - io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + if (sc->is_ventura) + io_request->RaidContext.raid_context_g35.numSGE = cmd->sge_count; + else { + /* + * numSGE store lower 8 bit of sge_count. numSGEExt store + * higher 8 bit of sge_count + */ + io_request->RaidContext.raid_context.numSGE = cmd->sge_count; + io_request->RaidContext.raid_context.numSGEExt = (uint8_t)(cmd->sge_count >> 8); + } } else { device_printf(sc->mrsas_dev, "Data map/load failed.\n"); return (1); Modified: head/sys/dev/mrsas/mrsas_fp.c ============================================================================== --- head/sys/dev/mrsas/mrsas_fp.c Fri Dec 14 07:59:09 2018 (r342060) +++ head/sys/dev/mrsas/mrsas_fp.c Fri Dec 14 08:00:01 2018 (r342061) @@ -966,8 +966,14 @@ mr_spanset_get_phy_params(struct mrsas_softc *sc, u_in } *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; - pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; - io_info->span_arm = pRAID_Context->spanArm; + if (sc->is_ventura) { + ((RAID_CONTEXT_G35 *) pRAID_Context)->spanArm = + (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + } else { + pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + io_info->span_arm = pRAID_Context->spanArm; + } return retval; } @@ -1160,6 +1166,15 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_ /* If IO on an invalid Pd, then FP is not possible */ if (io_info->devHandle == MR_PD_INVALID) io_info->fpOkForIo = FALSE; + /* + * if FP possible, set the SLUD bit in regLockFlags for + * ventura + */ + else if ((sc->is_ventura) && !isRead && + (raid->writeMode == MR_RL_WRITE_BACK_MODE) && (raid->level <= 1) && + raid->capability.fpCacheBypassCapable) { + ((RAID_CONTEXT_G35 *) pRAID_Context)->routingFlags.bits.sld = 1; + } return retval; } else if (isRead) { for (stripIdx = 0; stripIdx < num_strips; stripIdx++) { @@ -1674,8 +1689,14 @@ MR_GetPhyParams(struct mrsas_softc *sc, u_int32_t ld, } *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; - pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; - io_info->span_arm = pRAID_Context->spanArm; + if (sc->is_ventura) { + ((RAID_CONTEXT_G35 *) pRAID_Context)->spanArm = + (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + } else { + pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + io_info->span_arm = pRAID_Context->spanArm; + } return retval; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812140800.wBE801vi082890>