Home | History | Annotate | Line # | Download | only in namespace
nsxfname.c revision 1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: nsxfname - Public interfaces to the ACPI subsystem
      4  *                         ACPI Namespace oriented interfaces
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #define __NSXFNAME_C__
     46 
     47 #include "acpi.h"
     48 #include "accommon.h"
     49 #include "acnamesp.h"
     50 #include "acparser.h"
     51 #include "amlcode.h"
     52 
     53 
     54 #define _COMPONENT          ACPI_NAMESPACE
     55         ACPI_MODULE_NAME    ("nsxfname")
     56 
     57 /* Local prototypes */
     58 
     59 static char *
     60 AcpiNsCopyDeviceId (
     61     ACPI_DEVICE_ID          *Dest,
     62     ACPI_DEVICE_ID          *Source,
     63     char                    *StringArea);
     64 
     65 
     66 /******************************************************************************
     67  *
     68  * FUNCTION:    AcpiGetHandle
     69  *
     70  * PARAMETERS:  Parent          - Object to search under (search scope).
     71  *              Pathname        - Pointer to an asciiz string containing the
     72  *                                name
     73  *              RetHandle       - Where the return handle is returned
     74  *
     75  * RETURN:      Status
     76  *
     77  * DESCRIPTION: This routine will search for a caller specified name in the
     78  *              name space.  The caller can restrict the search region by
     79  *              specifying a non NULL parent.  The parent value is itself a
     80  *              namespace handle.
     81  *
     82  ******************************************************************************/
     83 
     84 ACPI_STATUS
     85 AcpiGetHandle (
     86     ACPI_HANDLE             Parent,
     87     ACPI_CONST_STRING       Pathname,
     88     ACPI_HANDLE             *RetHandle)
     89 {
     90     ACPI_STATUS             Status;
     91     ACPI_NAMESPACE_NODE     *Node = NULL;
     92     ACPI_NAMESPACE_NODE     *PrefixNode = NULL;
     93     ACPI_STRING             UPathname = __UNCONST(Pathname);
     94 
     95 
     96     ACPI_FUNCTION_ENTRY ();
     97 
     98 
     99     /* Parameter Validation */
    100 
    101     if (!RetHandle || !Pathname)
    102     {
    103         return (AE_BAD_PARAMETER);
    104     }
    105 
    106     /* Convert a parent handle to a prefix node */
    107 
    108     if (Parent)
    109     {
    110         PrefixNode = AcpiNsValidateHandle (Parent);
    111         if (!PrefixNode)
    112         {
    113             return (AE_BAD_PARAMETER);
    114         }
    115     }
    116 
    117     /*
    118      * Valid cases are:
    119      * 1) Fully qualified pathname
    120      * 2) Parent + Relative pathname
    121      *
    122      * Error for <null Parent + relative path>
    123      */
    124     if (AcpiNsValidRootPrefix (UPathname[0]))
    125     {
    126         /* Pathname is fully qualified (starts with '\') */
    127 
    128         /* Special case for root-only, since we can't search for it */
    129 
    130         if (!ACPI_STRCMP (UPathname, ACPI_NS_ROOT_PATH))
    131         {
    132             *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
    133             return (AE_OK);
    134         }
    135     }
    136     else if (!PrefixNode)
    137     {
    138         /* Relative path with null prefix is disallowed */
    139 
    140         return (AE_BAD_PARAMETER);
    141     }
    142 
    143     /* Find the Node and convert to a handle */
    144 
    145     Status = AcpiNsGetNode (PrefixNode, UPathname, ACPI_NS_NO_UPSEARCH, &Node);
    146     if (ACPI_SUCCESS (Status))
    147     {
    148         *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
    149     }
    150 
    151     return (Status);
    152 }
    153 
    154 ACPI_EXPORT_SYMBOL (AcpiGetHandle)
    155 
    156 
    157 /******************************************************************************
    158  *
    159  * FUNCTION:    AcpiGetName
    160  *
    161  * PARAMETERS:  Handle          - Handle to be converted to a pathname
    162  *              NameType        - Full pathname or single segment
    163  *              Buffer          - Buffer for returned path
    164  *
    165  * RETURN:      Pointer to a string containing the fully qualified Name.
    166  *
    167  * DESCRIPTION: This routine returns the fully qualified name associated with
    168  *              the Handle parameter.  This and the AcpiPathnameToHandle are
    169  *              complementary functions.
    170  *
    171  ******************************************************************************/
    172 
    173 ACPI_STATUS
    174 AcpiGetName (
    175     ACPI_HANDLE             Handle,
    176     UINT32                  NameType,
    177     ACPI_BUFFER             *Buffer)
    178 {
    179     ACPI_STATUS             Status;
    180     ACPI_NAMESPACE_NODE     *Node;
    181 
    182 
    183     /* Parameter validation */
    184 
    185     if (NameType > ACPI_NAME_TYPE_MAX)
    186     {
    187         return (AE_BAD_PARAMETER);
    188     }
    189 
    190     Status = AcpiUtValidateBuffer (Buffer);
    191     if (ACPI_FAILURE (Status))
    192     {
    193         return (Status);
    194     }
    195 
    196     if (NameType == ACPI_FULL_PATHNAME)
    197     {
    198         /* Get the full pathname (From the namespace root) */
    199 
    200         Status = AcpiNsHandleToPathname (Handle, Buffer);
    201         return (Status);
    202     }
    203 
    204     /*
    205      * Wants the single segment ACPI name.
    206      * Validate handle and convert to a namespace Node
    207      */
    208     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    209     if (ACPI_FAILURE (Status))
    210     {
    211         return (Status);
    212     }
    213 
    214     Node = AcpiNsValidateHandle (Handle);
    215     if (!Node)
    216     {
    217         Status = AE_BAD_PARAMETER;
    218         goto UnlockAndExit;
    219     }
    220 
    221     /* Validate/Allocate/Clear caller buffer */
    222 
    223     Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
    224     if (ACPI_FAILURE (Status))
    225     {
    226         goto UnlockAndExit;
    227     }
    228 
    229     /* Just copy the ACPI name from the Node and zero terminate it */
    230 
    231     ACPI_STRNCPY (Buffer->Pointer, AcpiUtGetNodeName (Node),
    232                 ACPI_NAME_SIZE);
    233     ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0;
    234     Status = AE_OK;
    235 
    236 
    237 UnlockAndExit:
    238 
    239     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    240     return (Status);
    241 }
    242 
    243 ACPI_EXPORT_SYMBOL (AcpiGetName)
    244 
    245 
    246 /******************************************************************************
    247  *
    248  * FUNCTION:    AcpiNsCopyDeviceId
    249  *
    250  * PARAMETERS:  Dest                - Pointer to the destination DEVICE_ID
    251  *              Source              - Pointer to the source DEVICE_ID
    252  *              StringArea          - Pointer to where to copy the dest string
    253  *
    254  * RETURN:      Pointer to the next string area
    255  *
    256  * DESCRIPTION: Copy a single DEVICE_ID, including the string data.
    257  *
    258  ******************************************************************************/
    259 
    260 static char *
    261 AcpiNsCopyDeviceId (
    262     ACPI_DEVICE_ID          *Dest,
    263     ACPI_DEVICE_ID          *Source,
    264     char                    *StringArea)
    265 {
    266     /* Create the destination DEVICE_ID */
    267 
    268     Dest->String = StringArea;
    269     Dest->Length = Source->Length;
    270 
    271     /* Copy actual string and return a pointer to the next string area */
    272 
    273     ACPI_MEMCPY (StringArea, Source->String, Source->Length);
    274     return (StringArea + Source->Length);
    275 }
    276 
    277 
    278 /******************************************************************************
    279  *
    280  * FUNCTION:    AcpiGetObjectInfo
    281  *
    282  * PARAMETERS:  Handle              - Object Handle
    283  *              ReturnBuffer        - Where the info is returned
    284  *
    285  * RETURN:      Status
    286  *
    287  * DESCRIPTION: Returns information about an object as gleaned from the
    288  *              namespace node and possibly by running several standard
    289  *              control methods (Such as in the case of a device.)
    290  *
    291  * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
    292  * _ADR, _SxW, and _SxD methods.
    293  *
    294  * Note: Allocates the return buffer, must be freed by the caller.
    295  *
    296  ******************************************************************************/
    297 
    298 ACPI_STATUS
    299 AcpiGetObjectInfo (
    300     ACPI_HANDLE             Handle,
    301     ACPI_DEVICE_INFO        **ReturnBuffer)
    302 {
    303     ACPI_NAMESPACE_NODE     *Node;
    304     ACPI_DEVICE_INFO        *Info;
    305     ACPI_DEVICE_ID_LIST     *CidList = NULL;
    306     ACPI_DEVICE_ID          *Hid = NULL;
    307     ACPI_DEVICE_ID          *Uid = NULL;
    308     char                    *NextIdString;
    309     ACPI_OBJECT_TYPE        Type;
    310     ACPI_NAME               Name;
    311     UINT8                   ParamCount= 0;
    312     UINT8                   Valid = 0;
    313     UINT32                  InfoSize;
    314     UINT32                  i;
    315     ACPI_STATUS             Status;
    316 
    317 
    318     /* Parameter validation */
    319 
    320     if (!Handle || !ReturnBuffer)
    321     {
    322         return (AE_BAD_PARAMETER);
    323     }
    324 
    325     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    326     if (ACPI_FAILURE (Status))
    327     {
    328         goto Cleanup;
    329     }
    330 
    331     Node = AcpiNsValidateHandle (Handle);
    332     if (!Node)
    333     {
    334         (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    335         return (AE_BAD_PARAMETER);
    336     }
    337 
    338     /* Get the namespace node data while the namespace is locked */
    339 
    340     InfoSize = sizeof (ACPI_DEVICE_INFO);
    341     Type = Node->Type;
    342     Name = Node->Name.Integer;
    343 
    344     if (Node->Type == ACPI_TYPE_METHOD)
    345     {
    346         ParamCount = Node->Object->Method.ParamCount;
    347     }
    348 
    349     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    350     if (ACPI_FAILURE (Status))
    351     {
    352         return (Status);
    353     }
    354 
    355     if ((Type == ACPI_TYPE_DEVICE) ||
    356         (Type == ACPI_TYPE_PROCESSOR))
    357     {
    358         /*
    359          * Get extra info for ACPI Device/Processor objects only:
    360          * Run the Device _HID, _UID, and _CID methods.
    361          *
    362          * Note: none of these methods are required, so they may or may
    363          * not be present for this device. The Info->Valid bitfield is used
    364          * to indicate which methods were found and run successfully.
    365          */
    366 
    367         /* Execute the Device._HID method */
    368 
    369         Status = AcpiUtExecute_HID (Node, &Hid);
    370         if (ACPI_SUCCESS (Status))
    371         {
    372             InfoSize += Hid->Length;
    373             Valid |= ACPI_VALID_HID;
    374         }
    375 
    376         /* Execute the Device._UID method */
    377 
    378         Status = AcpiUtExecute_UID (Node, &Uid);
    379         if (ACPI_SUCCESS (Status))
    380         {
    381             InfoSize += Uid->Length;
    382             Valid |= ACPI_VALID_UID;
    383         }
    384 
    385         /* Execute the Device._CID method */
    386 
    387         Status = AcpiUtExecute_CID (Node, &CidList);
    388         if (ACPI_SUCCESS (Status))
    389         {
    390             /* Add size of CID strings and CID pointer array */
    391 
    392             InfoSize += (CidList->ListSize - sizeof (ACPI_DEVICE_ID_LIST));
    393             Valid |= ACPI_VALID_CID;
    394         }
    395     }
    396 
    397     /*
    398      * Now that we have the variable-length data, we can allocate the
    399      * return buffer
    400      */
    401     Info = ACPI_ALLOCATE_ZEROED (InfoSize);
    402     if (!Info)
    403     {
    404         Status = AE_NO_MEMORY;
    405         goto Cleanup;
    406     }
    407 
    408     /* Get the fixed-length data */
    409 
    410     if ((Type == ACPI_TYPE_DEVICE) ||
    411         (Type == ACPI_TYPE_PROCESSOR))
    412     {
    413         /*
    414          * Get extra info for ACPI Device/Processor objects only:
    415          * Run the _STA, _ADR and, SxW, and _SxD methods.
    416          *
    417          * Note: none of these methods are required, so they may or may
    418          * not be present for this device. The Info->Valid bitfield is used
    419          * to indicate which methods were found and run successfully.
    420          */
    421 
    422         /* Execute the Device._STA method */
    423 
    424         Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
    425         if (ACPI_SUCCESS (Status))
    426         {
    427             Valid |= ACPI_VALID_STA;
    428         }
    429 
    430         /* Execute the Device._ADR method */
    431 
    432         Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
    433                     &Info->Address);
    434         if (ACPI_SUCCESS (Status))
    435         {
    436             Valid |= ACPI_VALID_ADR;
    437         }
    438 
    439         /* Execute the Device._SxW methods */
    440 
    441         Status = AcpiUtExecutePowerMethods (Node,
    442                     AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
    443                     Info->LowestDstates);
    444         if (ACPI_SUCCESS (Status))
    445         {
    446             Valid |= ACPI_VALID_SXWS;
    447         }
    448 
    449         /* Execute the Device._SxD methods */
    450 
    451         Status = AcpiUtExecutePowerMethods (Node,
    452                     AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
    453                     Info->HighestDstates);
    454         if (ACPI_SUCCESS (Status))
    455         {
    456             Valid |= ACPI_VALID_SXDS;
    457         }
    458     }
    459 
    460     /*
    461      * Create a pointer to the string area of the return buffer.
    462      * Point to the end of the base ACPI_DEVICE_INFO structure.
    463      */
    464     NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
    465     if (CidList)
    466     {
    467         /* Point past the CID DEVICE_ID array */
    468 
    469         NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_DEVICE_ID));
    470     }
    471 
    472     /*
    473      * Copy the HID, UID, and CIDs to the return buffer. The variable-length
    474      * strings are copied to the reserved area at the end of the buffer.
    475      *
    476      * For HID and CID, check if the ID is a PCI Root Bridge.
    477      */
    478     if (Hid)
    479     {
    480         NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
    481             Hid, NextIdString);
    482 
    483         if (AcpiUtIsPciRootBridge (Hid->String))
    484         {
    485             Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
    486         }
    487     }
    488 
    489     if (Uid)
    490     {
    491         NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
    492             Uid, NextIdString);
    493     }
    494 
    495     if (CidList)
    496     {
    497         Info->CompatibleIdList.Count = CidList->Count;
    498         Info->CompatibleIdList.ListSize = CidList->ListSize;
    499 
    500         /* Copy each CID */
    501 
    502         for (i = 0; i < CidList->Count; i++)
    503         {
    504             NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
    505                 &CidList->Ids[i], NextIdString);
    506 
    507             if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
    508             {
    509                 Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
    510             }
    511         }
    512     }
    513 
    514     /* Copy the fixed-length data */
    515 
    516     Info->InfoSize = InfoSize;
    517     Info->Type = Type;
    518     Info->Name = Name;
    519     Info->ParamCount = ParamCount;
    520     Info->Valid = Valid;
    521 
    522     *ReturnBuffer = Info;
    523     Status = AE_OK;
    524 
    525 
    526 Cleanup:
    527     if (Hid)
    528     {
    529         ACPI_FREE (Hid);
    530     }
    531     if (Uid)
    532     {
    533         ACPI_FREE (Uid);
    534     }
    535     if (CidList)
    536     {
    537         ACPI_FREE (CidList);
    538     }
    539     return (Status);
    540 }
    541 
    542 ACPI_EXPORT_SYMBOL (AcpiGetObjectInfo)
    543 
    544 
    545 /******************************************************************************
    546  *
    547  * FUNCTION:    AcpiInstallMethod
    548  *
    549  * PARAMETERS:  Buffer         - An ACPI table containing one control method
    550  *
    551  * RETURN:      Status
    552  *
    553  * DESCRIPTION: Install a control method into the namespace. If the method
    554  *              name already exists in the namespace, it is overwritten. The
    555  *              input buffer must contain a valid DSDT or SSDT containing a
    556  *              single control method.
    557  *
    558  ******************************************************************************/
    559 
    560 ACPI_STATUS
    561 AcpiInstallMethod (
    562     UINT8                   *Buffer)
    563 {
    564     ACPI_TABLE_HEADER       *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer);
    565     UINT8                   *AmlBuffer;
    566     UINT8                   *AmlStart;
    567     char                    *Path;
    568     ACPI_NAMESPACE_NODE     *Node;
    569     ACPI_OPERAND_OBJECT     *MethodObj;
    570     ACPI_PARSE_STATE        ParserState;
    571     UINT32                  AmlLength;
    572     UINT16                  Opcode;
    573     UINT8                   MethodFlags;
    574     ACPI_STATUS             Status;
    575 
    576 
    577     /* Parameter validation */
    578 
    579     if (!Buffer)
    580     {
    581         return (AE_BAD_PARAMETER);
    582     }
    583 
    584     /* Table must be a DSDT or SSDT */
    585 
    586     if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) &&
    587         !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
    588     {
    589         return (AE_BAD_HEADER);
    590     }
    591 
    592     /* First AML opcode in the table must be a control method */
    593 
    594     ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER);
    595     Opcode = AcpiPsPeekOpcode (&ParserState);
    596     if (Opcode != AML_METHOD_OP)
    597     {
    598         return (AE_BAD_PARAMETER);
    599     }
    600 
    601     /* Extract method information from the raw AML */
    602 
    603     ParserState.Aml += AcpiPsGetOpcodeSize (Opcode);
    604     ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState);
    605     Path = AcpiPsGetNextNamestring (&ParserState);
    606     MethodFlags = *ParserState.Aml++;
    607     AmlStart = ParserState.Aml;
    608     AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart);
    609 
    610     /*
    611      * Allocate resources up-front. We don't want to have to delete a new
    612      * node from the namespace if we cannot allocate memory.
    613      */
    614     AmlBuffer = ACPI_ALLOCATE (AmlLength);
    615     if (!AmlBuffer)
    616     {
    617         return (AE_NO_MEMORY);
    618     }
    619 
    620     MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
    621     if (!MethodObj)
    622     {
    623         ACPI_FREE (AmlBuffer);
    624         return (AE_NO_MEMORY);
    625     }
    626 
    627     /* Lock namespace for AcpiNsLookup, we may be creating a new node */
    628 
    629     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    630     if (ACPI_FAILURE (Status))
    631     {
    632         goto ErrorExit;
    633     }
    634 
    635     /* The lookup either returns an existing node or creates a new one */
    636 
    637     Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
    638                 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
    639 
    640     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    641 
    642     if (ACPI_FAILURE (Status)) /* NsLookup */
    643     {
    644         if (Status != AE_ALREADY_EXISTS)
    645         {
    646             goto ErrorExit;
    647         }
    648 
    649         /* Node existed previously, make sure it is a method node */
    650 
    651         if (Node->Type != ACPI_TYPE_METHOD)
    652         {
    653             Status = AE_TYPE;
    654             goto ErrorExit;
    655         }
    656     }
    657 
    658     /* Copy the method AML to the local buffer */
    659 
    660     ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength);
    661 
    662     /* Initialize the method object with the new method's information */
    663 
    664     MethodObj->Method.AmlStart = AmlBuffer;
    665     MethodObj->Method.AmlLength = AmlLength;
    666 
    667     MethodObj->Method.ParamCount = (UINT8)
    668         (MethodFlags & AML_METHOD_ARG_COUNT);
    669 
    670     if (MethodFlags & AML_METHOD_SERIALIZED)
    671     {
    672         MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED;
    673 
    674         MethodObj->Method.SyncLevel = (UINT8)
    675             ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
    676     }
    677 
    678     /*
    679      * Now that it is complete, we can attach the new method object to
    680      * the method Node (detaches/deletes any existing object)
    681      */
    682     Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD);
    683 
    684     /*
    685      * Flag indicates AML buffer is dynamic, must be deleted later.
    686      * Must be set only after attach above.
    687      */
    688     Node->Flags |= ANOBJ_ALLOCATED_BUFFER;
    689 
    690     /* Remove local reference to the method object */
    691 
    692     AcpiUtRemoveReference (MethodObj);
    693     return (Status);
    694 
    695 
    696 ErrorExit:
    697 
    698     ACPI_FREE (AmlBuffer);
    699     ACPI_FREE (MethodObj);
    700     return (Status);
    701 }
    702 
    703 ACPI_EXPORT_SYMBOL (AcpiInstallMethod)
    704