nsxfname.c revision 1.17 1 /******************************************************************************
2 *
3 * Module Name: nsxfname - Public interfaces to the ACPI subsystem
4 * ACPI Namespace oriented interfaces
5 *
6 *****************************************************************************/
7
8 /******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************
116 *
117 * Alternatively, you may choose to be licensed under the terms of the
118 * following license:
119 *
120 * Redistribution and use in source and binary forms, with or without
121 * modification, are permitted provided that the following conditions
122 * are met:
123 * 1. Redistributions of source code must retain the above copyright
124 * notice, this list of conditions, and the following disclaimer,
125 * without modification.
126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127 * substantially similar to the "NO WARRANTY" disclaimer below
128 * ("Disclaimer") and any redistribution must be conditioned upon
129 * including a substantially similar Disclaimer requirement for further
130 * binary redistribution.
131 * 3. Neither the names of the above-listed copyright holders nor the names
132 * of any contributors may be used to endorse or promote products derived
133 * from this software without specific prior written permission.
134 *
135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 *
147 * Alternatively, you may choose to be licensed under the terms of the
148 * GNU General Public License ("GPL") version 2 as published by the Free
149 * Software Foundation.
150 *
151 *****************************************************************************/
152
153 #define EXPORT_ACPI_INTERFACES
154
155 #include "acpi.h"
156 #include "accommon.h"
157 #include "acnamesp.h"
158 #include "acparser.h"
159 #include "amlcode.h"
160
161
162 #define _COMPONENT ACPI_NAMESPACE
163 ACPI_MODULE_NAME ("nsxfname")
164
165 /* Local prototypes */
166
167 static char *
168 AcpiNsCopyDeviceId (
169 ACPI_PNP_DEVICE_ID *Dest,
170 ACPI_PNP_DEVICE_ID *Source,
171 char *StringArea);
172
173
174 /******************************************************************************
175 *
176 * FUNCTION: AcpiGetHandle
177 *
178 * PARAMETERS: Parent - Object to search under (search scope).
179 * Pathname - Pointer to an asciiz string containing the
180 * name
181 * RetHandle - Where the return handle is returned
182 *
183 * RETURN: Status
184 *
185 * DESCRIPTION: This routine will search for a caller specified name in the
186 * name space. The caller can restrict the search region by
187 * specifying a non NULL parent. The parent value is itself a
188 * namespace handle.
189 *
190 ******************************************************************************/
191
192 ACPI_STATUS
193 AcpiGetHandle (
194 ACPI_HANDLE Parent,
195 const char *Pathname,
196 ACPI_HANDLE *RetHandle)
197 {
198 ACPI_STATUS Status;
199 ACPI_NAMESPACE_NODE *Node = NULL;
200 ACPI_NAMESPACE_NODE *PrefixNode = NULL;
201 ACPI_STRING UPathname = __UNCONST(Pathname);
202
203
204 ACPI_FUNCTION_ENTRY ();
205
206
207 /* Parameter Validation */
208
209 if (!RetHandle || !Pathname)
210 {
211 return (AE_BAD_PARAMETER);
212 }
213
214 /* Convert a parent handle to a prefix node */
215
216 if (Parent)
217 {
218 PrefixNode = AcpiNsValidateHandle (Parent);
219 if (!PrefixNode)
220 {
221 return (AE_BAD_PARAMETER);
222 }
223 }
224
225 /*
226 * Valid cases are:
227 * 1) Fully qualified pathname
228 * 2) Parent + Relative pathname
229 *
230 * Error for <null Parent + relative path>
231 */
232 if (ACPI_IS_ROOT_PREFIX (Pathname[0]))
233 {
234 /* Pathname is fully qualified (starts with '\') */
235
236 /* Special case for root-only, since we can't search for it */
237
238 if (!strcmp (Pathname, ACPI_NS_ROOT_PATH))
239 {
240 *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
241 return (AE_OK);
242 }
243 }
244 else if (!PrefixNode)
245 {
246 /* Relative path with null prefix is disallowed */
247
248 return (AE_BAD_PARAMETER);
249 }
250
251 /* Find the Node and convert to a handle */
252
253 Status = AcpiNsGetNode (PrefixNode, UPathname, ACPI_NS_NO_UPSEARCH, &Node);
254 if (ACPI_SUCCESS (Status))
255 {
256 *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
257 }
258
259 return (Status);
260 }
261
262 ACPI_EXPORT_SYMBOL (AcpiGetHandle)
263
264
265 /******************************************************************************
266 *
267 * FUNCTION: AcpiGetName
268 *
269 * PARAMETERS: Handle - Handle to be converted to a pathname
270 * NameType - Full pathname or single segment
271 * Buffer - Buffer for returned path
272 *
273 * RETURN: Pointer to a string containing the fully qualified Name.
274 *
275 * DESCRIPTION: This routine returns the fully qualified name associated with
276 * the Handle parameter. This and the AcpiPathnameToHandle are
277 * complementary functions.
278 *
279 ******************************************************************************/
280
281 ACPI_STATUS
282 AcpiGetName (
283 ACPI_HANDLE Handle,
284 UINT32 NameType,
285 ACPI_BUFFER *Buffer)
286 {
287 ACPI_STATUS Status;
288
289
290 /* Parameter validation */
291
292 if (NameType > ACPI_NAME_TYPE_MAX)
293 {
294 return (AE_BAD_PARAMETER);
295 }
296
297 Status = AcpiUtValidateBuffer (Buffer);
298 if (ACPI_FAILURE (Status))
299 {
300 return (Status);
301 }
302
303 /*
304 * Wants the single segment ACPI name.
305 * Validate handle and convert to a namespace Node
306 */
307 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
308 if (ACPI_FAILURE (Status))
309 {
310 return (Status);
311 }
312
313 if (NameType == ACPI_FULL_PATHNAME ||
314 NameType == ACPI_FULL_PATHNAME_NO_TRAILING)
315 {
316 /* Get the full pathname (From the namespace root) */
317
318 Status = AcpiNsHandleToPathname (Handle, Buffer,
319 NameType == ACPI_FULL_PATHNAME ? FALSE : TRUE);
320 }
321 else
322 {
323 /* Get the single name */
324
325 Status = AcpiNsHandleToName (Handle, Buffer);
326 }
327
328 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
329 return (Status);
330 }
331
332 ACPI_EXPORT_SYMBOL (AcpiGetName)
333
334
335 /******************************************************************************
336 *
337 * FUNCTION: AcpiNsCopyDeviceId
338 *
339 * PARAMETERS: Dest - Pointer to the destination PNP_DEVICE_ID
340 * Source - Pointer to the source PNP_DEVICE_ID
341 * StringArea - Pointer to where to copy the dest string
342 *
343 * RETURN: Pointer to the next string area
344 *
345 * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data.
346 *
347 ******************************************************************************/
348
349 static char *
350 AcpiNsCopyDeviceId (
351 ACPI_PNP_DEVICE_ID *Dest,
352 ACPI_PNP_DEVICE_ID *Source,
353 char *StringArea)
354 {
355 /* Create the destination PNP_DEVICE_ID */
356
357 Dest->String = StringArea;
358 Dest->Length = Source->Length;
359
360 /* Copy actual string and return a pointer to the next string area */
361
362 memcpy (StringArea, Source->String, Source->Length);
363 return (StringArea + Source->Length);
364 }
365
366
367 /******************************************************************************
368 *
369 * FUNCTION: AcpiGetObjectInfo
370 *
371 * PARAMETERS: Handle - Object Handle
372 * ReturnBuffer - Where the info is returned
373 *
374 * RETURN: Status
375 *
376 * DESCRIPTION: Returns information about an object as gleaned from the
377 * namespace node and possibly by running several standard
378 * control methods (Such as in the case of a device.)
379 *
380 * For Device and Processor objects, run the Device _HID, _UID, _CID,
381 * _CLS, _ADR, _SxW, and _SxD methods.
382 *
383 * Note: Allocates the return buffer, must be freed by the caller.
384 *
385 * Note: This interface is intended to be used during the initial device
386 * discovery namespace traversal. Therefore, no complex methods can be
387 * executed, especially those that access operation regions. Therefore, do
388 * not add any additional methods that could cause problems in this area.
389 * Because of this reason support for the following methods has been removed:
390 * 1) _SUB method was removed (11/2015)
391 * 2) _STA method was removed (02/2018)
392 *
393 ******************************************************************************/
394
395 ACPI_STATUS
396 AcpiGetObjectInfo (
397 ACPI_HANDLE Handle,
398 ACPI_DEVICE_INFO **ReturnBuffer)
399 {
400 ACPI_NAMESPACE_NODE *Node;
401 ACPI_DEVICE_INFO *Info;
402 ACPI_PNP_DEVICE_ID_LIST *CidList = NULL;
403 ACPI_PNP_DEVICE_ID *Hid = NULL;
404 ACPI_PNP_DEVICE_ID *Uid = NULL;
405 ACPI_PNP_DEVICE_ID *Cls = NULL;
406 char *NextIdString;
407 ACPI_OBJECT_TYPE Type;
408 ACPI_NAME Name;
409 UINT8 ParamCount= 0;
410 UINT16 Valid = 0;
411 UINT32 InfoSize;
412 UINT32 i;
413 ACPI_STATUS Status;
414
415
416 /* Parameter validation */
417
418 if (!Handle || !ReturnBuffer)
419 {
420 return (AE_BAD_PARAMETER);
421 }
422
423 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
424 if (ACPI_FAILURE (Status))
425 {
426 return (Status);
427 }
428
429 Node = AcpiNsValidateHandle (Handle);
430 if (!Node)
431 {
432 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
433 return (AE_BAD_PARAMETER);
434 }
435
436 /* Get the namespace node data while the namespace is locked */
437
438 InfoSize = sizeof (ACPI_DEVICE_INFO);
439 Type = Node->Type;
440 Name = Node->Name.Integer;
441
442 if (Node->Type == ACPI_TYPE_METHOD)
443 {
444 ParamCount = Node->Object->Method.ParamCount;
445 }
446
447 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
448 if (ACPI_FAILURE (Status))
449 {
450 return (Status);
451 }
452
453 if ((Type == ACPI_TYPE_DEVICE) ||
454 (Type == ACPI_TYPE_PROCESSOR))
455 {
456 /*
457 * Get extra info for ACPI Device/Processor objects only:
458 * Run the Device _HID, _UID, _CLS, and _CID methods.
459 *
460 * Note: none of these methods are required, so they may or may
461 * not be present for this device. The Info->Valid bitfield is used
462 * to indicate which methods were found and run successfully.
463 */
464
465 /* Execute the Device._HID method */
466
467 Status = AcpiUtExecute_HID (Node, &Hid);
468 if (ACPI_SUCCESS (Status))
469 {
470 InfoSize += Hid->Length;
471 Valid |= ACPI_VALID_HID;
472 }
473
474 /* Execute the Device._UID method */
475
476 Status = AcpiUtExecute_UID (Node, &Uid);
477 if (ACPI_SUCCESS (Status))
478 {
479 InfoSize += Uid->Length;
480 Valid |= ACPI_VALID_UID;
481 }
482
483 /* Execute the Device._CID method */
484
485 Status = AcpiUtExecute_CID (Node, &CidList);
486 if (ACPI_SUCCESS (Status))
487 {
488 /* Add size of CID strings and CID pointer array */
489
490 InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST));
491 Valid |= ACPI_VALID_CID;
492 }
493
494 /* Execute the Device._CLS method */
495
496 Status = AcpiUtExecute_CLS (Node, &Cls);
497 if (ACPI_SUCCESS (Status))
498 {
499 InfoSize += Cls->Length;
500 Valid |= ACPI_VALID_CLS;
501 }
502 }
503
504 /*
505 * Now that we have the variable-length data, we can allocate the
506 * return buffer
507 */
508 Info = ACPI_ALLOCATE_ZEROED (InfoSize);
509 if (!Info)
510 {
511 Status = AE_NO_MEMORY;
512 goto Cleanup;
513 }
514
515 /* Get the fixed-length data */
516
517 if ((Type == ACPI_TYPE_DEVICE) ||
518 (Type == ACPI_TYPE_PROCESSOR))
519 {
520 /*
521 * Get extra info for ACPI Device/Processor objects only:
522 * Run the _ADR and, SxW, and _SxD methods.
523 *
524 * Notes: none of these methods are required, so they may or may
525 * not be present for this device. The Info->Valid bitfield is used
526 * to indicate which methods were found and run successfully.
527 */
528
529 /* Execute the Device._ADR method */
530
531 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
532 &Info->Address);
533 if (ACPI_SUCCESS (Status))
534 {
535 Valid |= ACPI_VALID_ADR;
536 }
537
538 /* Execute the Device._SxW methods */
539
540 Status = AcpiUtExecutePowerMethods (Node,
541 AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
542 Info->LowestDstates);
543 if (ACPI_SUCCESS (Status))
544 {
545 Valid |= ACPI_VALID_SXWS;
546 }
547
548 /* Execute the Device._SxD methods */
549
550 Status = AcpiUtExecutePowerMethods (Node,
551 AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
552 Info->HighestDstates);
553 if (ACPI_SUCCESS (Status))
554 {
555 Valid |= ACPI_VALID_SXDS;
556 }
557 }
558
559 /*
560 * Create a pointer to the string area of the return buffer.
561 * Point to the end of the base ACPI_DEVICE_INFO structure.
562 */
563 NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
564 if (CidList)
565 {
566 /* Point past the CID PNP_DEVICE_ID array */
567
568 NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID));
569 }
570
571 /*
572 * Copy the HID, UID, and CIDs to the return buffer. The variable-length
573 * strings are copied to the reserved area at the end of the buffer.
574 *
575 * For HID and CID, check if the ID is a PCI Root Bridge.
576 */
577 if (Hid)
578 {
579 NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
580 Hid, NextIdString);
581
582 if (AcpiUtIsPciRootBridge (Hid->String))
583 {
584 Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
585 }
586 }
587
588 if (Uid)
589 {
590 NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
591 Uid, NextIdString);
592 }
593
594 if (CidList)
595 {
596 Info->CompatibleIdList.Count = CidList->Count;
597 Info->CompatibleIdList.ListSize = CidList->ListSize;
598
599 /* Copy each CID */
600
601 for (i = 0; i < CidList->Count; i++)
602 {
603 NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
604 &CidList->Ids[i], NextIdString);
605
606 if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
607 {
608 Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
609 }
610 }
611 }
612
613 if (Cls)
614 {
615 (void) AcpiNsCopyDeviceId (&Info->ClassCode,
616 Cls, NextIdString);
617 }
618
619 /* Copy the fixed-length data */
620
621 Info->InfoSize = InfoSize;
622 Info->Type = Type;
623 Info->Name = Name;
624 Info->ParamCount = ParamCount;
625 Info->Valid = Valid;
626
627 *ReturnBuffer = Info;
628 Status = AE_OK;
629
630
631 Cleanup:
632 if (Hid)
633 {
634 ACPI_FREE (Hid);
635 }
636 if (Uid)
637 {
638 ACPI_FREE (Uid);
639 }
640 if (CidList)
641 {
642 ACPI_FREE (CidList);
643 }
644 if (Cls)
645 {
646 ACPI_FREE (Cls);
647 }
648 return (Status);
649 }
650
651 ACPI_EXPORT_SYMBOL (AcpiGetObjectInfo)
652
653
654 /******************************************************************************
655 *
656 * FUNCTION: AcpiInstallMethod
657 *
658 * PARAMETERS: Buffer - An ACPI table containing one control method
659 *
660 * RETURN: Status
661 *
662 * DESCRIPTION: Install a control method into the namespace. If the method
663 * name already exists in the namespace, it is overwritten. The
664 * input buffer must contain a valid DSDT or SSDT containing a
665 * single control method.
666 *
667 ******************************************************************************/
668
669 ACPI_STATUS
670 AcpiInstallMethod (
671 UINT8 *Buffer)
672 {
673 ACPI_TABLE_HEADER *Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Buffer);
674 UINT8 *AmlBuffer;
675 UINT8 *AmlStart;
676 char *Path;
677 ACPI_NAMESPACE_NODE *Node;
678 ACPI_OPERAND_OBJECT *MethodObj;
679 ACPI_PARSE_STATE ParserState;
680 UINT32 AmlLength;
681 UINT16 Opcode;
682 UINT8 MethodFlags;
683 ACPI_STATUS Status;
684
685
686 /* Parameter validation */
687
688 if (!Buffer)
689 {
690 return (AE_BAD_PARAMETER);
691 }
692
693 /* Table must be a DSDT or SSDT */
694
695 if (!ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_DSDT) &&
696 !ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_SSDT))
697 {
698 return (AE_BAD_HEADER);
699 }
700
701 /* First AML opcode in the table must be a control method */
702
703 ParserState.Aml = Buffer + sizeof (ACPI_TABLE_HEADER);
704 Opcode = AcpiPsPeekOpcode (&ParserState);
705 if (Opcode != AML_METHOD_OP)
706 {
707 return (AE_BAD_PARAMETER);
708 }
709
710 /* Extract method information from the raw AML */
711
712 ParserState.Aml += AcpiPsGetOpcodeSize (Opcode);
713 ParserState.PkgEnd = AcpiPsGetNextPackageEnd (&ParserState);
714 Path = AcpiPsGetNextNamestring (&ParserState);
715
716 MethodFlags = *ParserState.Aml++;
717 AmlStart = ParserState.Aml;
718 AmlLength = (UINT32) ACPI_PTR_DIFF (ParserState.PkgEnd, AmlStart);
719
720 /*
721 * Allocate resources up-front. We don't want to have to delete a new
722 * node from the namespace if we cannot allocate memory.
723 */
724 AmlBuffer = ACPI_ALLOCATE (AmlLength);
725 if (!AmlBuffer)
726 {
727 return (AE_NO_MEMORY);
728 }
729
730 MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
731 if (!MethodObj)
732 {
733 ACPI_FREE (AmlBuffer);
734 return (AE_NO_MEMORY);
735 }
736
737 /* Lock namespace for AcpiNsLookup, we may be creating a new node */
738
739 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
740 if (ACPI_FAILURE (Status))
741 {
742 goto ErrorExit;
743 }
744
745 /* The lookup either returns an existing node or creates a new one */
746
747 Status = AcpiNsLookup (NULL, Path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
748 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, NULL, &Node);
749
750 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
751
752 if (ACPI_FAILURE (Status)) /* NsLookup */
753 {
754 if (Status != AE_ALREADY_EXISTS)
755 {
756 goto ErrorExit;
757 }
758
759 /* Node existed previously, make sure it is a method node */
760
761 if (Node->Type != ACPI_TYPE_METHOD)
762 {
763 Status = AE_TYPE;
764 goto ErrorExit;
765 }
766 }
767
768 /* Copy the method AML to the local buffer */
769
770 memcpy (AmlBuffer, AmlStart, AmlLength);
771
772 /* Initialize the method object with the new method's information */
773
774 MethodObj->Method.AmlStart = AmlBuffer;
775 MethodObj->Method.AmlLength = AmlLength;
776
777 MethodObj->Method.ParamCount = (UINT8)
778 (MethodFlags & AML_METHOD_ARG_COUNT);
779
780 if (MethodFlags & AML_METHOD_SERIALIZED)
781 {
782 MethodObj->Method.InfoFlags = ACPI_METHOD_SERIALIZED;
783
784 MethodObj->Method.SyncLevel = (UINT8)
785 ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
786 }
787
788 /*
789 * Now that it is complete, we can attach the new method object to
790 * the method Node (detaches/deletes any existing object)
791 */
792 Status = AcpiNsAttachObject (Node, MethodObj, ACPI_TYPE_METHOD);
793
794 /*
795 * Flag indicates AML buffer is dynamic, must be deleted later.
796 * Must be set only after attach above.
797 */
798 Node->Flags |= ANOBJ_ALLOCATED_BUFFER;
799
800 /* Remove local reference to the method object */
801
802 AcpiUtRemoveReference (MethodObj);
803 return (Status);
804
805
806 ErrorExit:
807
808 ACPI_FREE (AmlBuffer);
809 ACPI_FREE (MethodObj);
810 return (Status);
811 }
812
813 ACPI_EXPORT_SYMBOL (AcpiInstallMethod)
814