167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsnames - Name manipulation and search 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 4867754Smsmith 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_NAMESPACE 5191116Smsmith ACPI_MODULE_NAME ("nsnames") 5267754Smsmith 5367754Smsmith 5467754Smsmith/******************************************************************************* 5567754Smsmith * 5691116Smsmith * FUNCTION: AcpiNsGetExternalPathname 5791116Smsmith * 58151937Sjkim * PARAMETERS: Node - Namespace node whose pathname is needed 5991116Smsmith * 6091116Smsmith * RETURN: Pointer to storage containing the fully qualified name of 6191116Smsmith * the node, In external format (name segments separated by path 6291116Smsmith * separators.) 6391116Smsmith * 64193267Sjkim * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 65193267Sjkim * for error and debug statements. 6691116Smsmith * 6791116Smsmith ******************************************************************************/ 6867754Smsmith 69114237Snjlchar * 7091116SmsmithAcpiNsGetExternalPathname ( 7191116Smsmith ACPI_NAMESPACE_NODE *Node) 7291116Smsmith{ 73114237Snjl char *NameBuffer; 7467754Smsmith 7567754Smsmith 76167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node); 7767754Smsmith 7891116Smsmith 79306536Sjkim NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE); 8067754Smsmith return_PTR (NameBuffer); 8167754Smsmith} 8267754Smsmith 8367754Smsmith 8467754Smsmith/******************************************************************************* 8567754Smsmith * 8673561Smsmith * FUNCTION: AcpiNsGetPathnameLength 8773561Smsmith * 8873561Smsmith * PARAMETERS: Node - Namespace node 8973561Smsmith * 9073561Smsmith * RETURN: Length of path, including prefix 9173561Smsmith * 9273561Smsmith * DESCRIPTION: Get the length of the pathname string for this node 9373561Smsmith * 9473561Smsmith ******************************************************************************/ 9573561Smsmith 9691116SmsmithACPI_SIZE 9773561SmsmithAcpiNsGetPathnameLength ( 9873561Smsmith ACPI_NAMESPACE_NODE *Node) 9973561Smsmith{ 10091116Smsmith ACPI_SIZE Size; 10173561Smsmith 10283174Smsmith 10391116Smsmith ACPI_FUNCTION_ENTRY (); 10483174Smsmith 10583174Smsmith 106306536Sjkim Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE); 107306536Sjkim return (Size); 10873561Smsmith} 10973561Smsmith 11073561Smsmith 11173561Smsmith/******************************************************************************* 11273561Smsmith * 11367754Smsmith * FUNCTION: AcpiNsHandleToPathname 11467754Smsmith * 11567754Smsmith * PARAMETERS: TargetHandle - Handle of named object whose name is 11667754Smsmith * to be found 11791116Smsmith * Buffer - Where the pathname is returned 118306536Sjkim * NoTrailing - Remove trailing '_' for each name 119306536Sjkim * segment 12067754Smsmith * 12167754Smsmith * RETURN: Status, Buffer is filled with pathname if status is AE_OK 12267754Smsmith * 12367754Smsmith * DESCRIPTION: Build and return a full namespace pathname 12467754Smsmith * 12567754Smsmith ******************************************************************************/ 12667754Smsmith 12767754SmsmithACPI_STATUS 12867754SmsmithAcpiNsHandleToPathname ( 12967754Smsmith ACPI_HANDLE TargetHandle, 130306536Sjkim ACPI_BUFFER *Buffer, 131306536Sjkim BOOLEAN NoTrailing) 13267754Smsmith{ 13391116Smsmith ACPI_STATUS Status; 13467754Smsmith ACPI_NAMESPACE_NODE *Node; 13591116Smsmith ACPI_SIZE RequiredSize; 13667754Smsmith 13783174Smsmith 138167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 13967754Smsmith 14067754Smsmith 141200553Sjkim Node = AcpiNsValidateHandle (TargetHandle); 14267754Smsmith if (!Node) 14367754Smsmith { 14467754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 14567754Smsmith } 14667754Smsmith 14791116Smsmith /* Determine size required for the caller buffer */ 14867754Smsmith 149306536Sjkim RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 150193267Sjkim if (!RequiredSize) 151193267Sjkim { 152193267Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 153193267Sjkim } 15469746Smsmith 15591116Smsmith /* Validate/Allocate/Clear caller buffer */ 15669746Smsmith 15791116Smsmith Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 15891116Smsmith if (ACPI_FAILURE (Status)) 15967754Smsmith { 16091116Smsmith return_ACPI_STATUS (Status); 16167754Smsmith } 16267754Smsmith 16391116Smsmith /* Build the path in the caller buffer */ 16487031Smsmith 165306536Sjkim (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer, 166306536Sjkim RequiredSize, NoTrailing); 167193267Sjkim if (ACPI_FAILURE (Status)) 168193267Sjkim { 169193267Sjkim return_ACPI_STATUS (Status); 170193267Sjkim } 17167754Smsmith 172151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 173138287Smarks (char *) Buffer->Pointer, (UINT32) RequiredSize)); 17491116Smsmith return_ACPI_STATUS (AE_OK); 17567754Smsmith} 176306536Sjkim 177306536Sjkim 178306536Sjkim/******************************************************************************* 179306536Sjkim * 180306536Sjkim * FUNCTION: AcpiNsBuildNormalizedPath 181306536Sjkim * 182306536Sjkim * PARAMETERS: Node - Namespace node 183306536Sjkim * FullPath - Where the path name is returned 184306536Sjkim * PathSize - Size of returned path name buffer 185306536Sjkim * NoTrailing - Remove trailing '_' from each name segment 186306536Sjkim * 187306536Sjkim * RETURN: Return 1 if the AML path is empty, otherwise returning (length 188306536Sjkim * of pathname + 1) which means the 'FullPath' contains a trailing 189306536Sjkim * null. 190306536Sjkim * 191306536Sjkim * DESCRIPTION: Build and return a full namespace pathname. 192306536Sjkim * Note that if the size of 'FullPath' isn't large enough to 193306536Sjkim * contain the namespace node's path name, the actual required 194306536Sjkim * buffer length is returned, and it should be greater than 195306536Sjkim * 'PathSize'. So callers are able to check the returning value 196306536Sjkim * to determine the buffer size of 'FullPath'. 197306536Sjkim * 198306536Sjkim ******************************************************************************/ 199306536Sjkim 200306536SjkimUINT32 201306536SjkimAcpiNsBuildNormalizedPath ( 202306536Sjkim ACPI_NAMESPACE_NODE *Node, 203306536Sjkim char *FullPath, 204306536Sjkim UINT32 PathSize, 205306536Sjkim BOOLEAN NoTrailing) 206306536Sjkim{ 207306536Sjkim UINT32 Length = 0, i; 208306536Sjkim char Name[ACPI_NAME_SIZE]; 209306536Sjkim BOOLEAN DoNoTrailing; 210306536Sjkim char c, *Left, *Right; 211306536Sjkim ACPI_NAMESPACE_NODE *NextNode; 212306536Sjkim 213306536Sjkim 214306536Sjkim ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node); 215306536Sjkim 216306536Sjkim 217306536Sjkim#define ACPI_PATH_PUT8(Path, Size, Byte, Length) \ 218306536Sjkim do { \ 219306536Sjkim if ((Length) < (Size)) \ 220306536Sjkim { \ 221306536Sjkim (Path)[(Length)] = (Byte); \ 222306536Sjkim } \ 223306536Sjkim (Length)++; \ 224306536Sjkim } while (0) 225306536Sjkim 226306536Sjkim /* 227306536Sjkim * Make sure the PathSize is correct, so that we don't need to 228306536Sjkim * validate both FullPath and PathSize. 229306536Sjkim */ 230306536Sjkim if (!FullPath) 231306536Sjkim { 232306536Sjkim PathSize = 0; 233306536Sjkim } 234306536Sjkim 235306536Sjkim if (!Node) 236306536Sjkim { 237306536Sjkim goto BuildTrailingNull; 238306536Sjkim } 239306536Sjkim 240306536Sjkim NextNode = Node; 241306536Sjkim while (NextNode && NextNode != AcpiGbl_RootNode) 242306536Sjkim { 243306536Sjkim if (NextNode != Node) 244306536Sjkim { 245306536Sjkim ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length); 246306536Sjkim } 247306536Sjkim 248306536Sjkim ACPI_MOVE_32_TO_32 (Name, &NextNode->Name); 249306536Sjkim DoNoTrailing = NoTrailing; 250306536Sjkim for (i = 0; i < 4; i++) 251306536Sjkim { 252306536Sjkim c = Name[4-i-1]; 253306536Sjkim if (DoNoTrailing && c != '_') 254306536Sjkim { 255306536Sjkim DoNoTrailing = FALSE; 256306536Sjkim } 257306536Sjkim if (!DoNoTrailing) 258306536Sjkim { 259306536Sjkim ACPI_PATH_PUT8(FullPath, PathSize, c, Length); 260306536Sjkim } 261306536Sjkim } 262306536Sjkim 263306536Sjkim NextNode = NextNode->Parent; 264306536Sjkim } 265306536Sjkim 266306536Sjkim ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length); 267306536Sjkim 268306536Sjkim /* Reverse the path string */ 269306536Sjkim 270306536Sjkim if (Length <= PathSize) 271306536Sjkim { 272306536Sjkim Left = FullPath; 273306536Sjkim Right = FullPath+Length - 1; 274306536Sjkim 275306536Sjkim while (Left < Right) 276306536Sjkim { 277306536Sjkim c = *Left; 278306536Sjkim *Left++ = *Right; 279306536Sjkim *Right-- = c; 280306536Sjkim } 281306536Sjkim } 282306536Sjkim 283306536Sjkim /* Append the trailing null */ 284306536Sjkim 285306536SjkimBuildTrailingNull: 286306536Sjkim ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length); 287306536Sjkim 288306536Sjkim#undef ACPI_PATH_PUT8 289306536Sjkim 290306536Sjkim return_UINT32 (Length); 291306536Sjkim} 292306536Sjkim 293306536Sjkim 294306536Sjkim/******************************************************************************* 295306536Sjkim * 296306536Sjkim * FUNCTION: AcpiNsGetNormalizedPathname 297306536Sjkim * 298306536Sjkim * PARAMETERS: Node - Namespace node whose pathname is needed 299306536Sjkim * NoTrailing - Remove trailing '_' from each name segment 300306536Sjkim * 301306536Sjkim * RETURN: Pointer to storage containing the fully qualified name of 302306536Sjkim * the node, In external format (name segments separated by path 303306536Sjkim * separators.) 304306536Sjkim * 305306536Sjkim * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 306306536Sjkim * for error and debug statements. All trailing '_' will be 307306536Sjkim * removed from the full pathname if 'NoTrailing' is specified.. 308306536Sjkim * 309306536Sjkim ******************************************************************************/ 310306536Sjkim 311306536Sjkimchar * 312306536SjkimAcpiNsGetNormalizedPathname ( 313306536Sjkim ACPI_NAMESPACE_NODE *Node, 314306536Sjkim BOOLEAN NoTrailing) 315306536Sjkim{ 316306536Sjkim char *NameBuffer; 317306536Sjkim ACPI_SIZE Size; 318306536Sjkim 319306536Sjkim 320306536Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node); 321306536Sjkim 322306536Sjkim 323306536Sjkim /* Calculate required buffer size based on depth below root */ 324306536Sjkim 325306536Sjkim Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 326306536Sjkim if (!Size) 327306536Sjkim { 328306536Sjkim return_PTR (NULL); 329306536Sjkim } 330306536Sjkim 331306536Sjkim /* Allocate a buffer to be returned to caller */ 332306536Sjkim 333306536Sjkim NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 334306536Sjkim if (!NameBuffer) 335306536Sjkim { 336306536Sjkim ACPI_ERROR ((AE_INFO, 337306536Sjkim "Could not allocate %u bytes", (UINT32) Size)); 338306536Sjkim return_PTR (NULL); 339306536Sjkim } 340306536Sjkim 341306536Sjkim /* Build the path in the allocated buffer */ 342306536Sjkim 343306536Sjkim (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, Size, NoTrailing); 344306536Sjkim 345306536Sjkim return_PTR (NameBuffer); 346306536Sjkim} 347