167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsnames - Name manipulation and search 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, 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: AcpiNsBuildExternalPath 5767754Smsmith * 5891116Smsmith * PARAMETERS: Node - NS node whose pathname is needed 5991116Smsmith * Size - Size of the pathname 6091116Smsmith * *NameBuffer - Where to return the pathname 6167754Smsmith * 62193267Sjkim * RETURN: Status 63193267Sjkim * Places the pathname into the NameBuffer, in external format 6491116Smsmith * (name segments separated by path separators) 6567754Smsmith * 6691116Smsmith * DESCRIPTION: Generate a full pathaname 6767754Smsmith * 6867754Smsmith ******************************************************************************/ 6967754Smsmith 70193267SjkimACPI_STATUS 7191116SmsmithAcpiNsBuildExternalPath ( 7291116Smsmith ACPI_NAMESPACE_NODE *Node, 7391116Smsmith ACPI_SIZE Size, 74114237Snjl char *NameBuffer) 7567754Smsmith{ 7699679Siwasaki ACPI_SIZE Index; 7767754Smsmith ACPI_NAMESPACE_NODE *ParentNode; 7867754Smsmith 7967754Smsmith 80167802Sjkim ACPI_FUNCTION_ENTRY (); 8167754Smsmith 8267754Smsmith 8391116Smsmith /* Special case for root */ 8491116Smsmith 8591116Smsmith Index = Size - 1; 8691116Smsmith if (Index < ACPI_NAME_SIZE) 8767754Smsmith { 8891116Smsmith NameBuffer[0] = AML_ROOT_PREFIX; 8991116Smsmith NameBuffer[1] = 0; 90193267Sjkim return (AE_OK); 9167754Smsmith } 9267754Smsmith 9391116Smsmith /* Store terminator byte, then build name backwards */ 9467754Smsmith 9591116Smsmith ParentNode = Node; 9691116Smsmith NameBuffer[Index] = 0; 9767754Smsmith 9891116Smsmith while ((Index > ACPI_NAME_SIZE) && (ParentNode != AcpiGbl_RootNode)) 9991116Smsmith { 10091116Smsmith Index -= ACPI_NAME_SIZE; 10167754Smsmith 10291116Smsmith /* Put the name into the buffer */ 10391116Smsmith 104117521Snjl ACPI_MOVE_32_TO_32 ((NameBuffer + Index), &ParentNode->Name); 105209746Sjkim ParentNode = ParentNode->Parent; 10691116Smsmith 10791116Smsmith /* Prefix name with the path separator */ 10891116Smsmith 10991116Smsmith Index--; 110114237Snjl NameBuffer[Index] = ACPI_PATH_SEPARATOR; 11167754Smsmith } 11267754Smsmith 11391116Smsmith /* Overwrite final separator with the root prefix character */ 11467754Smsmith 11591116Smsmith NameBuffer[Index] = AML_ROOT_PREFIX; 11667754Smsmith 11791116Smsmith if (Index != 0) 11867754Smsmith { 119167802Sjkim ACPI_ERROR ((AE_INFO, 120204773Sjkim "Could not construct external pathname; index=%u, size=%u, Path=%s", 12199679Siwasaki (UINT32) Index, (UINT32) Size, &NameBuffer[Size])); 122193267Sjkim 123193267Sjkim return (AE_BAD_PARAMETER); 12467754Smsmith } 12567754Smsmith 126193267Sjkim return (AE_OK); 12791116Smsmith} 12867754Smsmith 12967754Smsmith 13091116Smsmith/******************************************************************************* 13191116Smsmith * 13291116Smsmith * FUNCTION: AcpiNsGetExternalPathname 13391116Smsmith * 134151937Sjkim * PARAMETERS: Node - Namespace node whose pathname is needed 13591116Smsmith * 13691116Smsmith * RETURN: Pointer to storage containing the fully qualified name of 13791116Smsmith * the node, In external format (name segments separated by path 13891116Smsmith * separators.) 13991116Smsmith * 140193267Sjkim * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 141193267Sjkim * for error and debug statements. 14291116Smsmith * 14391116Smsmith ******************************************************************************/ 14467754Smsmith 145114237Snjlchar * 14691116SmsmithAcpiNsGetExternalPathname ( 14791116Smsmith ACPI_NAMESPACE_NODE *Node) 14891116Smsmith{ 149193267Sjkim ACPI_STATUS Status; 150114237Snjl char *NameBuffer; 15191116Smsmith ACPI_SIZE Size; 15267754Smsmith 15367754Smsmith 154167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node); 15567754Smsmith 15691116Smsmith 15791116Smsmith /* Calculate required buffer size based on depth below root */ 15891116Smsmith 15991116Smsmith Size = AcpiNsGetPathnameLength (Node); 160193267Sjkim if (!Size) 161193267Sjkim { 162193267Sjkim return_PTR (NULL); 163193267Sjkim } 16491116Smsmith 16591116Smsmith /* Allocate a buffer to be returned to caller */ 16691116Smsmith 167167802Sjkim NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 16891116Smsmith if (!NameBuffer) 16967754Smsmith { 170193267Sjkim ACPI_ERROR ((AE_INFO, "Could not allocate %u bytes", (UINT32) Size)); 17191116Smsmith return_PTR (NULL); 17267754Smsmith } 17367754Smsmith 17491116Smsmith /* Build the path in the allocated buffer */ 17591116Smsmith 176193267Sjkim Status = AcpiNsBuildExternalPath (Node, Size, NameBuffer); 177193267Sjkim if (ACPI_FAILURE (Status)) 178193267Sjkim { 179193267Sjkim ACPI_FREE (NameBuffer); 180193267Sjkim return_PTR (NULL); 181193267Sjkim } 182193267Sjkim 18367754Smsmith return_PTR (NameBuffer); 18467754Smsmith} 18567754Smsmith 18667754Smsmith 18767754Smsmith/******************************************************************************* 18867754Smsmith * 18973561Smsmith * FUNCTION: AcpiNsGetPathnameLength 19073561Smsmith * 19173561Smsmith * PARAMETERS: Node - Namespace node 19273561Smsmith * 19373561Smsmith * RETURN: Length of path, including prefix 19473561Smsmith * 19573561Smsmith * DESCRIPTION: Get the length of the pathname string for this node 19673561Smsmith * 19773561Smsmith ******************************************************************************/ 19873561Smsmith 19991116SmsmithACPI_SIZE 20073561SmsmithAcpiNsGetPathnameLength ( 20173561Smsmith ACPI_NAMESPACE_NODE *Node) 20273561Smsmith{ 20391116Smsmith ACPI_SIZE Size; 20473561Smsmith ACPI_NAMESPACE_NODE *NextNode; 20573561Smsmith 20683174Smsmith 20791116Smsmith ACPI_FUNCTION_ENTRY (); 20883174Smsmith 20983174Smsmith 21073561Smsmith /* 21173561Smsmith * Compute length of pathname as 5 * number of name segments. 21273561Smsmith * Go back up the parent tree to the root 21373561Smsmith */ 21491116Smsmith Size = 0; 21591116Smsmith NextNode = Node; 21691116Smsmith 217100966Siwasaki while (NextNode && (NextNode != AcpiGbl_RootNode)) 21873561Smsmith { 219193267Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (NextNode) != ACPI_DESC_TYPE_NAMED) 220193267Sjkim { 221193267Sjkim ACPI_ERROR ((AE_INFO, 222193267Sjkim "Invalid Namespace Node (%p) while traversing namespace", 223193267Sjkim NextNode)); 224241973Sjkim return (0); 225193267Sjkim } 226114237Snjl Size += ACPI_PATH_SEGMENT_LENGTH; 227209746Sjkim NextNode = NextNode->Parent; 22873561Smsmith } 22973561Smsmith 230138287Smarks if (!Size) 231138287Smarks { 232193267Sjkim Size = 1; /* Root node case */ 233138287Smarks } 234138287Smarks 235138287Smarks return (Size + 1); /* +1 for null string terminator */ 23673561Smsmith} 23773561Smsmith 23873561Smsmith 23973561Smsmith/******************************************************************************* 24073561Smsmith * 24167754Smsmith * FUNCTION: AcpiNsHandleToPathname 24267754Smsmith * 24367754Smsmith * PARAMETERS: TargetHandle - Handle of named object whose name is 24467754Smsmith * to be found 24591116Smsmith * Buffer - Where the pathname is returned 24667754Smsmith * 24767754Smsmith * RETURN: Status, Buffer is filled with pathname if status is AE_OK 24867754Smsmith * 24967754Smsmith * DESCRIPTION: Build and return a full namespace pathname 25067754Smsmith * 25167754Smsmith ******************************************************************************/ 25267754Smsmith 25367754SmsmithACPI_STATUS 25467754SmsmithAcpiNsHandleToPathname ( 25567754Smsmith ACPI_HANDLE TargetHandle, 25691116Smsmith ACPI_BUFFER *Buffer) 25767754Smsmith{ 25891116Smsmith ACPI_STATUS Status; 25967754Smsmith ACPI_NAMESPACE_NODE *Node; 26091116Smsmith ACPI_SIZE RequiredSize; 26167754Smsmith 26283174Smsmith 263167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 26467754Smsmith 26567754Smsmith 266200553Sjkim Node = AcpiNsValidateHandle (TargetHandle); 26767754Smsmith if (!Node) 26867754Smsmith { 26967754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 27067754Smsmith } 27167754Smsmith 27291116Smsmith /* Determine size required for the caller buffer */ 27367754Smsmith 27491116Smsmith RequiredSize = AcpiNsGetPathnameLength (Node); 275193267Sjkim if (!RequiredSize) 276193267Sjkim { 277193267Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 278193267Sjkim } 27969746Smsmith 28091116Smsmith /* Validate/Allocate/Clear caller buffer */ 28169746Smsmith 28291116Smsmith Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 28391116Smsmith if (ACPI_FAILURE (Status)) 28467754Smsmith { 28591116Smsmith return_ACPI_STATUS (Status); 28667754Smsmith } 28767754Smsmith 28891116Smsmith /* Build the path in the caller buffer */ 28987031Smsmith 290193267Sjkim Status = AcpiNsBuildExternalPath (Node, RequiredSize, Buffer->Pointer); 291193267Sjkim if (ACPI_FAILURE (Status)) 292193267Sjkim { 293193267Sjkim return_ACPI_STATUS (Status); 294193267Sjkim } 29567754Smsmith 296151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 297138287Smarks (char *) Buffer->Pointer, (UINT32) RequiredSize)); 29891116Smsmith return_ACPI_STATUS (AE_OK); 29967754Smsmith} 300