Sync with trunk.
[reactos.git] / drivers / bus / acpi / acpica / events / evregion.c
1 /******************************************************************************
2 *
3 * Module Name: evregion - Operation Region support
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116
117 #define __EVREGION_C__
118
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acevents.h"
122 #include "acnamesp.h"
123 #include "acinterp.h"
124
125 #define _COMPONENT ACPI_EVENTS
126 ACPI_MODULE_NAME ("evregion")
127
128
129 extern UINT8 AcpiGbl_DefaultAddressSpaces[];
130
131 /* Local prototypes */
132
133 static void
134 AcpiEvOrphanEcRegMethod (
135 ACPI_NAMESPACE_NODE *EcDeviceNode);
136
137 static ACPI_STATUS
138 AcpiEvRegRun (
139 ACPI_HANDLE ObjHandle,
140 UINT32 Level,
141 void *Context,
142 void **ReturnValue);
143
144
145 /*******************************************************************************
146 *
147 * FUNCTION: AcpiEvInitializeOpRegions
148 *
149 * PARAMETERS: None
150 *
151 * RETURN: Status
152 *
153 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
154 * an installed default region handler.
155 *
156 ******************************************************************************/
157
158 ACPI_STATUS
159 AcpiEvInitializeOpRegions (
160 void)
161 {
162 ACPI_STATUS Status;
163 UINT32 i;
164
165
166 ACPI_FUNCTION_TRACE (EvInitializeOpRegions);
167
168
169 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
170 if (ACPI_FAILURE (Status))
171 {
172 return_ACPI_STATUS (Status);
173 }
174
175 /* Run the _REG methods for OpRegions in each default address space */
176
177 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
178 {
179 /*
180 * Make sure the installed handler is the DEFAULT handler. If not the
181 * default, the _REG methods will have already been run (when the
182 * handler was installed)
183 */
184 if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode,
185 AcpiGbl_DefaultAddressSpaces[i]))
186 {
187 Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode,
188 AcpiGbl_DefaultAddressSpaces[i]);
189 }
190 }
191
192 AcpiGbl_RegMethodsExecuted = TRUE;
193
194 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
195 return_ACPI_STATUS (Status);
196 }
197
198
199 /*******************************************************************************
200 *
201 * FUNCTION: AcpiEvAddressSpaceDispatch
202 *
203 * PARAMETERS: RegionObj - Internal region object
204 * FieldObj - Corresponding field. Can be NULL.
205 * Function - Read or Write operation
206 * RegionOffset - Where in the region to read or write
207 * BitWidth - Field width in bits (8, 16, 32, or 64)
208 * Value - Pointer to in or out value, must be
209 * a full 64-bit integer
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Dispatch an address space or operation region access to
214 * a previously installed handler.
215 *
216 ******************************************************************************/
217
218 ACPI_STATUS
219 AcpiEvAddressSpaceDispatch (
220 ACPI_OPERAND_OBJECT *RegionObj,
221 ACPI_OPERAND_OBJECT *FieldObj,
222 UINT32 Function,
223 UINT32 RegionOffset,
224 UINT32 BitWidth,
225 UINT64 *Value)
226 {
227 ACPI_STATUS Status;
228 ACPI_ADR_SPACE_HANDLER Handler;
229 ACPI_ADR_SPACE_SETUP RegionSetup;
230 ACPI_OPERAND_OBJECT *HandlerDesc;
231 ACPI_OPERAND_OBJECT *RegionObj2;
232 void *RegionContext = NULL;
233 ACPI_CONNECTION_INFO *Context;
234
235
236 ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
237
238
239 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
240 if (!RegionObj2)
241 {
242 return_ACPI_STATUS (AE_NOT_EXIST);
243 }
244
245 /* Ensure that there is a handler associated with this region */
246
247 HandlerDesc = RegionObj->Region.Handler;
248 if (!HandlerDesc)
249 {
250 ACPI_ERROR ((AE_INFO,
251 "No handler for Region [%4.4s] (%p) [%s]",
252 AcpiUtGetNodeName (RegionObj->Region.Node),
253 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
254
255 return_ACPI_STATUS (AE_NOT_EXIST);
256 }
257
258 Context = HandlerDesc->AddressSpace.Context;
259
260 /*
261 * It may be the case that the region has never been initialized.
262 * Some types of regions require special init code
263 */
264 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
265 {
266 /* This region has not been initialized yet, do it */
267
268 RegionSetup = HandlerDesc->AddressSpace.Setup;
269 if (!RegionSetup)
270 {
271 /* No initialization routine, exit with error */
272
273 ACPI_ERROR ((AE_INFO,
274 "No init routine for region(%p) [%s]",
275 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
276 return_ACPI_STATUS (AE_NOT_EXIST);
277 }
278
279 /*
280 * We must exit the interpreter because the region setup will
281 * potentially execute control methods (for example, the _REG method
282 * for this region)
283 */
284 AcpiExExitInterpreter ();
285
286 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
287 Context, &RegionContext);
288
289 /* Re-enter the interpreter */
290
291 AcpiExEnterInterpreter ();
292
293 /* Check for failure of the Region Setup */
294
295 if (ACPI_FAILURE (Status))
296 {
297 ACPI_EXCEPTION ((AE_INFO, Status,
298 "During region initialization: [%s]",
299 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
300 return_ACPI_STATUS (Status);
301 }
302
303 /* Region initialization may have been completed by RegionSetup */
304
305 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
306 {
307 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
308
309 /*
310 * Save the returned context for use in all accesses to
311 * the handler for this particular region
312 */
313 if (!(RegionObj2->Extra.RegionContext))
314 {
315 RegionObj2->Extra.RegionContext = RegionContext;
316 }
317 }
318 }
319
320 /* We have everything we need, we can invoke the address space handler */
321
322 Handler = HandlerDesc->AddressSpace.Handler;
323
324 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
325 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
326 &RegionObj->Region.Handler->AddressSpace, Handler,
327 ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset),
328 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
329
330 /*
331 * Special handling for GenericSerialBus and GeneralPurposeIo:
332 * There are three extra parameters that must be passed to the
333 * handler via the context:
334 * 1) Connection buffer, a resource template from Connection() op.
335 * 2) Length of the above buffer.
336 * 3) Actual access length from the AccessAs() op.
337 */
338 if (((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) ||
339 (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) &&
340 Context &&
341 FieldObj)
342 {
343 /* Get the Connection (ResourceTemplate) buffer */
344
345 Context->Connection = FieldObj->Field.ResourceBuffer;
346 Context->Length = FieldObj->Field.ResourceLength;
347 Context->AccessLength = FieldObj->Field.AccessLength;
348 }
349
350 if (!(HandlerDesc->AddressSpace.HandlerFlags &
351 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
352 {
353 /*
354 * For handlers other than the default (supplied) handlers, we must
355 * exit the interpreter because the handler *might* block -- we don't
356 * know what it will do, so we can't hold the lock on the intepreter.
357 */
358 AcpiExExitInterpreter();
359 }
360
361 /* Call the handler */
362
363 Status = Handler (Function,
364 (RegionObj->Region.Address + RegionOffset), BitWidth, Value,
365 Context, RegionObj2->Extra.RegionContext);
366
367 if (ACPI_FAILURE (Status))
368 {
369 ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
370 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
371 }
372
373 if (!(HandlerDesc->AddressSpace.HandlerFlags &
374 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
375 {
376 /*
377 * We just returned from a non-default handler, we must re-enter the
378 * interpreter
379 */
380 AcpiExEnterInterpreter ();
381 }
382
383 return_ACPI_STATUS (Status);
384 }
385
386
387 /*******************************************************************************
388 *
389 * FUNCTION: AcpiEvDetachRegion
390 *
391 * PARAMETERS: RegionObj - Region Object
392 * AcpiNsIsLocked - Namespace Region Already Locked?
393 *
394 * RETURN: None
395 *
396 * DESCRIPTION: Break the association between the handler and the region
397 * this is a two way association.
398 *
399 ******************************************************************************/
400
401 void
402 AcpiEvDetachRegion(
403 ACPI_OPERAND_OBJECT *RegionObj,
404 BOOLEAN AcpiNsIsLocked)
405 {
406 ACPI_OPERAND_OBJECT *HandlerObj;
407 ACPI_OPERAND_OBJECT *ObjDesc;
408 ACPI_OPERAND_OBJECT *StartDesc;
409 ACPI_OPERAND_OBJECT **LastObjPtr;
410 ACPI_ADR_SPACE_SETUP RegionSetup;
411 void **RegionContext;
412 ACPI_OPERAND_OBJECT *RegionObj2;
413 ACPI_STATUS Status;
414
415
416 ACPI_FUNCTION_TRACE (EvDetachRegion);
417
418
419 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
420 if (!RegionObj2)
421 {
422 return_VOID;
423 }
424 RegionContext = &RegionObj2->Extra.RegionContext;
425
426 /* Get the address handler from the region object */
427
428 HandlerObj = RegionObj->Region.Handler;
429 if (!HandlerObj)
430 {
431 /* This region has no handler, all done */
432
433 return_VOID;
434 }
435
436 /* Find this region in the handler's list */
437
438 ObjDesc = HandlerObj->AddressSpace.RegionList;
439 StartDesc = ObjDesc;
440 LastObjPtr = &HandlerObj->AddressSpace.RegionList;
441
442 while (ObjDesc)
443 {
444 /* Is this the correct Region? */
445
446 if (ObjDesc == RegionObj)
447 {
448 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
449 "Removing Region %p from address handler %p\n",
450 RegionObj, HandlerObj));
451
452 /* This is it, remove it from the handler's list */
453
454 *LastObjPtr = ObjDesc->Region.Next;
455 ObjDesc->Region.Next = NULL; /* Must clear field */
456
457 if (AcpiNsIsLocked)
458 {
459 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
460 if (ACPI_FAILURE (Status))
461 {
462 return_VOID;
463 }
464 }
465
466 /* Now stop region accesses by executing the _REG method */
467
468 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
469 if (ACPI_FAILURE (Status))
470 {
471 ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
472 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
473 }
474
475 if (AcpiNsIsLocked)
476 {
477 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
478 if (ACPI_FAILURE (Status))
479 {
480 return_VOID;
481 }
482 }
483
484 /*
485 * If the region has been activated, call the setup handler with
486 * the deactivate notification
487 */
488 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
489 {
490 RegionSetup = HandlerObj->AddressSpace.Setup;
491 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
492 HandlerObj->AddressSpace.Context, RegionContext);
493
494 /*
495 * RegionContext should have been released by the deactivate
496 * operation. We don't need access to it anymore here.
497 */
498 if (RegionContext)
499 {
500 *RegionContext = NULL;
501 }
502
503 /* Init routine may fail, Just ignore errors */
504
505 if (ACPI_FAILURE (Status))
506 {
507 ACPI_EXCEPTION ((AE_INFO, Status,
508 "from region handler - deactivate, [%s]",
509 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
510 }
511
512 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
513 }
514
515 /*
516 * Remove handler reference in the region
517 *
518 * NOTE: this doesn't mean that the region goes away, the region
519 * is just inaccessible as indicated to the _REG method
520 *
521 * If the region is on the handler's list, this must be the
522 * region's handler
523 */
524 RegionObj->Region.Handler = NULL;
525 AcpiUtRemoveReference (HandlerObj);
526
527 return_VOID;
528 }
529
530 /* Walk the linked list of handlers */
531
532 LastObjPtr = &ObjDesc->Region.Next;
533 ObjDesc = ObjDesc->Region.Next;
534
535 /* Prevent infinite loop if list is corrupted */
536
537 if (ObjDesc == StartDesc)
538 {
539 ACPI_ERROR ((AE_INFO,
540 "Circular handler list in region object %p",
541 RegionObj));
542 return_VOID;
543 }
544 }
545
546 /* If we get here, the region was not in the handler's region list */
547
548 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
549 "Cannot remove region %p from address handler %p\n",
550 RegionObj, HandlerObj));
551
552 return_VOID;
553 }
554
555
556 /*******************************************************************************
557 *
558 * FUNCTION: AcpiEvAttachRegion
559 *
560 * PARAMETERS: HandlerObj - Handler Object
561 * RegionObj - Region Object
562 * AcpiNsIsLocked - Namespace Region Already Locked?
563 *
564 * RETURN: None
565 *
566 * DESCRIPTION: Create the association between the handler and the region
567 * this is a two way association.
568 *
569 ******************************************************************************/
570
571 ACPI_STATUS
572 AcpiEvAttachRegion (
573 ACPI_OPERAND_OBJECT *HandlerObj,
574 ACPI_OPERAND_OBJECT *RegionObj,
575 BOOLEAN AcpiNsIsLocked)
576 {
577
578 ACPI_FUNCTION_TRACE (EvAttachRegion);
579
580
581 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
582 "Adding Region [%4.4s] %p to address handler %p [%s]\n",
583 AcpiUtGetNodeName (RegionObj->Region.Node),
584 RegionObj, HandlerObj,
585 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
586
587 /* Link this region to the front of the handler's list */
588
589 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
590 HandlerObj->AddressSpace.RegionList = RegionObj;
591
592 /* Install the region's handler */
593
594 if (RegionObj->Region.Handler)
595 {
596 return_ACPI_STATUS (AE_ALREADY_EXISTS);
597 }
598
599 RegionObj->Region.Handler = HandlerObj;
600 AcpiUtAddReference (HandlerObj);
601
602 return_ACPI_STATUS (AE_OK);
603 }
604
605
606 /*******************************************************************************
607 *
608 * FUNCTION: AcpiEvExecuteRegMethod
609 *
610 * PARAMETERS: RegionObj - Region object
611 * Function - Passed to _REG: On (1) or Off (0)
612 *
613 * RETURN: Status
614 *
615 * DESCRIPTION: Execute _REG method for a region
616 *
617 ******************************************************************************/
618
619 ACPI_STATUS
620 AcpiEvExecuteRegMethod (
621 ACPI_OPERAND_OBJECT *RegionObj,
622 UINT32 Function)
623 {
624 ACPI_EVALUATE_INFO *Info;
625 ACPI_OPERAND_OBJECT *Args[3];
626 ACPI_OPERAND_OBJECT *RegionObj2;
627 ACPI_STATUS Status;
628
629
630 ACPI_FUNCTION_TRACE (EvExecuteRegMethod);
631
632
633 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
634 if (!RegionObj2)
635 {
636 return_ACPI_STATUS (AE_NOT_EXIST);
637 }
638
639 if (RegionObj2->Extra.Method_REG == NULL)
640 {
641 return_ACPI_STATUS (AE_OK);
642 }
643
644 /* Allocate and initialize the evaluation information block */
645
646 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
647 if (!Info)
648 {
649 return_ACPI_STATUS (AE_NO_MEMORY);
650 }
651
652 Info->PrefixNode = RegionObj2->Extra.Method_REG;
653 Info->RelativePathname = NULL;
654 Info->Parameters = Args;
655 Info->Flags = ACPI_IGNORE_RETURN_VALUE;
656
657 /*
658 * The _REG method has two arguments:
659 *
660 * Arg0 - Integer:
661 * Operation region space ID Same value as RegionObj->Region.SpaceId
662 *
663 * Arg1 - Integer:
664 * connection status 1 for connecting the handler, 0 for disconnecting
665 * the handler (Passed as a parameter)
666 */
667 Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId);
668 if (!Args[0])
669 {
670 Status = AE_NO_MEMORY;
671 goto Cleanup1;
672 }
673
674 Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function);
675 if (!Args[1])
676 {
677 Status = AE_NO_MEMORY;
678 goto Cleanup2;
679 }
680
681 Args[2] = NULL; /* Terminate list */
682
683 /* Execute the method, no return value */
684
685 ACPI_DEBUG_EXEC (
686 AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL));
687
688 Status = AcpiNsEvaluate (Info);
689 AcpiUtRemoveReference (Args[1]);
690
691 Cleanup2:
692 AcpiUtRemoveReference (Args[0]);
693
694 Cleanup1:
695 ACPI_FREE (Info);
696 return_ACPI_STATUS (Status);
697 }
698
699
700 /*******************************************************************************
701 *
702 * FUNCTION: AcpiEvExecuteRegMethods
703 *
704 * PARAMETERS: Node - Namespace node for the device
705 * SpaceId - The address space ID
706 *
707 * RETURN: Status
708 *
709 * DESCRIPTION: Run all _REG methods for the input Space ID;
710 * Note: assumes namespace is locked, or system init time.
711 *
712 ******************************************************************************/
713
714 ACPI_STATUS
715 AcpiEvExecuteRegMethods (
716 ACPI_NAMESPACE_NODE *Node,
717 ACPI_ADR_SPACE_TYPE SpaceId)
718 {
719 ACPI_STATUS Status;
720
721
722 ACPI_FUNCTION_TRACE (EvExecuteRegMethods);
723
724
725 /*
726 * Run all _REG methods for all Operation Regions for this space ID. This
727 * is a separate walk in order to handle any interdependencies between
728 * regions and _REG methods. (i.e. handlers must be installed for all
729 * regions of this Space ID before we can run any _REG methods)
730 */
731 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
732 ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL,
733 &SpaceId, NULL);
734
735 /* Special case for EC: handle "orphan" _REG methods with no region */
736
737 if (SpaceId == ACPI_ADR_SPACE_EC)
738 {
739 AcpiEvOrphanEcRegMethod (Node);
740 }
741
742 return_ACPI_STATUS (Status);
743 }
744
745
746 /*******************************************************************************
747 *
748 * FUNCTION: AcpiEvRegRun
749 *
750 * PARAMETERS: WalkNamespace callback
751 *
752 * DESCRIPTION: Run _REG method for region objects of the requested spaceID
753 *
754 ******************************************************************************/
755
756 static ACPI_STATUS
757 AcpiEvRegRun (
758 ACPI_HANDLE ObjHandle,
759 UINT32 Level,
760 void *Context,
761 void **ReturnValue)
762 {
763 ACPI_OPERAND_OBJECT *ObjDesc;
764 ACPI_NAMESPACE_NODE *Node;
765 ACPI_ADR_SPACE_TYPE SpaceId;
766 ACPI_STATUS Status;
767
768
769 SpaceId = *ACPI_CAST_PTR (ACPI_ADR_SPACE_TYPE, Context);
770
771 /* Convert and validate the device handle */
772
773 Node = AcpiNsValidateHandle (ObjHandle);
774 if (!Node)
775 {
776 return (AE_BAD_PARAMETER);
777 }
778
779 /*
780 * We only care about regions.and objects that are allowed to have address
781 * space handlers
782 */
783 if ((Node->Type != ACPI_TYPE_REGION) &&
784 (Node != AcpiGbl_RootNode))
785 {
786 return (AE_OK);
787 }
788
789 /* Check for an existing internal object */
790
791 ObjDesc = AcpiNsGetAttachedObject (Node);
792 if (!ObjDesc)
793 {
794 /* No object, just exit */
795
796 return (AE_OK);
797 }
798
799 /* Object is a Region */
800
801 if (ObjDesc->Region.SpaceId != SpaceId)
802 {
803 /* This region is for a different address space, just ignore it */
804
805 return (AE_OK);
806 }
807
808 Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT);
809 return (Status);
810 }
811
812
813 /*******************************************************************************
814 *
815 * FUNCTION: AcpiEvOrphanEcRegMethod
816 *
817 * PARAMETERS: EcDeviceNode - Namespace node for an EC device
818 *
819 * RETURN: None
820 *
821 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
822 * device. This is a _REG method that has no corresponding region
823 * within the EC device scope. The orphan _REG method appears to
824 * have been enabled by the description of the ECDT in the ACPI
825 * specification: "The availability of the region space can be
826 * detected by providing a _REG method object underneath the
827 * Embedded Controller device."
828 *
829 * To quickly access the EC device, we use the EcDeviceNode used
830 * during EC handler installation. Otherwise, we would need to
831 * perform a time consuming namespace walk, executing _HID
832 * methods to find the EC device.
833 *
834 * MUTEX: Assumes the namespace is locked
835 *
836 ******************************************************************************/
837
838 static void
839 AcpiEvOrphanEcRegMethod (
840 ACPI_NAMESPACE_NODE *EcDeviceNode)
841 {
842 ACPI_HANDLE RegMethod;
843 ACPI_NAMESPACE_NODE *NextNode;
844 ACPI_STATUS Status;
845 ACPI_OBJECT_LIST Args;
846 ACPI_OBJECT Objects[2];
847
848
849 ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod);
850
851
852 if (!EcDeviceNode)
853 {
854 return_VOID;
855 }
856
857 /* Namespace is currently locked, must release */
858
859 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
860
861 /* Get a handle to a _REG method immediately under the EC device */
862
863 Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod);
864 if (ACPI_FAILURE (Status))
865 {
866 goto Exit; /* There is no _REG method present */
867 }
868
869 /*
870 * Execute the _REG method only if there is no Operation Region in
871 * this scope with the Embedded Controller space ID. Otherwise, it
872 * will already have been executed. Note, this allows for Regions
873 * with other space IDs to be present; but the code below will then
874 * execute the _REG method with the EmbeddedControl SpaceID argument.
875 */
876 NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL);
877 while (NextNode)
878 {
879 if ((NextNode->Type == ACPI_TYPE_REGION) &&
880 (NextNode->Object) &&
881 (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC))
882 {
883 goto Exit; /* Do not execute the _REG */
884 }
885
886 NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode);
887 }
888
889 /* Evaluate the _REG(EmbeddedControl,Connect) method */
890
891 Args.Count = 2;
892 Args.Pointer = Objects;
893 Objects[0].Type = ACPI_TYPE_INTEGER;
894 Objects[0].Integer.Value = ACPI_ADR_SPACE_EC;
895 Objects[1].Type = ACPI_TYPE_INTEGER;
896 Objects[1].Integer.Value = ACPI_REG_CONNECT;
897
898 Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
899
900 Exit:
901 /* We ignore all errors from above, don't care */
902
903 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
904 return_VOID;
905 }