167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 467754Smsmith * parents and siblings and Scope manipulation 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 1070243Smsmith * All rights reserved. 1167754Smsmith * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 2667754Smsmith * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 3067754Smsmith * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 4467754Smsmith 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_NAMESPACE 5191116Smsmith ACPI_MODULE_NAME ("nsutils") 5267754Smsmith 53151937Sjkim/* Local prototypes */ 5467754Smsmith 55151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 56151937SjkimACPI_NAME 57151937SjkimAcpiNsFindParentName ( 58151937Sjkim ACPI_NAMESPACE_NODE *NodeToSearch); 59151937Sjkim#endif 60151937Sjkim 61151937Sjkim 6277424Smsmith/******************************************************************************* 6367754Smsmith * 64114237Snjl * FUNCTION: AcpiNsPrintNodePathname 65114237Snjl * 66151937Sjkim * PARAMETERS: Node - Object 67151937Sjkim * Message - Prefix message 68114237Snjl * 69114237Snjl * DESCRIPTION: Print an object's full namespace pathname 70114237Snjl * Manages allocation/freeing of a pathname buffer 71114237Snjl * 72114237Snjl ******************************************************************************/ 73114237Snjl 74114237Snjlvoid 75114237SnjlAcpiNsPrintNodePathname ( 76114237Snjl ACPI_NAMESPACE_NODE *Node, 77193267Sjkim const char *Message) 78114237Snjl{ 79114237Snjl ACPI_BUFFER Buffer; 80114237Snjl ACPI_STATUS Status; 81114237Snjl 82114237Snjl 83123315Snjl if (!Node) 84123315Snjl { 85123315Snjl AcpiOsPrintf ("[NULL NAME]"); 86123315Snjl return; 87123315Snjl } 88123315Snjl 89138287Smarks /* Convert handle to full pathname and print it (with supplied message) */ 90114237Snjl 91114237Snjl Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 92114237Snjl 93306536Sjkim Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 94114237Snjl if (ACPI_SUCCESS (Status)) 95114237Snjl { 96151937Sjkim if (Message) 97117521Snjl { 98151937Sjkim AcpiOsPrintf ("%s ", Message); 99117521Snjl } 100117521Snjl 101117521Snjl AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 102167802Sjkim ACPI_FREE (Buffer.Pointer); 103114237Snjl } 104114237Snjl} 105114237Snjl 106114237Snjl 107114237Snjl/******************************************************************************* 108114237Snjl * 10967754Smsmith * FUNCTION: AcpiNsGetType 11067754Smsmith * 111151937Sjkim * PARAMETERS: Node - Parent Node to be examined 11267754Smsmith * 11367754Smsmith * RETURN: Type field from Node whose handle is passed 11467754Smsmith * 115151937Sjkim * DESCRIPTION: Return the type of a Namespace node 116151937Sjkim * 11777424Smsmith ******************************************************************************/ 11867754Smsmith 11991116SmsmithACPI_OBJECT_TYPE 12067754SmsmithAcpiNsGetType ( 12177424Smsmith ACPI_NAMESPACE_NODE *Node) 12267754Smsmith{ 123167802Sjkim ACPI_FUNCTION_TRACE (NsGetType); 12467754Smsmith 12567754Smsmith 12677424Smsmith if (!Node) 12767754Smsmith { 128167802Sjkim ACPI_WARNING ((AE_INFO, "Null Node parameter")); 129246849Sjkim return_UINT8 (ACPI_TYPE_ANY); 13067754Smsmith } 13167754Smsmith 132246849Sjkim return_UINT8 (Node->Type); 13367754Smsmith} 13467754Smsmith 13567754Smsmith 13677424Smsmith/******************************************************************************* 13767754Smsmith * 13867754Smsmith * FUNCTION: AcpiNsLocal 13967754Smsmith * 140151937Sjkim * PARAMETERS: Type - A namespace object type 14167754Smsmith * 14267754Smsmith * RETURN: LOCAL if names must be found locally in objects of the 14367754Smsmith * passed type, 0 if enclosing scopes should be searched 14467754Smsmith * 145151937Sjkim * DESCRIPTION: Returns scope rule for the given object type. 146151937Sjkim * 14777424Smsmith ******************************************************************************/ 14867754Smsmith 14967754SmsmithUINT32 15067754SmsmithAcpiNsLocal ( 15191116Smsmith ACPI_OBJECT_TYPE Type) 15267754Smsmith{ 153167802Sjkim ACPI_FUNCTION_TRACE (NsLocal); 15467754Smsmith 15567754Smsmith 15677424Smsmith if (!AcpiUtValidObjectType (Type)) 15767754Smsmith { 15867754Smsmith /* Type code out of range */ 15967754Smsmith 160204773Sjkim ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 161246849Sjkim return_UINT32 (ACPI_NS_NORMAL); 16267754Smsmith } 16367754Smsmith 164246849Sjkim return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 16567754Smsmith} 16667754Smsmith 16767754Smsmith 16877424Smsmith/******************************************************************************* 16967754Smsmith * 17077424Smsmith * FUNCTION: AcpiNsGetInternalNameLength 17167754Smsmith * 17283174Smsmith * PARAMETERS: Info - Info struct initialized with the 17377424Smsmith * external name pointer. 17467754Smsmith * 175151937Sjkim * RETURN: None 17667754Smsmith * 17783174Smsmith * DESCRIPTION: Calculate the length of the internal (AML) namestring 17877424Smsmith * corresponding to the external (ASL) namestring. 17967754Smsmith * 18077424Smsmith ******************************************************************************/ 18167754Smsmith 18299679Siwasakivoid 18377424SmsmithAcpiNsGetInternalNameLength ( 18477424Smsmith ACPI_NAMESTRING_INFO *Info) 18567754Smsmith{ 186193267Sjkim const char *NextExternalChar; 18767754Smsmith UINT32 i; 18867754Smsmith 18967754Smsmith 19091116Smsmith ACPI_FUNCTION_ENTRY (); 19183174Smsmith 19283174Smsmith 19377424Smsmith NextExternalChar = Info->ExternalName; 19477424Smsmith Info->NumCarats = 0; 19577424Smsmith Info->NumSegments = 0; 19677424Smsmith Info->FullyQualified = FALSE; 19783174Smsmith 19867754Smsmith /* 199306536Sjkim * For the internal name, the required length is 4 bytes per segment, 200306536Sjkim * plus 1 each for RootPrefix, MultiNamePrefixOp, segment count, 201306536Sjkim * trailing null (which is not really needed, but no there's harm in 202306536Sjkim * putting it there) 20367754Smsmith * 204138287Smarks * strlen() + 1 covers the first NameSeg, which has no path separator 20567754Smsmith */ 206245582Sjkim if (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 20767754Smsmith { 20877424Smsmith Info->FullyQualified = TRUE; 20977424Smsmith NextExternalChar++; 210193267Sjkim 211193267Sjkim /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 212193267Sjkim 213245582Sjkim while (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 214193267Sjkim { 215193267Sjkim NextExternalChar++; 216193267Sjkim } 21767754Smsmith } 21869450Smsmith else 21969450Smsmith { 220193267Sjkim /* Handle Carat prefixes */ 221193267Sjkim 222245582Sjkim while (ACPI_IS_PARENT_PREFIX (*NextExternalChar)) 22369450Smsmith { 22477424Smsmith Info->NumCarats++; 22577424Smsmith NextExternalChar++; 22669450Smsmith } 22769450Smsmith } 22869450Smsmith 22967754Smsmith /* 230138287Smarks * Determine the number of ACPI name "segments" by counting the number of 231138287Smarks * path separators within the string. Start with one segment since the 232138287Smarks * segment count is [(# separators) + 1], and zero separators is ok. 23367754Smsmith */ 23477424Smsmith if (*NextExternalChar) 23567754Smsmith { 23677424Smsmith Info->NumSegments = 1; 23777424Smsmith for (i = 0; NextExternalChar[i]; i++) 23867754Smsmith { 239245582Sjkim if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i])) 24069450Smsmith { 24177424Smsmith Info->NumSegments++; 24269450Smsmith } 24367754Smsmith } 24467754Smsmith } 24567754Smsmith 24683174Smsmith Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 247306536Sjkim 4 + Info->NumCarats; 24867754Smsmith 24977424Smsmith Info->NextExternalChar = NextExternalChar; 25077424Smsmith} 25167754Smsmith 25267754Smsmith 25377424Smsmith/******************************************************************************* 25477424Smsmith * 25577424Smsmith * FUNCTION: AcpiNsBuildInternalName 25677424Smsmith * 25777424Smsmith * PARAMETERS: Info - Info struct fully initialized 25877424Smsmith * 25977424Smsmith * RETURN: Status 26077424Smsmith * 26183174Smsmith * DESCRIPTION: Construct the internal (AML) namestring 26277424Smsmith * corresponding to the external (ASL) namestring. 26377424Smsmith * 26477424Smsmith ******************************************************************************/ 26577424Smsmith 26677424SmsmithACPI_STATUS 26777424SmsmithAcpiNsBuildInternalName ( 26877424Smsmith ACPI_NAMESTRING_INFO *Info) 26977424Smsmith{ 27077424Smsmith UINT32 NumSegments = Info->NumSegments; 271114237Snjl char *InternalName = Info->InternalName; 272193267Sjkim const char *ExternalName = Info->NextExternalChar; 273114237Snjl char *Result = NULL; 274193267Sjkim UINT32 i; 27577424Smsmith 27677424Smsmith 277167802Sjkim ACPI_FUNCTION_TRACE (NsBuildInternalName); 27877424Smsmith 27983174Smsmith 28067754Smsmith /* Setup the correct prefixes, counts, and pointers */ 28167754Smsmith 28277424Smsmith if (Info->FullyQualified) 28367754Smsmith { 284245582Sjkim InternalName[0] = AML_ROOT_PREFIX; 28569450Smsmith 28669450Smsmith if (NumSegments <= 1) 28769450Smsmith { 28869450Smsmith Result = &InternalName[1]; 28969450Smsmith } 29069450Smsmith else if (NumSegments == 2) 29169450Smsmith { 29269450Smsmith InternalName[1] = AML_DUAL_NAME_PREFIX; 29369450Smsmith Result = &InternalName[2]; 29469450Smsmith } 29569450Smsmith else 29669450Smsmith { 29769450Smsmith InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 29869450Smsmith InternalName[2] = (char) NumSegments; 29969450Smsmith Result = &InternalName[3]; 30069450Smsmith } 30167754Smsmith } 30267754Smsmith else 30367754Smsmith { 30469450Smsmith /* 30569450Smsmith * Not fully qualified. 30669450Smsmith * Handle Carats first, then append the name segments 30769450Smsmith */ 30869450Smsmith i = 0; 30977424Smsmith if (Info->NumCarats) 31069450Smsmith { 31177424Smsmith for (i = 0; i < Info->NumCarats; i++) 31269450Smsmith { 313245582Sjkim InternalName[i] = AML_PARENT_PREFIX; 31469450Smsmith } 31569450Smsmith } 31669450Smsmith 31791116Smsmith if (NumSegments <= 1) 31869450Smsmith { 31969450Smsmith Result = &InternalName[i]; 32069450Smsmith } 32169450Smsmith else if (NumSegments == 2) 32269450Smsmith { 32369450Smsmith InternalName[i] = AML_DUAL_NAME_PREFIX; 324193267Sjkim Result = &InternalName[(ACPI_SIZE) i+1]; 32569450Smsmith } 32669450Smsmith else 32769450Smsmith { 32869450Smsmith InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 329193267Sjkim InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 330193267Sjkim Result = &InternalName[(ACPI_SIZE) i+2]; 33169450Smsmith } 33267754Smsmith } 33367754Smsmith 33467754Smsmith /* Build the name (minus path separators) */ 33567754Smsmith 33667754Smsmith for (; NumSegments; NumSegments--) 33767754Smsmith { 33867754Smsmith for (i = 0; i < ACPI_NAME_SIZE; i++) 33967754Smsmith { 340245582Sjkim if (ACPI_IS_PATH_SEPARATOR (*ExternalName) || 34167754Smsmith (*ExternalName == 0)) 34267754Smsmith { 34377424Smsmith /* Pad the segment with underscore(s) if segment is short */ 34467754Smsmith 34567754Smsmith Result[i] = '_'; 34667754Smsmith } 34767754Smsmith else 34867754Smsmith { 34977424Smsmith /* Convert the character to uppercase and save it */ 35067754Smsmith 351306536Sjkim Result[i] = (char) toupper ((int) *ExternalName); 35267754Smsmith ExternalName++; 35367754Smsmith } 35467754Smsmith } 35567754Smsmith 35667754Smsmith /* Now we must have a path separator, or the pathname is bad */ 35767754Smsmith 358245582Sjkim if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) && 35967754Smsmith (*ExternalName != 0)) 36067754Smsmith { 361233250Sjkim return_ACPI_STATUS (AE_BAD_PATHNAME); 36267754Smsmith } 36367754Smsmith 36467754Smsmith /* Move on the next segment */ 36567754Smsmith 36667754Smsmith ExternalName++; 36767754Smsmith Result += ACPI_NAME_SIZE; 36867754Smsmith } 36967754Smsmith 37077424Smsmith /* Terminate the string */ 37167754Smsmith 37267754Smsmith *Result = 0; 37367754Smsmith 37477424Smsmith if (Info->FullyQualified) 37567754Smsmith { 376123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 37799146Siwasaki InternalName, InternalName)); 37867754Smsmith } 37967754Smsmith else 38067754Smsmith { 381123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 38299146Siwasaki InternalName, InternalName)); 38367754Smsmith } 38467754Smsmith 38567754Smsmith return_ACPI_STATUS (AE_OK); 38667754Smsmith} 38767754Smsmith 38867754Smsmith 38977424Smsmith/******************************************************************************* 39067754Smsmith * 39177424Smsmith * FUNCTION: AcpiNsInternalizeName 39277424Smsmith * 39377424Smsmith * PARAMETERS: *ExternalName - External representation of name 39477424Smsmith * **Converted Name - Where to return the resulting 39577424Smsmith * internal represention of the name 39677424Smsmith * 39777424Smsmith * RETURN: Status 39877424Smsmith * 39977424Smsmith * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 40077424Smsmith * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 40177424Smsmith * 40277424Smsmith *******************************************************************************/ 40377424Smsmith 40477424SmsmithACPI_STATUS 40577424SmsmithAcpiNsInternalizeName ( 406193267Sjkim const char *ExternalName, 407114237Snjl char **ConvertedName) 40877424Smsmith{ 409114237Snjl char *InternalName; 41077424Smsmith ACPI_NAMESTRING_INFO Info; 41177424Smsmith ACPI_STATUS Status; 41277424Smsmith 41377424Smsmith 414167802Sjkim ACPI_FUNCTION_TRACE (NsInternalizeName); 41577424Smsmith 41677424Smsmith 41777424Smsmith if ((!ExternalName) || 41877424Smsmith (*ExternalName == 0) || 41977424Smsmith (!ConvertedName)) 42077424Smsmith { 42177424Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 42277424Smsmith } 42377424Smsmith 42477424Smsmith /* Get the length of the new internal name */ 42577424Smsmith 42677424Smsmith Info.ExternalName = ExternalName; 42777424Smsmith AcpiNsGetInternalNameLength (&Info); 42877424Smsmith 42977424Smsmith /* We need a segment to store the internal name */ 43077424Smsmith 431167802Sjkim InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 43277424Smsmith if (!InternalName) 43377424Smsmith { 43477424Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 43577424Smsmith } 43677424Smsmith 43777424Smsmith /* Build the name */ 43877424Smsmith 43977424Smsmith Info.InternalName = InternalName; 44077424Smsmith Status = AcpiNsBuildInternalName (&Info); 44177424Smsmith if (ACPI_FAILURE (Status)) 44277424Smsmith { 443167802Sjkim ACPI_FREE (InternalName); 44477424Smsmith return_ACPI_STATUS (Status); 44577424Smsmith } 44677424Smsmith 44777424Smsmith *ConvertedName = InternalName; 44877424Smsmith return_ACPI_STATUS (AE_OK); 44977424Smsmith} 45077424Smsmith 45177424Smsmith 45277424Smsmith/******************************************************************************* 45377424Smsmith * 45467754Smsmith * FUNCTION: AcpiNsExternalizeName 45567754Smsmith * 456151937Sjkim * PARAMETERS: InternalNameLength - Lenth of the internal name below 457151937Sjkim * InternalName - Internal representation of name 458151937Sjkim * ConvertedNameLength - Where the length is returned 459151937Sjkim * ConvertedName - Where the resulting external name 460151937Sjkim * is returned 46167754Smsmith * 46267754Smsmith * RETURN: Status 46367754Smsmith * 46467754Smsmith * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 465151937Sjkim * to its external (printable) form (e.g. "\_PR_.CPU0") 46667754Smsmith * 46777424Smsmith ******************************************************************************/ 46867754Smsmith 46967754SmsmithACPI_STATUS 47067754SmsmithAcpiNsExternalizeName ( 47167754Smsmith UINT32 InternalNameLength, 472193267Sjkim const char *InternalName, 47367754Smsmith UINT32 *ConvertedNameLength, 47467754Smsmith char **ConvertedName) 47567754Smsmith{ 476193267Sjkim UINT32 NamesIndex = 0; 477193267Sjkim UINT32 NumSegments = 0; 478193267Sjkim UINT32 RequiredLength; 479193267Sjkim UINT32 PrefixLength = 0; 480193267Sjkim UINT32 i = 0; 481193267Sjkim UINT32 j = 0; 48267754Smsmith 48367754Smsmith 484167802Sjkim ACPI_FUNCTION_TRACE (NsExternalizeName); 48567754Smsmith 48667754Smsmith 48767754Smsmith if (!InternalNameLength || 48867754Smsmith !InternalName || 48967754Smsmith !ConvertedName) 49067754Smsmith { 49167754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 49267754Smsmith } 49367754Smsmith 494193267Sjkim /* Check for a prefix (one '\' | one or more '^') */ 495193267Sjkim 49667754Smsmith switch (InternalName[0]) 49767754Smsmith { 498245582Sjkim case AML_ROOT_PREFIX: 499250838Sjkim 50067754Smsmith PrefixLength = 1; 50167754Smsmith break; 50267754Smsmith 503245582Sjkim case AML_PARENT_PREFIX: 504250838Sjkim 50567754Smsmith for (i = 0; i < InternalNameLength; i++) 50667754Smsmith { 507245582Sjkim if (ACPI_IS_PARENT_PREFIX (InternalName[i])) 50867754Smsmith { 50967754Smsmith PrefixLength = i + 1; 51067754Smsmith } 511102550Siwasaki else 512102550Siwasaki { 513102550Siwasaki break; 514102550Siwasaki } 51567754Smsmith } 51667754Smsmith 51767754Smsmith if (i == InternalNameLength) 51867754Smsmith { 51967754Smsmith PrefixLength = i; 52067754Smsmith } 52167754Smsmith 52267754Smsmith break; 52399679Siwasaki 52499679Siwasaki default: 525250838Sjkim 52699679Siwasaki break; 52767754Smsmith } 52867754Smsmith 52967754Smsmith /* 530193267Sjkim * Check for object names. Note that there could be 0-255 of these 53167754Smsmith * 4-byte elements. 53267754Smsmith */ 53367754Smsmith if (PrefixLength < InternalNameLength) 53467754Smsmith { 53567754Smsmith switch (InternalName[PrefixLength]) 53667754Smsmith { 53791116Smsmith case AML_MULTI_NAME_PREFIX_OP: 53867754Smsmith 53991116Smsmith /* <count> 4-byte names */ 54067754Smsmith 54167754Smsmith NamesIndex = PrefixLength + 2; 542193267Sjkim NumSegments = (UINT8) 543193267Sjkim InternalName[(ACPI_SIZE) PrefixLength + 1]; 54467754Smsmith break; 54567754Smsmith 54691116Smsmith case AML_DUAL_NAME_PREFIX: 54767754Smsmith 54891116Smsmith /* Two 4-byte names */ 54967754Smsmith 55067754Smsmith NamesIndex = PrefixLength + 1; 55191116Smsmith NumSegments = 2; 55267754Smsmith break; 55367754Smsmith 55491116Smsmith case 0: 55567754Smsmith 55691116Smsmith /* NullName */ 55767754Smsmith 55867754Smsmith NamesIndex = 0; 55991116Smsmith NumSegments = 0; 56067754Smsmith break; 56167754Smsmith 56291116Smsmith default: 56367754Smsmith 56491116Smsmith /* one 4-byte name */ 56567754Smsmith 56667754Smsmith NamesIndex = PrefixLength; 56791116Smsmith NumSegments = 1; 56867754Smsmith break; 56967754Smsmith } 57067754Smsmith } 57167754Smsmith 57267754Smsmith /* 57367754Smsmith * Calculate the length of ConvertedName, which equals the length 57467754Smsmith * of the prefix, length of all object names, length of any required 57567754Smsmith * punctuation ('.') between object names, plus the NULL terminator. 57667754Smsmith */ 57791116Smsmith RequiredLength = PrefixLength + (4 * NumSegments) + 578306536Sjkim ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 57967754Smsmith 58067754Smsmith /* 581241973Sjkim * Check to see if we're still in bounds. If not, there's a problem 58267754Smsmith * with InternalName (invalid format). 58367754Smsmith */ 58491116Smsmith if (RequiredLength > InternalNameLength) 58567754Smsmith { 586167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid internal name")); 58767754Smsmith return_ACPI_STATUS (AE_BAD_PATHNAME); 58867754Smsmith } 58967754Smsmith 590193267Sjkim /* Build the ConvertedName */ 591193267Sjkim 592167802Sjkim *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 59367754Smsmith if (!(*ConvertedName)) 59467754Smsmith { 59567754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 59667754Smsmith } 59767754Smsmith 59867754Smsmith j = 0; 59967754Smsmith 60067754Smsmith for (i = 0; i < PrefixLength; i++) 60167754Smsmith { 60267754Smsmith (*ConvertedName)[j++] = InternalName[i]; 60367754Smsmith } 60467754Smsmith 60591116Smsmith if (NumSegments > 0) 60667754Smsmith { 60791116Smsmith for (i = 0; i < NumSegments; i++) 60867754Smsmith { 60967754Smsmith if (i > 0) 61067754Smsmith { 61167754Smsmith (*ConvertedName)[j++] = '.'; 61267754Smsmith } 61367754Smsmith 614241973Sjkim /* Copy and validate the 4-char name segment */ 615241973Sjkim 616306536Sjkim ACPI_MOVE_NAME (&(*ConvertedName)[j], 617306536Sjkim &InternalName[NamesIndex]); 618241973Sjkim AcpiUtRepairName (&(*ConvertedName)[j]); 619241973Sjkim 620241973Sjkim j += ACPI_NAME_SIZE; 621241973Sjkim NamesIndex += ACPI_NAME_SIZE; 62267754Smsmith } 62367754Smsmith } 62467754Smsmith 62591116Smsmith if (ConvertedNameLength) 62691116Smsmith { 62799679Siwasaki *ConvertedNameLength = (UINT32) RequiredLength; 62891116Smsmith } 62991116Smsmith 63067754Smsmith return_ACPI_STATUS (AE_OK); 63167754Smsmith} 63267754Smsmith 63367754Smsmith 63477424Smsmith/******************************************************************************* 63567754Smsmith * 636200553Sjkim * FUNCTION: AcpiNsValidateHandle 63767754Smsmith * 638200553Sjkim * PARAMETERS: Handle - Handle to be validated and typecast to a 639200553Sjkim * namespace node. 64067754Smsmith * 641200553Sjkim * RETURN: A pointer to a namespace node 64267754Smsmith * 643200553Sjkim * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 644200553Sjkim * cases for the root node. 64567754Smsmith * 646200553Sjkim * NOTE: Real integer handles would allow for more verification 647151937Sjkim * and keep all pointers within this subsystem - however this introduces 648200553Sjkim * more overhead and has not been necessary to this point. Drivers 649200553Sjkim * holding handles are typically notified before a node becomes invalid 650200553Sjkim * due to a table unload. 65187031Smsmith * 65277424Smsmith ******************************************************************************/ 65367754Smsmith 65467754SmsmithACPI_NAMESPACE_NODE * 655200553SjkimAcpiNsValidateHandle ( 65667754Smsmith ACPI_HANDLE Handle) 65767754Smsmith{ 65867754Smsmith 65991116Smsmith ACPI_FUNCTION_ENTRY (); 66083174Smsmith 66183174Smsmith 662193267Sjkim /* Parameter validation */ 663193267Sjkim 664167802Sjkim if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 66567754Smsmith { 66667754Smsmith return (AcpiGbl_RootNode); 66767754Smsmith } 66867754Smsmith 66967754Smsmith /* We can at least attempt to verify the handle */ 67067754Smsmith 67191116Smsmith if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 67267754Smsmith { 67367754Smsmith return (NULL); 67467754Smsmith } 67567754Smsmith 676167802Sjkim return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 67767754Smsmith} 67867754Smsmith 67967754Smsmith 68077424Smsmith/******************************************************************************* 68167754Smsmith * 68267754Smsmith * FUNCTION: AcpiNsTerminate 68367754Smsmith * 68467754Smsmith * PARAMETERS: none 68567754Smsmith * 68667754Smsmith * RETURN: none 68767754Smsmith * 688151937Sjkim * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 68967754Smsmith * 69067754Smsmith ******************************************************************************/ 69167754Smsmith 69267754Smsmithvoid 693151937SjkimAcpiNsTerminate ( 694151937Sjkim void) 69567754Smsmith{ 696281075Sdim ACPI_STATUS Status; 69767754Smsmith 69867754Smsmith 699167802Sjkim ACPI_FUNCTION_TRACE (NsTerminate); 70067754Smsmith 70167754Smsmith 702306536Sjkim#ifdef ACPI_EXEC_APP 703306536Sjkim { 704306536Sjkim ACPI_OPERAND_OBJECT *Prev; 705306536Sjkim ACPI_OPERAND_OBJECT *Next; 706306536Sjkim 707306536Sjkim /* Delete any module-level code blocks */ 708306536Sjkim 709306536Sjkim Next = AcpiGbl_ModuleCodeList; 710306536Sjkim while (Next) 711306536Sjkim { 712306536Sjkim Prev = Next; 713306536Sjkim Next = Next->Method.Mutex; 714306536Sjkim Prev->Method.Mutex = NULL; /* Clear the Mutex (cheated) field */ 715306536Sjkim AcpiUtRemoveReference (Prev); 716306536Sjkim } 717306536Sjkim } 718306536Sjkim#endif 719306536Sjkim 72067754Smsmith /* 721281075Sdim * Free the entire namespace -- all nodes and all objects 722281075Sdim * attached to the nodes 72367754Smsmith */ 724117521Snjl AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 72567754Smsmith 726281075Sdim /* Delete any objects attached to the root node */ 72767754Smsmith 728281075Sdim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 729281075Sdim if (ACPI_FAILURE (Status)) 73067754Smsmith { 731281075Sdim return_VOID; 73267754Smsmith } 73367754Smsmith 734281075Sdim AcpiNsDeleteNode (AcpiGbl_RootNode); 735281075Sdim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 736281075Sdim 73782367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 73867754Smsmith return_VOID; 73967754Smsmith} 74067754Smsmith 74167754Smsmith 74277424Smsmith/******************************************************************************* 74367754Smsmith * 74467754Smsmith * FUNCTION: AcpiNsOpensScope 74567754Smsmith * 74667754Smsmith * PARAMETERS: Type - A valid namespace type 74767754Smsmith * 74867754Smsmith * RETURN: NEWSCOPE if the passed type "opens a name scope" according 74967754Smsmith * to the ACPI specification, else 0 75067754Smsmith * 75177424Smsmith ******************************************************************************/ 75267754Smsmith 75367754SmsmithUINT32 75467754SmsmithAcpiNsOpensScope ( 75591116Smsmith ACPI_OBJECT_TYPE Type) 75667754Smsmith{ 757243347Sjkim ACPI_FUNCTION_ENTRY (); 75867754Smsmith 75967754Smsmith 760243347Sjkim if (Type > ACPI_TYPE_LOCAL_MAX) 76167754Smsmith { 76267754Smsmith /* type code out of range */ 76367754Smsmith 764204773Sjkim ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 765243347Sjkim return (ACPI_NS_NORMAL); 76667754Smsmith } 76767754Smsmith 768243347Sjkim return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 76967754Smsmith} 77067754Smsmith 77167754Smsmith 77277424Smsmith/******************************************************************************* 77367754Smsmith * 774167802Sjkim * FUNCTION: AcpiNsGetNode 77567754Smsmith * 77667754Smsmith * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 77767754Smsmith * \ (backslash) and ^ (carat) prefixes, and the 77867754Smsmith * . (period) to separate segments are supported. 779167802Sjkim * PrefixNode - Root of subtree to be searched, or NS_ALL for the 780241973Sjkim * root of the name space. If Name is fully 78167754Smsmith * qualified (first INT8 is '\'), the passed value 78267754Smsmith * of Scope will not be accessed. 78391116Smsmith * Flags - Used to indicate whether to perform upsearch or 78491116Smsmith * not. 78567754Smsmith * ReturnNode - Where the Node is returned 78667754Smsmith * 78767754Smsmith * DESCRIPTION: Look up a name relative to a given scope and return the 788241973Sjkim * corresponding Node. NOTE: Scope can be null. 78967754Smsmith * 79067754Smsmith * MUTEX: Locks namespace 79167754Smsmith * 79277424Smsmith ******************************************************************************/ 79367754Smsmith 79467754SmsmithACPI_STATUS 795167802SjkimAcpiNsGetNode ( 796167802Sjkim ACPI_NAMESPACE_NODE *PrefixNode, 797193267Sjkim const char *Pathname, 79891116Smsmith UINT32 Flags, 79967754Smsmith ACPI_NAMESPACE_NODE **ReturnNode) 80067754Smsmith{ 80167754Smsmith ACPI_GENERIC_STATE ScopeInfo; 80267754Smsmith ACPI_STATUS Status; 803167802Sjkim char *InternalPath; 80467754Smsmith 80567754Smsmith 806193267Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 80767754Smsmith 80867754Smsmith 809245582Sjkim /* Simplest case is a null pathname */ 810245582Sjkim 811167802Sjkim if (!Pathname) 81267754Smsmith { 813167802Sjkim *ReturnNode = PrefixNode; 814167802Sjkim if (!PrefixNode) 815114237Snjl { 816167802Sjkim *ReturnNode = AcpiGbl_RootNode; 817114237Snjl } 818306536Sjkim 819167802Sjkim return_ACPI_STATUS (AE_OK); 82067754Smsmith } 82167754Smsmith 822245582Sjkim /* Quick check for a reference to the root */ 823245582Sjkim 824245582Sjkim if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1])) 825245582Sjkim { 826245582Sjkim *ReturnNode = AcpiGbl_RootNode; 827245582Sjkim return_ACPI_STATUS (AE_OK); 828245582Sjkim } 829245582Sjkim 830167802Sjkim /* Convert path to internal representation */ 831167802Sjkim 832167802Sjkim Status = AcpiNsInternalizeName (Pathname, &InternalPath); 833167802Sjkim if (ACPI_FAILURE (Status)) 834167802Sjkim { 835167802Sjkim return_ACPI_STATUS (Status); 836167802Sjkim } 837167802Sjkim 83891116Smsmith /* Must lock namespace during lookup */ 83967754Smsmith 84091116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 84191116Smsmith if (ACPI_FAILURE (Status)) 84291116Smsmith { 843126372Snjl goto Cleanup; 84491116Smsmith } 84567754Smsmith 84669746Smsmith /* Setup lookup scope (search starting point) */ 84767754Smsmith 848167802Sjkim ScopeInfo.Scope.Node = PrefixNode; 84967754Smsmith 85067754Smsmith /* Lookup the name in the namespace */ 85167754Smsmith 852167802Sjkim Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 853306536Sjkim ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 854306536Sjkim NULL, ReturnNode); 85567754Smsmith if (ACPI_FAILURE (Status)) 85667754Smsmith { 857193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 858306536Sjkim Pathname, AcpiFormatException (Status))); 85967754Smsmith } 86067754Smsmith 86191116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 862114237Snjl 863126372SnjlCleanup: 864167802Sjkim ACPI_FREE (InternalPath); 86567754Smsmith return_ACPI_STATUS (Status); 86667754Smsmith} 867