1 /******************************************************************************* 2 * 3 * Module Name: nsnames - Name manipulation and search 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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: AcpiNsBuildExternalPath 57 * 58 * PARAMETERS: Node - NS node whose pathname is needed 59 * Size - Size of the pathname 60 * *NameBuffer - Where to return the pathname 61 * 62 * RETURN: Status 63 * Places the pathname into the NameBuffer, in external format 64 * (name segments separated by path separators) 65 * 66 * DESCRIPTION: Generate a full pathaname 67 * 68 ******************************************************************************/ 69 70 ACPI_STATUS 71 AcpiNsBuildExternalPath ( 72 ACPI_NAMESPACE_NODE *Node, 73 ACPI_SIZE Size, 74 char *NameBuffer) 75 { 76 ACPI_SIZE Index; 77 ACPI_NAMESPACE_NODE *ParentNode; 78 79 80 ACPI_FUNCTION_ENTRY (); 81 82 83 /* Special case for root */ 84 85 Index = Size - 1; 86 if (Index < ACPI_NAME_SIZE) 87 { 88 NameBuffer[0] = AML_ROOT_PREFIX; 89 NameBuffer[1] = 0; 90 return (AE_OK); 91 } 92 93 /* Store terminator byte, then build name backwards */ 94 95 ParentNode = Node; 96 NameBuffer[Index] = 0; 97 98 while ((Index > ACPI_NAME_SIZE) && (ParentNode != AcpiGbl_RootNode)) 99 { 100 Index -= ACPI_NAME_SIZE; 101 102 /* Put the name into the buffer */ 103 104 ACPI_MOVE_32_TO_32 ((NameBuffer + Index), &ParentNode->Name); 105 ParentNode = ParentNode->Parent; 106 107 /* Prefix name with the path separator */ 108 109 Index--; 110 NameBuffer[Index] = ACPI_PATH_SEPARATOR; 111 } 112 113 /* Overwrite final separator with the root prefix character */ 114 115 NameBuffer[Index] = AML_ROOT_PREFIX; 116 117 if (Index != 0) 118 { 119 ACPI_ERROR ((AE_INFO, 120 "Could not construct external pathname; index=%u, size=%u, Path=%s", 121 (UINT32) Index, (UINT32) Size, &NameBuffer[Size])); 122 123 return (AE_BAD_PARAMETER); 124 } 125 126 return (AE_OK); 127 } 128 129 130 /******************************************************************************* 131 * 132 * FUNCTION: AcpiNsGetExternalPathname 133 * 134 * PARAMETERS: Node - Namespace node whose pathname is needed 135 * 136 * RETURN: Pointer to storage containing the fully qualified name of 137 * the node, In external format (name segments separated by path 138 * separators.) 139 * 140 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually 141 * for error and debug statements. 142 * 143 ******************************************************************************/ 144 145 char * 146 AcpiNsGetExternalPathname ( 147 ACPI_NAMESPACE_NODE *Node) 148 { 149 ACPI_STATUS Status; 150 char *NameBuffer; 151 ACPI_SIZE Size; 152 153 154 ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node); 155 156 157 /* Calculate required buffer size based on depth below root */ 158 159 Size = AcpiNsGetPathnameLength (Node); 160 if (!Size) 161 { 162 return_PTR (NULL); 163 } 164 165 /* Allocate a buffer to be returned to caller */ 166 167 NameBuffer = ACPI_ALLOCATE_ZEROED (Size); 168 if (!NameBuffer) 169 { 170 ACPI_ERROR ((AE_INFO, "Could not allocate %u bytes", (UINT32) Size)); 171 return_PTR (NULL); 172 } 173 174 /* Build the path in the allocated buffer */ 175 176 Status = AcpiNsBuildExternalPath (Node, Size, NameBuffer); 177 if (ACPI_FAILURE (Status)) 178 { 179 ACPI_FREE (NameBuffer); 180 return_PTR (NULL); 181 } 182 183 return_PTR (NameBuffer); 184 } 185 186 187 /******************************************************************************* 188 * 189 * FUNCTION: AcpiNsGetPathnameLength 190 * 191 * PARAMETERS: Node - Namespace node 192 * 193 * RETURN: Length of path, including prefix 194 * 195 * DESCRIPTION: Get the length of the pathname string for this node 196 * 197 ******************************************************************************/ 198 199 ACPI_SIZE 200 AcpiNsGetPathnameLength ( 201 ACPI_NAMESPACE_NODE *Node) 202 { 203 ACPI_SIZE Size; 204 ACPI_NAMESPACE_NODE *NextNode; 205 206 207 ACPI_FUNCTION_ENTRY (); 208 209 210 /* 211 * Compute length of pathname as 5 * number of name segments. 212 * Go back up the parent tree to the root 213 */ 214 Size = 0; 215 NextNode = Node; 216 217 while (NextNode && (NextNode != AcpiGbl_RootNode)) 218 { 219 if (ACPI_GET_DESCRIPTOR_TYPE (NextNode) != ACPI_DESC_TYPE_NAMED) 220 { 221 ACPI_ERROR ((AE_INFO, 222 "Invalid Namespace Node (%p) while traversing namespace", 223 NextNode)); 224 return (0); 225 } 226 Size += ACPI_PATH_SEGMENT_LENGTH; 227 NextNode = NextNode->Parent; 228 } 229 230 if (!Size) 231 { 232 Size = 1; /* Root node case */ 233 } 234 235 return (Size + 1); /* +1 for null string terminator */ 236 } 237 238 239 /******************************************************************************* 240 * 241 * FUNCTION: AcpiNsHandleToPathname 242 * 243 * PARAMETERS: TargetHandle - Handle of named object whose name is 244 * to be found 245 * Buffer - Where the pathname is returned 246 * 247 * RETURN: Status, Buffer is filled with pathname if status is AE_OK 248 * 249 * DESCRIPTION: Build and return a full namespace pathname 250 * 251 ******************************************************************************/ 252 253 ACPI_STATUS 254 AcpiNsHandleToPathname ( 255 ACPI_HANDLE TargetHandle, 256 ACPI_BUFFER *Buffer) 257 { 258 ACPI_STATUS Status; 259 ACPI_NAMESPACE_NODE *Node; 260 ACPI_SIZE RequiredSize; 261 262 263 ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle); 264 265 266 Node = AcpiNsValidateHandle (TargetHandle); 267 if (!Node) 268 { 269 return_ACPI_STATUS (AE_BAD_PARAMETER); 270 } 271 272 /* Determine size required for the caller buffer */ 273 274 RequiredSize = AcpiNsGetPathnameLength (Node); 275 if (!RequiredSize) 276 { 277 return_ACPI_STATUS (AE_BAD_PARAMETER); 278 } 279 280 /* Validate/Allocate/Clear caller buffer */ 281 282 Status = AcpiUtInitializeBuffer (Buffer, RequiredSize); 283 if (ACPI_FAILURE (Status)) 284 { 285 return_ACPI_STATUS (Status); 286 } 287 288 /* Build the path in the caller buffer */ 289 290 Status = AcpiNsBuildExternalPath (Node, RequiredSize, Buffer->Pointer); 291 if (ACPI_FAILURE (Status)) 292 { 293 return_ACPI_STATUS (Status); 294 } 295 296 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n", 297 (char *) Buffer->Pointer, (UINT32) RequiredSize)); 298 return_ACPI_STATUS (AE_OK); 299 } 300