Path: blob/main/sys/contrib/dev/acpica/components/namespace/nsnames.c
48524 views
/*******************************************************************************1*2* Module Name: nsnames - Name manipulation and search3*4******************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/amlcode.h>154#include <contrib/dev/acpica/include/acnamesp.h>155156157#define _COMPONENT ACPI_NAMESPACE158ACPI_MODULE_NAME ("nsnames")159160161/*******************************************************************************162*163* FUNCTION: AcpiNsGetExternalPathname164*165* PARAMETERS: Node - Namespace node whose pathname is needed166*167* RETURN: Pointer to storage containing the fully qualified name of168* the node, In external format (name segments separated by path169* separators.)170*171* DESCRIPTION: Used to obtain the full pathname to a namespace node, usually172* for error and debug statements.173*174******************************************************************************/175176char *177AcpiNsGetExternalPathname (178ACPI_NAMESPACE_NODE *Node)179{180char *NameBuffer;181182183ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);184185186NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE);187return_PTR (NameBuffer);188}189190191/*******************************************************************************192*193* FUNCTION: AcpiNsGetPathnameLength194*195* PARAMETERS: Node - Namespace node196*197* RETURN: Length of path, including prefix198*199* DESCRIPTION: Get the length of the pathname string for this node200*201******************************************************************************/202203ACPI_SIZE204AcpiNsGetPathnameLength (205ACPI_NAMESPACE_NODE *Node)206{207ACPI_SIZE Size;208209210/* Validate the Node */211212if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)213{214ACPI_ERROR ((AE_INFO,215"Invalid/cached reference target node: %p, descriptor type %d",216Node, ACPI_GET_DESCRIPTOR_TYPE (Node)));217return (0);218}219220Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE);221return (Size);222}223224225/*******************************************************************************226*227* FUNCTION: AcpiNsHandleToName228*229* PARAMETERS: TargetHandle - Handle of named object whose name is230* to be found231* Buffer - Where the name is returned232*233* RETURN: Status, Buffer is filled with name if status is AE_OK234*235* DESCRIPTION: Build and return a full namespace name236*237******************************************************************************/238239ACPI_STATUS240AcpiNsHandleToName (241ACPI_HANDLE TargetHandle,242ACPI_BUFFER *Buffer)243{244ACPI_STATUS Status;245ACPI_NAMESPACE_NODE *Node;246const char *NodeName;247248249ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle);250251252Node = AcpiNsValidateHandle (TargetHandle);253if (!Node)254{255return_ACPI_STATUS (AE_BAD_PARAMETER);256}257258/* Validate/Allocate/Clear caller buffer */259260Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);261if (ACPI_FAILURE (Status))262{263return_ACPI_STATUS (Status);264}265266/* Just copy the ACPI name from the Node and zero terminate it */267268NodeName = AcpiUtGetNodeName (Node);269ACPI_COPY_NAMESEG (Buffer->Pointer, NodeName);270((char *) Buffer->Pointer) [ACPI_NAMESEG_SIZE] = 0;271272ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer));273return_ACPI_STATUS (AE_OK);274}275276277/*******************************************************************************278*279* FUNCTION: AcpiNsHandleToPathname280*281* PARAMETERS: TargetHandle - Handle of named object whose name is282* to be found283* Buffer - Where the pathname is returned284* NoTrailing - Remove trailing '_' for each name285* segment286*287* RETURN: Status, Buffer is filled with pathname if status is AE_OK288*289* DESCRIPTION: Build and return a full namespace pathname290*291******************************************************************************/292293ACPI_STATUS294AcpiNsHandleToPathname (295ACPI_HANDLE TargetHandle,296ACPI_BUFFER *Buffer,297BOOLEAN NoTrailing)298{299ACPI_STATUS Status;300ACPI_NAMESPACE_NODE *Node;301ACPI_SIZE RequiredSize;302303304ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);305306307Node = AcpiNsValidateHandle (TargetHandle);308if (!Node)309{310return_ACPI_STATUS (AE_BAD_PARAMETER);311}312313/* Determine size required for the caller buffer */314315RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);316if (!RequiredSize)317{318return_ACPI_STATUS (AE_BAD_PARAMETER);319}320321/* Validate/Allocate/Clear caller buffer */322323Status = AcpiUtInitializeBuffer (Buffer, RequiredSize);324if (ACPI_FAILURE (Status))325{326return_ACPI_STATUS (Status);327}328329/* Build the path in the caller buffer */330331(void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer,332(UINT32) RequiredSize, NoTrailing);333334ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",335(char *) Buffer->Pointer, (UINT32) RequiredSize));336return_ACPI_STATUS (AE_OK);337}338339340/*******************************************************************************341*342* FUNCTION: AcpiNsBuildNormalizedPath343*344* PARAMETERS: Node - Namespace node345* FullPath - Where the path name is returned346* PathSize - Size of returned path name buffer347* NoTrailing - Remove trailing '_' from each name segment348*349* RETURN: Return 1 if the AML path is empty, otherwise returning (length350* of pathname + 1) which means the 'FullPath' contains a trailing351* null.352*353* DESCRIPTION: Build and return a full namespace pathname.354* Note that if the size of 'FullPath' isn't large enough to355* contain the namespace node's path name, the actual required356* buffer length is returned, and it should be greater than357* 'PathSize'. So callers are able to check the returning value358* to determine the buffer size of 'FullPath'.359*360******************************************************************************/361362UINT32363AcpiNsBuildNormalizedPath (364ACPI_NAMESPACE_NODE *Node,365char *FullPath,366UINT32 PathSize,367BOOLEAN NoTrailing)368{369UINT32 Length = 0, i;370char Name[ACPI_NAMESEG_SIZE] ACPI_NONSTRING;371BOOLEAN DoNoTrailing;372char c, *Left, *Right;373ACPI_NAMESPACE_NODE *NextNode;374375376ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node);377378379#define ACPI_PATH_PUT8(Path, Size, Byte, Length) \380do { \381if ((Length) < (Size)) \382{ \383(Path)[(Length)] = (Byte); \384} \385(Length)++; \386} while (0)387388/*389* Make sure the PathSize is correct, so that we don't need to390* validate both FullPath and PathSize.391*/392if (!FullPath)393{394PathSize = 0;395}396397if (!Node)398{399goto BuildTrailingNull;400}401402NextNode = Node;403while (NextNode && NextNode != AcpiGbl_RootNode)404{405if (NextNode != Node)406{407ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length);408}409410ACPI_MOVE_32_TO_32 (Name, &NextNode->Name);411DoNoTrailing = NoTrailing;412for (i = 0; i < 4; i++)413{414c = Name[4-i-1];415if (DoNoTrailing && c != '_')416{417DoNoTrailing = FALSE;418}419if (!DoNoTrailing)420{421ACPI_PATH_PUT8(FullPath, PathSize, c, Length);422}423}424425NextNode = NextNode->Parent;426}427428ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length);429430/* Reverse the path string */431432if (Length <= PathSize)433{434Left = FullPath;435Right = FullPath+Length - 1;436437while (Left < Right)438{439c = *Left;440*Left++ = *Right;441*Right-- = c;442}443}444445/* Append the trailing null */446447BuildTrailingNull:448ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length);449450#undef ACPI_PATH_PUT8451452return_UINT32 (Length);453}454455456/*******************************************************************************457*458* FUNCTION: AcpiNsGetNormalizedPathname459*460* PARAMETERS: Node - Namespace node whose pathname is needed461* NoTrailing - Remove trailing '_' from each name segment462*463* RETURN: Pointer to storage containing the fully qualified name of464* the node, In external format (name segments separated by path465* separators.)466*467* DESCRIPTION: Used to obtain the full pathname to a namespace node, usually468* for error and debug statements. All trailing '_' will be469* removed from the full pathname if 'NoTrailing' is specified..470*471******************************************************************************/472473char *474AcpiNsGetNormalizedPathname (475ACPI_NAMESPACE_NODE *Node,476BOOLEAN NoTrailing)477{478char *NameBuffer;479ACPI_SIZE Size;480481482ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node);483484485/* Calculate required buffer size based on depth below root */486487Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);488if (!Size)489{490return_PTR (NULL);491}492493/* Allocate a buffer to be returned to caller */494495NameBuffer = ACPI_ALLOCATE_ZEROED (Size);496if (!NameBuffer)497{498ACPI_ERROR ((AE_INFO,499"Could not allocate %u bytes", (UINT32) Size));500return_PTR (NULL);501}502503/* Build the path in the allocated buffer */504505(void) AcpiNsBuildNormalizedPath (Node, NameBuffer, (UINT32) Size, NoTrailing);506507ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%s: Path \"%s\"\n",508ACPI_GET_FUNCTION_NAME, NameBuffer));509510return_PTR (NameBuffer);511}512513514/*******************************************************************************515*516* FUNCTION: AcpiNsBuildPrefixedPathname517*518* PARAMETERS: PrefixScope - Scope/Path that prefixes the internal path519* InternalPath - Name or path of the namespace node520*521* RETURN: None522*523* DESCRIPTION: Construct a fully qualified pathname from a concatenation of:524* 1) Path associated with the PrefixScope namespace node525* 2) External path representation of the Internal path526*527******************************************************************************/528529char *530AcpiNsBuildPrefixedPathname (531ACPI_GENERIC_STATE *PrefixScope,532const char *InternalPath)533{534ACPI_STATUS Status;535char *FullPath = NULL;536char *ExternalPath = NULL;537char *PrefixPath = NULL;538ACPI_SIZE PrefixPathLength = 0;539540541/* If there is a prefix, get the pathname to it */542543if (PrefixScope && PrefixScope->Scope.Node)544{545PrefixPath = AcpiNsGetNormalizedPathname (PrefixScope->Scope.Node, TRUE);546if (PrefixPath)547{548PrefixPathLength = strlen (PrefixPath);549}550}551552Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,553NULL, &ExternalPath);554if (ACPI_FAILURE (Status))555{556goto Cleanup;557}558559/* Merge the prefix path and the path. 2 is for one dot and trailing null */560561FullPath = ACPI_ALLOCATE_ZEROED (562PrefixPathLength + strlen (ExternalPath) + 2);563if (!FullPath)564{565goto Cleanup;566}567568/* Don't merge if the External path is already fully qualified */569570if (PrefixPath &&571(*ExternalPath != '\\') &&572(*ExternalPath != '^'))573{574strcat (FullPath, PrefixPath);575if (PrefixPath[1])576{577strcat (FullPath, ".");578}579}580581AcpiNsNormalizePathname (ExternalPath);582strcat (FullPath, ExternalPath);583584Cleanup:585if (PrefixPath)586{587ACPI_FREE (PrefixPath);588}589if (ExternalPath)590{591ACPI_FREE (ExternalPath);592}593594return (FullPath);595}596597598/*******************************************************************************599*600* FUNCTION: AcpiNsNormalizePathname601*602* PARAMETERS: OriginalPath - Path to be normalized, in External format603*604* RETURN: The original path is processed in-place605*606* DESCRIPTION: Remove trailing underscores from each element of a path.607*608* For example: \A___.B___.C___ becomes \A.B.C609*610******************************************************************************/611612void613AcpiNsNormalizePathname (614char *OriginalPath)615{616char *InputPath = OriginalPath;617char *NewPathBuffer;618char *NewPath;619UINT32 i;620621622/* Allocate a temp buffer in which to construct the new path */623624NewPathBuffer = ACPI_ALLOCATE_ZEROED (strlen (InputPath) + 1);625NewPath = NewPathBuffer;626if (!NewPathBuffer)627{628return;629}630631/* Special characters may appear at the beginning of the path */632633if (*InputPath == '\\')634{635*NewPath = *InputPath;636NewPath++;637InputPath++;638}639640while (*InputPath == '^')641{642*NewPath = *InputPath;643NewPath++;644InputPath++;645}646647/* Remainder of the path */648649while (*InputPath)650{651/* Do one nameseg at a time */652653for (i = 0; (i < ACPI_NAMESEG_SIZE) && *InputPath; i++)654{655if ((i == 0) || (*InputPath != '_')) /* First char is allowed to be underscore */656{657*NewPath = *InputPath;658NewPath++;659}660661InputPath++;662}663664/* Dot means that there are more namesegs to come */665666if (*InputPath == '.')667{668*NewPath = *InputPath;669NewPath++;670InputPath++;671}672}673674*NewPath = 0;675strcpy (OriginalPath, NewPathBuffer);676ACPI_FREE (NewPathBuffer);677}678679680