1*a159c266SJung-uk Kim /******************************************************************************* 2*a159c266SJung-uk Kim * 3*a159c266SJung-uk Kim * Module Name: nsnames - Name manipulation and search 4*a159c266SJung-uk Kim * 5*a159c266SJung-uk Kim ******************************************************************************/ 6*a159c266SJung-uk Kim 7*a159c266SJung-uk Kim /* 8*a159c266SJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9*a159c266SJung-uk Kim * All rights reserved. 10*a159c266SJung-uk Kim * 11*a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13*a159c266SJung-uk Kim * are met: 14*a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*a159c266SJung-uk Kim * without modification. 17*a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*a159c266SJung-uk Kim * binary redistribution. 22*a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*a159c266SJung-uk Kim * from this software without specific prior written permission. 25*a159c266SJung-uk Kim * 26*a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*a159c266SJung-uk Kim * Software Foundation. 29*a159c266SJung-uk Kim * 30*a159c266SJung-uk Kim * NO WARRANTY 31*a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*a159c266SJung-uk Kim */ 43*a159c266SJung-uk Kim 44*a159c266SJung-uk Kim #define __NSNAMES_C__ 45*a159c266SJung-uk Kim 46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 50*a159c266SJung-uk Kim 51*a159c266SJung-uk Kim 52*a159c266SJung-uk Kim #define _COMPONENT ACPI_NAMESPACE 53*a159c266SJung-uk Kim ACPI_MODULE_NAME ("nsnames") 54*a159c266SJung-uk Kim 55*a159c266SJung-uk Kim 56*a159c266SJung-uk Kim /******************************************************************************* 57*a159c266SJung-uk Kim * 58*a159c266SJung-uk Kim * FUNCTION: AcpiNsBuildExternalPath 59*a159c266SJung-uk Kim * 60*a159c266SJung-uk Kim * PARAMETERS: Node - NS node whose pathname is needed 61*a159c266SJung-uk Kim * Size - Size of the pathname 62*a159c266SJung-uk Kim * *NameBuffer - Where to return the pathname 63*a159c266SJung-uk Kim * 64*a159c266SJung-uk Kim * RETURN: Status 65*a159c266SJung-uk Kim * Places the pathname into the NameBuffer, in external format 66*a159c266SJung-uk Kim * (name segments separated by path separators) 67*a159c266SJung-uk Kim * 68*a159c266SJung-uk Kim * DESCRIPTION: Generate a full pathaname 69*a159c266SJung-uk Kim * 70*a159c266SJung-uk Kim ******************************************************************************/ 71*a159c266SJung-uk Kim 72*a159c266SJung-uk Kim ACPI_STATUS 73*a159c266SJung-uk Kim AcpiNsBuildExternalPath ( 74*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node, 75*a159c266SJung-uk Kim ACPI_SIZE Size, 76*a159c266SJung-uk Kim char *NameBuffer) 77*a159c266SJung-uk Kim { 78*a159c266SJung-uk Kim ACPI_SIZE Index; 79*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *ParentNode; 80*a159c266SJung-uk Kim 81*a159c266SJung-uk Kim 82*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 83*a159c266SJung-uk Kim 84*a159c266SJung-uk Kim 85*a159c266SJung-uk Kim /* Special case for root */ 86*a159c266SJung-uk Kim 87*a159c266SJung-uk Kim Index = Size - 1; 88*a159c266SJung-uk Kim if (Index < ACPI_NAME_SIZE) 89*a159c266SJung-uk Kim { 90*a159c266SJung-uk Kim NameBuffer[0] = AML_ROOT_PREFIX; 91*a159c266SJung-uk Kim NameBuffer[1] = 0; 92*a159c266SJung-uk Kim return (AE_OK); 93*a159c266SJung-uk Kim } 94*a159c266SJung-uk Kim 95*a159c266SJung-uk Kim /* Store terminator byte, then build name backwards */ 96*a159c266SJung-uk Kim 97*a159c266SJung-uk Kim ParentNode = Node; 98*a159c266SJung-uk Kim NameBuffer[Index] = 0; 99*a159c266SJung-uk Kim 100*a159c266SJung-uk Kim while ((Index > ACPI_NAME_SIZE) && (ParentNode != AcpiGbl_RootNode)) 101*a159c266SJung-uk Kim { 102*a159c266SJung-uk Kim Index -= ACPI_NAME_SIZE; 103*a159c266SJung-uk Kim 104*a159c266SJung-uk Kim /* Put the name into the buffer */ 105*a159c266SJung-uk Kim 106*a159c266SJung-uk Kim ACPI_MOVE_32_TO_32 ((NameBuffer + Index), &ParentNode->Name); 107*a159c266SJung-uk Kim ParentNode = ParentNode->Parent; 108*a159c266SJung-uk Kim 109*a159c266SJung-uk Kim /* Prefix name with the path separator */ 110*a159c266SJung-uk Kim 111*a159c266SJung-uk Kim Index--; 112*a159c266SJung-uk Kim NameBuffer[Index] = ACPI_PATH_SEPARATOR; 113*a159c266SJung-uk Kim } 114*a159c266SJung-uk Kim 115*a159c266SJung-uk Kim /* Overwrite final separator with the root prefix character */ 116*a159c266SJung-uk Kim 117*a159c266SJung-uk Kim NameBuffer[Index] = AML_ROOT_PREFIX; 118*a159c266SJung-uk Kim 119*a159c266SJung-uk Kim if (Index != 0) 120*a159c266SJung-uk Kim { 121*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, 122*a159c266SJung-uk Kim "Could not construct external pathname; index=%u, size=%u, Path=%s", 123*a159c266SJung-uk Kim (UINT32) Index, (UINT32) Size, &NameBuffer[Size])); 124*a159c266SJung-uk Kim 125*a159c266SJung-uk Kim return (AE_BAD_PARAMETER); 126*a159c266SJung-uk Kim } 127*a159c266SJung-uk Kim 128*a159c266SJung-uk Kim return (AE_OK); 129*a159c266SJung-uk Kim } 130*a159c266SJung-uk Kim 131*a159c266SJung-uk Kim 132*a159c266SJung-uk Kim /******************************************************************************* 133*a159c266SJung-uk Kim * 134*a159c266SJung-uk Kim * FUNCTION: AcpiNsGetExternalPathname 135*a159c266SJung-uk Kim * 136*a159c266SJung-uk Kim * PARAMETERS: Node - Namespace node whose pathname is needed 137*a159c266SJung-uk Kim * 138*a159c266SJung-uk Kim * RETURN: Pointer to storage containing the fully qualified name of 139*a159c266SJung-uk Kim * the node, In external format (name segments separated by path 140*a159c266SJung-uk Kim * separators.) 141*a159c266SJung-uk Kim * 142*a159c266SJung-uk Kim * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 143*a159c266SJung-uk Kim * for error and debug statements. 144*a159c266SJung-uk Kim * 145*a159c266SJung-uk Kim ******************************************************************************/ 146*a159c266SJung-uk Kim 147*a159c266SJung-uk Kim char * 148*a159c266SJung-uk Kim AcpiNsGetExternalPathname ( 149*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node) 150*a159c266SJung-uk Kim { 151*a159c266SJung-uk Kim ACPI_STATUS Status; 152*a159c266SJung-uk Kim char *NameBuffer; 153*a159c266SJung-uk Kim ACPI_SIZE Size; 154*a159c266SJung-uk Kim 155*a159c266SJung-uk Kim 156*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node); 157*a159c266SJung-uk Kim 158*a159c266SJung-uk Kim 159*a159c266SJung-uk Kim /* Calculate required buffer size based on depth below root */ 160*a159c266SJung-uk Kim 161*a159c266SJung-uk Kim Size = AcpiNsGetPathnameLength (Node); 162*a159c266SJung-uk Kim if (!Size) 163*a159c266SJung-uk Kim { 164*a159c266SJung-uk Kim return_PTR (NULL); 165*a159c266SJung-uk Kim } 166*a159c266SJung-uk Kim 167*a159c266SJung-uk Kim /* Allocate a buffer to be returned to caller */ 168*a159c266SJung-uk Kim 169*a159c266SJung-uk Kim NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 170*a159c266SJung-uk Kim if (!NameBuffer) 171*a159c266SJung-uk Kim { 172*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, "Could not allocate %u bytes", (UINT32) Size)); 173*a159c266SJung-uk Kim return_PTR (NULL); 174*a159c266SJung-uk Kim } 175*a159c266SJung-uk Kim 176*a159c266SJung-uk Kim /* Build the path in the allocated buffer */ 177*a159c266SJung-uk Kim 178*a159c266SJung-uk Kim Status = AcpiNsBuildExternalPath (Node, Size, NameBuffer); 179*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 180*a159c266SJung-uk Kim { 181*a159c266SJung-uk Kim ACPI_FREE (NameBuffer); 182*a159c266SJung-uk Kim return_PTR (NULL); 183*a159c266SJung-uk Kim } 184*a159c266SJung-uk Kim 185*a159c266SJung-uk Kim return_PTR (NameBuffer); 186*a159c266SJung-uk Kim } 187*a159c266SJung-uk Kim 188*a159c266SJung-uk Kim 189*a159c266SJung-uk Kim /******************************************************************************* 190*a159c266SJung-uk Kim * 191*a159c266SJung-uk Kim * FUNCTION: AcpiNsGetPathnameLength 192*a159c266SJung-uk Kim * 193*a159c266SJung-uk Kim * PARAMETERS: Node - Namespace node 194*a159c266SJung-uk Kim * 195*a159c266SJung-uk Kim * RETURN: Length of path, including prefix 196*a159c266SJung-uk Kim * 197*a159c266SJung-uk Kim * DESCRIPTION: Get the length of the pathname string for this node 198*a159c266SJung-uk Kim * 199*a159c266SJung-uk Kim ******************************************************************************/ 200*a159c266SJung-uk Kim 201*a159c266SJung-uk Kim ACPI_SIZE 202*a159c266SJung-uk Kim AcpiNsGetPathnameLength ( 203*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node) 204*a159c266SJung-uk Kim { 205*a159c266SJung-uk Kim ACPI_SIZE Size; 206*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *NextNode; 207*a159c266SJung-uk Kim 208*a159c266SJung-uk Kim 209*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 210*a159c266SJung-uk Kim 211*a159c266SJung-uk Kim 212*a159c266SJung-uk Kim /* 213*a159c266SJung-uk Kim * Compute length of pathname as 5 * number of name segments. 214*a159c266SJung-uk Kim * Go back up the parent tree to the root 215*a159c266SJung-uk Kim */ 216*a159c266SJung-uk Kim Size = 0; 217*a159c266SJung-uk Kim NextNode = Node; 218*a159c266SJung-uk Kim 219*a159c266SJung-uk Kim while (NextNode && (NextNode != AcpiGbl_RootNode)) 220*a159c266SJung-uk Kim { 221*a159c266SJung-uk Kim if (ACPI_GET_DESCRIPTOR_TYPE (NextNode) != ACPI_DESC_TYPE_NAMED) 222*a159c266SJung-uk Kim { 223*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, 224*a159c266SJung-uk Kim "Invalid Namespace Node (%p) while traversing namespace", 225*a159c266SJung-uk Kim NextNode)); 226*a159c266SJung-uk Kim return 0; 227*a159c266SJung-uk Kim } 228*a159c266SJung-uk Kim Size += ACPI_PATH_SEGMENT_LENGTH; 229*a159c266SJung-uk Kim NextNode = NextNode->Parent; 230*a159c266SJung-uk Kim } 231*a159c266SJung-uk Kim 232*a159c266SJung-uk Kim if (!Size) 233*a159c266SJung-uk Kim { 234*a159c266SJung-uk Kim Size = 1; /* Root node case */ 235*a159c266SJung-uk Kim } 236*a159c266SJung-uk Kim 237*a159c266SJung-uk Kim return (Size + 1); /* +1 for null string terminator */ 238*a159c266SJung-uk Kim } 239*a159c266SJung-uk Kim 240*a159c266SJung-uk Kim 241*a159c266SJung-uk Kim /******************************************************************************* 242*a159c266SJung-uk Kim * 243*a159c266SJung-uk Kim * FUNCTION: AcpiNsHandleToPathname 244*a159c266SJung-uk Kim * 245*a159c266SJung-uk Kim * PARAMETERS: TargetHandle - Handle of named object whose name is 246*a159c266SJung-uk Kim * to be found 247*a159c266SJung-uk Kim * Buffer - Where the pathname is returned 248*a159c266SJung-uk Kim * 249*a159c266SJung-uk Kim * RETURN: Status, Buffer is filled with pathname if status is AE_OK 250*a159c266SJung-uk Kim * 251*a159c266SJung-uk Kim * DESCRIPTION: Build and return a full namespace pathname 252*a159c266SJung-uk Kim * 253*a159c266SJung-uk Kim ******************************************************************************/ 254*a159c266SJung-uk Kim 255*a159c266SJung-uk Kim ACPI_STATUS 256*a159c266SJung-uk Kim AcpiNsHandleToPathname ( 257*a159c266SJung-uk Kim ACPI_HANDLE TargetHandle, 258*a159c266SJung-uk Kim ACPI_BUFFER *Buffer) 259*a159c266SJung-uk Kim { 260*a159c266SJung-uk Kim ACPI_STATUS Status; 261*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node; 262*a159c266SJung-uk Kim ACPI_SIZE RequiredSize; 263*a159c266SJung-uk Kim 264*a159c266SJung-uk Kim 265*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 266*a159c266SJung-uk Kim 267*a159c266SJung-uk Kim 268*a159c266SJung-uk Kim Node = AcpiNsValidateHandle (TargetHandle); 269*a159c266SJung-uk Kim if (!Node) 270*a159c266SJung-uk Kim { 271*a159c266SJung-uk Kim return_ACPI_STATUS (AE_BAD_PARAMETER); 272*a159c266SJung-uk Kim } 273*a159c266SJung-uk Kim 274*a159c266SJung-uk Kim /* Determine size required for the caller buffer */ 275*a159c266SJung-uk Kim 276*a159c266SJung-uk Kim RequiredSize = AcpiNsGetPathnameLength (Node); 277*a159c266SJung-uk Kim if (!RequiredSize) 278*a159c266SJung-uk Kim { 279*a159c266SJung-uk Kim return_ACPI_STATUS (AE_BAD_PARAMETER); 280*a159c266SJung-uk Kim } 281*a159c266SJung-uk Kim 282*a159c266SJung-uk Kim /* Validate/Allocate/Clear caller buffer */ 283*a159c266SJung-uk Kim 284*a159c266SJung-uk Kim Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 285*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 286*a159c266SJung-uk Kim { 287*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 288*a159c266SJung-uk Kim } 289*a159c266SJung-uk Kim 290*a159c266SJung-uk Kim /* Build the path in the caller buffer */ 291*a159c266SJung-uk Kim 292*a159c266SJung-uk Kim Status = AcpiNsBuildExternalPath (Node, RequiredSize, Buffer->Pointer); 293*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 294*a159c266SJung-uk Kim { 295*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 296*a159c266SJung-uk Kim } 297*a159c266SJung-uk Kim 298*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 299*a159c266SJung-uk Kim (char *) Buffer->Pointer, (UINT32) RequiredSize)); 300*a159c266SJung-uk Kim return_ACPI_STATUS (AE_OK); 301*a159c266SJung-uk Kim } 302*a159c266SJung-uk Kim 303*a159c266SJung-uk Kim 304