nsutils.c revision 250838
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 467754Smsmith * parents and siblings and Scope manipulation 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, 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 4567754Smsmith#define __NSUTILS_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 5167754Smsmith 5277424Smsmith#define _COMPONENT ACPI_NAMESPACE 5391116Smsmith ACPI_MODULE_NAME ("nsutils") 5467754Smsmith 55151937Sjkim/* Local prototypes */ 5667754Smsmith 57151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 58151937SjkimACPI_NAME 59151937SjkimAcpiNsFindParentName ( 60151937Sjkim ACPI_NAMESPACE_NODE *NodeToSearch); 61151937Sjkim#endif 62151937Sjkim 63151937Sjkim 6477424Smsmith/******************************************************************************* 6567754Smsmith * 66114237Snjl * FUNCTION: AcpiNsPrintNodePathname 67114237Snjl * 68151937Sjkim * PARAMETERS: Node - Object 69151937Sjkim * Message - Prefix message 70114237Snjl * 71114237Snjl * DESCRIPTION: Print an object's full namespace pathname 72114237Snjl * Manages allocation/freeing of a pathname buffer 73114237Snjl * 74114237Snjl ******************************************************************************/ 75114237Snjl 76114237Snjlvoid 77114237SnjlAcpiNsPrintNodePathname ( 78114237Snjl ACPI_NAMESPACE_NODE *Node, 79193267Sjkim const char *Message) 80114237Snjl{ 81114237Snjl ACPI_BUFFER Buffer; 82114237Snjl ACPI_STATUS Status; 83114237Snjl 84114237Snjl 85123315Snjl if (!Node) 86123315Snjl { 87123315Snjl AcpiOsPrintf ("[NULL NAME]"); 88123315Snjl return; 89123315Snjl } 90123315Snjl 91138287Smarks /* Convert handle to full pathname and print it (with supplied message) */ 92114237Snjl 93114237Snjl Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 94114237Snjl 95114237Snjl Status = AcpiNsHandleToPathname (Node, &Buffer); 96114237Snjl if (ACPI_SUCCESS (Status)) 97114237Snjl { 98151937Sjkim if (Message) 99117521Snjl { 100151937Sjkim AcpiOsPrintf ("%s ", Message); 101117521Snjl } 102117521Snjl 103117521Snjl AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 104167802Sjkim ACPI_FREE (Buffer.Pointer); 105114237Snjl } 106114237Snjl} 107114237Snjl 108114237Snjl 109114237Snjl/******************************************************************************* 110114237Snjl * 11167754Smsmith * FUNCTION: AcpiNsGetType 11267754Smsmith * 113151937Sjkim * PARAMETERS: Node - Parent Node to be examined 11467754Smsmith * 11567754Smsmith * RETURN: Type field from Node whose handle is passed 11667754Smsmith * 117151937Sjkim * DESCRIPTION: Return the type of a Namespace node 118151937Sjkim * 11977424Smsmith ******************************************************************************/ 12067754Smsmith 12191116SmsmithACPI_OBJECT_TYPE 12267754SmsmithAcpiNsGetType ( 12377424Smsmith ACPI_NAMESPACE_NODE *Node) 12467754Smsmith{ 125167802Sjkim ACPI_FUNCTION_TRACE (NsGetType); 12667754Smsmith 12767754Smsmith 12877424Smsmith if (!Node) 12967754Smsmith { 130167802Sjkim ACPI_WARNING ((AE_INFO, "Null Node parameter")); 131246849Sjkim return_UINT8 (ACPI_TYPE_ANY); 13267754Smsmith } 13367754Smsmith 134246849Sjkim return_UINT8 (Node->Type); 13567754Smsmith} 13667754Smsmith 13767754Smsmith 13877424Smsmith/******************************************************************************* 13967754Smsmith * 14067754Smsmith * FUNCTION: AcpiNsLocal 14167754Smsmith * 142151937Sjkim * PARAMETERS: Type - A namespace object type 14367754Smsmith * 14467754Smsmith * RETURN: LOCAL if names must be found locally in objects of the 14567754Smsmith * passed type, 0 if enclosing scopes should be searched 14667754Smsmith * 147151937Sjkim * DESCRIPTION: Returns scope rule for the given object type. 148151937Sjkim * 14977424Smsmith ******************************************************************************/ 15067754Smsmith 15167754SmsmithUINT32 15267754SmsmithAcpiNsLocal ( 15391116Smsmith ACPI_OBJECT_TYPE Type) 15467754Smsmith{ 155167802Sjkim ACPI_FUNCTION_TRACE (NsLocal); 15667754Smsmith 15767754Smsmith 15877424Smsmith if (!AcpiUtValidObjectType (Type)) 15967754Smsmith { 16067754Smsmith /* Type code out of range */ 16167754Smsmith 162204773Sjkim ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 163246849Sjkim return_UINT32 (ACPI_NS_NORMAL); 16467754Smsmith } 16567754Smsmith 166246849Sjkim return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 16767754Smsmith} 16867754Smsmith 16967754Smsmith 17077424Smsmith/******************************************************************************* 17167754Smsmith * 17277424Smsmith * FUNCTION: AcpiNsGetInternalNameLength 17367754Smsmith * 17483174Smsmith * PARAMETERS: Info - Info struct initialized with the 17577424Smsmith * external name pointer. 17667754Smsmith * 177151937Sjkim * RETURN: None 17867754Smsmith * 17983174Smsmith * DESCRIPTION: Calculate the length of the internal (AML) namestring 18077424Smsmith * corresponding to the external (ASL) namestring. 18167754Smsmith * 18277424Smsmith ******************************************************************************/ 18367754Smsmith 18499679Siwasakivoid 18577424SmsmithAcpiNsGetInternalNameLength ( 18677424Smsmith ACPI_NAMESTRING_INFO *Info) 18767754Smsmith{ 188193267Sjkim const char *NextExternalChar; 18967754Smsmith UINT32 i; 19067754Smsmith 19167754Smsmith 19291116Smsmith ACPI_FUNCTION_ENTRY (); 19383174Smsmith 19483174Smsmith 19577424Smsmith NextExternalChar = Info->ExternalName; 19677424Smsmith Info->NumCarats = 0; 19777424Smsmith Info->NumSegments = 0; 19877424Smsmith Info->FullyQualified = FALSE; 19983174Smsmith 20067754Smsmith /* 201138287Smarks * For the internal name, the required length is 4 bytes per segment, plus 202138287Smarks * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null 203138287Smarks * (which is not really needed, but no there's harm in putting it there) 20467754Smsmith * 205138287Smarks * strlen() + 1 covers the first NameSeg, which has no path separator 20667754Smsmith */ 207245582Sjkim if (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 20867754Smsmith { 20977424Smsmith Info->FullyQualified = TRUE; 21077424Smsmith NextExternalChar++; 211193267Sjkim 212193267Sjkim /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 213193267Sjkim 214245582Sjkim while (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 215193267Sjkim { 216193267Sjkim NextExternalChar++; 217193267Sjkim } 21867754Smsmith } 21969450Smsmith else 22069450Smsmith { 221193267Sjkim /* Handle Carat prefixes */ 222193267Sjkim 223245582Sjkim while (ACPI_IS_PARENT_PREFIX (*NextExternalChar)) 22469450Smsmith { 22577424Smsmith Info->NumCarats++; 22677424Smsmith NextExternalChar++; 22769450Smsmith } 22869450Smsmith } 22969450Smsmith 23067754Smsmith /* 231138287Smarks * Determine the number of ACPI name "segments" by counting the number of 232138287Smarks * path separators within the string. Start with one segment since the 233138287Smarks * segment count is [(# separators) + 1], and zero separators is ok. 23467754Smsmith */ 23577424Smsmith if (*NextExternalChar) 23667754Smsmith { 23777424Smsmith Info->NumSegments = 1; 23877424Smsmith for (i = 0; NextExternalChar[i]; i++) 23967754Smsmith { 240245582Sjkim if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i])) 24169450Smsmith { 24277424Smsmith Info->NumSegments++; 24369450Smsmith } 24467754Smsmith } 24567754Smsmith } 24667754Smsmith 24783174Smsmith Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 24877424Smsmith 4 + Info->NumCarats; 24967754Smsmith 25077424Smsmith Info->NextExternalChar = NextExternalChar; 25177424Smsmith} 25267754Smsmith 25367754Smsmith 25477424Smsmith/******************************************************************************* 25577424Smsmith * 25677424Smsmith * FUNCTION: AcpiNsBuildInternalName 25777424Smsmith * 25877424Smsmith * PARAMETERS: Info - Info struct fully initialized 25977424Smsmith * 26077424Smsmith * RETURN: Status 26177424Smsmith * 26283174Smsmith * DESCRIPTION: Construct the internal (AML) namestring 26377424Smsmith * corresponding to the external (ASL) namestring. 26477424Smsmith * 26577424Smsmith ******************************************************************************/ 26677424Smsmith 26777424SmsmithACPI_STATUS 26877424SmsmithAcpiNsBuildInternalName ( 26977424Smsmith ACPI_NAMESTRING_INFO *Info) 27077424Smsmith{ 27177424Smsmith UINT32 NumSegments = Info->NumSegments; 272114237Snjl char *InternalName = Info->InternalName; 273193267Sjkim const char *ExternalName = Info->NextExternalChar; 274114237Snjl char *Result = NULL; 275193267Sjkim UINT32 i; 27677424Smsmith 27777424Smsmith 278167802Sjkim ACPI_FUNCTION_TRACE (NsBuildInternalName); 27977424Smsmith 28083174Smsmith 28167754Smsmith /* Setup the correct prefixes, counts, and pointers */ 28267754Smsmith 28377424Smsmith if (Info->FullyQualified) 28467754Smsmith { 285245582Sjkim InternalName[0] = AML_ROOT_PREFIX; 28669450Smsmith 28769450Smsmith if (NumSegments <= 1) 28869450Smsmith { 28969450Smsmith Result = &InternalName[1]; 29069450Smsmith } 29169450Smsmith else if (NumSegments == 2) 29269450Smsmith { 29369450Smsmith InternalName[1] = AML_DUAL_NAME_PREFIX; 29469450Smsmith Result = &InternalName[2]; 29569450Smsmith } 29669450Smsmith else 29769450Smsmith { 29869450Smsmith InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 29969450Smsmith InternalName[2] = (char) NumSegments; 30069450Smsmith Result = &InternalName[3]; 30169450Smsmith } 30267754Smsmith } 30367754Smsmith else 30467754Smsmith { 30569450Smsmith /* 30669450Smsmith * Not fully qualified. 30769450Smsmith * Handle Carats first, then append the name segments 30869450Smsmith */ 30969450Smsmith i = 0; 31077424Smsmith if (Info->NumCarats) 31169450Smsmith { 31277424Smsmith for (i = 0; i < Info->NumCarats; i++) 31369450Smsmith { 314245582Sjkim InternalName[i] = AML_PARENT_PREFIX; 31569450Smsmith } 31669450Smsmith } 31769450Smsmith 31891116Smsmith if (NumSegments <= 1) 31969450Smsmith { 32069450Smsmith Result = &InternalName[i]; 32169450Smsmith } 32269450Smsmith else if (NumSegments == 2) 32369450Smsmith { 32469450Smsmith InternalName[i] = AML_DUAL_NAME_PREFIX; 325193267Sjkim Result = &InternalName[(ACPI_SIZE) i+1]; 32669450Smsmith } 32769450Smsmith else 32869450Smsmith { 32969450Smsmith InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 330193267Sjkim InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 331193267Sjkim Result = &InternalName[(ACPI_SIZE) i+2]; 33269450Smsmith } 33367754Smsmith } 33467754Smsmith 33567754Smsmith /* Build the name (minus path separators) */ 33667754Smsmith 33767754Smsmith for (; NumSegments; NumSegments--) 33867754Smsmith { 33967754Smsmith for (i = 0; i < ACPI_NAME_SIZE; i++) 34067754Smsmith { 341245582Sjkim if (ACPI_IS_PATH_SEPARATOR (*ExternalName) || 34267754Smsmith (*ExternalName == 0)) 34367754Smsmith { 34477424Smsmith /* Pad the segment with underscore(s) if segment is short */ 34567754Smsmith 34667754Smsmith Result[i] = '_'; 34767754Smsmith } 34867754Smsmith else 34967754Smsmith { 35077424Smsmith /* Convert the character to uppercase and save it */ 35167754Smsmith 35299679Siwasaki Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName); 35367754Smsmith ExternalName++; 35467754Smsmith } 35567754Smsmith } 35667754Smsmith 35767754Smsmith /* Now we must have a path separator, or the pathname is bad */ 35867754Smsmith 359245582Sjkim if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) && 36067754Smsmith (*ExternalName != 0)) 36167754Smsmith { 362233250Sjkim return_ACPI_STATUS (AE_BAD_PATHNAME); 36367754Smsmith } 36467754Smsmith 36567754Smsmith /* Move on the next segment */ 36667754Smsmith 36767754Smsmith ExternalName++; 36867754Smsmith Result += ACPI_NAME_SIZE; 36967754Smsmith } 37067754Smsmith 37177424Smsmith /* Terminate the string */ 37267754Smsmith 37367754Smsmith *Result = 0; 37467754Smsmith 37577424Smsmith if (Info->FullyQualified) 37667754Smsmith { 377123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 37899146Siwasaki InternalName, InternalName)); 37967754Smsmith } 38067754Smsmith else 38167754Smsmith { 382123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 38399146Siwasaki InternalName, InternalName)); 38467754Smsmith } 38567754Smsmith 38667754Smsmith return_ACPI_STATUS (AE_OK); 38767754Smsmith} 38867754Smsmith 38967754Smsmith 39077424Smsmith/******************************************************************************* 39167754Smsmith * 39277424Smsmith * FUNCTION: AcpiNsInternalizeName 39377424Smsmith * 39477424Smsmith * PARAMETERS: *ExternalName - External representation of name 39577424Smsmith * **Converted Name - Where to return the resulting 39677424Smsmith * internal represention of the name 39777424Smsmith * 39877424Smsmith * RETURN: Status 39977424Smsmith * 40077424Smsmith * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 40177424Smsmith * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 40277424Smsmith * 40377424Smsmith *******************************************************************************/ 40477424Smsmith 40577424SmsmithACPI_STATUS 40677424SmsmithAcpiNsInternalizeName ( 407193267Sjkim const char *ExternalName, 408114237Snjl char **ConvertedName) 40977424Smsmith{ 410114237Snjl char *InternalName; 41177424Smsmith ACPI_NAMESTRING_INFO Info; 41277424Smsmith ACPI_STATUS Status; 41377424Smsmith 41477424Smsmith 415167802Sjkim ACPI_FUNCTION_TRACE (NsInternalizeName); 41677424Smsmith 41777424Smsmith 41877424Smsmith if ((!ExternalName) || 41977424Smsmith (*ExternalName == 0) || 42077424Smsmith (!ConvertedName)) 42177424Smsmith { 42277424Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 42377424Smsmith } 42477424Smsmith 42577424Smsmith /* Get the length of the new internal name */ 42677424Smsmith 42777424Smsmith Info.ExternalName = ExternalName; 42877424Smsmith AcpiNsGetInternalNameLength (&Info); 42977424Smsmith 43077424Smsmith /* We need a segment to store the internal name */ 43177424Smsmith 432167802Sjkim InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 43377424Smsmith if (!InternalName) 43477424Smsmith { 43577424Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 43677424Smsmith } 43777424Smsmith 43877424Smsmith /* Build the name */ 43977424Smsmith 44077424Smsmith Info.InternalName = InternalName; 44177424Smsmith Status = AcpiNsBuildInternalName (&Info); 44277424Smsmith if (ACPI_FAILURE (Status)) 44377424Smsmith { 444167802Sjkim ACPI_FREE (InternalName); 44577424Smsmith return_ACPI_STATUS (Status); 44677424Smsmith } 44777424Smsmith 44877424Smsmith *ConvertedName = InternalName; 44977424Smsmith return_ACPI_STATUS (AE_OK); 45077424Smsmith} 45177424Smsmith 45277424Smsmith 45377424Smsmith/******************************************************************************* 45477424Smsmith * 45567754Smsmith * FUNCTION: AcpiNsExternalizeName 45667754Smsmith * 457151937Sjkim * PARAMETERS: InternalNameLength - Lenth of the internal name below 458151937Sjkim * InternalName - Internal representation of name 459151937Sjkim * ConvertedNameLength - Where the length is returned 460151937Sjkim * ConvertedName - Where the resulting external name 461151937Sjkim * is returned 46267754Smsmith * 46367754Smsmith * RETURN: Status 46467754Smsmith * 46567754Smsmith * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 466151937Sjkim * to its external (printable) form (e.g. "\_PR_.CPU0") 46767754Smsmith * 46877424Smsmith ******************************************************************************/ 46967754Smsmith 47067754SmsmithACPI_STATUS 47167754SmsmithAcpiNsExternalizeName ( 47267754Smsmith UINT32 InternalNameLength, 473193267Sjkim const char *InternalName, 47467754Smsmith UINT32 *ConvertedNameLength, 47567754Smsmith char **ConvertedName) 47667754Smsmith{ 477193267Sjkim UINT32 NamesIndex = 0; 478193267Sjkim UINT32 NumSegments = 0; 479193267Sjkim UINT32 RequiredLength; 480193267Sjkim UINT32 PrefixLength = 0; 481193267Sjkim UINT32 i = 0; 482193267Sjkim UINT32 j = 0; 48367754Smsmith 48467754Smsmith 485167802Sjkim ACPI_FUNCTION_TRACE (NsExternalizeName); 48667754Smsmith 48767754Smsmith 48867754Smsmith if (!InternalNameLength || 48967754Smsmith !InternalName || 49067754Smsmith !ConvertedName) 49167754Smsmith { 49267754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 49367754Smsmith } 49467754Smsmith 495193267Sjkim /* Check for a prefix (one '\' | one or more '^') */ 496193267Sjkim 49767754Smsmith switch (InternalName[0]) 49867754Smsmith { 499245582Sjkim case AML_ROOT_PREFIX: 500250838Sjkim 50167754Smsmith PrefixLength = 1; 50267754Smsmith break; 50367754Smsmith 504245582Sjkim case AML_PARENT_PREFIX: 505250838Sjkim 50667754Smsmith for (i = 0; i < InternalNameLength; i++) 50767754Smsmith { 508245582Sjkim if (ACPI_IS_PARENT_PREFIX (InternalName[i])) 50967754Smsmith { 51067754Smsmith PrefixLength = i + 1; 51167754Smsmith } 512102550Siwasaki else 513102550Siwasaki { 514102550Siwasaki break; 515102550Siwasaki } 51667754Smsmith } 51767754Smsmith 51867754Smsmith if (i == InternalNameLength) 51967754Smsmith { 52067754Smsmith PrefixLength = i; 52167754Smsmith } 52267754Smsmith 52367754Smsmith break; 52499679Siwasaki 52599679Siwasaki default: 526250838Sjkim 52799679Siwasaki break; 52867754Smsmith } 52967754Smsmith 53067754Smsmith /* 531193267Sjkim * Check for object names. Note that there could be 0-255 of these 53267754Smsmith * 4-byte elements. 53367754Smsmith */ 53467754Smsmith if (PrefixLength < InternalNameLength) 53567754Smsmith { 53667754Smsmith switch (InternalName[PrefixLength]) 53767754Smsmith { 53891116Smsmith case AML_MULTI_NAME_PREFIX_OP: 53967754Smsmith 54091116Smsmith /* <count> 4-byte names */ 54167754Smsmith 54267754Smsmith NamesIndex = PrefixLength + 2; 543193267Sjkim NumSegments = (UINT8) 544193267Sjkim InternalName[(ACPI_SIZE) PrefixLength + 1]; 54567754Smsmith break; 54667754Smsmith 54791116Smsmith case AML_DUAL_NAME_PREFIX: 54867754Smsmith 54991116Smsmith /* Two 4-byte names */ 55067754Smsmith 55167754Smsmith NamesIndex = PrefixLength + 1; 55291116Smsmith NumSegments = 2; 55367754Smsmith break; 55467754Smsmith 55591116Smsmith case 0: 55667754Smsmith 55791116Smsmith /* NullName */ 55867754Smsmith 55967754Smsmith NamesIndex = 0; 56091116Smsmith NumSegments = 0; 56167754Smsmith break; 56267754Smsmith 56391116Smsmith default: 56467754Smsmith 56591116Smsmith /* one 4-byte name */ 56667754Smsmith 56767754Smsmith NamesIndex = PrefixLength; 56891116Smsmith NumSegments = 1; 56967754Smsmith break; 57067754Smsmith } 57167754Smsmith } 57267754Smsmith 57367754Smsmith /* 57467754Smsmith * Calculate the length of ConvertedName, which equals the length 57567754Smsmith * of the prefix, length of all object names, length of any required 57667754Smsmith * punctuation ('.') between object names, plus the NULL terminator. 57767754Smsmith */ 57891116Smsmith RequiredLength = PrefixLength + (4 * NumSegments) + 57991116Smsmith ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 58067754Smsmith 58167754Smsmith /* 582241973Sjkim * Check to see if we're still in bounds. If not, there's a problem 58367754Smsmith * with InternalName (invalid format). 58467754Smsmith */ 58591116Smsmith if (RequiredLength > InternalNameLength) 58667754Smsmith { 587167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid internal name")); 58867754Smsmith return_ACPI_STATUS (AE_BAD_PATHNAME); 58967754Smsmith } 59067754Smsmith 591193267Sjkim /* Build the ConvertedName */ 592193267Sjkim 593167802Sjkim *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 59467754Smsmith if (!(*ConvertedName)) 59567754Smsmith { 59667754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 59767754Smsmith } 59867754Smsmith 59967754Smsmith j = 0; 60067754Smsmith 60167754Smsmith for (i = 0; i < PrefixLength; i++) 60267754Smsmith { 60367754Smsmith (*ConvertedName)[j++] = InternalName[i]; 60467754Smsmith } 60567754Smsmith 60691116Smsmith if (NumSegments > 0) 60767754Smsmith { 60891116Smsmith for (i = 0; i < NumSegments; i++) 60967754Smsmith { 61067754Smsmith if (i > 0) 61167754Smsmith { 61267754Smsmith (*ConvertedName)[j++] = '.'; 61367754Smsmith } 61467754Smsmith 615241973Sjkim /* Copy and validate the 4-char name segment */ 616241973Sjkim 617241973Sjkim ACPI_MOVE_NAME (&(*ConvertedName)[j], &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{ 69667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 69767754Smsmith 69867754Smsmith 699167802Sjkim ACPI_FUNCTION_TRACE (NsTerminate); 70067754Smsmith 70167754Smsmith 70267754Smsmith /* 703117521Snjl * 1) Free the entire namespace -- all nodes and objects 70477424Smsmith * 705117521Snjl * Delete all object descriptors attached to namepsace nodes 70667754Smsmith */ 707117521Snjl AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 70867754Smsmith 709117521Snjl /* Detach any objects attached to the root */ 71067754Smsmith 711117521Snjl ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode); 71267754Smsmith if (ObjDesc) 71367754Smsmith { 714117521Snjl AcpiNsDetachObject (AcpiGbl_RootNode); 71567754Smsmith } 71667754Smsmith 71782367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 71867754Smsmith return_VOID; 71967754Smsmith} 72067754Smsmith 72167754Smsmith 72277424Smsmith/******************************************************************************* 72367754Smsmith * 72467754Smsmith * FUNCTION: AcpiNsOpensScope 72567754Smsmith * 72667754Smsmith * PARAMETERS: Type - A valid namespace type 72767754Smsmith * 72867754Smsmith * RETURN: NEWSCOPE if the passed type "opens a name scope" according 72967754Smsmith * to the ACPI specification, else 0 73067754Smsmith * 73177424Smsmith ******************************************************************************/ 73267754Smsmith 73367754SmsmithUINT32 73467754SmsmithAcpiNsOpensScope ( 73591116Smsmith ACPI_OBJECT_TYPE Type) 73667754Smsmith{ 737243347Sjkim ACPI_FUNCTION_ENTRY (); 73867754Smsmith 73967754Smsmith 740243347Sjkim if (Type > ACPI_TYPE_LOCAL_MAX) 74167754Smsmith { 74267754Smsmith /* type code out of range */ 74367754Smsmith 744204773Sjkim ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 745243347Sjkim return (ACPI_NS_NORMAL); 74667754Smsmith } 74767754Smsmith 748243347Sjkim return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 74967754Smsmith} 75067754Smsmith 75167754Smsmith 75277424Smsmith/******************************************************************************* 75367754Smsmith * 754167802Sjkim * FUNCTION: AcpiNsGetNode 75567754Smsmith * 75667754Smsmith * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 75767754Smsmith * \ (backslash) and ^ (carat) prefixes, and the 75867754Smsmith * . (period) to separate segments are supported. 759167802Sjkim * PrefixNode - Root of subtree to be searched, or NS_ALL for the 760241973Sjkim * root of the name space. If Name is fully 76167754Smsmith * qualified (first INT8 is '\'), the passed value 76267754Smsmith * of Scope will not be accessed. 76391116Smsmith * Flags - Used to indicate whether to perform upsearch or 76491116Smsmith * not. 76567754Smsmith * ReturnNode - Where the Node is returned 76667754Smsmith * 76767754Smsmith * DESCRIPTION: Look up a name relative to a given scope and return the 768241973Sjkim * corresponding Node. NOTE: Scope can be null. 76967754Smsmith * 77067754Smsmith * MUTEX: Locks namespace 77167754Smsmith * 77277424Smsmith ******************************************************************************/ 77367754Smsmith 77467754SmsmithACPI_STATUS 775167802SjkimAcpiNsGetNode ( 776167802Sjkim ACPI_NAMESPACE_NODE *PrefixNode, 777193267Sjkim const char *Pathname, 77891116Smsmith UINT32 Flags, 77967754Smsmith ACPI_NAMESPACE_NODE **ReturnNode) 78067754Smsmith{ 78167754Smsmith ACPI_GENERIC_STATE ScopeInfo; 78267754Smsmith ACPI_STATUS Status; 783167802Sjkim char *InternalPath; 78467754Smsmith 78567754Smsmith 786193267Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 78767754Smsmith 78867754Smsmith 789245582Sjkim /* Simplest case is a null pathname */ 790245582Sjkim 791167802Sjkim if (!Pathname) 79267754Smsmith { 793167802Sjkim *ReturnNode = PrefixNode; 794167802Sjkim if (!PrefixNode) 795114237Snjl { 796167802Sjkim *ReturnNode = AcpiGbl_RootNode; 797114237Snjl } 798167802Sjkim return_ACPI_STATUS (AE_OK); 79967754Smsmith } 80067754Smsmith 801245582Sjkim /* Quick check for a reference to the root */ 802245582Sjkim 803245582Sjkim if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1])) 804245582Sjkim { 805245582Sjkim *ReturnNode = AcpiGbl_RootNode; 806245582Sjkim return_ACPI_STATUS (AE_OK); 807245582Sjkim } 808245582Sjkim 809167802Sjkim /* Convert path to internal representation */ 810167802Sjkim 811167802Sjkim Status = AcpiNsInternalizeName (Pathname, &InternalPath); 812167802Sjkim if (ACPI_FAILURE (Status)) 813167802Sjkim { 814167802Sjkim return_ACPI_STATUS (Status); 815167802Sjkim } 816167802Sjkim 81791116Smsmith /* Must lock namespace during lookup */ 81867754Smsmith 81991116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 82091116Smsmith if (ACPI_FAILURE (Status)) 82191116Smsmith { 822126372Snjl goto Cleanup; 82391116Smsmith } 82467754Smsmith 82569746Smsmith /* Setup lookup scope (search starting point) */ 82667754Smsmith 827167802Sjkim ScopeInfo.Scope.Node = PrefixNode; 82867754Smsmith 82967754Smsmith /* Lookup the name in the namespace */ 83067754Smsmith 831167802Sjkim Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 832167802Sjkim ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 833167802Sjkim NULL, ReturnNode); 83467754Smsmith if (ACPI_FAILURE (Status)) 83567754Smsmith { 836193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 837167802Sjkim Pathname, AcpiFormatException (Status))); 83867754Smsmith } 83967754Smsmith 84091116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 841114237Snjl 842126372SnjlCleanup: 843167802Sjkim ACPI_FREE (InternalPath); 84467754Smsmith return_ACPI_STATUS (Status); 84567754Smsmith} 846