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