1 /******************************************************************************* 2 * 3 * Module Name: nsnames - Name manipulation and search 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/amlcode.h> 47 #include <contrib/dev/acpica/include/acnamesp.h> 48 49 50 #define _COMPONENT ACPI_NAMESPACE 51 ACPI_MODULE_NAME ("nsnames") 52 53 54 /******************************************************************************* 55 * 56 * FUNCTION: AcpiNsGetExternalPathname 57 * 58 * PARAMETERS: Node - Namespace node whose pathname is needed 59 * 60 * RETURN: Pointer to storage containing the fully qualified name of 61 * the node, In external format (name segments separated by path 62 * separators.) 63 * 64 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 65 * for error and debug statements. 66 * 67 ******************************************************************************/ 68 69 char * 70 AcpiNsGetExternalPathname ( 71 ACPI_NAMESPACE_NODE *Node) 72 { 73 char *NameBuffer; 74 75 76 ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node); 77 78 79 NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE); 80 return_PTR (NameBuffer); 81 } 82 83 84 /******************************************************************************* 85 * 86 * FUNCTION: AcpiNsGetPathnameLength 87 * 88 * PARAMETERS: Node - Namespace node 89 * 90 * RETURN: Length of path, including prefix 91 * 92 * DESCRIPTION: Get the length of the pathname string for this node 93 * 94 ******************************************************************************/ 95 96 ACPI_SIZE 97 AcpiNsGetPathnameLength ( 98 ACPI_NAMESPACE_NODE *Node) 99 { 100 ACPI_SIZE Size; 101 102 103 ACPI_FUNCTION_ENTRY (); 104 105 106 Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE); 107 return (Size); 108 } 109 110 111 /******************************************************************************* 112 * 113 * FUNCTION: AcpiNsHandleToName 114 * 115 * PARAMETERS: TargetHandle - Handle of named object whose name is 116 * to be found 117 * Buffer - Where the name is returned 118 * 119 * RETURN: Status, Buffer is filled with name if status is AE_OK 120 * 121 * DESCRIPTION: Build and return a full namespace name 122 * 123 ******************************************************************************/ 124 125 ACPI_STATUS 126 AcpiNsHandleToName ( 127 ACPI_HANDLE TargetHandle, 128 ACPI_BUFFER *Buffer) 129 { 130 ACPI_STATUS Status; 131 ACPI_NAMESPACE_NODE *Node; 132 const char *NodeName; 133 134 135 ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle); 136 137 138 Node = AcpiNsValidateHandle (TargetHandle); 139 if (!Node) 140 { 141 return_ACPI_STATUS (AE_BAD_PARAMETER); 142 } 143 144 /* Validate/Allocate/Clear caller buffer */ 145 146 Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH); 147 if (ACPI_FAILURE (Status)) 148 { 149 return_ACPI_STATUS (Status); 150 } 151 152 /* Just copy the ACPI name from the Node and zero terminate it */ 153 154 NodeName = AcpiUtGetNodeName (Node); 155 ACPI_MOVE_NAME (Buffer->Pointer, NodeName); 156 ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0; 157 158 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer)); 159 return_ACPI_STATUS (AE_OK); 160 } 161 162 163 /******************************************************************************* 164 * 165 * FUNCTION: AcpiNsHandleToPathname 166 * 167 * PARAMETERS: TargetHandle - Handle of named object whose name is 168 * to be found 169 * Buffer - Where the pathname is returned 170 * NoTrailing - Remove trailing '_' for each name 171 * segment 172 * 173 * RETURN: Status, Buffer is filled with pathname if status is AE_OK 174 * 175 * DESCRIPTION: Build and return a full namespace pathname 176 * 177 ******************************************************************************/ 178 179 ACPI_STATUS 180 AcpiNsHandleToPathname ( 181 ACPI_HANDLE TargetHandle, 182 ACPI_BUFFER *Buffer, 183 BOOLEAN NoTrailing) 184 { 185 ACPI_STATUS Status; 186 ACPI_NAMESPACE_NODE *Node; 187 ACPI_SIZE RequiredSize; 188 189 190 ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 191 192 193 Node = AcpiNsValidateHandle (TargetHandle); 194 if (!Node) 195 { 196 return_ACPI_STATUS (AE_BAD_PARAMETER); 197 } 198 199 /* Determine size required for the caller buffer */ 200 201 RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 202 if (!RequiredSize) 203 { 204 return_ACPI_STATUS (AE_BAD_PARAMETER); 205 } 206 207 /* Validate/Allocate/Clear caller buffer */ 208 209 Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 210 if (ACPI_FAILURE (Status)) 211 { 212 return_ACPI_STATUS (Status); 213 } 214 215 /* Build the path in the caller buffer */ 216 217 (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer, 218 RequiredSize, NoTrailing); 219 if (ACPI_FAILURE (Status)) 220 { 221 return_ACPI_STATUS (Status); 222 } 223 224 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 225 (char *) Buffer->Pointer, (UINT32) RequiredSize)); 226 return_ACPI_STATUS (AE_OK); 227 } 228 229 230 /******************************************************************************* 231 * 232 * FUNCTION: AcpiNsBuildNormalizedPath 233 * 234 * PARAMETERS: Node - Namespace node 235 * FullPath - Where the path name is returned 236 * PathSize - Size of returned path name buffer 237 * NoTrailing - Remove trailing '_' from each name segment 238 * 239 * RETURN: Return 1 if the AML path is empty, otherwise returning (length 240 * of pathname + 1) which means the 'FullPath' contains a trailing 241 * null. 242 * 243 * DESCRIPTION: Build and return a full namespace pathname. 244 * Note that if the size of 'FullPath' isn't large enough to 245 * contain the namespace node's path name, the actual required 246 * buffer length is returned, and it should be greater than 247 * 'PathSize'. So callers are able to check the returning value 248 * to determine the buffer size of 'FullPath'. 249 * 250 ******************************************************************************/ 251 252 UINT32 253 AcpiNsBuildNormalizedPath ( 254 ACPI_NAMESPACE_NODE *Node, 255 char *FullPath, 256 UINT32 PathSize, 257 BOOLEAN NoTrailing) 258 { 259 UINT32 Length = 0, i; 260 char Name[ACPI_NAME_SIZE]; 261 BOOLEAN DoNoTrailing; 262 char c, *Left, *Right; 263 ACPI_NAMESPACE_NODE *NextNode; 264 265 266 ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node); 267 268 269 #define ACPI_PATH_PUT8(Path, Size, Byte, Length) \ 270 do { \ 271 if ((Length) < (Size)) \ 272 { \ 273 (Path)[(Length)] = (Byte); \ 274 } \ 275 (Length)++; \ 276 } while (0) 277 278 /* 279 * Make sure the PathSize is correct, so that we don't need to 280 * validate both FullPath and PathSize. 281 */ 282 if (!FullPath) 283 { 284 PathSize = 0; 285 } 286 287 if (!Node) 288 { 289 goto BuildTrailingNull; 290 } 291 292 NextNode = Node; 293 while (NextNode && NextNode != AcpiGbl_RootNode) 294 { 295 if (NextNode != Node) 296 { 297 ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length); 298 } 299 300 ACPI_MOVE_32_TO_32 (Name, &NextNode->Name); 301 DoNoTrailing = NoTrailing; 302 for (i = 0; i < 4; i++) 303 { 304 c = Name[4-i-1]; 305 if (DoNoTrailing && c != '_') 306 { 307 DoNoTrailing = FALSE; 308 } 309 if (!DoNoTrailing) 310 { 311 ACPI_PATH_PUT8(FullPath, PathSize, c, Length); 312 } 313 } 314 315 NextNode = NextNode->Parent; 316 } 317 318 ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length); 319 320 /* Reverse the path string */ 321 322 if (Length <= PathSize) 323 { 324 Left = FullPath; 325 Right = FullPath+Length - 1; 326 327 while (Left < Right) 328 { 329 c = *Left; 330 *Left++ = *Right; 331 *Right-- = c; 332 } 333 } 334 335 /* Append the trailing null */ 336 337 BuildTrailingNull: 338 ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length); 339 340 #undef ACPI_PATH_PUT8 341 342 return_UINT32 (Length); 343 } 344 345 346 /******************************************************************************* 347 * 348 * FUNCTION: AcpiNsGetNormalizedPathname 349 * 350 * PARAMETERS: Node - Namespace node whose pathname is needed 351 * NoTrailing - Remove trailing '_' from each name segment 352 * 353 * RETURN: Pointer to storage containing the fully qualified name of 354 * the node, In external format (name segments separated by path 355 * separators.) 356 * 357 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 358 * for error and debug statements. All trailing '_' will be 359 * removed from the full pathname if 'NoTrailing' is specified.. 360 * 361 ******************************************************************************/ 362 363 char * 364 AcpiNsGetNormalizedPathname ( 365 ACPI_NAMESPACE_NODE *Node, 366 BOOLEAN NoTrailing) 367 { 368 char *NameBuffer; 369 ACPI_SIZE Size; 370 371 372 ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node); 373 374 375 /* Calculate required buffer size based on depth below root */ 376 377 Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 378 if (!Size) 379 { 380 return_PTR (NULL); 381 } 382 383 /* Allocate a buffer to be returned to caller */ 384 385 NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 386 if (!NameBuffer) 387 { 388 ACPI_ERROR ((AE_INFO, 389 "Could not allocate %u bytes", (UINT32) Size)); 390 return_PTR (NULL); 391 } 392 393 /* Build the path in the allocated buffer */ 394 395 (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, Size, NoTrailing); 396 397 return_PTR (NameBuffer); 398 } 399