ReactOS 0.4.16-dev-401-g45b008d
evregion.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: evregion - Operation Region support
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48#include "acinterp.h"
49
50#define _COMPONENT ACPI_EVENTS
51 ACPI_MODULE_NAME ("evregion")
52
53
55
56/* Local prototypes */
57
58static void
62
63
64static ACPI_STATUS
66 ACPI_HANDLE ObjHandle,
68 void *Context,
69 void **ReturnValue);
70
71
72/*******************************************************************************
73 *
74 * FUNCTION: AcpiEvInitializeOpRegions
75 *
76 * PARAMETERS: None
77 *
78 * RETURN: Status
79 *
80 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
81 * an installed default region handler.
82 *
83 ******************************************************************************/
84
87 void)
88{
90 UINT32 i;
91
92
93 ACPI_FUNCTION_TRACE (EvInitializeOpRegions);
94
95
97 if (ACPI_FAILURE (Status))
98 {
100 }
101
102 /* Run the _REG methods for OpRegions in each default address space */
103
104 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
105 {
106 /*
107 * Make sure the installed handler is the DEFAULT handler. If not the
108 * default, the _REG methods will have already been run (when the
109 * handler was installed)
110 */
111 if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode,
113 {
114 AcpiEvExecuteRegMethods (AcpiGbl_RootNode,
116 }
117 }
118
121}
122
123
124/*******************************************************************************
125 *
126 * FUNCTION: AcpiEvAddressSpaceDispatch
127 *
128 * PARAMETERS: RegionObj - Internal region object
129 * FieldObj - Corresponding field. Can be NULL.
130 * Function - Read or Write operation
131 * RegionOffset - Where in the region to read or write
132 * BitWidth - Field width in bits (8, 16, 32, or 64)
133 * Value - Pointer to in or out value, must be
134 * a full 64-bit integer
135 *
136 * RETURN: Status
137 *
138 * DESCRIPTION: Dispatch an address space or operation region access to
139 * a previously installed handler.
140 *
141 * NOTE: During early initialization, we always install the default region
142 * handlers for Memory, I/O and PCI_Config. This ensures that these operation
143 * region address spaces are always available as per the ACPI specification.
144 * This is especially needed in order to support the execution of
145 * module-level AML code during loading of the ACPI tables.
146 *
147 ******************************************************************************/
148
151 ACPI_OPERAND_OBJECT *RegionObj,
152 ACPI_OPERAND_OBJECT *FieldObj,
154 UINT32 RegionOffset,
155 UINT32 BitWidth,
156 UINT64 *Value)
157{
160 ACPI_ADR_SPACE_SETUP RegionSetup;
161 ACPI_OPERAND_OBJECT *HandlerDesc;
162 ACPI_OPERAND_OBJECT *RegionObj2;
163 void *RegionContext = NULL;
165 ACPI_MUTEX ContextMutex;
166 BOOLEAN ContextLocked;
167 ACPI_PHYSICAL_ADDRESS Address;
168
169
170 ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
171
172
173 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
174 if (!RegionObj2)
175 {
177 }
178
179 /* Ensure that there is a handler associated with this region */
180
181 HandlerDesc = RegionObj->Region.Handler;
182 if (!HandlerDesc)
183 {
185 "No handler for Region [%4.4s] (%p) [%s]",
186 AcpiUtGetNodeName (RegionObj->Region.Node),
187 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
188
190 }
191
192 Context = HandlerDesc->AddressSpace.Context;
193 ContextMutex = HandlerDesc->AddressSpace.ContextMutex;
194 ContextLocked = FALSE;
195
196 /*
197 * It may be the case that the region has never been initialized.
198 * Some types of regions require special init code
199 */
200 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
201 {
202 /* This region has not been initialized yet, do it */
203
204 RegionSetup = HandlerDesc->AddressSpace.Setup;
205 if (!RegionSetup)
206 {
207 /* No initialization routine, exit with error */
208
210 "No init routine for region(%p) [%s]",
211 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
213 }
214
216 {
217 ACPI_PCC_INFO *Ctx = HandlerDesc->AddressSpace.Context;
218
219 Ctx->InternalBuffer = FieldObj->Field.InternalPccBuffer;
220 Ctx->Length = (UINT16) RegionObj->Region.Length;
221 Ctx->SubspaceId = (UINT8) RegionObj->Region.Address;
222 }
223
225 {
226 ACPI_FFH_INFO *Ctx = HandlerDesc->AddressSpace.Context;
227
228 Ctx->Length = RegionObj->Region.Length;
229 Ctx->Offset = RegionObj->Region.Address;
230 }
231
232 /*
233 * We must exit the interpreter because the region setup will
234 * potentially execute control methods (for example, the _REG method
235 * for this region)
236 */
238
239 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
240 Context, &RegionContext);
241
242 /* Re-enter the interpreter */
243
245
246 /* Check for failure of the Region Setup */
247
248 if (ACPI_FAILURE (Status))
249 {
251 "During region initialization: [%s]",
252 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
254 }
255
256 /* Region initialization may have been completed by RegionSetup */
257
258 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
259 {
260 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
261
262 /*
263 * Save the returned context for use in all accesses to
264 * the handler for this particular region
265 */
266 if (!(RegionObj2->Extra.RegionContext))
267 {
268 RegionObj2->Extra.RegionContext = RegionContext;
269 }
270 }
271 }
272
273 /* We have everything we need, we can invoke the address space handler */
274
275 Handler = HandlerDesc->AddressSpace.Handler;
276 Address = (RegionObj->Region.Address + RegionOffset);
277
279 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
280 &RegionObj->Region.Handler->AddressSpace, Handler,
282 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
283
284 if (!(HandlerDesc->AddressSpace.HandlerFlags &
286 {
287 /*
288 * For handlers other than the default (supplied) handlers, we must
289 * exit the interpreter because the handler *might* block -- we don't
290 * know what it will do, so we can't hold the lock on the interpreter.
291 */
293 }
294
295 /*
296 * Special handling for GenericSerialBus and GeneralPurposeIo:
297 * There are three extra parameters that must be passed to the
298 * handler via the context:
299 * 1) Connection buffer, a resource template from Connection() op
300 * 2) Length of the above buffer
301 * 3) Actual access length from the AccessAs() op
302 *
303 * Since we pass these extra parameters via the context, which is
304 * shared between threads, we must lock the context to avoid these
305 * parameters being changed from another thread before the handler
306 * has completed running.
307 *
308 * In addition, for GeneralPurposeIo, the Address and BitWidth fields
309 * are defined as follows:
310 * 1) Address is the pin number index of the field (bit offset from
311 * the previous Connection)
312 * 2) BitWidth is the actual bit length of the field (number of pins)
313 */
314 if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS ||
315 RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) &&
316 Context &&
317 FieldObj)
318 {
319
321 if (ACPI_FAILURE (Status))
322 {
323 goto ReEnterInterpreter;
324 }
325
326 ContextLocked = TRUE;
327
328 /* Get the Connection (ResourceTemplate) buffer */
329
330 Context->Connection = FieldObj->Field.ResourceBuffer;
331 Context->Length = FieldObj->Field.ResourceLength;
332 Context->AccessLength = FieldObj->Field.AccessLength;
333
334 if (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)
335 {
336 Address = FieldObj->Field.PinNumberIndex;
337 BitWidth = FieldObj->Field.BitLength;
338 }
339 }
340
341 /* Call the handler */
342
343 Status = Handler (Function, Address, BitWidth, Value, Context,
344 RegionObj2->Extra.RegionContext);
345
346 if (ContextLocked)
347 {
348 AcpiOsReleaseMutex (ContextMutex);
349 }
350
351 if (ACPI_FAILURE (Status))
352 {
353 ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
354 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
355
356 /*
357 * Special case for an EC timeout. These are seen so frequently
358 * that an additional error message is helpful
359 */
360 if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
361 (Status == AE_TIME))
362 {
364 "Timeout from EC hardware or EC device driver"));
365 }
366 }
367
368ReEnterInterpreter:
369 if (!(HandlerDesc->AddressSpace.HandlerFlags &
371 {
372 /*
373 * We just returned from a non-default handler, we must re-enter the
374 * interpreter
375 */
377 }
378
380}
381
382
383/*******************************************************************************
384 *
385 * FUNCTION: AcpiEvDetachRegion
386 *
387 * PARAMETERS: RegionObj - Region Object
388 * AcpiNsIsLocked - Namespace Region Already Locked?
389 *
390 * RETURN: None
391 *
392 * DESCRIPTION: Break the association between the handler and the region
393 * this is a two way association.
394 *
395 ******************************************************************************/
396
397void
399 ACPI_OPERAND_OBJECT *RegionObj,
400 BOOLEAN AcpiNsIsLocked)
401{
402 ACPI_OPERAND_OBJECT *HandlerObj;
403 ACPI_OPERAND_OBJECT *ObjDesc;
404 ACPI_OPERAND_OBJECT *StartDesc;
405 ACPI_OPERAND_OBJECT **LastObjPtr;
406 ACPI_ADR_SPACE_SETUP RegionSetup;
407 void **RegionContext;
408 ACPI_OPERAND_OBJECT *RegionObj2;
410
411
412 ACPI_FUNCTION_TRACE (EvDetachRegion);
413
414
415 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
416 if (!RegionObj2)
417 {
419 }
420 RegionContext = &RegionObj2->Extra.RegionContext;
421
422 /* Get the address handler from the region object */
423
424 HandlerObj = RegionObj->Region.Handler;
425 if (!HandlerObj)
426 {
427 /* This region has no handler, all done */
428
430 }
431
432 /* Find this region in the handler's list */
433
434 ObjDesc = HandlerObj->AddressSpace.RegionList;
435 StartDesc = ObjDesc;
436 LastObjPtr = &HandlerObj->AddressSpace.RegionList;
437
438 while (ObjDesc)
439 {
440 /* Is this the correct Region? */
441
442 if (ObjDesc == RegionObj)
443 {
445 "Removing Region %p from address handler %p\n",
446 RegionObj, HandlerObj));
447
448 /* This is it, remove it from the handler's list */
449
450 *LastObjPtr = ObjDesc->Region.Next;
451 ObjDesc->Region.Next = NULL; /* Must clear field */
452
453 if (AcpiNsIsLocked)
454 {
456 if (ACPI_FAILURE (Status))
457 {
459 }
460 }
461
462 /* Now stop region accesses by executing the _REG method */
463
465 if (ACPI_FAILURE (Status))
466 {
467 ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
468 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
469 }
470
471 if (AcpiNsIsLocked)
472 {
474 if (ACPI_FAILURE (Status))
475 {
477 }
478 }
479
480 /*
481 * If the region has been activated, call the setup handler with
482 * the deactivate notification
483 */
484 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
485 {
486 RegionSetup = HandlerObj->AddressSpace.Setup;
487 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
488 HandlerObj->AddressSpace.Context, RegionContext);
489
490 /*
491 * RegionContext should have been released by the deactivate
492 * operation. We don't need access to it anymore here.
493 */
494 if (RegionContext)
495 {
496 *RegionContext = NULL;
497 }
498
499 /* Init routine may fail, Just ignore errors */
500
501 if (ACPI_FAILURE (Status))
502 {
504 "from region handler - deactivate, [%s]",
505 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
506 }
507
508 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
509 }
510
511 /*
512 * Remove handler reference in the region
513 *
514 * NOTE: this doesn't mean that the region goes away, the region
515 * is just inaccessible as indicated to the _REG method
516 *
517 * If the region is on the handler's list, this must be the
518 * region's handler
519 */
520 RegionObj->Region.Handler = NULL;
521 AcpiUtRemoveReference (HandlerObj);
522
524 }
525
526 /* Walk the linked list of handlers */
527
528 LastObjPtr = &ObjDesc->Region.Next;
529 ObjDesc = ObjDesc->Region.Next;
530
531 /* Prevent infinite loop if list is corrupted */
532
533 if (ObjDesc == StartDesc)
534 {
536 "Circular handler list in region object %p",
537 RegionObj));
539 }
540 }
541
542 /* If we get here, the region was not in the handler's region list */
543
545 "Cannot remove region %p from address handler %p\n",
546 RegionObj, HandlerObj));
547
549}
550
551
552/*******************************************************************************
553 *
554 * FUNCTION: AcpiEvAttachRegion
555 *
556 * PARAMETERS: HandlerObj - Handler Object
557 * RegionObj - Region Object
558 * AcpiNsIsLocked - Namespace Region Already Locked?
559 *
560 * RETURN: None
561 *
562 * DESCRIPTION: Create the association between the handler and the region
563 * this is a two way association.
564 *
565 ******************************************************************************/
566
569 ACPI_OPERAND_OBJECT *HandlerObj,
570 ACPI_OPERAND_OBJECT *RegionObj,
571 BOOLEAN AcpiNsIsLocked)
572{
573
574 ACPI_FUNCTION_TRACE (EvAttachRegion);
575
576
577 /* Install the region's handler */
578
579 if (RegionObj->Region.Handler)
580 {
582 }
583
585 "Adding Region [%4.4s] %p to address handler %p [%s]\n",
586 AcpiUtGetNodeName (RegionObj->Region.Node),
587 RegionObj, HandlerObj,
588 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
589
590 /* Link this region to the front of the handler's list */
591
592 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
593 HandlerObj->AddressSpace.RegionList = RegionObj;
594 RegionObj->Region.Handler = HandlerObj;
595 AcpiUtAddReference (HandlerObj);
596
598}
599
600
601/*******************************************************************************
602 *
603 * FUNCTION: AcpiEvExecuteRegMethod
604 *
605 * PARAMETERS: RegionObj - Region object
606 * Function - Passed to _REG: On (1) or Off (0)
607 *
608 * RETURN: Status
609 *
610 * DESCRIPTION: Execute _REG method for a region
611 *
612 ******************************************************************************/
613
616 ACPI_OPERAND_OBJECT *RegionObj,
618{
621 ACPI_OPERAND_OBJECT *RegionObj2;
622 const ACPI_NAME *RegNamePtr = ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__REG);
623 ACPI_NAMESPACE_NODE *MethodNode;
626
627
628 ACPI_FUNCTION_TRACE (EvExecuteRegMethod);
629
630
631 if (!AcpiGbl_NamespaceInitialized ||
632 RegionObj->Region.Handler == NULL)
633 {
635 }
636
637 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
638 if (!RegionObj2)
639 {
641 }
642
643 /*
644 * Find any "_REG" method associated with this region definition.
645 * The method should always be updated as this function may be
646 * invoked after a namespace change.
647 */
648 Node = RegionObj->Region.Node->Parent;
650 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
651 if (ACPI_SUCCESS (Status))
652 {
653 /*
654 * The _REG method is optional and there can be only one per
655 * region definition. This will be executed when the handler is
656 * attached or removed.
657 */
658 RegionObj2->Extra.Method_REG = MethodNode;
659 }
660 if (RegionObj2->Extra.Method_REG == NULL)
661 {
663 }
664
665 /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */
666
667 if ((Function == ACPI_REG_CONNECT &&
668 RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) ||
670 !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED)))
671 {
673 }
674
675 /* Allocate and initialize the evaluation information block */
676
678 if (!Info)
679 {
681 }
682
683 Info->PrefixNode = RegionObj2->Extra.Method_REG;
684 Info->RelativePathname = NULL;
685 Info->Parameters = Args;
687
688 /*
689 * The _REG method has two arguments:
690 *
691 * Arg0 - Integer:
692 * Operation region space ID Same value as RegionObj->Region.SpaceId
693 *
694 * Arg1 - Integer:
695 * connection status 1 for connecting the handler, 0 for disconnecting
696 * the handler (Passed as a parameter)
697 */
699 if (!Args[0])
700 {
702 goto Cleanup1;
703 }
704
706 if (!Args[1])
707 {
709 goto Cleanup2;
710 }
711
712 Args[2] = NULL; /* Terminate list */
713
714 /* Execute the method, no return value */
715
717 AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL));
718
721
722 if (ACPI_FAILURE (Status))
723 {
724 goto Cleanup2;
725 }
726
728 {
729 RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED;
730 }
731 else
732 {
733 RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED;
734 }
735
736Cleanup2:
738
739Cleanup1:
740 ACPI_FREE (Info);
742}
743
744
745/*******************************************************************************
746 *
747 * FUNCTION: AcpiEvExecuteRegMethods
748 *
749 * PARAMETERS: Node - Namespace node for the device
750 * SpaceId - The address space ID
751 * Function - Passed to _REG: On (1) or Off (0)
752 *
753 * RETURN: None
754 *
755 * DESCRIPTION: Run all _REG methods for the input Space ID;
756 * Note: assumes namespace is locked, or system init time.
757 *
758 ******************************************************************************/
759
760void
765{
767
768
769 ACPI_FUNCTION_TRACE (EvExecuteRegMethods);
770
771 /*
772 * These address spaces do not need a call to _REG, since the ACPI
773 * specification defines them as: "must always be accessible". Since
774 * they never change state (never become unavailable), no need to ever
775 * call _REG on them. Also, a DataTable is not a "real" address space,
776 * so do not call _REG. September 2018.
777 */
781 {
783 }
784
785 Info.SpaceId = SpaceId;
786 Info.Function = Function;
787 Info.RegRunCount = 0;
788
790 " Running _REG methods for SpaceId %s\n",
791 AcpiUtGetRegionName (Info.SpaceId)));
792
793 /*
794 * Run all _REG methods for all Operation Regions for this space ID. This
795 * is a separate walk in order to handle any interdependencies between
796 * regions and _REG methods. (i.e. handlers must be installed for all
797 * regions of this Space ID before we can run any _REG methods)
798 */
801
802 /*
803 * Special case for EC and GPIO: handle "orphan" _REG methods with
804 * no region.
805 */
807 {
809 }
810
812 " Executed %u _REG methods for SpaceId %s\n",
813 Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));
814
816}
817
818
819/*******************************************************************************
820 *
821 * FUNCTION: AcpiEvRegRun
822 *
823 * PARAMETERS: WalkNamespace callback
824 *
825 * DESCRIPTION: Run _REG method for region objects of the requested spaceID
826 *
827 ******************************************************************************/
828
829static ACPI_STATUS
831 ACPI_HANDLE ObjHandle,
833 void *Context,
834 void **ReturnValue)
835{
836 ACPI_OPERAND_OBJECT *ObjDesc;
840
841
843
844 /* Convert and validate the device handle */
845
846 Node = AcpiNsValidateHandle (ObjHandle);
847 if (!Node)
848 {
849 return (AE_BAD_PARAMETER);
850 }
851
852 /*
853 * We only care about regions and objects that are allowed to have
854 * address space handlers
855 */
856 if ((Node->Type != ACPI_TYPE_REGION) &&
857 (Node != AcpiGbl_RootNode))
858 {
859 return (AE_OK);
860 }
861
862 /* Check for an existing internal object */
863
864 ObjDesc = AcpiNsGetAttachedObject (Node);
865 if (!ObjDesc)
866 {
867 /* No object, just exit */
868
869 return (AE_OK);
870 }
871
872 /* Object is a Region */
873
874 if (ObjDesc->Region.SpaceId != Info->SpaceId)
875 {
876 /* This region is for a different address space, just ignore it */
877
878 return (AE_OK);
879 }
880
881 Info->RegRunCount++;
882 Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function);
883 return (Status);
884}
885
886
887/*******************************************************************************
888 *
889 * FUNCTION: AcpiEvExecuteOrphanRegMethod
890 *
891 * PARAMETERS: DeviceNode - Namespace node for an ACPI device
892 * SpaceId - The address space ID
893 *
894 * RETURN: None
895 *
896 * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
897 * device. This is a _REG method that has no corresponding region
898 * within the device's scope. ACPI tables depending on these
899 * "orphan" _REG methods have been seen for both EC and GPIO
900 * Operation Regions. Presumably the Windows ACPI implementation
901 * always calls the _REG method independent of the presence of
902 * an actual Operation Region with the correct address space ID.
903 *
904 * MUTEX: Assumes the namespace is locked
905 *
906 ******************************************************************************/
907
908static void
912{
913 ACPI_HANDLE RegMethod;
914 ACPI_NAMESPACE_NODE *NextNode;
917 ACPI_OBJECT Objects[2];
918
919
920 ACPI_FUNCTION_TRACE (EvExecuteOrphanRegMethod);
921
922
923 if (!DeviceNode)
924 {
926 }
927
928 /* Namespace is currently locked, must release */
929
931
932 /* Get a handle to a _REG method immediately under the EC device */
933
935 if (ACPI_FAILURE (Status))
936 {
937 goto Exit; /* There is no _REG method present */
938 }
939
940 /*
941 * Execute the _REG method only if there is no Operation Region in
942 * this scope with the Embedded Controller space ID. Otherwise, it
943 * will already have been executed. Note, this allows for Regions
944 * with other space IDs to be present; but the code below will then
945 * execute the _REG method with the EmbeddedControl SpaceID argument.
946 */
947 NextNode = AcpiNsGetNextNode (DeviceNode, NULL);
948 while (NextNode)
949 {
950 if ((NextNode->Type == ACPI_TYPE_REGION) &&
951 (NextNode->Object) &&
952 (NextNode->Object->Region.SpaceId == SpaceId))
953 {
954 goto Exit; /* Do not execute the _REG */
955 }
956
957 NextNode = AcpiNsGetNextNode (DeviceNode, NextNode);
958 }
959
960 /* Evaluate the _REG(SpaceId,Connect) method */
961
962 Args.Count = 2;
963 Args.Pointer = Objects;
964 Objects[0].Type = ACPI_TYPE_INTEGER;
965 Objects[0].Integer.Value = SpaceId;
966 Objects[1].Type = ACPI_TYPE_INTEGER;
967 Objects[1].Integer.Value = ACPI_REG_CONNECT;
968
969 (void) AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
970
971Exit:
972 /* We ignore all errors from above, don't care */
973
976}
@ DeviceNode
Definition: Node.h:9
unsigned short UINT16
unsigned char BOOLEAN
unsigned long long UINT64
unsigned char UINT8
unsigned int UINT32
char ** Args
Definition: acdebug.h:353
UINT32 void void ** ReturnValue
Definition: acevents.h:216
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_ALREADY_EXISTS
Definition: acexcep.h:115
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_NOT_EXIST
Definition: acexcep.h:114
#define AE_TIME
Definition: acexcep.h:125
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_MTX_NAMESPACE
Definition: aclocal.h:85
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define METHOD_NAME__REG
Definition: acnames.h:70
ACPI_OPERAND_OBJECT * AcpiNsGetSecondaryObject(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: nsobject.c:346
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
#define ACPI_NS_WALK_UNLOCK
Definition: acnamesp.h:77
ACPI_NAMESPACE_NODE * AcpiNsValidateHandle(ACPI_HANDLE Handle)
Definition: nsutils.c:655
ACPI_STATUS AcpiNsSearchOneScope(UINT32 EntryName, ACPI_NAMESPACE_NODE *Node, ACPI_OBJECT_TYPE Type, ACPI_NAMESPACE_NODE **RetNode)
Definition: nssearch.c:98
ACPI_STATUS AcpiNsWalkNamespace(ACPI_OBJECT_TYPE Type, ACPI_HANDLE StartObject, UINT32 MaxDepth, UINT32 Flags, ACPI_WALK_CALLBACK DescendingCallback, ACPI_WALK_CALLBACK AscendingCallback, void *Context, void **ReturnValue)
Definition: nswalk.c:190
ACPI_NAMESPACE_NODE * AcpiNsGetNextNode(ACPI_NAMESPACE_NODE *Parent, ACPI_NAMESPACE_NODE *Child)
Definition: nswalk.c:72
ACPI_STATUS AcpiNsEvaluate(ACPI_EVALUATE_INFO *Info)
Definition: nseval.c:82
#define AOPOBJ_REG_CONNECTED
Definition: acobject.h:98
#define AOPOBJ_SETUP_COMPLETE
Definition: acobject.h:99
#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED
Definition: acobject.h:426
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_DEBUG_EXEC(a)
Definition: acoutput.h:477
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
#define return_VOID
Definition: acoutput.h:495
#define ACPI_DB_OPREGION
Definition: acoutput.h:167
#define ACPI_DB_NAMES
Definition: acoutput.h:166
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE SpaceId
Definition: acpixf.h:832
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:672
#define ACPI_IGNORE_RETURN_VALUE
Definition: acstruct.h:231
#define ACPI_ADR_SPACE_EC
Definition: actypes.h:864
#define ACPI_REGION_DEACTIVATE
Definition: actypes.h:1246
#define ACPI_MUTEX
Definition: actypes.h:273
UINT8 ACPI_ADR_SPACE_TYPE
Definition: actypes.h:859
#define ACPI_REGION_ACTIVATE
Definition: actypes.h:1245
#define AcpiOsAcquireMutex(Handle, Time)
Definition: actypes.h:276
#define ACPI_REG_CONNECT
Definition: actypes.h:890
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:862
#define ACPI_TYPE_REGION
Definition: actypes.h:697
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_ADR_SPACE_PLATFORM_COMM
Definition: actypes.h:871
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:861
#define ACPI_TYPE_ANY
Definition: actypes.h:687
ACPI_STATUS(* ACPI_ADR_SPACE_SETUP)(ACPI_HANDLE RegionHandle, UINT32 Function, void *HandlerContext, void **RegionContext)
Definition: actypes.h:1239
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:870
#define AcpiOsReleaseMutex(Handle)
Definition: actypes.h:277
ACPI_STATUS(* ACPI_ADR_SPACE_HANDLER)(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: actypes.h:1203
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_ADR_SPACE_FIXED_HARDWARE
Definition: actypes.h:885
#define ACPI_ADR_SPACE_DATA_TABLE
Definition: actypes.h:884
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
#define ACPI_REG_DISCONNECT
Definition: actypes.h:889
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
UINT32 ACPI_NAME
Definition: actypes.h:461
#define ACPI_TYPE_METHOD
Definition: actypes.h:695
#define ACPI_ADR_SPACE_GPIO
Definition: actypes.h:869
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:125
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
ACPI_OPERAND_OBJECT * AcpiUtCreateIntegerObject(UINT64 Value)
Definition: utobject.c:223
void AcpiUtAddReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:752
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
#define ACPI_NUM_DEFAULT_SPACES
Definition: acconfig.h:202
BOOLEAN AcpiEvHasDefaultHandler(ACPI_NAMESPACE_NODE *Node, ACPI_ADR_SPACE_TYPE SpaceId)
Definition: evhandler.c:166
ACPI_STATUS AcpiEvExecuteRegMethod(ACPI_OPERAND_OBJECT *RegionObj, UINT32 Function)
Definition: evregion.c:615
ACPI_STATUS AcpiEvAddressSpaceDispatch(ACPI_OPERAND_OBJECT *RegionObj, ACPI_OPERAND_OBJECT *FieldObj, UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, UINT64 *Value)
Definition: evregion.c:150
void AcpiEvExecuteRegMethods(ACPI_NAMESPACE_NODE *Node, ACPI_ADR_SPACE_TYPE SpaceId, UINT32 Function)
Definition: evregion.c:761
ACPI_STATUS AcpiEvAttachRegion(ACPI_OPERAND_OBJECT *HandlerObj, ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:568
void AcpiEvDetachRegion(ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:398
static void AcpiEvExecuteOrphanRegMethod(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_ADR_SPACE_TYPE SpaceId)
Definition: evregion.c:909
static ACPI_STATUS AcpiEvRegRun(ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue)
Definition: evregion.c:830
UINT8 AcpiGbl_DefaultAddressSpaces[]
Definition: evhandler.c:66
ACPI_STATUS AcpiEvInitializeOpRegions(void)
Definition: evregion.c:86
void AcpiExExitInterpreter(void)
Definition: exutils.c:139
void AcpiExEnterInterpreter(void)
Definition: exutils.c:91
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ACPI_STATUS AcpiEvaluateObject(ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer)
Definition: nsxfeval.c:217
ACPI_STATUS AcpiGetHandle(ACPI_HANDLE Parent, ACPI_STRING Pathname, ACPI_HANDLE *RetHandle)
Definition: nsxfname.c:85
static WCHAR Address[46]
Definition: ping.c:68
static void Exit(void)
Definition: sock.c:1330
UINT64 Offset
Definition: actypes.h:1234
UINT64 Length
Definition: actypes.h:1235
union acpi_operand_object * Object
Definition: aclocal.h:187
struct acpi_namespace_node * Parent
Definition: aclocal.h:192
union acpi_operand_object * RegionList
Definition: acobject.h:419
ACPI_ADR_SPACE_HANDLER Handler
Definition: acobject.h:414
ACPI_MUTEX ContextMutex
Definition: acobject.h:417
ACPI_ADR_SPACE_SETUP Setup
Definition: acobject.h:418
ACPI_OBJECT_COMMON_HEADER ACPI_NAMESPACE_NODE * Method_REG
Definition: acobject.h:481
void * RegionContext
Definition: acobject.h:483
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO UINT16 ResourceLength
Definition: acobject.h:345
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:203
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
ACPI_PHYSICAL_ADDRESS Address
Definition: acobject.h:206
union acpi_operand_object * Handler
Definition: acobject.h:204
union acpi_operand_object * Next
Definition: acobject.h:205
UINT16 Length
Definition: actypes.h:1227
UINT8 SubspaceId
Definition: actypes.h:1226
UINT8 * InternalBuffer
Definition: actypes.h:1228
ACPI_OBJECT_TYPE Type
Definition: actypes.h:970
struct acpi_object::@622 Integer
ACPI_OBJECT_REGION_FIELD Field
Definition: acobject.h:534
ACPI_OBJECT_ADDR_HANDLER AddressSpace
Definition: acobject.h:539
ACPI_OBJECT_REGION Region
Definition: acobject.h:527
ACPI_OBJECT_EXTRA Extra
Definition: acobject.h:541
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56