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