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