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: AcpiNsHandleToPathname 114 * 115 * PARAMETERS: TargetHandle - Handle of named object whose name is 116 * to be found 117 * Buffer - Where the pathname is returned 118 * NoTrailing - Remove trailing '_' for each name 119 * segment 120 * 121 * RETURN: Status, Buffer is filled with pathname if status is AE_OK 122 * 123 * DESCRIPTION: Build and return a full namespace pathname 124 * 125 ******************************************************************************/ 126 127 ACPI_STATUS 128 AcpiNsHandleToPathname ( 129 ACPI_HANDLE TargetHandle, 130 ACPI_BUFFER *Buffer, 131 BOOLEAN NoTrailing) 132 { 133 ACPI_STATUS Status; 134 ACPI_NAMESPACE_NODE *Node; 135 ACPI_SIZE RequiredSize; 136 137 138 ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 139 140 141 Node = AcpiNsValidateHandle (TargetHandle); 142 if (!Node) 143 { 144 return_ACPI_STATUS (AE_BAD_PARAMETER); 145 } 146 147 /* Determine size required for the caller buffer */ 148 149 RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 150 if (!RequiredSize) 151 { 152 return_ACPI_STATUS (AE_BAD_PARAMETER); 153 } 154 155 /* Validate/Allocate/Clear caller buffer */ 156 157 Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 158 if (ACPI_FAILURE (Status)) 159 { 160 return_ACPI_STATUS (Status); 161 } 162 163 /* Build the path in the caller buffer */ 164 165 (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer, 166 RequiredSize, NoTrailing); 167 if (ACPI_FAILURE (Status)) 168 { 169 return_ACPI_STATUS (Status); 170 } 171 172 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 173 (char *) Buffer->Pointer, (UINT32) RequiredSize)); 174 return_ACPI_STATUS (AE_OK); 175 } 176 177 178 /******************************************************************************* 179 * 180 * FUNCTION: AcpiNsBuildNormalizedPath 181 * 182 * PARAMETERS: Node - Namespace node 183 * FullPath - Where the path name is returned 184 * PathSize - Size of returned path name buffer 185 * NoTrailing - Remove trailing '_' from each name segment 186 * 187 * RETURN: Return 1 if the AML path is empty, otherwise returning (length 188 * of pathname + 1) which means the 'FullPath' contains a trailing 189 * null. 190 * 191 * DESCRIPTION: Build and return a full namespace pathname. 192 * Note that if the size of 'FullPath' isn't large enough to 193 * contain the namespace node's path name, the actual required 194 * buffer length is returned, and it should be greater than 195 * 'PathSize'. So callers are able to check the returning value 196 * to determine the buffer size of 'FullPath'. 197 * 198 ******************************************************************************/ 199 200 UINT32 201 AcpiNsBuildNormalizedPath ( 202 ACPI_NAMESPACE_NODE *Node, 203 char *FullPath, 204 UINT32 PathSize, 205 BOOLEAN NoTrailing) 206 { 207 UINT32 Length = 0, i; 208 char Name[ACPI_NAME_SIZE]; 209 BOOLEAN DoNoTrailing; 210 char c, *Left, *Right; 211 ACPI_NAMESPACE_NODE *NextNode; 212 213 214 ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node); 215 216 217 #define ACPI_PATH_PUT8(Path, Size, Byte, Length) \ 218 do { \ 219 if ((Length) < (Size)) \ 220 { \ 221 (Path)[(Length)] = (Byte); \ 222 } \ 223 (Length)++; \ 224 } while (0) 225 226 /* 227 * Make sure the PathSize is correct, so that we don't need to 228 * validate both FullPath and PathSize. 229 */ 230 if (!FullPath) 231 { 232 PathSize = 0; 233 } 234 235 if (!Node) 236 { 237 goto BuildTrailingNull; 238 } 239 240 NextNode = Node; 241 while (NextNode && NextNode != AcpiGbl_RootNode) 242 { 243 if (NextNode != Node) 244 { 245 ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length); 246 } 247 248 ACPI_MOVE_32_TO_32 (Name, &NextNode->Name); 249 DoNoTrailing = NoTrailing; 250 for (i = 0; i < 4; i++) 251 { 252 c = Name[4-i-1]; 253 if (DoNoTrailing && c != '_') 254 { 255 DoNoTrailing = FALSE; 256 } 257 if (!DoNoTrailing) 258 { 259 ACPI_PATH_PUT8(FullPath, PathSize, c, Length); 260 } 261 } 262 263 NextNode = NextNode->Parent; 264 } 265 266 ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length); 267 268 /* Reverse the path string */ 269 270 if (Length <= PathSize) 271 { 272 Left = FullPath; 273 Right = FullPath+Length - 1; 274 275 while (Left < Right) 276 { 277 c = *Left; 278 *Left++ = *Right; 279 *Right-- = c; 280 } 281 } 282 283 /* Append the trailing null */ 284 285 BuildTrailingNull: 286 ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length); 287 288 #undef ACPI_PATH_PUT8 289 290 return_UINT32 (Length); 291 } 292 293 294 /******************************************************************************* 295 * 296 * FUNCTION: AcpiNsGetNormalizedPathname 297 * 298 * PARAMETERS: Node - Namespace node whose pathname is needed 299 * NoTrailing - Remove trailing '_' from each name segment 300 * 301 * RETURN: Pointer to storage containing the fully qualified name of 302 * the node, In external format (name segments separated by path 303 * separators.) 304 * 305 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 306 * for error and debug statements. All trailing '_' will be 307 * removed from the full pathname if 'NoTrailing' is specified.. 308 * 309 ******************************************************************************/ 310 311 char * 312 AcpiNsGetNormalizedPathname ( 313 ACPI_NAMESPACE_NODE *Node, 314 BOOLEAN NoTrailing) 315 { 316 char *NameBuffer; 317 ACPI_SIZE Size; 318 319 320 ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node); 321 322 323 /* Calculate required buffer size based on depth below root */ 324 325 Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing); 326 if (!Size) 327 { 328 return_PTR (NULL); 329 } 330 331 /* Allocate a buffer to be returned to caller */ 332 333 NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 334 if (!NameBuffer) 335 { 336 ACPI_ERROR ((AE_INFO, 337 "Could not allocate %u bytes", (UINT32) Size)); 338 return_PTR (NULL); 339 } 340 341 /* Build the path in the allocated buffer */ 342 343 (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, Size, NoTrailing); 344 345 return_PTR (NameBuffer); 346 } 347