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