|
||||
Warning, cross-references for /kernel/drivers/acpica/nsutils.c need to be fixed.
0001 /****************************************************************************** 0002 * 0003 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 0004 * parents and siblings and Scope manipulation 0005 * 0006 *****************************************************************************/ 0007 0008 /****************************************************************************** 0009 * 0010 * 1. Copyright Notice 0011 * 0012 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 0013 * All rights reserved. 0014 * 0015 * 2. License 0016 * 0017 * 2.1. This is your license from Intel Corp. under its intellectual property 0018 * rights. You may have additional license terms from the party that provided 0019 * you this software, covering your right to use that party's intellectual 0020 * property rights. 0021 * 0022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0023 * copy of the source code appearing in this file ("Covered Code") an 0024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0025 * base code distributed originally by Intel ("Original Intel Code") to copy, 0026 * make derivatives, distribute, use and display any portion of the Covered 0027 * Code in any form, with the right to sublicense such rights; and 0028 * 0029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0030 * license (with the right to sublicense), under only those claims of Intel 0031 * patents that are infringed by the Original Intel Code, to make, use, sell, 0032 * offer to sell, and import the Covered Code and derivative works thereof 0033 * solely to the minimum extent necessary to exercise the above copyright 0034 * license, and in no event shall the patent license extend to any additions 0035 * to or modifications of the Original Intel Code. No other license or right 0036 * is granted directly or by implication, estoppel or otherwise; 0037 * 0038 * The above copyright and patent license is granted only if the following 0039 * conditions are met: 0040 * 0041 * 3. Conditions 0042 * 0043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0044 * Redistribution of source code of any substantial portion of the Covered 0045 * Code or modification with rights to further distribute source must include 0046 * the above Copyright Notice, the above License, this list of Conditions, 0047 * and the following Disclaimer and Export Compliance provision. In addition, 0048 * Licensee must cause all Covered Code to which Licensee contributes to 0049 * contain a file documenting the changes Licensee made to create that Covered 0050 * Code and the date of any change. Licensee must include in that file the 0051 * documentation of any changes made by any predecessor Licensee. Licensee 0052 * must include a prominent statement that the modification is derived, 0053 * directly or indirectly, from Original Intel Code. 0054 * 0055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0056 * Redistribution of source code of any substantial portion of the Covered 0057 * Code or modification without rights to further distribute source must 0058 * include the following Disclaimer and Export Compliance provision in the 0059 * documentation and/or other materials provided with distribution. In 0060 * addition, Licensee may not authorize further sublicense of source of any 0061 * portion of the Covered Code, and must include terms to the effect that the 0062 * license from Licensee to its licensee is limited to the intellectual 0063 * property embodied in the software Licensee provides to its licensee, and 0064 * not to intellectual property embodied in modifications its licensee may 0065 * make. 0066 * 0067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0068 * substantial portion of the Covered Code or modification must reproduce the 0069 * above Copyright Notice, and the following Disclaimer and Export Compliance 0070 * provision in the documentation and/or other materials provided with the 0071 * distribution. 0072 * 0073 * 3.4. Intel retains all right, title, and interest in and to the Original 0074 * Intel Code. 0075 * 0076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0077 * Intel shall be used in advertising or otherwise to promote the sale, use or 0078 * other dealings in products derived from or relating to the Covered Code 0079 * without prior written authorization from Intel. 0080 * 0081 * 4. Disclaimer and Export Compliance 0082 * 0083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 *****************************************************************************/ 0116 0117 #define __NSUTILS_C__ 0118 0119 #include "acpi.h" 0120 #include "accommon.h" 0121 #include "acnamesp.h" 0122 #include "amlcode.h" 0123 0124 #define _COMPONENT ACPI_NAMESPACE 0125 ACPI_MODULE_NAME ("nsutils") 0126 0127 /* Local prototypes */ 0128 0129 static BOOLEAN 0130 AcpiNsValidPathSeparator ( 0131 char Sep); 0132 0133 #ifdef ACPI_OBSOLETE_FUNCTIONS 0134 ACPI_NAME 0135 AcpiNsFindParentName ( 0136 ACPI_NAMESPACE_NODE *NodeToSearch); 0137 #endif 0138 0139 0140 /******************************************************************************* 0141 * 0142 * FUNCTION: AcpiNsReportError 0143 * 0144 * PARAMETERS: ModuleName - Caller's module name (for error output) 0145 * LineNumber - Caller's line number (for error output) 0146 * InternalName - Name or path of the namespace node 0147 * LookupStatus - Exception code from NS lookup 0148 * 0149 * RETURN: None 0150 * 0151 * DESCRIPTION: Print warning message with full pathname 0152 * 0153 ******************************************************************************/ 0154 0155 void 0156 AcpiNsReportError ( 0157 const char *ModuleName, 0158 UINT32 LineNumber, 0159 const char *InternalName, 0160 ACPI_STATUS LookupStatus) 0161 { 0162 ACPI_STATUS Status; 0163 UINT32 BadName; 0164 char *Name = NULL; 0165 0166 0167 AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber); 0168 0169 if (LookupStatus == AE_BAD_CHARACTER) 0170 { 0171 /* There is a non-ascii character in the name */ 0172 0173 ACPI_MOVE_32_TO_32 (&BadName, ACPI_CAST_PTR (UINT32, InternalName)); 0174 AcpiOsPrintf ("[0x%4.4X] (NON-ASCII)", BadName); 0175 } 0176 else 0177 { 0178 /* Convert path to external format */ 0179 0180 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, 0181 InternalName, NULL, &Name); 0182 0183 /* Print target name */ 0184 0185 if (ACPI_SUCCESS (Status)) 0186 { 0187 AcpiOsPrintf ("[%s]", Name); 0188 } 0189 else 0190 { 0191 AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]"); 0192 } 0193 0194 if (Name) 0195 { 0196 ACPI_FREE (Name); 0197 } 0198 } 0199 0200 AcpiOsPrintf (" Namespace lookup failure, %s\n", 0201 AcpiFormatException (LookupStatus)); 0202 } 0203 0204 0205 /******************************************************************************* 0206 * 0207 * FUNCTION: AcpiNsReportMethodError 0208 * 0209 * PARAMETERS: ModuleName - Caller's module name (for error output) 0210 * LineNumber - Caller's line number (for error output) 0211 * Message - Error message to use on failure 0212 * PrefixNode - Prefix relative to the path 0213 * Path - Path to the node (optional) 0214 * MethodStatus - Execution status 0215 * 0216 * RETURN: None 0217 * 0218 * DESCRIPTION: Print warning message with full pathname 0219 * 0220 ******************************************************************************/ 0221 0222 void 0223 AcpiNsReportMethodError ( 0224 const char *ModuleName, 0225 UINT32 LineNumber, 0226 const char *Message, 0227 ACPI_NAMESPACE_NODE *PrefixNode, 0228 const char *Path, 0229 ACPI_STATUS MethodStatus) 0230 { 0231 ACPI_STATUS Status; 0232 ACPI_NAMESPACE_NODE *Node = PrefixNode; 0233 0234 0235 AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber); 0236 0237 if (Path) 0238 { 0239 Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH, 0240 &Node); 0241 if (ACPI_FAILURE (Status)) 0242 { 0243 AcpiOsPrintf ("[Could not get node by pathname]"); 0244 } 0245 } 0246 0247 AcpiNsPrintNodePathname (Node, Message); 0248 AcpiOsPrintf (", %s\n", AcpiFormatException (MethodStatus)); 0249 } 0250 0251 0252 /******************************************************************************* 0253 * 0254 * FUNCTION: AcpiNsPrintNodePathname 0255 * 0256 * PARAMETERS: Node - Object 0257 * Message - Prefix message 0258 * 0259 * DESCRIPTION: Print an object's full namespace pathname 0260 * Manages allocation/freeing of a pathname buffer 0261 * 0262 ******************************************************************************/ 0263 0264 void 0265 AcpiNsPrintNodePathname ( 0266 ACPI_NAMESPACE_NODE *Node, 0267 const char *Message) 0268 { 0269 ACPI_BUFFER Buffer; 0270 ACPI_STATUS Status; 0271 0272 0273 if (!Node) 0274 { 0275 AcpiOsPrintf ("[NULL NAME]"); 0276 return; 0277 } 0278 0279 /* Convert handle to full pathname and print it (with supplied message) */ 0280 0281 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 0282 0283 Status = AcpiNsHandleToPathname (Node, &Buffer); 0284 if (ACPI_SUCCESS (Status)) 0285 { 0286 if (Message) 0287 { 0288 AcpiOsPrintf ("%s ", Message); 0289 } 0290 0291 AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 0292 ACPI_FREE (Buffer.Pointer); 0293 } 0294 } 0295 0296 0297 /******************************************************************************* 0298 * 0299 * FUNCTION: AcpiNsValidRootPrefix 0300 * 0301 * PARAMETERS: Prefix - Character to be checked 0302 * 0303 * RETURN: TRUE if a valid prefix 0304 * 0305 * DESCRIPTION: Check if a character is a valid ACPI Root prefix 0306 * 0307 ******************************************************************************/ 0308 0309 BOOLEAN 0310 AcpiNsValidRootPrefix ( 0311 char Prefix) 0312 { 0313 0314 return ((BOOLEAN) (Prefix == '\\')); 0315 } 0316 0317 0318 /******************************************************************************* 0319 * 0320 * FUNCTION: AcpiNsValidPathSeparator 0321 * 0322 * PARAMETERS: Sep - Character to be checked 0323 * 0324 * RETURN: TRUE if a valid path separator 0325 * 0326 * DESCRIPTION: Check if a character is a valid ACPI path separator 0327 * 0328 ******************************************************************************/ 0329 0330 static BOOLEAN 0331 AcpiNsValidPathSeparator ( 0332 char Sep) 0333 { 0334 0335 return ((BOOLEAN) (Sep == '.')); 0336 } 0337 0338 0339 /******************************************************************************* 0340 * 0341 * FUNCTION: AcpiNsGetType 0342 * 0343 * PARAMETERS: Node - Parent Node to be examined 0344 * 0345 * RETURN: Type field from Node whose handle is passed 0346 * 0347 * DESCRIPTION: Return the type of a Namespace node 0348 * 0349 ******************************************************************************/ 0350 0351 ACPI_OBJECT_TYPE 0352 AcpiNsGetType ( 0353 ACPI_NAMESPACE_NODE *Node) 0354 { 0355 ACPI_FUNCTION_TRACE (NsGetType); 0356 0357 0358 if (!Node) 0359 { 0360 ACPI_WARNING ((AE_INFO, "Null Node parameter")); 0361 return_UINT32 (ACPI_TYPE_ANY); 0362 } 0363 0364 return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type); 0365 } 0366 0367 0368 /******************************************************************************* 0369 * 0370 * FUNCTION: AcpiNsLocal 0371 * 0372 * PARAMETERS: Type - A namespace object type 0373 * 0374 * RETURN: LOCAL if names must be found locally in objects of the 0375 * passed type, 0 if enclosing scopes should be searched 0376 * 0377 * DESCRIPTION: Returns scope rule for the given object type. 0378 * 0379 ******************************************************************************/ 0380 0381 UINT32 0382 AcpiNsLocal ( 0383 ACPI_OBJECT_TYPE Type) 0384 { 0385 ACPI_FUNCTION_TRACE (NsLocal); 0386 0387 0388 if (!AcpiUtValidObjectType (Type)) 0389 { 0390 /* Type code out of range */ 0391 0392 ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type)); 0393 return_UINT32 (ACPI_NS_NORMAL); 0394 } 0395 0396 return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 0397 } 0398 0399 0400 /******************************************************************************* 0401 * 0402 * FUNCTION: AcpiNsGetInternalNameLength 0403 * 0404 * PARAMETERS: Info - Info struct initialized with the 0405 * external name pointer. 0406 * 0407 * RETURN: None 0408 * 0409 * DESCRIPTION: Calculate the length of the internal (AML) namestring 0410 * corresponding to the external (ASL) namestring. 0411 * 0412 ******************************************************************************/ 0413 0414 void 0415 AcpiNsGetInternalNameLength ( 0416 ACPI_NAMESTRING_INFO *Info) 0417 { 0418 const char *NextExternalChar; 0419 UINT32 i; 0420 0421 0422 ACPI_FUNCTION_ENTRY (); 0423 0424 0425 NextExternalChar = Info->ExternalName; 0426 Info->NumCarats = 0; 0427 Info->NumSegments = 0; 0428 Info->FullyQualified = FALSE; 0429 0430 /* 0431 * For the internal name, the required length is 4 bytes per segment, plus 0432 * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null 0433 * (which is not really needed, but no there's harm in putting it there) 0434 * 0435 * strlen() + 1 covers the first NameSeg, which has no path separator 0436 */ 0437 if (AcpiNsValidRootPrefix (*NextExternalChar)) 0438 { 0439 Info->FullyQualified = TRUE; 0440 NextExternalChar++; 0441 0442 /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 0443 0444 while (AcpiNsValidRootPrefix (*NextExternalChar)) 0445 { 0446 NextExternalChar++; 0447 } 0448 } 0449 else 0450 { 0451 /* Handle Carat prefixes */ 0452 0453 while (*NextExternalChar == '^') 0454 { 0455 Info->NumCarats++; 0456 NextExternalChar++; 0457 } 0458 } 0459 0460 /* 0461 * Determine the number of ACPI name "segments" by counting the number of 0462 * path separators within the string. Start with one segment since the 0463 * segment count is [(# separators) + 1], and zero separators is ok. 0464 */ 0465 if (*NextExternalChar) 0466 { 0467 Info->NumSegments = 1; 0468 for (i = 0; NextExternalChar[i]; i++) 0469 { 0470 if (AcpiNsValidPathSeparator (NextExternalChar[i])) 0471 { 0472 Info->NumSegments++; 0473 } 0474 } 0475 } 0476 0477 Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 0478 4 + Info->NumCarats; 0479 0480 Info->NextExternalChar = NextExternalChar; 0481 } 0482 0483 0484 /******************************************************************************* 0485 * 0486 * FUNCTION: AcpiNsBuildInternalName 0487 * 0488 * PARAMETERS: Info - Info struct fully initialized 0489 * 0490 * RETURN: Status 0491 * 0492 * DESCRIPTION: Construct the internal (AML) namestring 0493 * corresponding to the external (ASL) namestring. 0494 * 0495 ******************************************************************************/ 0496 0497 ACPI_STATUS 0498 AcpiNsBuildInternalName ( 0499 ACPI_NAMESTRING_INFO *Info) 0500 { 0501 UINT32 NumSegments = Info->NumSegments; 0502 char *InternalName = Info->InternalName; 0503 const char *ExternalName = Info->NextExternalChar; 0504 char *Result = NULL; 0505 UINT32 i; 0506 0507 0508 ACPI_FUNCTION_TRACE (NsBuildInternalName); 0509 0510 0511 /* Setup the correct prefixes, counts, and pointers */ 0512 0513 if (Info->FullyQualified) 0514 { 0515 InternalName[0] = '\\'; 0516 0517 if (NumSegments <= 1) 0518 { 0519 Result = &InternalName[1]; 0520 } 0521 else if (NumSegments == 2) 0522 { 0523 InternalName[1] = AML_DUAL_NAME_PREFIX; 0524 Result = &InternalName[2]; 0525 } 0526 else 0527 { 0528 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 0529 InternalName[2] = (char) NumSegments; 0530 Result = &InternalName[3]; 0531 } 0532 } 0533 else 0534 { 0535 /* 0536 * Not fully qualified. 0537 * Handle Carats first, then append the name segments 0538 */ 0539 i = 0; 0540 if (Info->NumCarats) 0541 { 0542 for (i = 0; i < Info->NumCarats; i++) 0543 { 0544 InternalName[i] = '^'; 0545 } 0546 } 0547 0548 if (NumSegments <= 1) 0549 { 0550 Result = &InternalName[i]; 0551 } 0552 else if (NumSegments == 2) 0553 { 0554 InternalName[i] = AML_DUAL_NAME_PREFIX; 0555 Result = &InternalName[(ACPI_SIZE) i+1]; 0556 } 0557 else 0558 { 0559 InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 0560 InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 0561 Result = &InternalName[(ACPI_SIZE) i+2]; 0562 } 0563 } 0564 0565 /* Build the name (minus path separators) */ 0566 0567 for (; NumSegments; NumSegments--) 0568 { 0569 for (i = 0; i < ACPI_NAME_SIZE; i++) 0570 { 0571 if (AcpiNsValidPathSeparator (*ExternalName) || 0572 (*ExternalName == 0)) 0573 { 0574 /* Pad the segment with underscore(s) if segment is short */ 0575 0576 Result[i] = '_'; 0577 } 0578 else 0579 { 0580 /* Convert the character to uppercase and save it */ 0581 0582 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName); 0583 ExternalName++; 0584 } 0585 } 0586 0587 /* Now we must have a path separator, or the pathname is bad */ 0588 0589 if (!AcpiNsValidPathSeparator (*ExternalName) && 0590 (*ExternalName != 0)) 0591 { 0592 return_ACPI_STATUS (AE_BAD_PARAMETER); 0593 } 0594 0595 /* Move on the next segment */ 0596 0597 ExternalName++; 0598 Result += ACPI_NAME_SIZE; 0599 } 0600 0601 /* Terminate the string */ 0602 0603 *Result = 0; 0604 0605 if (Info->FullyQualified) 0606 { 0607 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 0608 InternalName, InternalName)); 0609 } 0610 else 0611 { 0612 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 0613 InternalName, InternalName)); 0614 } 0615 0616 return_ACPI_STATUS (AE_OK); 0617 } 0618 0619 0620 /******************************************************************************* 0621 * 0622 * FUNCTION: AcpiNsInternalizeName 0623 * 0624 * PARAMETERS: *ExternalName - External representation of name 0625 * **Converted Name - Where to return the resulting 0626 * internal represention of the name 0627 * 0628 * RETURN: Status 0629 * 0630 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 0631 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 0632 * 0633 *******************************************************************************/ 0634 0635 ACPI_STATUS 0636 AcpiNsInternalizeName ( 0637 const char *ExternalName, 0638 char **ConvertedName) 0639 { 0640 char *InternalName; 0641 ACPI_NAMESTRING_INFO Info; 0642 ACPI_STATUS Status; 0643 0644 0645 ACPI_FUNCTION_TRACE (NsInternalizeName); 0646 0647 0648 if ((!ExternalName) || 0649 (*ExternalName == 0) || 0650 (!ConvertedName)) 0651 { 0652 return_ACPI_STATUS (AE_BAD_PARAMETER); 0653 } 0654 0655 /* Get the length of the new internal name */ 0656 0657 Info.ExternalName = ExternalName; 0658 AcpiNsGetInternalNameLength (&Info); 0659 0660 /* We need a segment to store the internal name */ 0661 0662 InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 0663 if (!InternalName) 0664 { 0665 return_ACPI_STATUS (AE_NO_MEMORY); 0666 } 0667 0668 /* Build the name */ 0669 0670 Info.InternalName = InternalName; 0671 Status = AcpiNsBuildInternalName (&Info); 0672 if (ACPI_FAILURE (Status)) 0673 { 0674 ACPI_FREE (InternalName); 0675 return_ACPI_STATUS (Status); 0676 } 0677 0678 *ConvertedName = InternalName; 0679 return_ACPI_STATUS (AE_OK); 0680 } 0681 0682 0683 /******************************************************************************* 0684 * 0685 * FUNCTION: AcpiNsExternalizeName 0686 * 0687 * PARAMETERS: InternalNameLength - Lenth of the internal name below 0688 * InternalName - Internal representation of name 0689 * ConvertedNameLength - Where the length is returned 0690 * ConvertedName - Where the resulting external name 0691 * is returned 0692 * 0693 * RETURN: Status 0694 * 0695 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 0696 * to its external (printable) form (e.g. "\_PR_.CPU0") 0697 * 0698 ******************************************************************************/ 0699 0700 ACPI_STATUS 0701 AcpiNsExternalizeName ( 0702 UINT32 InternalNameLength, 0703 const char *InternalName, 0704 UINT32 *ConvertedNameLength, 0705 char **ConvertedName) 0706 { 0707 UINT32 NamesIndex = 0; 0708 UINT32 NumSegments = 0; 0709 UINT32 RequiredLength; 0710 UINT32 PrefixLength = 0; 0711 UINT32 i = 0; 0712 UINT32 j = 0; 0713 0714 0715 ACPI_FUNCTION_TRACE (NsExternalizeName); 0716 0717 0718 if (!InternalNameLength || 0719 !InternalName || 0720 !ConvertedName) 0721 { 0722 return_ACPI_STATUS (AE_BAD_PARAMETER); 0723 } 0724 0725 /* Check for a prefix (one '\' | one or more '^') */ 0726 0727 switch (InternalName[0]) 0728 { 0729 case '\\': 0730 PrefixLength = 1; 0731 break; 0732 0733 case '^': 0734 for (i = 0; i < InternalNameLength; i++) 0735 { 0736 if (InternalName[i] == '^') 0737 { 0738 PrefixLength = i + 1; 0739 } 0740 else 0741 { 0742 break; 0743 } 0744 } 0745 0746 if (i == InternalNameLength) 0747 { 0748 PrefixLength = i; 0749 } 0750 0751 break; 0752 0753 default: 0754 break; 0755 } 0756 0757 /* 0758 * Check for object names. Note that there could be 0-255 of these 0759 * 4-byte elements. 0760 */ 0761 if (PrefixLength < InternalNameLength) 0762 { 0763 switch (InternalName[PrefixLength]) 0764 { 0765 case AML_MULTI_NAME_PREFIX_OP: 0766 0767 /* <count> 4-byte names */ 0768 0769 NamesIndex = PrefixLength + 2; 0770 NumSegments = (UINT8) 0771 InternalName[(ACPI_SIZE) PrefixLength + 1]; 0772 break; 0773 0774 case AML_DUAL_NAME_PREFIX: 0775 0776 /* Two 4-byte names */ 0777 0778 NamesIndex = PrefixLength + 1; 0779 NumSegments = 2; 0780 break; 0781 0782 case 0: 0783 0784 /* NullName */ 0785 0786 NamesIndex = 0; 0787 NumSegments = 0; 0788 break; 0789 0790 default: 0791 0792 /* one 4-byte name */ 0793 0794 NamesIndex = PrefixLength; 0795 NumSegments = 1; 0796 break; 0797 } 0798 } 0799 0800 /* 0801 * Calculate the length of ConvertedName, which equals the length 0802 * of the prefix, length of all object names, length of any required 0803 * punctuation ('.') between object names, plus the NULL terminator. 0804 */ 0805 RequiredLength = PrefixLength + (4 * NumSegments) + 0806 ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 0807 0808 /* 0809 * Check to see if we're still in bounds. If not, there's a problem 0810 * with InternalName (invalid format). 0811 */ 0812 if (RequiredLength > InternalNameLength) 0813 { 0814 ACPI_ERROR ((AE_INFO, "Invalid internal name")); 0815 return_ACPI_STATUS (AE_BAD_PATHNAME); 0816 } 0817 0818 /* Build the ConvertedName */ 0819 0820 *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 0821 if (!(*ConvertedName)) 0822 { 0823 return_ACPI_STATUS (AE_NO_MEMORY); 0824 } 0825 0826 j = 0; 0827 0828 for (i = 0; i < PrefixLength; i++) 0829 { 0830 (*ConvertedName)[j++] = InternalName[i]; 0831 } 0832 0833 if (NumSegments > 0) 0834 { 0835 for (i = 0; i < NumSegments; i++) 0836 { 0837 if (i > 0) 0838 { 0839 (*ConvertedName)[j++] = '.'; 0840 } 0841 0842 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 0843 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 0844 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 0845 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 0846 } 0847 } 0848 0849 if (ConvertedNameLength) 0850 { 0851 *ConvertedNameLength = (UINT32) RequiredLength; 0852 } 0853 0854 return_ACPI_STATUS (AE_OK); 0855 } 0856 0857 0858 /******************************************************************************* 0859 * 0860 * FUNCTION: AcpiNsMapHandleToNode 0861 * 0862 * PARAMETERS: Handle - Handle to be converted to an Node 0863 * 0864 * RETURN: A Name table entry pointer 0865 * 0866 * DESCRIPTION: Convert a namespace handle to a real Node 0867 * 0868 * Note: Real integer handles would allow for more verification 0869 * and keep all pointers within this subsystem - however this introduces 0870 * more (and perhaps unnecessary) overhead. 0871 * 0872 * The current implemenation is basically a placeholder until such time comes 0873 * that it is needed. 0874 * 0875 ******************************************************************************/ 0876 0877 ACPI_NAMESPACE_NODE * 0878 AcpiNsMapHandleToNode ( 0879 ACPI_HANDLE Handle) 0880 { 0881 0882 ACPI_FUNCTION_ENTRY (); 0883 0884 0885 /* Parameter validation */ 0886 0887 if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 0888 { 0889 return (AcpiGbl_RootNode); 0890 } 0891 0892 /* We can at least attempt to verify the handle */ 0893 0894 if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 0895 { 0896 return (NULL); 0897 } 0898 0899 return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 0900 } 0901 0902 0903 /******************************************************************************* 0904 * 0905 * FUNCTION: AcpiNsConvertEntryToHandle 0906 * 0907 * PARAMETERS: Node - Node to be converted to a Handle 0908 * 0909 * RETURN: A user handle 0910 * 0911 * DESCRIPTION: Convert a real Node to a namespace handle 0912 * 0913 ******************************************************************************/ 0914 0915 ACPI_HANDLE 0916 AcpiNsConvertEntryToHandle ( 0917 ACPI_NAMESPACE_NODE *Node) 0918 { 0919 0920 0921 /* 0922 * Simple implementation for now; 0923 */ 0924 return ((ACPI_HANDLE) Node); 0925 0926 0927 /* Example future implementation --------------------- 0928 0929 if (!Node) 0930 { 0931 return (NULL); 0932 } 0933 0934 if (Node == AcpiGbl_RootNode) 0935 { 0936 return (ACPI_ROOT_OBJECT); 0937 } 0938 0939 0940 return ((ACPI_HANDLE) Node); 0941 ------------------------------------------------------*/ 0942 } 0943 0944 0945 /******************************************************************************* 0946 * 0947 * FUNCTION: AcpiNsTerminate 0948 * 0949 * PARAMETERS: none 0950 * 0951 * RETURN: none 0952 * 0953 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 0954 * 0955 ******************************************************************************/ 0956 0957 void 0958 AcpiNsTerminate ( 0959 void) 0960 { 0961 ACPI_OPERAND_OBJECT *ObjDesc; 0962 0963 0964 ACPI_FUNCTION_TRACE (NsTerminate); 0965 0966 0967 /* 0968 * 1) Free the entire namespace -- all nodes and objects 0969 * 0970 * Delete all object descriptors attached to namepsace nodes 0971 */ 0972 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 0973 0974 /* Detach any objects attached to the root */ 0975 0976 ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode); 0977 if (ObjDesc) 0978 { 0979 AcpiNsDetachObject (AcpiGbl_RootNode); 0980 } 0981 0982 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 0983 return_VOID; 0984 } 0985 0986 0987 /******************************************************************************* 0988 * 0989 * FUNCTION: AcpiNsOpensScope 0990 * 0991 * PARAMETERS: Type - A valid namespace type 0992 * 0993 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 0994 * to the ACPI specification, else 0 0995 * 0996 ******************************************************************************/ 0997 0998 UINT32 0999 AcpiNsOpensScope ( 1000 ACPI_OBJECT_TYPE Type) 1001 { 1002 ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type)); 1003 1004 1005 if (!AcpiUtValidObjectType (Type)) 1006 { 1007 /* type code out of range */ 1008 1009 ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type)); 1010 return_UINT32 (ACPI_NS_NORMAL); 1011 } 1012 1013 return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 1014 } 1015 1016 1017 /******************************************************************************* 1018 * 1019 * FUNCTION: AcpiNsGetNode 1020 * 1021 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 1022 * \ (backslash) and ^ (carat) prefixes, and the 1023 * . (period) to separate segments are supported. 1024 * PrefixNode - Root of subtree to be searched, or NS_ALL for the 1025 * root of the name space. If Name is fully 1026 * qualified (first INT8 is '\'), the passed value 1027 * of Scope will not be accessed. 1028 * Flags - Used to indicate whether to perform upsearch or 1029 * not. 1030 * ReturnNode - Where the Node is returned 1031 * 1032 * DESCRIPTION: Look up a name relative to a given scope and return the 1033 * corresponding Node. NOTE: Scope can be null. 1034 * 1035 * MUTEX: Locks namespace 1036 * 1037 ******************************************************************************/ 1038 1039 ACPI_STATUS 1040 AcpiNsGetNode ( 1041 ACPI_NAMESPACE_NODE *PrefixNode, 1042 const char *Pathname, 1043 UINT32 Flags, 1044 ACPI_NAMESPACE_NODE **ReturnNode) 1045 { 1046 ACPI_GENERIC_STATE ScopeInfo; 1047 ACPI_STATUS Status; 1048 char *InternalPath; 1049 1050 1051 ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 1052 1053 1054 if (!Pathname) 1055 { 1056 *ReturnNode = PrefixNode; 1057 if (!PrefixNode) 1058 { 1059 *ReturnNode = AcpiGbl_RootNode; 1060 } 1061 return_ACPI_STATUS (AE_OK); 1062 } 1063 1064 /* Convert path to internal representation */ 1065 1066 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 1067 if (ACPI_FAILURE (Status)) 1068 { 1069 return_ACPI_STATUS (Status); 1070 } 1071 1072 /* Must lock namespace during lookup */ 1073 1074 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1075 if (ACPI_FAILURE (Status)) 1076 { 1077 goto Cleanup; 1078 } 1079 1080 /* Setup lookup scope (search starting point) */ 1081 1082 ScopeInfo.Scope.Node = PrefixNode; 1083 1084 /* Lookup the name in the namespace */ 1085 1086 Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 1087 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 1088 NULL, ReturnNode); 1089 if (ACPI_FAILURE (Status)) 1090 { 1091 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 1092 Pathname, AcpiFormatException (Status))); 1093 } 1094 1095 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1096 1097 Cleanup: 1098 ACPI_FREE (InternalPath); 1099 return_ACPI_STATUS (Status); 1100 } 1101 1102 1103 /******************************************************************************* 1104 * 1105 * FUNCTION: AcpiNsGetParentNode 1106 * 1107 * PARAMETERS: Node - Current table entry 1108 * 1109 * RETURN: Parent entry of the given entry 1110 * 1111 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. 1112 * 1113 ******************************************************************************/ 1114 1115 ACPI_NAMESPACE_NODE * 1116 AcpiNsGetParentNode ( 1117 ACPI_NAMESPACE_NODE *Node) 1118 { 1119 ACPI_FUNCTION_ENTRY (); 1120 1121 1122 if (!Node) 1123 { 1124 return (NULL); 1125 } 1126 1127 /* 1128 * Walk to the end of this peer list. The last entry is marked with a flag 1129 * and the peer pointer is really a pointer back to the parent. This saves 1130 * putting a parent back pointer in each and every named object! 1131 */ 1132 while (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 1133 { 1134 Node = Node->Peer; 1135 } 1136 1137 return (Node->Peer); 1138 } 1139 1140 1141 /******************************************************************************* 1142 * 1143 * FUNCTION: AcpiNsGetNextValidNode 1144 * 1145 * PARAMETERS: Node - Current table entry 1146 * 1147 * RETURN: Next valid Node in the linked node list. NULL if no more valid 1148 * nodes. 1149 * 1150 * DESCRIPTION: Find the next valid node within a name table. 1151 * Useful for implementing NULL-end-of-list loops. 1152 * 1153 ******************************************************************************/ 1154 1155 ACPI_NAMESPACE_NODE * 1156 AcpiNsGetNextValidNode ( 1157 ACPI_NAMESPACE_NODE *Node) 1158 { 1159 1160 /* If we are at the end of this peer list, return NULL */ 1161 1162 if (Node->Flags & ANOBJ_END_OF_PEER_LIST) 1163 { 1164 return NULL; 1165 } 1166 1167 /* Otherwise just return the next peer */ 1168 1169 return (Node->Peer); 1170 } 1171 1172 1173 #ifdef ACPI_OBSOLETE_FUNCTIONS 1174 /******************************************************************************* 1175 * 1176 * FUNCTION: AcpiNsFindParentName 1177 * 1178 * PARAMETERS: *ChildNode - Named Obj whose name is to be found 1179 * 1180 * RETURN: The ACPI name 1181 * 1182 * DESCRIPTION: Search for the given obj in its parent scope and return the 1183 * name segment, or "????" if the parent name can't be found 1184 * (which "should not happen"). 1185 * 1186 ******************************************************************************/ 1187 1188 ACPI_NAME 1189 AcpiNsFindParentName ( 1190 ACPI_NAMESPACE_NODE *ChildNode) 1191 { 1192 ACPI_NAMESPACE_NODE *ParentNode; 1193 1194 1195 ACPI_FUNCTION_TRACE (NsFindParentName); 1196 1197 1198 if (ChildNode) 1199 { 1200 /* Valid entry. Get the parent Node */ 1201 1202 ParentNode = AcpiNsGetParentNode (ChildNode); 1203 if (ParentNode) 1204 { 1205 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 1206 "Parent of %p [%4.4s] is %p [%4.4s]\n", 1207 ChildNode, AcpiUtGetNodeName (ChildNode), 1208 ParentNode, AcpiUtGetNodeName (ParentNode))); 1209 1210 if (ParentNode->Name.Integer) 1211 { 1212 return_VALUE ((ACPI_NAME) ParentNode->Name.Integer); 1213 } 1214 } 1215 1216 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 1217 "Unable to find parent of %p (%4.4s)\n", 1218 ChildNode, AcpiUtGetNodeName (ChildNode))); 1219 } 1220 1221 return_VALUE (ACPI_UNKNOWN_NAME); 1222 } 1223 #endif 1224 1225
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |