Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennsutils.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 00004 * parents and siblings and Scope manipulation 00005 * 00006 *****************************************************************************/ 00007 00008 /****************************************************************************** 00009 * 00010 * 1. Copyright Notice 00011 * 00012 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00013 * All rights reserved. 00014 * 00015 * 2. License 00016 * 00017 * 2.1. This is your license from Intel Corp. under its intellectual property 00018 * rights. You may have additional license terms from the party that provided 00019 * you this software, covering your right to use that party's intellectual 00020 * property rights. 00021 * 00022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00023 * copy of the source code appearing in this file ("Covered Code") an 00024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00025 * base code distributed originally by Intel ("Original Intel Code") to copy, 00026 * make derivatives, distribute, use and display any portion of the Covered 00027 * Code in any form, with the right to sublicense such rights; and 00028 * 00029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00030 * license (with the right to sublicense), under only those claims of Intel 00031 * patents that are infringed by the Original Intel Code, to make, use, sell, 00032 * offer to sell, and import the Covered Code and derivative works thereof 00033 * solely to the minimum extent necessary to exercise the above copyright 00034 * license, and in no event shall the patent license extend to any additions 00035 * to or modifications of the Original Intel Code. No other license or right 00036 * is granted directly or by implication, estoppel or otherwise; 00037 * 00038 * The above copyright and patent license is granted only if the following 00039 * conditions are met: 00040 * 00041 * 3. Conditions 00042 * 00043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00044 * Redistribution of source code of any substantial portion of the Covered 00045 * Code or modification with rights to further distribute source must include 00046 * the above Copyright Notice, the above License, this list of Conditions, 00047 * and the following Disclaimer and Export Compliance provision. In addition, 00048 * Licensee must cause all Covered Code to which Licensee contributes to 00049 * contain a file documenting the changes Licensee made to create that Covered 00050 * Code and the date of any change. Licensee must include in that file the 00051 * documentation of any changes made by any predecessor Licensee. Licensee 00052 * must include a prominent statement that the modification is derived, 00053 * directly or indirectly, from Original Intel Code. 00054 * 00055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00056 * Redistribution of source code of any substantial portion of the Covered 00057 * Code or modification without rights to further distribute source must 00058 * include the following Disclaimer and Export Compliance provision in the 00059 * documentation and/or other materials provided with distribution. In 00060 * addition, Licensee may not authorize further sublicense of source of any 00061 * portion of the Covered Code, and must include terms to the effect that the 00062 * license from Licensee to its licensee is limited to the intellectual 00063 * property embodied in the software Licensee provides to its licensee, and 00064 * not to intellectual property embodied in modifications its licensee may 00065 * make. 00066 * 00067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00068 * substantial portion of the Covered Code or modification must reproduce the 00069 * above Copyright Notice, and the following Disclaimer and Export Compliance 00070 * provision in the documentation and/or other materials provided with the 00071 * distribution. 00072 * 00073 * 3.4. Intel retains all right, title, and interest in and to the Original 00074 * Intel Code. 00075 * 00076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00077 * Intel shall be used in advertising or otherwise to promote the sale, use or 00078 * other dealings in products derived from or relating to the Covered Code 00079 * without prior written authorization from Intel. 00080 * 00081 * 4. Disclaimer and Export Compliance 00082 * 00083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00089 * PARTICULAR PURPOSE. 00090 * 00091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00098 * LIMITED REMEDY. 00099 * 00100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00101 * software or system incorporating such software without first obtaining any 00102 * required license or other approval from the U. S. Department of Commerce or 00103 * any other agency or department of the United States Government. In the 00104 * event Licensee exports any such software from the United States or 00105 * re-exports any such software from a foreign destination, Licensee shall 00106 * ensure that the distribution and export/re-export of the software is in 00107 * compliance with all laws, regulations, orders, or other restrictions of the 00108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00109 * any of its subsidiaries will export/re-export any technical data, process, 00110 * software, or service, directly or indirectly, to any country for which the 00111 * United States government or any agency thereof requires an export license, 00112 * other governmental approval, or letter of assurance, without first obtaining 00113 * such license, approval or letter. 00114 * 00115 *****************************************************************************/ 00116 00117 #define __NSUTILS_C__ 00118 00119 #include "acpi.h" 00120 #include "accommon.h" 00121 #include "acnamesp.h" 00122 #include "amlcode.h" 00123 00124 #define _COMPONENT ACPI_NAMESPACE 00125 ACPI_MODULE_NAME ("nsutils") 00126 00127 /* Local prototypes */ 00128 00129 static BOOLEAN 00130 AcpiNsValidPathSeparator ( 00131 char Sep); 00132 00133 #ifdef ACPI_OBSOLETE_FUNCTIONS 00134 ACPI_NAME 00135 AcpiNsFindParentName ( 00136 ACPI_NAMESPACE_NODE *NodeToSearch); 00137 #endif 00138 00139 00140 /******************************************************************************* 00141 * 00142 * FUNCTION: AcpiNsPrintNodePathname 00143 * 00144 * PARAMETERS: Node - Object 00145 * Message - Prefix message 00146 * 00147 * DESCRIPTION: Print an object's full namespace pathname 00148 * Manages allocation/freeing of a pathname buffer 00149 * 00150 ******************************************************************************/ 00151 00152 void 00153 AcpiNsPrintNodePathname ( 00154 ACPI_NAMESPACE_NODE *Node, 00155 const char *Message) 00156 { 00157 ACPI_BUFFER Buffer; 00158 ACPI_STATUS Status; 00159 00160 00161 if (!Node) 00162 { 00163 AcpiOsPrintf ("[NULL NAME]"); 00164 return; 00165 } 00166 00167 /* Convert handle to full pathname and print it (with supplied message) */ 00168 00169 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 00170 00171 Status = AcpiNsHandleToPathname (Node, &Buffer); 00172 if (ACPI_SUCCESS (Status)) 00173 { 00174 if (Message) 00175 { 00176 AcpiOsPrintf ("%s ", Message); 00177 } 00178 00179 AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 00180 ACPI_FREE (Buffer.Pointer); 00181 } 00182 } 00183 00184 00185 /******************************************************************************* 00186 * 00187 * FUNCTION: AcpiNsValidRootPrefix 00188 * 00189 * PARAMETERS: Prefix - Character to be checked 00190 * 00191 * RETURN: TRUE if a valid prefix 00192 * 00193 * DESCRIPTION: Check if a character is a valid ACPI Root prefix 00194 * 00195 ******************************************************************************/ 00196 00197 BOOLEAN 00198 AcpiNsValidRootPrefix ( 00199 char Prefix) 00200 { 00201 00202 return ((BOOLEAN) (Prefix == '\\')); 00203 } 00204 00205 00206 /******************************************************************************* 00207 * 00208 * FUNCTION: AcpiNsValidPathSeparator 00209 * 00210 * PARAMETERS: Sep - Character to be checked 00211 * 00212 * RETURN: TRUE if a valid path separator 00213 * 00214 * DESCRIPTION: Check if a character is a valid ACPI path separator 00215 * 00216 ******************************************************************************/ 00217 00218 static BOOLEAN 00219 AcpiNsValidPathSeparator ( 00220 char Sep) 00221 { 00222 00223 return ((BOOLEAN) (Sep == '.')); 00224 } 00225 00226 00227 /******************************************************************************* 00228 * 00229 * FUNCTION: AcpiNsGetType 00230 * 00231 * PARAMETERS: Node - Parent Node to be examined 00232 * 00233 * RETURN: Type field from Node whose handle is passed 00234 * 00235 * DESCRIPTION: Return the type of a Namespace node 00236 * 00237 ******************************************************************************/ 00238 00239 ACPI_OBJECT_TYPE 00240 AcpiNsGetType ( 00241 ACPI_NAMESPACE_NODE *Node) 00242 { 00243 ACPI_FUNCTION_TRACE (NsGetType); 00244 00245 00246 if (!Node) 00247 { 00248 ACPI_WARNING ((AE_INFO, "Null Node parameter")); 00249 return_UINT32 (ACPI_TYPE_ANY); 00250 } 00251 00252 return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type); 00253 } 00254 00255 00256 /******************************************************************************* 00257 * 00258 * FUNCTION: AcpiNsLocal 00259 * 00260 * PARAMETERS: Type - A namespace object type 00261 * 00262 * RETURN: LOCAL if names must be found locally in objects of the 00263 * passed type, 0 if enclosing scopes should be searched 00264 * 00265 * DESCRIPTION: Returns scope rule for the given object type. 00266 * 00267 ******************************************************************************/ 00268 00269 UINT32 00270 AcpiNsLocal ( 00271 ACPI_OBJECT_TYPE Type) 00272 { 00273 ACPI_FUNCTION_TRACE (NsLocal); 00274 00275 00276 if (!AcpiUtValidObjectType (Type)) 00277 { 00278 /* Type code out of range */ 00279 00280 ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 00281 return_UINT32 (ACPI_NS_NORMAL); 00282 } 00283 00284 return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 00285 } 00286 00287 00288 /******************************************************************************* 00289 * 00290 * FUNCTION: AcpiNsGetInternalNameLength 00291 * 00292 * PARAMETERS: Info - Info struct initialized with the 00293 * external name pointer. 00294 * 00295 * RETURN: None 00296 * 00297 * DESCRIPTION: Calculate the length of the internal (AML) namestring 00298 * corresponding to the external (ASL) namestring. 00299 * 00300 ******************************************************************************/ 00301 00302 void 00303 AcpiNsGetInternalNameLength ( 00304 ACPI_NAMESTRING_INFO *Info) 00305 { 00306 const char *NextExternalChar; 00307 UINT32 i; 00308 00309 00310 ACPI_FUNCTION_ENTRY (); 00311 00312 00313 NextExternalChar = Info->ExternalName; 00314 Info->NumCarats = 0; 00315 Info->NumSegments = 0; 00316 Info->FullyQualified = FALSE; 00317 00318 /* 00319 * For the internal name, the required length is 4 bytes per segment, plus 00320 * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null 00321 * (which is not really needed, but no there's harm in putting it there) 00322 * 00323 * strlen() + 1 covers the first NameSeg, which has no path separator 00324 */ 00325 if (AcpiNsValidRootPrefix (*NextExternalChar)) 00326 { 00327 Info->FullyQualified = TRUE; 00328 NextExternalChar++; 00329 00330 /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 00331 00332 while (AcpiNsValidRootPrefix (*NextExternalChar)) 00333 { 00334 NextExternalChar++; 00335 } 00336 } 00337 else 00338 { 00339 /* Handle Carat prefixes */ 00340 00341 while (*NextExternalChar == '^') 00342 { 00343 Info->NumCarats++; 00344 NextExternalChar++; 00345 } 00346 } 00347 00348 /* 00349 * Determine the number of ACPI name "segments" by counting the number of 00350 * path separators within the string. Start with one segment since the 00351 * segment count is [(# separators) + 1], and zero separators is ok. 00352 */ 00353 if (*NextExternalChar) 00354 { 00355 Info->NumSegments = 1; 00356 for (i = 0; NextExternalChar[i]; i++) 00357 { 00358 if (AcpiNsValidPathSeparator (NextExternalChar[i])) 00359 { 00360 Info->NumSegments++; 00361 } 00362 } 00363 } 00364 00365 Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 00366 4 + Info->NumCarats; 00367 00368 Info->NextExternalChar = NextExternalChar; 00369 } 00370 00371 00372 /******************************************************************************* 00373 * 00374 * FUNCTION: AcpiNsBuildInternalName 00375 * 00376 * PARAMETERS: Info - Info struct fully initialized 00377 * 00378 * RETURN: Status 00379 * 00380 * DESCRIPTION: Construct the internal (AML) namestring 00381 * corresponding to the external (ASL) namestring. 00382 * 00383 ******************************************************************************/ 00384 00385 ACPI_STATUS 00386 AcpiNsBuildInternalName ( 00387 ACPI_NAMESTRING_INFO *Info) 00388 { 00389 UINT32 NumSegments = Info->NumSegments; 00390 char *InternalName = Info->InternalName; 00391 const char *ExternalName = Info->NextExternalChar; 00392 char *Result = NULL; 00393 UINT32 i; 00394 00395 00396 ACPI_FUNCTION_TRACE (NsBuildInternalName); 00397 00398 00399 /* Setup the correct prefixes, counts, and pointers */ 00400 00401 if (Info->FullyQualified) 00402 { 00403 InternalName[0] = '\\'; 00404 00405 if (NumSegments <= 1) 00406 { 00407 Result = &InternalName[1]; 00408 } 00409 else if (NumSegments == 2) 00410 { 00411 InternalName[1] = AML_DUAL_NAME_PREFIX; 00412 Result = &InternalName[2]; 00413 } 00414 else 00415 { 00416 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 00417 InternalName[2] = (char) NumSegments; 00418 Result = &InternalName[3]; 00419 } 00420 } 00421 else 00422 { 00423 /* 00424 * Not fully qualified. 00425 * Handle Carats first, then append the name segments 00426 */ 00427 i = 0; 00428 if (Info->NumCarats) 00429 { 00430 for (i = 0; i < Info->NumCarats; i++) 00431 { 00432 InternalName[i] = '^'; 00433 } 00434 } 00435 00436 if (NumSegments <= 1) 00437 { 00438 Result = &InternalName[i]; 00439 } 00440 else if (NumSegments == 2) 00441 { 00442 InternalName[i] = AML_DUAL_NAME_PREFIX; 00443 Result = &InternalName[(ACPI_SIZE) i+1]; 00444 } 00445 else 00446 { 00447 InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 00448 InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 00449 Result = &InternalName[(ACPI_SIZE) i+2]; 00450 } 00451 } 00452 00453 /* Build the name (minus path separators) */ 00454 00455 for (; NumSegments; NumSegments--) 00456 { 00457 for (i = 0; i < ACPI_NAME_SIZE; i++) 00458 { 00459 if (AcpiNsValidPathSeparator (*ExternalName) || 00460 (*ExternalName == 0)) 00461 { 00462 /* Pad the segment with underscore(s) if segment is short */ 00463 00464 Result[i] = '_'; 00465 } 00466 else 00467 { 00468 /* Convert the character to uppercase and save it */ 00469 00470 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName); 00471 ExternalName++; 00472 } 00473 } 00474 00475 /* Now we must have a path separator, or the pathname is bad */ 00476 00477 if (!AcpiNsValidPathSeparator (*ExternalName) && 00478 (*ExternalName != 0)) 00479 { 00480 return_ACPI_STATUS (AE_BAD_PARAMETER); 00481 } 00482 00483 /* Move on the next segment */ 00484 00485 ExternalName++; 00486 Result += ACPI_NAME_SIZE; 00487 } 00488 00489 /* Terminate the string */ 00490 00491 *Result = 0; 00492 00493 if (Info->FullyQualified) 00494 { 00495 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 00496 InternalName, InternalName)); 00497 } 00498 else 00499 { 00500 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 00501 InternalName, InternalName)); 00502 } 00503 00504 return_ACPI_STATUS (AE_OK); 00505 } 00506 00507 00508 /******************************************************************************* 00509 * 00510 * FUNCTION: AcpiNsInternalizeName 00511 * 00512 * PARAMETERS: *ExternalName - External representation of name 00513 * **Converted Name - Where to return the resulting 00514 * internal represention of the name 00515 * 00516 * RETURN: Status 00517 * 00518 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 00519 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 00520 * 00521 *******************************************************************************/ 00522 00523 ACPI_STATUS 00524 AcpiNsInternalizeName ( 00525 const char *ExternalName, 00526 char **ConvertedName) 00527 { 00528 char *InternalName; 00529 ACPI_NAMESTRING_INFO Info; 00530 ACPI_STATUS Status; 00531 00532 00533 ACPI_FUNCTION_TRACE (NsInternalizeName); 00534 00535 00536 if ((!ExternalName) || 00537 (*ExternalName == 0) || 00538 (!ConvertedName)) 00539 { 00540 return_ACPI_STATUS (AE_BAD_PARAMETER); 00541 } 00542 00543 /* Get the length of the new internal name */ 00544 00545 Info.ExternalName = ExternalName; 00546 AcpiNsGetInternalNameLength (&Info); 00547 00548 /* We need a segment to store the internal name */ 00549 00550 InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 00551 if (!InternalName) 00552 { 00553 return_ACPI_STATUS (AE_NO_MEMORY); 00554 } 00555 00556 /* Build the name */ 00557 00558 Info.InternalName = InternalName; 00559 Status = AcpiNsBuildInternalName (&Info); 00560 if (ACPI_FAILURE (Status)) 00561 { 00562 ACPI_FREE (InternalName); 00563 return_ACPI_STATUS (Status); 00564 } 00565 00566 *ConvertedName = InternalName; 00567 return_ACPI_STATUS (AE_OK); 00568 } 00569 00570 00571 /******************************************************************************* 00572 * 00573 * FUNCTION: AcpiNsExternalizeName 00574 * 00575 * PARAMETERS: InternalNameLength - Lenth of the internal name below 00576 * InternalName - Internal representation of name 00577 * ConvertedNameLength - Where the length is returned 00578 * ConvertedName - Where the resulting external name 00579 * is returned 00580 * 00581 * RETURN: Status 00582 * 00583 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 00584 * to its external (printable) form (e.g. "\_PR_.CPU0") 00585 * 00586 ******************************************************************************/ 00587 00588 ACPI_STATUS 00589 AcpiNsExternalizeName ( 00590 UINT32 InternalNameLength, 00591 const char *InternalName, 00592 UINT32 *ConvertedNameLength, 00593 char **ConvertedName) 00594 { 00595 UINT32 NamesIndex = 0; 00596 UINT32 NumSegments = 0; 00597 UINT32 RequiredLength; 00598 UINT32 PrefixLength = 0; 00599 UINT32 i = 0; 00600 UINT32 j = 0; 00601 00602 00603 ACPI_FUNCTION_TRACE (NsExternalizeName); 00604 00605 00606 if (!InternalNameLength || 00607 !InternalName || 00608 !ConvertedName) 00609 { 00610 return_ACPI_STATUS (AE_BAD_PARAMETER); 00611 } 00612 00613 /* Check for a prefix (one '\' | one or more '^') */ 00614 00615 switch (InternalName[0]) 00616 { 00617 case '\\': 00618 PrefixLength = 1; 00619 break; 00620 00621 case '^': 00622 for (i = 0; i < InternalNameLength; i++) 00623 { 00624 if (InternalName[i] == '^') 00625 { 00626 PrefixLength = i + 1; 00627 } 00628 else 00629 { 00630 break; 00631 } 00632 } 00633 00634 if (i == InternalNameLength) 00635 { 00636 PrefixLength = i; 00637 } 00638 00639 break; 00640 00641 default: 00642 break; 00643 } 00644 00645 /* 00646 * Check for object names. Note that there could be 0-255 of these 00647 * 4-byte elements. 00648 */ 00649 if (PrefixLength < InternalNameLength) 00650 { 00651 switch (InternalName[PrefixLength]) 00652 { 00653 case AML_MULTI_NAME_PREFIX_OP: 00654 00655 /* <count> 4-byte names */ 00656 00657 NamesIndex = PrefixLength + 2; 00658 NumSegments = (UINT8) 00659 InternalName[(ACPI_SIZE) PrefixLength + 1]; 00660 break; 00661 00662 case AML_DUAL_NAME_PREFIX: 00663 00664 /* Two 4-byte names */ 00665 00666 NamesIndex = PrefixLength + 1; 00667 NumSegments = 2; 00668 break; 00669 00670 case 0: 00671 00672 /* NullName */ 00673 00674 NamesIndex = 0; 00675 NumSegments = 0; 00676 break; 00677 00678 default: 00679 00680 /* one 4-byte name */ 00681 00682 NamesIndex = PrefixLength; 00683 NumSegments = 1; 00684 break; 00685 } 00686 } 00687 00688 /* 00689 * Calculate the length of ConvertedName, which equals the length 00690 * of the prefix, length of all object names, length of any required 00691 * punctuation ('.') between object names, plus the NULL terminator. 00692 */ 00693 RequiredLength = PrefixLength + (4 * NumSegments) + 00694 ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 00695 00696 /* 00697 * Check to see if we're still in bounds. If not, there's a problem 00698 * with InternalName (invalid format). 00699 */ 00700 if (RequiredLength > InternalNameLength) 00701 { 00702 ACPI_ERROR ((AE_INFO, "Invalid internal name")); 00703 return_ACPI_STATUS (AE_BAD_PATHNAME); 00704 } 00705 00706 /* Build the ConvertedName */ 00707 00708 *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 00709 if (!(*ConvertedName)) 00710 { 00711 return_ACPI_STATUS (AE_NO_MEMORY); 00712 } 00713 00714 j = 0; 00715 00716 for (i = 0; i < PrefixLength; i++) 00717 { 00718 (*ConvertedName)[j++] = InternalName[i]; 00719 } 00720 00721 if (NumSegments > 0) 00722 { 00723 for (i = 0; i < NumSegments; i++) 00724 { 00725 if (i > 0) 00726 { 00727 (*ConvertedName)[j++] = '.'; 00728 } 00729 00730 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 00731 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 00732 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 00733 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 00734 } 00735 } 00736 00737 if (ConvertedNameLength) 00738 { 00739 *ConvertedNameLength = (UINT32) RequiredLength; 00740 } 00741 00742 return_ACPI_STATUS (AE_OK); 00743 } 00744 00745 00746 /******************************************************************************* 00747 * 00748 * FUNCTION: AcpiNsValidateHandle 00749 * 00750 * PARAMETERS: Handle - Handle to be validated and typecast to a 00751 * namespace node. 00752 * 00753 * RETURN: A pointer to a namespace node 00754 * 00755 * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 00756 * cases for the root node. 00757 * 00758 * NOTE: Real integer handles would allow for more verification 00759 * and keep all pointers within this subsystem - however this introduces 00760 * more overhead and has not been necessary to this point. Drivers 00761 * holding handles are typically notified before a node becomes invalid 00762 * due to a table unload. 00763 * 00764 ******************************************************************************/ 00765 00766 ACPI_NAMESPACE_NODE * 00767 AcpiNsValidateHandle ( 00768 ACPI_HANDLE Handle) 00769 { 00770 00771 ACPI_FUNCTION_ENTRY (); 00772 00773 00774 /* Parameter validation */ 00775 00776 if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 00777 { 00778 return (AcpiGbl_RootNode); 00779 } 00780 00781 /* We can at least attempt to verify the handle */ 00782 00783 if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 00784 { 00785 return (NULL); 00786 } 00787 00788 return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 00789 } 00790 00791 00792 /******************************************************************************* 00793 * 00794 * FUNCTION: AcpiNsTerminate 00795 * 00796 * PARAMETERS: none 00797 * 00798 * RETURN: none 00799 * 00800 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 00801 * 00802 ******************************************************************************/ 00803 00804 void 00805 AcpiNsTerminate ( 00806 void) 00807 { 00808 ACPI_OPERAND_OBJECT *ObjDesc; 00809 00810 00811 ACPI_FUNCTION_TRACE (NsTerminate); 00812 00813 00814 /* 00815 * 1) Free the entire namespace -- all nodes and objects 00816 * 00817 * Delete all object descriptors attached to namepsace nodes 00818 */ 00819 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 00820 00821 /* Detach any objects attached to the root */ 00822 00823 ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode); 00824 if (ObjDesc) 00825 { 00826 AcpiNsDetachObject (AcpiGbl_RootNode); 00827 } 00828 00829 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 00830 return_VOID; 00831 } 00832 00833 00834 /******************************************************************************* 00835 * 00836 * FUNCTION: AcpiNsOpensScope 00837 * 00838 * PARAMETERS: Type - A valid namespace type 00839 * 00840 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 00841 * to the ACPI specification, else 0 00842 * 00843 ******************************************************************************/ 00844 00845 UINT32 00846 AcpiNsOpensScope ( 00847 ACPI_OBJECT_TYPE Type) 00848 { 00849 ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type)); 00850 00851 00852 if (!AcpiUtValidObjectType (Type)) 00853 { 00854 /* type code out of range */ 00855 00856 ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 00857 return_UINT32 (ACPI_NS_NORMAL); 00858 } 00859 00860 return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 00861 } 00862 00863 00864 /******************************************************************************* 00865 * 00866 * FUNCTION: AcpiNsGetNode 00867 * 00868 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 00869 * \ (backslash) and ^ (carat) prefixes, and the 00870 * . (period) to separate segments are supported. 00871 * PrefixNode - Root of subtree to be searched, or NS_ALL for the 00872 * root of the name space. If Name is fully 00873 * qualified (first INT8 is '\'), the passed value 00874 * of Scope will not be accessed. 00875 * Flags - Used to indicate whether to perform upsearch or 00876 * not. 00877 * ReturnNode - Where the Node is returned 00878 * 00879 * DESCRIPTION: Look up a name relative to a given scope and return the 00880 * corresponding Node. NOTE: Scope can be null. 00881 * 00882 * MUTEX: Locks namespace 00883 * 00884 ******************************************************************************/ 00885 00886 ACPI_STATUS 00887 AcpiNsGetNode ( 00888 ACPI_NAMESPACE_NODE *PrefixNode, 00889 const char *Pathname, 00890 UINT32 Flags, 00891 ACPI_NAMESPACE_NODE **ReturnNode) 00892 { 00893 ACPI_GENERIC_STATE ScopeInfo; 00894 ACPI_STATUS Status; 00895 char *InternalPath; 00896 00897 00898 ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 00899 00900 00901 if (!Pathname) 00902 { 00903 *ReturnNode = PrefixNode; 00904 if (!PrefixNode) 00905 { 00906 *ReturnNode = AcpiGbl_RootNode; 00907 } 00908 return_ACPI_STATUS (AE_OK); 00909 } 00910 00911 /* Convert path to internal representation */ 00912 00913 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 00914 if (ACPI_FAILURE (Status)) 00915 { 00916 return_ACPI_STATUS (Status); 00917 } 00918 00919 /* Must lock namespace during lookup */ 00920 00921 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00922 if (ACPI_FAILURE (Status)) 00923 { 00924 goto Cleanup; 00925 } 00926 00927 /* Setup lookup scope (search starting point) */ 00928 00929 ScopeInfo.Scope.Node = PrefixNode; 00930 00931 /* Lookup the name in the namespace */ 00932 00933 Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 00934 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 00935 NULL, ReturnNode); 00936 if (ACPI_FAILURE (Status)) 00937 { 00938 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 00939 Pathname, AcpiFormatException (Status))); 00940 } 00941 00942 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00943 00944 Cleanup: 00945 ACPI_FREE (InternalPath); 00946 return_ACPI_STATUS (Status); 00947 } Generated on Sun May 27 2012 04:27:21 for ReactOS by
1.7.6.1
|