1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4ae115bc7Smrj * parents and siblings and Scope manipulation 5ae115bc7Smrj * 6ae115bc7Smrj *****************************************************************************/ 7ae115bc7Smrj 826f3cdf0SGordon Ross /* 9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 10ae115bc7Smrj * All rights reserved. 11ae115bc7Smrj * 1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1426f3cdf0SGordon Ross * are met: 1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1726f3cdf0SGordon Ross * without modification. 1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2226f3cdf0SGordon Ross * binary redistribution. 2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2526f3cdf0SGordon Ross * from this software without specific prior written permission. 26ae115bc7Smrj * 2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2926f3cdf0SGordon Ross * Software Foundation. 30ae115bc7Smrj * 3126f3cdf0SGordon Ross * NO WARRANTY 3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4326f3cdf0SGordon Ross */ 44ae115bc7Smrj 45ae115bc7Smrj #include "acpi.h" 46aa2aa9a6SDana Myers #include "accommon.h" 47ae115bc7Smrj #include "acnamesp.h" 48ae115bc7Smrj #include "amlcode.h" 49ae115bc7Smrj 50ae115bc7Smrj #define _COMPONENT ACPI_NAMESPACE 51ae115bc7Smrj ACPI_MODULE_NAME ("nsutils") 52ae115bc7Smrj 53ae115bc7Smrj /* Local prototypes */ 54ae115bc7Smrj 55ae115bc7Smrj #ifdef ACPI_OBSOLETE_FUNCTIONS 56ae115bc7Smrj ACPI_NAME 57ae115bc7Smrj AcpiNsFindParentName ( 58ae115bc7Smrj ACPI_NAMESPACE_NODE *NodeToSearch); 59ae115bc7Smrj #endif 60ae115bc7Smrj 61ae115bc7Smrj 62ae115bc7Smrj /******************************************************************************* 63ae115bc7Smrj * 64ae115bc7Smrj * FUNCTION: AcpiNsPrintNodePathname 65ae115bc7Smrj * 66ae115bc7Smrj * PARAMETERS: Node - Object 67ae115bc7Smrj * Message - Prefix message 68ae115bc7Smrj * 69ae115bc7Smrj * DESCRIPTION: Print an object's full namespace pathname 70ae115bc7Smrj * Manages allocation/freeing of a pathname buffer 71ae115bc7Smrj * 72ae115bc7Smrj ******************************************************************************/ 73ae115bc7Smrj 74ae115bc7Smrj void 75ae115bc7Smrj AcpiNsPrintNodePathname ( 76ae115bc7Smrj ACPI_NAMESPACE_NODE *Node, 77db2bae30SDana Myers const char *Message) 78ae115bc7Smrj { 79ae115bc7Smrj ACPI_BUFFER Buffer; 80ae115bc7Smrj ACPI_STATUS Status; 81ae115bc7Smrj 82ae115bc7Smrj 83ae115bc7Smrj if (!Node) 84ae115bc7Smrj { 85ae115bc7Smrj AcpiOsPrintf ("[NULL NAME]"); 86ae115bc7Smrj return; 87ae115bc7Smrj } 88ae115bc7Smrj 89ae115bc7Smrj /* Convert handle to full pathname and print it (with supplied message) */ 90ae115bc7Smrj 91ae115bc7Smrj Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 92ae115bc7Smrj 93*385cc6b4SJerry Jelinek Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 94ae115bc7Smrj if (ACPI_SUCCESS (Status)) 95ae115bc7Smrj { 96ae115bc7Smrj if (Message) 97ae115bc7Smrj { 98ae115bc7Smrj AcpiOsPrintf ("%s ", Message); 99ae115bc7Smrj } 100ae115bc7Smrj 101ae115bc7Smrj AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 102ae115bc7Smrj ACPI_FREE (Buffer.Pointer); 103ae115bc7Smrj } 104ae115bc7Smrj } 105ae115bc7Smrj 106ae115bc7Smrj 107ae115bc7Smrj /******************************************************************************* 108ae115bc7Smrj * 109ae115bc7Smrj * FUNCTION: AcpiNsGetType 110ae115bc7Smrj * 111ae115bc7Smrj * PARAMETERS: Node - Parent Node to be examined 112ae115bc7Smrj * 113ae115bc7Smrj * RETURN: Type field from Node whose handle is passed 114ae115bc7Smrj * 115ae115bc7Smrj * DESCRIPTION: Return the type of a Namespace node 116ae115bc7Smrj * 117ae115bc7Smrj ******************************************************************************/ 118ae115bc7Smrj 119ae115bc7Smrj ACPI_OBJECT_TYPE 120ae115bc7Smrj AcpiNsGetType ( 121ae115bc7Smrj ACPI_NAMESPACE_NODE *Node) 122ae115bc7Smrj { 123ae115bc7Smrj ACPI_FUNCTION_TRACE (NsGetType); 124ae115bc7Smrj 125ae115bc7Smrj 126ae115bc7Smrj if (!Node) 127ae115bc7Smrj { 128ae115bc7Smrj ACPI_WARNING ((AE_INFO, "Null Node parameter")); 129*385cc6b4SJerry Jelinek return_UINT8 (ACPI_TYPE_ANY); 130ae115bc7Smrj } 131ae115bc7Smrj 132*385cc6b4SJerry Jelinek return_UINT8 (Node->Type); 133ae115bc7Smrj } 134ae115bc7Smrj 135ae115bc7Smrj 136ae115bc7Smrj /******************************************************************************* 137ae115bc7Smrj * 138ae115bc7Smrj * FUNCTION: AcpiNsLocal 139ae115bc7Smrj * 140ae115bc7Smrj * PARAMETERS: Type - A namespace object type 141ae115bc7Smrj * 142ae115bc7Smrj * RETURN: LOCAL if names must be found locally in objects of the 143ae115bc7Smrj * passed type, 0 if enclosing scopes should be searched 144ae115bc7Smrj * 145ae115bc7Smrj * DESCRIPTION: Returns scope rule for the given object type. 146ae115bc7Smrj * 147ae115bc7Smrj ******************************************************************************/ 148ae115bc7Smrj 149ae115bc7Smrj UINT32 150ae115bc7Smrj AcpiNsLocal ( 151ae115bc7Smrj ACPI_OBJECT_TYPE Type) 152ae115bc7Smrj { 153ae115bc7Smrj ACPI_FUNCTION_TRACE (NsLocal); 154ae115bc7Smrj 155ae115bc7Smrj 156ae115bc7Smrj if (!AcpiUtValidObjectType (Type)) 157ae115bc7Smrj { 158ae115bc7Smrj /* Type code out of range */ 159ae115bc7Smrj 16026f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 161ae115bc7Smrj return_UINT32 (ACPI_NS_NORMAL); 162ae115bc7Smrj } 163ae115bc7Smrj 164*385cc6b4SJerry Jelinek return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 165ae115bc7Smrj } 166ae115bc7Smrj 167ae115bc7Smrj 168ae115bc7Smrj /******************************************************************************* 169ae115bc7Smrj * 170ae115bc7Smrj * FUNCTION: AcpiNsGetInternalNameLength 171ae115bc7Smrj * 172ae115bc7Smrj * PARAMETERS: Info - Info struct initialized with the 173ae115bc7Smrj * external name pointer. 174ae115bc7Smrj * 175ae115bc7Smrj * RETURN: None 176ae115bc7Smrj * 177ae115bc7Smrj * DESCRIPTION: Calculate the length of the internal (AML) namestring 178ae115bc7Smrj * corresponding to the external (ASL) namestring. 179ae115bc7Smrj * 180ae115bc7Smrj ******************************************************************************/ 181ae115bc7Smrj 182ae115bc7Smrj void 183ae115bc7Smrj AcpiNsGetInternalNameLength ( 184ae115bc7Smrj ACPI_NAMESTRING_INFO *Info) 185ae115bc7Smrj { 186db2bae30SDana Myers const char *NextExternalChar; 187ae115bc7Smrj UINT32 i; 188ae115bc7Smrj 189ae115bc7Smrj 190ae115bc7Smrj ACPI_FUNCTION_ENTRY (); 191ae115bc7Smrj 192ae115bc7Smrj 193ae115bc7Smrj NextExternalChar = Info->ExternalName; 194ae115bc7Smrj Info->NumCarats = 0; 195ae115bc7Smrj Info->NumSegments = 0; 196ae115bc7Smrj Info->FullyQualified = FALSE; 197ae115bc7Smrj 198ae115bc7Smrj /* 199*385cc6b4SJerry Jelinek * For the internal name, the required length is 4 bytes per segment, 200*385cc6b4SJerry Jelinek * plus 1 each for RootPrefix, MultiNamePrefixOp, segment count, 201*385cc6b4SJerry Jelinek * trailing null (which is not really needed, but no there's harm in 202*385cc6b4SJerry Jelinek * putting it there) 203ae115bc7Smrj * 204ae115bc7Smrj * strlen() + 1 covers the first NameSeg, which has no path separator 205ae115bc7Smrj */ 206*385cc6b4SJerry Jelinek if (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 207ae115bc7Smrj { 208ae115bc7Smrj Info->FullyQualified = TRUE; 209ae115bc7Smrj NextExternalChar++; 210aa2aa9a6SDana Myers 211aa2aa9a6SDana Myers /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 212aa2aa9a6SDana Myers 213*385cc6b4SJerry Jelinek while (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 214aa2aa9a6SDana Myers { 215aa2aa9a6SDana Myers NextExternalChar++; 216aa2aa9a6SDana Myers } 217ae115bc7Smrj } 218ae115bc7Smrj else 219ae115bc7Smrj { 220aa2aa9a6SDana Myers /* Handle Carat prefixes */ 221aa2aa9a6SDana Myers 222*385cc6b4SJerry Jelinek while (ACPI_IS_PARENT_PREFIX (*NextExternalChar)) 223ae115bc7Smrj { 224ae115bc7Smrj Info->NumCarats++; 225ae115bc7Smrj NextExternalChar++; 226ae115bc7Smrj } 227ae115bc7Smrj } 228ae115bc7Smrj 229ae115bc7Smrj /* 230ae115bc7Smrj * Determine the number of ACPI name "segments" by counting the number of 231ae115bc7Smrj * path separators within the string. Start with one segment since the 232ae115bc7Smrj * segment count is [(# separators) + 1], and zero separators is ok. 233ae115bc7Smrj */ 234ae115bc7Smrj if (*NextExternalChar) 235ae115bc7Smrj { 236ae115bc7Smrj Info->NumSegments = 1; 237ae115bc7Smrj for (i = 0; NextExternalChar[i]; i++) 238ae115bc7Smrj { 239*385cc6b4SJerry Jelinek if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i])) 240ae115bc7Smrj { 241ae115bc7Smrj Info->NumSegments++; 242ae115bc7Smrj } 243ae115bc7Smrj } 244ae115bc7Smrj } 245ae115bc7Smrj 246ae115bc7Smrj Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 247ae115bc7Smrj 4 + Info->NumCarats; 248ae115bc7Smrj 249ae115bc7Smrj Info->NextExternalChar = NextExternalChar; 250ae115bc7Smrj } 251ae115bc7Smrj 252ae115bc7Smrj 253ae115bc7Smrj /******************************************************************************* 254ae115bc7Smrj * 255ae115bc7Smrj * FUNCTION: AcpiNsBuildInternalName 256ae115bc7Smrj * 257ae115bc7Smrj * PARAMETERS: Info - Info struct fully initialized 258ae115bc7Smrj * 259ae115bc7Smrj * RETURN: Status 260ae115bc7Smrj * 261ae115bc7Smrj * DESCRIPTION: Construct the internal (AML) namestring 262ae115bc7Smrj * corresponding to the external (ASL) namestring. 263ae115bc7Smrj * 264ae115bc7Smrj ******************************************************************************/ 265ae115bc7Smrj 266ae115bc7Smrj ACPI_STATUS 267ae115bc7Smrj AcpiNsBuildInternalName ( 268ae115bc7Smrj ACPI_NAMESTRING_INFO *Info) 269ae115bc7Smrj { 270ae115bc7Smrj UINT32 NumSegments = Info->NumSegments; 271ae115bc7Smrj char *InternalName = Info->InternalName; 272db2bae30SDana Myers const char *ExternalName = Info->NextExternalChar; 273ae115bc7Smrj char *Result = NULL; 274db2bae30SDana Myers UINT32 i; 275ae115bc7Smrj 276ae115bc7Smrj 277ae115bc7Smrj ACPI_FUNCTION_TRACE (NsBuildInternalName); 278ae115bc7Smrj 279ae115bc7Smrj 280ae115bc7Smrj /* Setup the correct prefixes, counts, and pointers */ 281ae115bc7Smrj 282ae115bc7Smrj if (Info->FullyQualified) 283ae115bc7Smrj { 284*385cc6b4SJerry Jelinek InternalName[0] = AML_ROOT_PREFIX; 285ae115bc7Smrj 286ae115bc7Smrj if (NumSegments <= 1) 287ae115bc7Smrj { 288ae115bc7Smrj Result = &InternalName[1]; 289ae115bc7Smrj } 290ae115bc7Smrj else if (NumSegments == 2) 291ae115bc7Smrj { 292ae115bc7Smrj InternalName[1] = AML_DUAL_NAME_PREFIX; 293ae115bc7Smrj Result = &InternalName[2]; 294ae115bc7Smrj } 295ae115bc7Smrj else 296ae115bc7Smrj { 297ae115bc7Smrj InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 298ae115bc7Smrj InternalName[2] = (char) NumSegments; 299ae115bc7Smrj Result = &InternalName[3]; 300ae115bc7Smrj } 301ae115bc7Smrj } 302ae115bc7Smrj else 303ae115bc7Smrj { 304ae115bc7Smrj /* 305ae115bc7Smrj * Not fully qualified. 306ae115bc7Smrj * Handle Carats first, then append the name segments 307ae115bc7Smrj */ 308ae115bc7Smrj i = 0; 309ae115bc7Smrj if (Info->NumCarats) 310ae115bc7Smrj { 311ae115bc7Smrj for (i = 0; i < Info->NumCarats; i++) 312ae115bc7Smrj { 313*385cc6b4SJerry Jelinek InternalName[i] = AML_PARENT_PREFIX; 314ae115bc7Smrj } 315ae115bc7Smrj } 316ae115bc7Smrj 317ae115bc7Smrj if (NumSegments <= 1) 318ae115bc7Smrj { 319ae115bc7Smrj Result = &InternalName[i]; 320ae115bc7Smrj } 321ae115bc7Smrj else if (NumSegments == 2) 322ae115bc7Smrj { 323ae115bc7Smrj InternalName[i] = AML_DUAL_NAME_PREFIX; 324db2bae30SDana Myers Result = &InternalName[(ACPI_SIZE) i+1]; 325ae115bc7Smrj } 326ae115bc7Smrj else 327ae115bc7Smrj { 328ae115bc7Smrj InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 329db2bae30SDana Myers InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 330db2bae30SDana Myers Result = &InternalName[(ACPI_SIZE) i+2]; 331ae115bc7Smrj } 332ae115bc7Smrj } 333ae115bc7Smrj 334ae115bc7Smrj /* Build the name (minus path separators) */ 335ae115bc7Smrj 336ae115bc7Smrj for (; NumSegments; NumSegments--) 337ae115bc7Smrj { 338ae115bc7Smrj for (i = 0; i < ACPI_NAME_SIZE; i++) 339ae115bc7Smrj { 340*385cc6b4SJerry Jelinek if (ACPI_IS_PATH_SEPARATOR (*ExternalName) || 341ae115bc7Smrj (*ExternalName == 0)) 342ae115bc7Smrj { 343ae115bc7Smrj /* Pad the segment with underscore(s) if segment is short */ 344ae115bc7Smrj 345ae115bc7Smrj Result[i] = '_'; 346ae115bc7Smrj } 347ae115bc7Smrj else 348ae115bc7Smrj { 349ae115bc7Smrj /* Convert the character to uppercase and save it */ 350ae115bc7Smrj 351*385cc6b4SJerry Jelinek Result[i] = (char) toupper ((int) *ExternalName); 352ae115bc7Smrj ExternalName++; 353ae115bc7Smrj } 354ae115bc7Smrj } 355ae115bc7Smrj 356ae115bc7Smrj /* Now we must have a path separator, or the pathname is bad */ 357ae115bc7Smrj 358*385cc6b4SJerry Jelinek if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) && 359ae115bc7Smrj (*ExternalName != 0)) 360ae115bc7Smrj { 361*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PATHNAME); 362ae115bc7Smrj } 363ae115bc7Smrj 364ae115bc7Smrj /* Move on the next segment */ 365ae115bc7Smrj 366ae115bc7Smrj ExternalName++; 367ae115bc7Smrj Result += ACPI_NAME_SIZE; 368ae115bc7Smrj } 369ae115bc7Smrj 370ae115bc7Smrj /* Terminate the string */ 371ae115bc7Smrj 372ae115bc7Smrj *Result = 0; 373ae115bc7Smrj 374ae115bc7Smrj if (Info->FullyQualified) 375ae115bc7Smrj { 376ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 377ae115bc7Smrj InternalName, InternalName)); 378ae115bc7Smrj } 379ae115bc7Smrj else 380ae115bc7Smrj { 381ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 382ae115bc7Smrj InternalName, InternalName)); 383ae115bc7Smrj } 384ae115bc7Smrj 385ae115bc7Smrj return_ACPI_STATUS (AE_OK); 386ae115bc7Smrj } 387ae115bc7Smrj 388ae115bc7Smrj 389ae115bc7Smrj /******************************************************************************* 390ae115bc7Smrj * 391ae115bc7Smrj * FUNCTION: AcpiNsInternalizeName 392ae115bc7Smrj * 393ae115bc7Smrj * PARAMETERS: *ExternalName - External representation of name 394ae115bc7Smrj * **Converted Name - Where to return the resulting 395ae115bc7Smrj * internal represention of the name 396ae115bc7Smrj * 397ae115bc7Smrj * RETURN: Status 398ae115bc7Smrj * 399ae115bc7Smrj * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 400ae115bc7Smrj * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 401ae115bc7Smrj * 402ae115bc7Smrj *******************************************************************************/ 403ae115bc7Smrj 404ae115bc7Smrj ACPI_STATUS 405ae115bc7Smrj AcpiNsInternalizeName ( 406db2bae30SDana Myers const char *ExternalName, 407ae115bc7Smrj char **ConvertedName) 408ae115bc7Smrj { 409ae115bc7Smrj char *InternalName; 410ae115bc7Smrj ACPI_NAMESTRING_INFO Info; 411ae115bc7Smrj ACPI_STATUS Status; 412ae115bc7Smrj 413ae115bc7Smrj 414ae115bc7Smrj ACPI_FUNCTION_TRACE (NsInternalizeName); 415ae115bc7Smrj 416ae115bc7Smrj 417ae115bc7Smrj if ((!ExternalName) || 418ae115bc7Smrj (*ExternalName == 0) || 419ae115bc7Smrj (!ConvertedName)) 420ae115bc7Smrj { 421ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 422ae115bc7Smrj } 423ae115bc7Smrj 424ae115bc7Smrj /* Get the length of the new internal name */ 425ae115bc7Smrj 426ae115bc7Smrj Info.ExternalName = ExternalName; 427ae115bc7Smrj AcpiNsGetInternalNameLength (&Info); 428ae115bc7Smrj 429ae115bc7Smrj /* We need a segment to store the internal name */ 430ae115bc7Smrj 431ae115bc7Smrj InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 432ae115bc7Smrj if (!InternalName) 433ae115bc7Smrj { 434ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY); 435ae115bc7Smrj } 436ae115bc7Smrj 437ae115bc7Smrj /* Build the name */ 438ae115bc7Smrj 439ae115bc7Smrj Info.InternalName = InternalName; 440ae115bc7Smrj Status = AcpiNsBuildInternalName (&Info); 441ae115bc7Smrj if (ACPI_FAILURE (Status)) 442ae115bc7Smrj { 443ae115bc7Smrj ACPI_FREE (InternalName); 444ae115bc7Smrj return_ACPI_STATUS (Status); 445ae115bc7Smrj } 446ae115bc7Smrj 447ae115bc7Smrj *ConvertedName = InternalName; 448ae115bc7Smrj return_ACPI_STATUS (AE_OK); 449ae115bc7Smrj } 450ae115bc7Smrj 451ae115bc7Smrj 452ae115bc7Smrj /******************************************************************************* 453ae115bc7Smrj * 454ae115bc7Smrj * FUNCTION: AcpiNsExternalizeName 455ae115bc7Smrj * 456ae115bc7Smrj * PARAMETERS: InternalNameLength - Lenth of the internal name below 457ae115bc7Smrj * InternalName - Internal representation of name 458ae115bc7Smrj * ConvertedNameLength - Where the length is returned 459ae115bc7Smrj * ConvertedName - Where the resulting external name 460ae115bc7Smrj * is returned 461ae115bc7Smrj * 462ae115bc7Smrj * RETURN: Status 463ae115bc7Smrj * 464ae115bc7Smrj * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 465ae115bc7Smrj * to its external (printable) form (e.g. "\_PR_.CPU0") 466ae115bc7Smrj * 467ae115bc7Smrj ******************************************************************************/ 468ae115bc7Smrj 469ae115bc7Smrj ACPI_STATUS 470ae115bc7Smrj AcpiNsExternalizeName ( 471ae115bc7Smrj UINT32 InternalNameLength, 472db2bae30SDana Myers const char *InternalName, 473ae115bc7Smrj UINT32 *ConvertedNameLength, 474ae115bc7Smrj char **ConvertedName) 475ae115bc7Smrj { 476db2bae30SDana Myers UINT32 NamesIndex = 0; 477db2bae30SDana Myers UINT32 NumSegments = 0; 478db2bae30SDana Myers UINT32 RequiredLength; 479db2bae30SDana Myers UINT32 PrefixLength = 0; 480db2bae30SDana Myers UINT32 i = 0; 481db2bae30SDana Myers UINT32 j = 0; 482ae115bc7Smrj 483ae115bc7Smrj 484ae115bc7Smrj ACPI_FUNCTION_TRACE (NsExternalizeName); 485ae115bc7Smrj 486ae115bc7Smrj 487ae115bc7Smrj if (!InternalNameLength || 488ae115bc7Smrj !InternalName || 489ae115bc7Smrj !ConvertedName) 490ae115bc7Smrj { 491ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 492ae115bc7Smrj } 493ae115bc7Smrj 494aa2aa9a6SDana Myers /* Check for a prefix (one '\' | one or more '^') */ 495aa2aa9a6SDana Myers 496ae115bc7Smrj switch (InternalName[0]) 497ae115bc7Smrj { 498*385cc6b4SJerry Jelinek case AML_ROOT_PREFIX: 499*385cc6b4SJerry Jelinek 500ae115bc7Smrj PrefixLength = 1; 501ae115bc7Smrj break; 502ae115bc7Smrj 503*385cc6b4SJerry Jelinek case AML_PARENT_PREFIX: 504*385cc6b4SJerry Jelinek 505ae115bc7Smrj for (i = 0; i < InternalNameLength; i++) 506ae115bc7Smrj { 507*385cc6b4SJerry Jelinek if (ACPI_IS_PARENT_PREFIX (InternalName[i])) 508ae115bc7Smrj { 509ae115bc7Smrj PrefixLength = i + 1; 510ae115bc7Smrj } 511ae115bc7Smrj else 512ae115bc7Smrj { 513ae115bc7Smrj break; 514ae115bc7Smrj } 515ae115bc7Smrj } 516ae115bc7Smrj 517ae115bc7Smrj if (i == InternalNameLength) 518ae115bc7Smrj { 519ae115bc7Smrj PrefixLength = i; 520ae115bc7Smrj } 521ae115bc7Smrj 522ae115bc7Smrj break; 523ae115bc7Smrj 524ae115bc7Smrj default: 525*385cc6b4SJerry Jelinek 526ae115bc7Smrj break; 527ae115bc7Smrj } 528ae115bc7Smrj 529ae115bc7Smrj /* 530ae115bc7Smrj * Check for object names. Note that there could be 0-255 of these 531ae115bc7Smrj * 4-byte elements. 532ae115bc7Smrj */ 533ae115bc7Smrj if (PrefixLength < InternalNameLength) 534ae115bc7Smrj { 535ae115bc7Smrj switch (InternalName[PrefixLength]) 536ae115bc7Smrj { 537ae115bc7Smrj case AML_MULTI_NAME_PREFIX_OP: 538ae115bc7Smrj 539ae115bc7Smrj /* <count> 4-byte names */ 540ae115bc7Smrj 541ae115bc7Smrj NamesIndex = PrefixLength + 2; 542db2bae30SDana Myers NumSegments = (UINT8) 543db2bae30SDana Myers InternalName[(ACPI_SIZE) PrefixLength + 1]; 544ae115bc7Smrj break; 545ae115bc7Smrj 546ae115bc7Smrj case AML_DUAL_NAME_PREFIX: 547ae115bc7Smrj 548ae115bc7Smrj /* Two 4-byte names */ 549ae115bc7Smrj 550ae115bc7Smrj NamesIndex = PrefixLength + 1; 551ae115bc7Smrj NumSegments = 2; 552ae115bc7Smrj break; 553ae115bc7Smrj 554ae115bc7Smrj case 0: 555ae115bc7Smrj 556ae115bc7Smrj /* NullName */ 557ae115bc7Smrj 558ae115bc7Smrj NamesIndex = 0; 559ae115bc7Smrj NumSegments = 0; 560ae115bc7Smrj break; 561ae115bc7Smrj 562ae115bc7Smrj default: 563ae115bc7Smrj 564ae115bc7Smrj /* one 4-byte name */ 565ae115bc7Smrj 566ae115bc7Smrj NamesIndex = PrefixLength; 567ae115bc7Smrj NumSegments = 1; 568ae115bc7Smrj break; 569ae115bc7Smrj } 570ae115bc7Smrj } 571ae115bc7Smrj 572ae115bc7Smrj /* 573ae115bc7Smrj * Calculate the length of ConvertedName, which equals the length 574ae115bc7Smrj * of the prefix, length of all object names, length of any required 575ae115bc7Smrj * punctuation ('.') between object names, plus the NULL terminator. 576ae115bc7Smrj */ 577ae115bc7Smrj RequiredLength = PrefixLength + (4 * NumSegments) + 578ae115bc7Smrj ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 579ae115bc7Smrj 580ae115bc7Smrj /* 581ae115bc7Smrj * Check to see if we're still in bounds. If not, there's a problem 582ae115bc7Smrj * with InternalName (invalid format). 583ae115bc7Smrj */ 584ae115bc7Smrj if (RequiredLength > InternalNameLength) 585ae115bc7Smrj { 586ae115bc7Smrj ACPI_ERROR ((AE_INFO, "Invalid internal name")); 587ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PATHNAME); 588ae115bc7Smrj } 589ae115bc7Smrj 590aa2aa9a6SDana Myers /* Build the ConvertedName */ 591aa2aa9a6SDana Myers 592ae115bc7Smrj *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 593ae115bc7Smrj if (!(*ConvertedName)) 594ae115bc7Smrj { 595ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY); 596ae115bc7Smrj } 597ae115bc7Smrj 598ae115bc7Smrj j = 0; 599ae115bc7Smrj 600ae115bc7Smrj for (i = 0; i < PrefixLength; i++) 601ae115bc7Smrj { 602ae115bc7Smrj (*ConvertedName)[j++] = InternalName[i]; 603ae115bc7Smrj } 604ae115bc7Smrj 605ae115bc7Smrj if (NumSegments > 0) 606ae115bc7Smrj { 607ae115bc7Smrj for (i = 0; i < NumSegments; i++) 608ae115bc7Smrj { 609ae115bc7Smrj if (i > 0) 610ae115bc7Smrj { 611ae115bc7Smrj (*ConvertedName)[j++] = '.'; 612ae115bc7Smrj } 613ae115bc7Smrj 614*385cc6b4SJerry Jelinek /* Copy and validate the 4-char name segment */ 615*385cc6b4SJerry Jelinek 616*385cc6b4SJerry Jelinek ACPI_MOVE_NAME (&(*ConvertedName)[j], 617*385cc6b4SJerry Jelinek &InternalName[NamesIndex]); 618*385cc6b4SJerry Jelinek AcpiUtRepairName (&(*ConvertedName)[j]); 619*385cc6b4SJerry Jelinek 620*385cc6b4SJerry Jelinek j += ACPI_NAME_SIZE; 621*385cc6b4SJerry Jelinek NamesIndex += ACPI_NAME_SIZE; 622ae115bc7Smrj } 623ae115bc7Smrj } 624ae115bc7Smrj 625ae115bc7Smrj if (ConvertedNameLength) 626ae115bc7Smrj { 627ae115bc7Smrj *ConvertedNameLength = (UINT32) RequiredLength; 628ae115bc7Smrj } 629ae115bc7Smrj 630ae115bc7Smrj return_ACPI_STATUS (AE_OK); 631ae115bc7Smrj } 632ae115bc7Smrj 633ae115bc7Smrj 634ae115bc7Smrj /******************************************************************************* 635ae115bc7Smrj * 63626f3cdf0SGordon Ross * FUNCTION: AcpiNsValidateHandle 637ae115bc7Smrj * 63826f3cdf0SGordon Ross * PARAMETERS: Handle - Handle to be validated and typecast to a 63926f3cdf0SGordon Ross * namespace node. 640ae115bc7Smrj * 64126f3cdf0SGordon Ross * RETURN: A pointer to a namespace node 642ae115bc7Smrj * 64326f3cdf0SGordon Ross * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 64426f3cdf0SGordon Ross * cases for the root node. 645ae115bc7Smrj * 64626f3cdf0SGordon Ross * NOTE: Real integer handles would allow for more verification 647ae115bc7Smrj * and keep all pointers within this subsystem - however this introduces 64826f3cdf0SGordon Ross * more overhead and has not been necessary to this point. Drivers 64926f3cdf0SGordon Ross * holding handles are typically notified before a node becomes invalid 65026f3cdf0SGordon Ross * due to a table unload. 651aa2aa9a6SDana Myers * 652ae115bc7Smrj ******************************************************************************/ 653ae115bc7Smrj 654ae115bc7Smrj ACPI_NAMESPACE_NODE * 65526f3cdf0SGordon Ross AcpiNsValidateHandle ( 656ae115bc7Smrj ACPI_HANDLE Handle) 657ae115bc7Smrj { 658ae115bc7Smrj 659ae115bc7Smrj ACPI_FUNCTION_ENTRY (); 660ae115bc7Smrj 661ae115bc7Smrj 662aa2aa9a6SDana Myers /* Parameter validation */ 663aa2aa9a6SDana Myers 664ae115bc7Smrj if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 665ae115bc7Smrj { 666ae115bc7Smrj return (AcpiGbl_RootNode); 667ae115bc7Smrj } 668ae115bc7Smrj 669ae115bc7Smrj /* We can at least attempt to verify the handle */ 670ae115bc7Smrj 671ae115bc7Smrj if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 672ae115bc7Smrj { 673ae115bc7Smrj return (NULL); 674ae115bc7Smrj } 675ae115bc7Smrj 676ae115bc7Smrj return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 677ae115bc7Smrj } 678ae115bc7Smrj 679ae115bc7Smrj 680ae115bc7Smrj /******************************************************************************* 681ae115bc7Smrj * 682ae115bc7Smrj * FUNCTION: AcpiNsTerminate 683ae115bc7Smrj * 684ae115bc7Smrj * PARAMETERS: none 685ae115bc7Smrj * 686ae115bc7Smrj * RETURN: none 687ae115bc7Smrj * 688ae115bc7Smrj * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 689ae115bc7Smrj * 690ae115bc7Smrj ******************************************************************************/ 691ae115bc7Smrj 692ae115bc7Smrj void 693ae115bc7Smrj AcpiNsTerminate ( 694ae115bc7Smrj void) 695ae115bc7Smrj { 696*385cc6b4SJerry Jelinek ACPI_STATUS Status; 697ae115bc7Smrj 698ae115bc7Smrj 699ae115bc7Smrj ACPI_FUNCTION_TRACE (NsTerminate); 700ae115bc7Smrj 701ae115bc7Smrj 702*385cc6b4SJerry Jelinek #ifdef ACPI_EXEC_APP 703*385cc6b4SJerry Jelinek { 704*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *Prev; 705*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *Next; 706*385cc6b4SJerry Jelinek 707*385cc6b4SJerry Jelinek /* Delete any module-level code blocks */ 708*385cc6b4SJerry Jelinek 709*385cc6b4SJerry Jelinek Next = AcpiGbl_ModuleCodeList; 710*385cc6b4SJerry Jelinek while (Next) 711*385cc6b4SJerry Jelinek { 712*385cc6b4SJerry Jelinek Prev = Next; 713*385cc6b4SJerry Jelinek Next = Next->Method.Mutex; 714*385cc6b4SJerry Jelinek Prev->Method.Mutex = NULL; /* Clear the Mutex (cheated) field */ 715*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Prev); 716*385cc6b4SJerry Jelinek } 717*385cc6b4SJerry Jelinek } 718*385cc6b4SJerry Jelinek #endif 719*385cc6b4SJerry Jelinek 720ae115bc7Smrj /* 721*385cc6b4SJerry Jelinek * Free the entire namespace -- all nodes and all objects 722*385cc6b4SJerry Jelinek * attached to the nodes 723ae115bc7Smrj */ 724ae115bc7Smrj AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 725ae115bc7Smrj 726*385cc6b4SJerry Jelinek /* Delete any objects attached to the root node */ 727ae115bc7Smrj 728*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 729*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 730ae115bc7Smrj { 731*385cc6b4SJerry Jelinek return_VOID; 732ae115bc7Smrj } 733ae115bc7Smrj 734*385cc6b4SJerry Jelinek AcpiNsDeleteNode (AcpiGbl_RootNode); 735*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 736*385cc6b4SJerry Jelinek 737ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 738ae115bc7Smrj return_VOID; 739ae115bc7Smrj } 740ae115bc7Smrj 741ae115bc7Smrj 742ae115bc7Smrj /******************************************************************************* 743ae115bc7Smrj * 744ae115bc7Smrj * FUNCTION: AcpiNsOpensScope 745ae115bc7Smrj * 746ae115bc7Smrj * PARAMETERS: Type - A valid namespace type 747ae115bc7Smrj * 748ae115bc7Smrj * RETURN: NEWSCOPE if the passed type "opens a name scope" according 749ae115bc7Smrj * to the ACPI specification, else 0 750ae115bc7Smrj * 751ae115bc7Smrj ******************************************************************************/ 752ae115bc7Smrj 753ae115bc7Smrj UINT32 754ae115bc7Smrj AcpiNsOpensScope ( 755ae115bc7Smrj ACPI_OBJECT_TYPE Type) 756ae115bc7Smrj { 757*385cc6b4SJerry Jelinek ACPI_FUNCTION_ENTRY (); 758ae115bc7Smrj 759ae115bc7Smrj 760*385cc6b4SJerry Jelinek if (Type > ACPI_TYPE_LOCAL_MAX) 761ae115bc7Smrj { 762ae115bc7Smrj /* type code out of range */ 763ae115bc7Smrj 76426f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 765*385cc6b4SJerry Jelinek return (ACPI_NS_NORMAL); 766ae115bc7Smrj } 767ae115bc7Smrj 768*385cc6b4SJerry Jelinek return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 769ae115bc7Smrj } 770ae115bc7Smrj 771ae115bc7Smrj 772ae115bc7Smrj /******************************************************************************* 773ae115bc7Smrj * 774ae115bc7Smrj * FUNCTION: AcpiNsGetNode 775ae115bc7Smrj * 776ae115bc7Smrj * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 777ae115bc7Smrj * \ (backslash) and ^ (carat) prefixes, and the 778ae115bc7Smrj * . (period) to separate segments are supported. 779ae115bc7Smrj * PrefixNode - Root of subtree to be searched, or NS_ALL for the 780ae115bc7Smrj * root of the name space. If Name is fully 781ae115bc7Smrj * qualified (first INT8 is '\'), the passed value 782ae115bc7Smrj * of Scope will not be accessed. 783ae115bc7Smrj * Flags - Used to indicate whether to perform upsearch or 784ae115bc7Smrj * not. 785ae115bc7Smrj * ReturnNode - Where the Node is returned 786ae115bc7Smrj * 787ae115bc7Smrj * DESCRIPTION: Look up a name relative to a given scope and return the 788ae115bc7Smrj * corresponding Node. NOTE: Scope can be null. 789ae115bc7Smrj * 790ae115bc7Smrj * MUTEX: Locks namespace 791ae115bc7Smrj * 792ae115bc7Smrj ******************************************************************************/ 793ae115bc7Smrj 794ae115bc7Smrj ACPI_STATUS 795ae115bc7Smrj AcpiNsGetNode ( 796ae115bc7Smrj ACPI_NAMESPACE_NODE *PrefixNode, 797db2bae30SDana Myers const char *Pathname, 798ae115bc7Smrj UINT32 Flags, 799ae115bc7Smrj ACPI_NAMESPACE_NODE **ReturnNode) 800ae115bc7Smrj { 801ae115bc7Smrj ACPI_GENERIC_STATE ScopeInfo; 802ae115bc7Smrj ACPI_STATUS Status; 803ae115bc7Smrj char *InternalPath; 804ae115bc7Smrj 805ae115bc7Smrj 80657190917SDana Myers ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 807ae115bc7Smrj 808ae115bc7Smrj 809*385cc6b4SJerry Jelinek /* Simplest case is a null pathname */ 810*385cc6b4SJerry Jelinek 811ae115bc7Smrj if (!Pathname) 812ae115bc7Smrj { 813ae115bc7Smrj *ReturnNode = PrefixNode; 814ae115bc7Smrj if (!PrefixNode) 815ae115bc7Smrj { 816ae115bc7Smrj *ReturnNode = AcpiGbl_RootNode; 817ae115bc7Smrj } 818*385cc6b4SJerry Jelinek 819*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 820*385cc6b4SJerry Jelinek } 821*385cc6b4SJerry Jelinek 822*385cc6b4SJerry Jelinek /* Quick check for a reference to the root */ 823*385cc6b4SJerry Jelinek 824*385cc6b4SJerry Jelinek if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1])) 825*385cc6b4SJerry Jelinek { 826*385cc6b4SJerry Jelinek *ReturnNode = AcpiGbl_RootNode; 827ae115bc7Smrj return_ACPI_STATUS (AE_OK); 828ae115bc7Smrj } 829ae115bc7Smrj 830ae115bc7Smrj /* Convert path to internal representation */ 831ae115bc7Smrj 832ae115bc7Smrj Status = AcpiNsInternalizeName (Pathname, &InternalPath); 833ae115bc7Smrj if (ACPI_FAILURE (Status)) 834ae115bc7Smrj { 835ae115bc7Smrj return_ACPI_STATUS (Status); 836ae115bc7Smrj } 837ae115bc7Smrj 838ae115bc7Smrj /* Must lock namespace during lookup */ 839ae115bc7Smrj 840ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 841ae115bc7Smrj if (ACPI_FAILURE (Status)) 842ae115bc7Smrj { 843ae115bc7Smrj goto Cleanup; 844ae115bc7Smrj } 845ae115bc7Smrj 846ae115bc7Smrj /* Setup lookup scope (search starting point) */ 847ae115bc7Smrj 848ae115bc7Smrj ScopeInfo.Scope.Node = PrefixNode; 849ae115bc7Smrj 850ae115bc7Smrj /* Lookup the name in the namespace */ 851ae115bc7Smrj 852ae115bc7Smrj Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 853ae115bc7Smrj ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 854ae115bc7Smrj NULL, ReturnNode); 855ae115bc7Smrj if (ACPI_FAILURE (Status)) 856ae115bc7Smrj { 857aa2aa9a6SDana Myers ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 858ae115bc7Smrj Pathname, AcpiFormatException (Status))); 859ae115bc7Smrj } 860ae115bc7Smrj 861ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 862ae115bc7Smrj 863ae115bc7Smrj Cleanup: 864ae115bc7Smrj ACPI_FREE (InternalPath); 865ae115bc7Smrj return_ACPI_STATUS (Status); 866ae115bc7Smrj } 867