Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/nsxfname.c need to be fixed.

0001 /******************************************************************************
0002  *
0003  * Module Name: nsxfname - Public interfaces to the ACPI subsystem
0004  *                         ACPI Namespace oriented interfaces
0005  *
0006  *****************************************************************************/
0007 
0008 /******************************************************************************
0009  *
0010  * 1. Copyright Notice
0011  *
0012  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0013  * All rights reserved.
0014  *
0015  * 2. License
0016  *
0017  * 2.1. This is your license from Intel Corp. under its intellectual property
0018  * rights.  You may have additional license terms from the party that provided
0019  * you this software, covering your right to use that party's intellectual
0020  * property rights.
0021  *
0022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0023  * copy of the source code appearing in this file ("Covered Code") an
0024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0025  * base code distributed originally by Intel ("Original Intel Code") to copy,
0026  * make derivatives, distribute, use and display any portion of the Covered
0027  * Code in any form, with the right to sublicense such rights; and
0028  *
0029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0030  * license (with the right to sublicense), under only those claims of Intel
0031  * patents that are infringed by the Original Intel Code, to make, use, sell,
0032  * offer to sell, and import the Covered Code and derivative works thereof
0033  * solely to the minimum extent necessary to exercise the above copyright
0034  * license, and in no event shall the patent license extend to any additions
0035  * to or modifications of the Original Intel Code.  No other license or right
0036  * is granted directly or by implication, estoppel or otherwise;
0037  *
0038  * The above copyright and patent license is granted only if the following
0039  * conditions are met:
0040  *
0041  * 3. Conditions
0042  *
0043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0044  * Redistribution of source code of any substantial portion of the Covered
0045  * Code or modification with rights to further distribute source must include
0046  * the above Copyright Notice, the above License, this list of Conditions,
0047  * and the following Disclaimer and Export Compliance provision.  In addition,
0048  * Licensee must cause all Covered Code to which Licensee contributes to
0049  * contain a file documenting the changes Licensee made to create that Covered
0050  * Code and the date of any change.  Licensee must include in that file the
0051  * documentation of any changes made by any predecessor Licensee.  Licensee
0052  * must include a prominent statement that the modification is derived,
0053  * directly or indirectly, from Original Intel Code.
0054  *
0055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0056  * Redistribution of source code of any substantial portion of the Covered
0057  * Code or modification without rights to further distribute source must
0058  * include the following Disclaimer and Export Compliance provision in the
0059  * documentation and/or other materials provided with distribution.  In
0060  * addition, Licensee may not authorize further sublicense of source of any
0061  * portion of the Covered Code, and must include terms to the effect that the
0062  * license from Licensee to its licensee is limited to the intellectual
0063  * property embodied in the software Licensee provides to its licensee, and
0064  * not to intellectual property embodied in modifications its licensee may
0065  * make.
0066  *
0067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0068  * substantial portion of the Covered Code or modification must reproduce the
0069  * above Copyright Notice, and the following Disclaimer and Export Compliance
0070  * provision in the documentation and/or other materials provided with the
0071  * distribution.
0072  *
0073  * 3.4. Intel retains all right, title, and interest in and to the Original
0074  * Intel Code.
0075  *
0076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0077  * Intel shall be used in advertising or otherwise to promote the sale, use or
0078  * other dealings in products derived from or relating to the Covered Code
0079  * without prior written authorization from Intel.
0080  *
0081  * 4. Disclaimer and Export Compliance
0082  *
0083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0089  * PARTICULAR PURPOSE.
0090  *
0091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0098  * LIMITED REMEDY.
0099  *
0100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0101  * software or system incorporating such software without first obtaining any
0102  * required license or other approval from the U. S. Department of Commerce or
0103  * any other agency or department of the United States Government.  In the
0104  * event Licensee exports any such software from the United States or
0105  * re-exports any such software from a foreign destination, Licensee shall
0106  * ensure that the distribution and export/re-export of the software is in
0107  * compliance with all laws, regulations, orders, or other restrictions of the
0108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0109  * any of its subsidiaries will export/re-export any technical data, process,
0110  * software, or service, directly or indirectly, to any country for which the
0111  * United States government or any agency thereof requires an export license,
0112  * other governmental approval, or letter of assurance, without first obtaining
0113  * such license, approval or letter.
0114  *
0115  *****************************************************************************/
0116 
0117 #define __NSXFNAME_C__
0118 
0119 #include "acpi.h"
0120 #include "accommon.h"
0121 #include "acnamesp.h"
0122 #include "acparser.h"
0123 #include "amlcode.h"
0124 
0125 
0126 #define _COMPONENT          ACPI_NAMESPACE
0127         ACPI_MODULE_NAME    ("nsxfname")
0128 
0129 /* Local prototypes */
0130 
0131 static char *
0132 AcpiNsCopyDeviceId (
0133     ACPI_DEVICE_ID          *Dest,
0134     ACPI_DEVICE_ID          *Source,
0135     char                    *StringArea);
0136 
0137 
0138 /******************************************************************************
0139  *
0140  * FUNCTION:    AcpiGetHandle
0141  *
0142  * PARAMETERS:  Parent          - Object to search under (search scope).
0143  *              Pathname        - Pointer to an asciiz string containing the
0144  *                                name
0145  *              RetHandle       - Where the return handle is returned
0146  *
0147  * RETURN:      Status
0148  *
0149  * DESCRIPTION: This routine will search for a caller specified name in the
0150  *              name space.  The caller can restrict the search region by
0151  *              specifying a non NULL parent.  The parent value is itself a
0152  *              namespace handle.
0153  *
0154  ******************************************************************************/
0155 
0156 ACPI_STATUS
0157 AcpiGetHandle (
0158     ACPI_HANDLE             Parent,
0159     ACPI_STRING             Pathname,
0160     ACPI_HANDLE             *RetHandle)
0161 {
0162     ACPI_STATUS             Status;
0163     ACPI_NAMESPACE_NODE     *Node = NULL;
0164     ACPI_NAMESPACE_NODE     *PrefixNode = NULL;
0165 
0166 
0167     ACPI_FUNCTION_ENTRY ();
0168 
0169 
0170     /* Parameter Validation */
0171 
0172     if (!RetHandle || !Pathname)
0173     {
0174         return (AE_BAD_PARAMETER);
0175     }
0176 
0177     /* Convert a parent handle to a prefix node */
0178 
0179     if (Parent)
0180     {
0181         PrefixNode = AcpiNsMapHandleToNode (Parent);
0182         if (!PrefixNode)
0183         {
0184             return (AE_BAD_PARAMETER);
0185         }
0186     }
0187 
0188     /*
0189      * Valid cases are:
0190      * 1) Fully qualified pathname
0191      * 2) Parent + Relative pathname
0192      *
0193      * Error for <null Parent + relative path>
0194      */
0195     if (AcpiNsValidRootPrefix (Pathname[0]))
0196     {
0197         /* Pathname is fully qualified (starts with '\') */
0198 
0199         /* Special case for root-only, since we can't search for it */
0200 
0201         if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH))
0202         {
0203             *RetHandle = AcpiNsConvertEntryToHandle (AcpiGbl_RootNode);
0204             return (AE_OK);
0205         }
0206     }
0207     else if (!PrefixNode)
0208     {
0209         /* Relative path with null prefix is disallowed */
0210 
0211         return (AE_BAD_PARAMETER);
0212     }
0213 
0214     /* Find the Node and convert to a handle */
0215 
0216     Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node);
0217     if (ACPI_SUCCESS (Status))
0218     {
0219         *RetHandle = AcpiNsConvertEntryToHandle (Node);
0220     }
0221 
0222     return (Status);
0223 }
0224 
0225 ACPI_EXPORT_SYMBOL (AcpiGetHandle)
0226 
0227 
0228 /******************************************************************************
0229  *
0230  * FUNCTION:    AcpiGetName
0231  *
0232  * PARAMETERS:  Handle          - Handle to be converted to a pathname
0233  *              NameType        - Full pathname or single segment
0234  *              Buffer          - Buffer for returned path
0235  *
0236  * RETURN:      Pointer to a string containing the fully qualified Name.
0237  *
0238  * DESCRIPTION: This routine returns the fully qualified name associated with
0239  *              the Handle parameter.  This and the AcpiPathnameToHandle are
0240  *              complementary functions.
0241  *
0242  ******************************************************************************/
0243 
0244 ACPI_STATUS
0245 AcpiGetName (
0246     ACPI_HANDLE             Handle,
0247     UINT32                  NameType,
0248     ACPI_BUFFER             *Buffer)
0249 {
0250     ACPI_STATUS             Status;
0251     ACPI_NAMESPACE_NODE     *Node;
0252 
0253 
0254     /* Parameter validation */
0255 
0256     if (NameType > ACPI_NAME_TYPE_MAX)
0257     {
0258         return (AE_BAD_PARAMETER);
0259     }
0260 
0261     Status = AcpiUtValidateBuffer (Buffer);
0262     if (ACPI_FAILURE (Status))
0263     {
0264         return (Status);
0265     }
0266 
0267     if (NameType == ACPI_FULL_PATHNAME)
0268     {
0269         /* Get the full pathname (From the namespace root) */
0270 
0271         Status = AcpiNsHandleToPathname (Handle, Buffer);
0272         return (Status);
0273     }
0274 
0275     /*
0276      * Wants the single segment ACPI name.
0277      * Validate handle and convert to a namespace Node
0278      */
0279     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0280     if (ACPI_FAILURE (Status))
0281     {
0282         return (Status);
0283     }
0284 
0285     Node = AcpiNsMapHandleToNode (Handle);
0286     if (!Node)
0287     {
0288         Status = AE_BAD_PARAMETER;
0289         goto UnlockAndExit;
0290     }
0291 
0292     /* Validate/Allocate/Clear caller buffer */
0293 
0294     Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
0295     if (ACPI_FAILURE (Status))
0296     {
0297         goto UnlockAndExit;
0298     }
0299 
0300     /* Just copy the ACPI name from the Node and zero terminate it */
0301 
0302     ACPI_STRNCPY (Buffer->Pointer, AcpiUtGetNodeName (Node),
0303                 ACPI_NAME_SIZE);
0304     ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0;
0305     Status = AE_OK;
0306 
0307 
0308 UnlockAndExit:
0309 
0310     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0311     return (Status);
0312 }
0313 
0314 ACPI_EXPORT_SYMBOL (AcpiGetName)
0315 
0316 
0317 /******************************************************************************
0318  *
0319  * FUNCTION:    AcpiNsCopyDeviceId
0320  *
0321  * PARAMETERS:  Dest                - Pointer to the destination DEVICE_ID
0322  *              Source              - Pointer to the source DEVICE_ID
0323  *              StringArea          - Pointer to where to copy the dest string
0324  *
0325  * RETURN:      Pointer to the next string area
0326  *
0327  * DESCRIPTION: Copy a single DEVICE_ID, including the string data.
0328  *
0329  ******************************************************************************/
0330 
0331 static char *
0332 AcpiNsCopyDeviceId (
0333     ACPI_DEVICE_ID          *Dest,
0334     ACPI_DEVICE_ID          *Source,
0335     char                    *StringArea)
0336 {
0337     /* Create the destination DEVICE_ID */
0338 
0339     Dest->String = StringArea;
0340     Dest->Length = Source->Length;
0341 
0342     /* Copy actual string and return a pointer to the next string area */
0343 
0344     ACPI_MEMCPY (StringArea, Source->String, Source->Length);
0345     return (StringArea + Source->Length);
0346 }
0347 
0348 
0349 /******************************************************************************
0350  *
0351  * FUNCTION:    AcpiGetObjectInfo
0352  *
0353  * PARAMETERS:  Handle              - Object Handle
0354  *              ReturnBuffer        - Where the info is returned
0355  *
0356  * RETURN:      Status
0357  *
0358  * DESCRIPTION: Returns information about an object as gleaned from the
0359  *              namespace node and possibly by running several standard
0360  *              control methods (Such as in the case of a device.)
0361  *
0362  * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
0363  * _ADR, _SxW, and _SxD methods.
0364  *
0365  * Note: Allocates the return buffer, must be freed by the caller.
0366  *
0367  ******************************************************************************/
0368 
0369 ACPI_STATUS
0370 AcpiGetObjectInfo (
0371     ACPI_HANDLE             Handle,
0372     ACPI_DEVICE_INFO        **ReturnBuffer)
0373 {
0374     ACPI_NAMESPACE_NODE     *Node;
0375     ACPI_DEVICE_INFO        *Info;
0376     ACPI_DEVICE_ID_LIST     *CidList = NULL;
0377     ACPI_DEVICE_ID          *Hid = NULL;
0378     ACPI_DEVICE_ID          *Uid = NULL;
0379     char                    *NextIdString;
0380     ACPI_OBJECT_TYPE        Type;
0381     ACPI_NAME               Name;
0382     UINT8                   ParamCount= 0;
0383     UINT8                   Valid = 0;
0384     UINT32                  InfoSize;
0385     UINT32                  i;
0386     ACPI_STATUS             Status;
0387 
0388 
0389     /* Parameter validation */
0390 
0391     if (!Handle || !ReturnBuffer)
0392     {
0393         return (AE_BAD_PARAMETER);
0394     }
0395 
0396     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0397     if (ACPI_FAILURE (Status))
0398     {
0399         goto Cleanup;
0400     }
0401 
0402     Node = AcpiNsMapHandleToNode (Handle);
0403     if (!Node)
0404     {
0405         (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0406         return (AE_BAD_PARAMETER);
0407     }
0408 
0409     /* Get the namespace node data while the namespace is locked */
0410 
0411     InfoSize = sizeof (ACPI_DEVICE_INFO);
0412     Type = Node->Type;
0413     Name = Node->Name.Integer;
0414 
0415     if (Node->Type == ACPI_TYPE_METHOD)
0416     {
0417         ParamCount = Node->Object->Method.ParamCount;
0418     }
0419 
0420     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0421     if (ACPI_FAILURE (Status))
0422     {
0423         return (Status);
0424     }
0425 
0426     if ((Type == ACPI_TYPE_DEVICE) ||
0427         (Type == ACPI_TYPE_PROCESSOR))
0428     {
0429         /*
0430          * Get extra info for ACPI Device/Processor objects only:
0431          * Run the Device _HID, _UID, and _CID methods.
0432          *
0433          * Note: none of these methods are required, so they may or may
0434          * not be present for this device. The Info->Valid bitfield is used
0435          * to indicate which methods were found and run successfully.
0436          */
0437 
0438         /* Execute the Device._HID method */
0439 
0440         Status = AcpiUtExecute_HID (Node, &Hid);
0441         if (ACPI_SUCCESS (Status))
0442         {
0443             InfoSize += Hid->Length;
0444             Valid |= ACPI_VALID_HID;
0445         }
0446 
0447         /* Execute the Device._UID method */
0448 
0449         Status = AcpiUtExecute_UID (Node, &Uid);
0450         if (ACPI_SUCCESS (Status))
0451         {
0452             InfoSize += Uid->Length;
0453             Valid |= ACPI_VALID_UID;
0454         }
0455 
0456         /* Execute the Device._CID method */
0457 
0458         Status = AcpiUtExecute_CID (Node, &CidList);
0459         if (ACPI_SUCCESS (Status))
0460         {
0461             /* Add size of CID strings and CID pointer array */
0462 
0463             InfoSize += (CidList->ListSize - sizeof (ACPI_DEVICE_ID_LIST));
0464             Valid |= ACPI_VALID_CID;
0465         }
0466     }
0467 
0468     /*
0469      * Now that we have the variable-length data, we can allocate the
0470      * return buffer
0471      */
0472     Info = ACPI_ALLOCATE_ZEROED (InfoSize);
0473     if (!Info)
0474     {
0475         Status = AE_NO_MEMORY;
0476         goto Cleanup;
0477     }
0478 
0479     /* Get the fixed-length data */
0480 
0481     if ((Type == ACPI_TYPE_DEVICE) ||
0482         (Type == ACPI_TYPE_PROCESSOR))
0483     {
0484         /*
0485          * Get extra info for ACPI Device/Processor objects only:
0486          * Run the _STA, _ADR and, SxW, and _SxD methods.
0487          *
0488          * Note: none of these methods are required, so they may or may
0489          * not be present for this device. The Info->Valid bitfield is used
0490          * to indicate which methods were found and run successfully.
0491          */
0492 
0493         /* Execute the Device._STA method */
0494 
0495         Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
0496         if (ACPI_SUCCESS (Status))
0497         {
0498             Valid |= ACPI_VALID_STA;
0499         }
0500 
0501         /* Execute the Device._ADR method */
0502 
0503         Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
0504                     &Info->Address);
0505         if (ACPI_SUCCESS (Status))
0506         {
0507             Valid |= ACPI_VALID_ADR;
0508         }
0509 
0510         /* Execute the Device._SxW methods */
0511 
0512         Status = AcpiUtExecutePowerMethods (Node,
0513                     AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
0514                     Info->LowestDstates);
0515         if (ACPI_SUCCESS (Status))
0516         {
0517             Valid |= ACPI_VALID_SXWS;
0518         }
0519 
0520         /* Execute the Device._SxD methods */
0521 
0522         Status = AcpiUtExecutePowerMethods (Node,
0523                     AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
0524                     Info->HighestDstates);
0525         if (ACPI_SUCCESS (Status))
0526         {
0527             Valid |= ACPI_VALID_SXDS;
0528         }
0529     }
0530 
0531     /*
0532      * Create a pointer to the string area of the return buffer.
0533      * Point to the end of the base ACPI_DEVICE_INFO structure.
0534      */
0535     NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
0536     if (CidList)
0537     {
0538         /* Point past the CID DEVICE_ID array */
0539 
0540         NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_DEVICE_ID));
0541     }
0542 
0543     /*
0544      * Copy the HID, UID, and CIDs to the return buffer. The variable-length
0545      * strings are copied to the reserved area at the end of the buffer.
0546      *
0547      * For HID and CID, check if the ID is a PCI Root Bridge.
0548      */
0549     if (Hid)
0550     {
0551         NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
0552             Hid, NextIdString);
0553 
0554         if (AcpiUtIsPciRootBridge (Hid->String))
0555         {
0556             Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
0557         }
0558     }
0559 
0560     if (Uid)
0561     {
0562         NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
0563             Uid, NextIdString);
0564     }
0565 
0566     if (CidList)
0567     {
0568         Info->CompatibleIdList.Count = CidList->Count;
0569         Info->CompatibleIdList.ListSize = CidList->ListSize;
0570 
0571         /* Copy each CID */
0572 
0573         for (i = 0; i < CidList->Count; i++)
0574         {
0575             NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
0576                 &CidList->Ids[i], NextIdString);
0577 
0578             if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
0579             {
0580                 Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
0581             }
0582         }
0583     }
0584 
0585     /* Copy the fixed-length data */
0586 
0587     Info->InfoSize = InfoSize;
0588     Info->Type = Type;
0589     Info->Name = Name;
0590     Info->ParamCount = ParamCount;
0591     Info->Valid = Valid;
0592 
0593     *ReturnBuffer = Info;
0594     Status = AE_OK;
0595 
0596 
0597 Cleanup:
0598     if (Hid)
0599     {
0600         ACPI_FREE (Hid);
0601     }
0602     if (Uid)
0603     {
0604         ACPI_FREE (Uid);
0605     }
0606     if (CidList)
0607     {
0608         ACPI_FREE (CidList);
0609     }
0610     return (Status);
0611 }
0612 
0613 ACPI_EXPORT_SYMBOL (AcpiGetObjectInfo)
0614 
0615 
0616 /******************************************************************************
0617  *
0618  * FUNCTION:    AcpiInstallMethod
0619  *
0620  * PARAMETERS:  Buffer         - An ACPI table containing one control method
0621  *
0622  * RETURN:      Status
0623  *
0624  * DESCRIPTION: Install a control method into the namespace. If the method
0625  *              name already exists in the namespace, it is overwritten. The
0626  *              input buffer must contain a valid DSDT or SSDT containing a
0627  *              single control method.
0628  *
0629  ******************************************************************************/
0630 
0631 ACPI_STATUS
0632 AcpiInstallMethod (
0633     UINT8                   *Buffer)
0634 {
0635     ACPI_TABLE_HEADER       *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer);
0636     UINT8                   *AmlBuffer;
0637     UINT8                   *AmlStart;
0638     char                    *Path;
0639     ACPI_NAMESPACE_NODE     *Node;
0640     ACPI_OPERAND_OBJECT     *MethodObj;
0641     ACPI_PARSE_STATE        ParserState;
0642     UINT32                  AmlLength;
0643     UINT16                  Opcode;
0644     UINT8                   MethodFlags;
0645     ACPI_STATUS             Status;
0646 
0647 
0648     /* Parameter validation */
0649 
0650     if (!Buffer)
0651     {
0652         return (AE_BAD_PARAMETER);
0653     }
0654 
0655     /* Table must be a DSDT or SSDT */
0656 
0657     if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) &&
0658         !ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
0659     {
0660         return (AE_BAD_HEADER);
0661     }
0662 
0663     /* First AML opcode in the table must be a control method */
0664 
0665     ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER);
0666     Opcode = AcpiPsPeekOpcode (&ParserState);
0667     if (Opcode != AML_METHOD_OP)
0668     {
0669         return (AE_BAD_PARAMETER);
0670     }
0671 
0672     /* Extract method information from the raw AML */
0673 
0674     ParserState.Aml += AcpiPsGetOpcodeSize (Opcode);
0675     ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState);
0676     Path = AcpiPsGetNextNamestring (&ParserState);
0677     MethodFlags = *ParserState.Aml++;
0678     AmlStart = ParserState.Aml;
0679     AmlLength = ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart);
0680 
0681     /*
0682      * Allocate resources up-front. We don't want to have to delete a new
0683      * node from the namespace if we cannot allocate memory.
0684      */
0685     AmlBuffer = ACPI_ALLOCATE (AmlLength);
0686     if (!AmlBuffer)
0687     {
0688         return (AE_NO_MEMORY);
0689     }
0690 
0691     MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
0692     if (!MethodObj)
0693     {
0694         ACPI_FREE (AmlBuffer);
0695         return (AE_NO_MEMORY);
0696     }
0697 
0698     /* Lock namespace for AcpiNsLookup, we may be creating a new node */
0699 
0700     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0701     if (ACPI_FAILURE (Status))
0702     {
0703         goto ErrorExit;
0704     }
0705 
0706     /* The lookup either returns an existing node or creates a new one */
0707 
0708     Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
0709                 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
0710 
0711     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0712 
0713     if (ACPI_FAILURE (Status)) /* NsLookup */
0714     {
0715         if (Status != AE_ALREADY_EXISTS)
0716         {
0717             goto ErrorExit;
0718         }
0719 
0720         /* Node existed previously, make sure it is a method node */
0721 
0722         if (Node->Type != ACPI_TYPE_METHOD)
0723         {
0724             Status = AE_TYPE;
0725             goto ErrorExit;
0726         }
0727     }
0728 
0729     /* Copy the method AML to the local buffer */
0730 
0731     ACPI_MEMCPY (AmlBuffer, AmlStart, AmlLength);
0732 
0733     /* Initialize the method object with the new method's information */
0734 
0735     MethodObj->Method.AmlStart = AmlBuffer;
0736     MethodObj->Method.AmlLength = AmlLength;
0737 
0738     MethodObj->Method.ParamCount = (UINT8)
0739         (MethodFlags & AML_METHOD_ARG_COUNT);
0740 
0741     MethodObj->Method.MethodFlags = (UINT8)
0742         (MethodFlags & ~AML_METHOD_ARG_COUNT);
0743 
0744     if (MethodFlags & AML_METHOD_SERIALIZED)
0745     {
0746         MethodObj->Method.SyncLevel = (UINT8)
0747             ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
0748     }
0749 
0750     /*
0751      * Now that it is complete, we can attach the new method object to
0752      * the method Node (detaches/deletes any existing object)
0753      */
0754     Status = AcpiNsAttachObject (Node, MethodObj,
0755                 ACPI_TYPE_METHOD);
0756 
0757     /*
0758      * Flag indicates AML buffer is dynamic, must be deleted later.
0759      * Must be set only after attach above.
0760      */
0761     Node->Flags |= ANOBJ_ALLOCATED_BUFFER;
0762 
0763     /* Remove local reference to the method object */
0764 
0765     AcpiUtRemoveReference (MethodObj);
0766     return (Status);
0767 
0768 
0769 ErrorExit:
0770 
0771     ACPI_FREE (AmlBuffer);
0772     ACPI_FREE (MethodObj);
0773     return (Status);
0774 }
0775 
0776 ACPI_EXPORT_SYMBOL (AcpiInstallMethod)