ReactOS  0.4.15-dev-2155-g06f57e1
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 - 2020, 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 MERCHANTIBILITY 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 
58 static void
62 
63 
64 static ACPI_STATUS
66  ACPI_HANDLE ObjHandle,
67  UINT32 Level,
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_PHYSICAL_ADDRESS Address;
166 
167 
168  ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
169 
170 
171  RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
172  if (!RegionObj2)
173  {
175  }
176 
177  /* Ensure that there is a handler associated with this region */
178 
179  HandlerDesc = RegionObj->Region.Handler;
180  if (!HandlerDesc)
181  {
183  "No handler for Region [%4.4s] (%p) [%s]",
184  AcpiUtGetNodeName (RegionObj->Region.Node),
185  RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
186 
188  }
189 
190  Context = HandlerDesc->AddressSpace.Context;
191 
192  /*
193  * It may be the case that the region has never been initialized.
194  * Some types of regions require special init code
195  */
196  if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
197  {
198  /* This region has not been initialized yet, do it */
199 
200  RegionSetup = HandlerDesc->AddressSpace.Setup;
201  if (!RegionSetup)
202  {
203  /* No initialization routine, exit with error */
204 
206  "No init routine for region(%p) [%s]",
207  RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
209  }
210 
211  /*
212  * We must exit the interpreter because the region setup will
213  * potentially execute control methods (for example, the _REG method
214  * for this region)
215  */
217 
218  Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
219  Context, &RegionContext);
220 
221  /* Re-enter the interpreter */
222 
224 
225  /* Check for failure of the Region Setup */
226 
227  if (ACPI_FAILURE (Status))
228  {
230  "During region initialization: [%s]",
231  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
233  }
234 
235  /* Region initialization may have been completed by RegionSetup */
236 
237  if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
238  {
239  RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
240 
241  /*
242  * Save the returned context for use in all accesses to
243  * the handler for this particular region
244  */
245  if (!(RegionObj2->Extra.RegionContext))
246  {
247  RegionObj2->Extra.RegionContext = RegionContext;
248  }
249  }
250  }
251 
252  /* We have everything we need, we can invoke the address space handler */
253 
254  Handler = HandlerDesc->AddressSpace.Handler;
255  Address = (RegionObj->Region.Address + RegionOffset);
256 
257  /*
258  * Special handling for GenericSerialBus and GeneralPurposeIo:
259  * There are three extra parameters that must be passed to the
260  * handler via the context:
261  * 1) Connection buffer, a resource template from Connection() op
262  * 2) Length of the above buffer
263  * 3) Actual access length from the AccessAs() op
264  *
265  * In addition, for GeneralPurposeIo, the Address and BitWidth fields
266  * are defined as follows:
267  * 1) Address is the pin number index of the field (bit offset from
268  * the previous Connection)
269  * 2) BitWidth is the actual bit length of the field (number of pins)
270  */
271  if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) &&
272  Context &&
273  FieldObj)
274  {
275  /* Get the Connection (ResourceTemplate) buffer */
276 
277  Context->Connection = FieldObj->Field.ResourceBuffer;
278  Context->Length = FieldObj->Field.ResourceLength;
279  Context->AccessLength = FieldObj->Field.AccessLength;
280  }
281  if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) &&
282  Context &&
283  FieldObj)
284  {
285  /* Get the Connection (ResourceTemplate) buffer */
286 
287  Context->Connection = FieldObj->Field.ResourceBuffer;
288  Context->Length = FieldObj->Field.ResourceLength;
289  Context->AccessLength = FieldObj->Field.AccessLength;
290  Address = FieldObj->Field.PinNumberIndex;
291  BitWidth = FieldObj->Field.BitLength;
292  }
293 
295  "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
296  &RegionObj->Region.Handler->AddressSpace, Handler,
298  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
299 
300  if (!(HandlerDesc->AddressSpace.HandlerFlags &
302  {
303  /*
304  * For handlers other than the default (supplied) handlers, we must
305  * exit the interpreter because the handler *might* block -- we don't
306  * know what it will do, so we can't hold the lock on the interpreter.
307  */
309  }
310 
311  /* Call the handler */
312 
313  Status = Handler (Function, Address, BitWidth, Value, Context,
314  RegionObj2->Extra.RegionContext);
315 
316  if (ACPI_FAILURE (Status))
317  {
318  ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
319  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
320 
321  /*
322  * Special case for an EC timeout. These are seen so frequently
323  * that an additional error message is helpful
324  */
325  if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
326  (Status == AE_TIME))
327  {
329  "Timeout from EC hardware or EC device driver"));
330  }
331  }
332 
333  if (!(HandlerDesc->AddressSpace.HandlerFlags &
335  {
336  /*
337  * We just returned from a non-default handler, we must re-enter the
338  * interpreter
339  */
341  }
342 
344 }
345 
346 
347 /*******************************************************************************
348  *
349  * FUNCTION: AcpiEvDetachRegion
350  *
351  * PARAMETERS: RegionObj - Region Object
352  * AcpiNsIsLocked - Namespace Region Already Locked?
353  *
354  * RETURN: None
355  *
356  * DESCRIPTION: Break the association between the handler and the region
357  * this is a two way association.
358  *
359  ******************************************************************************/
360 
361 void
363  ACPI_OPERAND_OBJECT *RegionObj,
364  BOOLEAN AcpiNsIsLocked)
365 {
366  ACPI_OPERAND_OBJECT *HandlerObj;
367  ACPI_OPERAND_OBJECT *ObjDesc;
368  ACPI_OPERAND_OBJECT *StartDesc;
369  ACPI_OPERAND_OBJECT **LastObjPtr;
370  ACPI_ADR_SPACE_SETUP RegionSetup;
371  void **RegionContext;
372  ACPI_OPERAND_OBJECT *RegionObj2;
374 
375 
376  ACPI_FUNCTION_TRACE (EvDetachRegion);
377 
378 
379  RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
380  if (!RegionObj2)
381  {
382  return_VOID;
383  }
384  RegionContext = &RegionObj2->Extra.RegionContext;
385 
386  /* Get the address handler from the region object */
387 
388  HandlerObj = RegionObj->Region.Handler;
389  if (!HandlerObj)
390  {
391  /* This region has no handler, all done */
392 
393  return_VOID;
394  }
395 
396  /* Find this region in the handler's list */
397 
398  ObjDesc = HandlerObj->AddressSpace.RegionList;
399  StartDesc = ObjDesc;
400  LastObjPtr = &HandlerObj->AddressSpace.RegionList;
401 
402  while (ObjDesc)
403  {
404  /* Is this the correct Region? */
405 
406  if (ObjDesc == RegionObj)
407  {
409  "Removing Region %p from address handler %p\n",
410  RegionObj, HandlerObj));
411 
412  /* This is it, remove it from the handler's list */
413 
414  *LastObjPtr = ObjDesc->Region.Next;
415  ObjDesc->Region.Next = NULL; /* Must clear field */
416 
417  if (AcpiNsIsLocked)
418  {
420  if (ACPI_FAILURE (Status))
421  {
422  return_VOID;
423  }
424  }
425 
426  /* Now stop region accesses by executing the _REG method */
427 
429  if (ACPI_FAILURE (Status))
430  {
431  ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
432  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
433  }
434 
435  if (AcpiNsIsLocked)
436  {
438  if (ACPI_FAILURE (Status))
439  {
440  return_VOID;
441  }
442  }
443 
444  /*
445  * If the region has been activated, call the setup handler with
446  * the deactivate notification
447  */
448  if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
449  {
450  RegionSetup = HandlerObj->AddressSpace.Setup;
451  Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
452  HandlerObj->AddressSpace.Context, RegionContext);
453 
454  /*
455  * RegionContext should have been released by the deactivate
456  * operation. We don't need access to it anymore here.
457  */
458  if (RegionContext)
459  {
460  *RegionContext = NULL;
461  }
462 
463  /* Init routine may fail, Just ignore errors */
464 
465  if (ACPI_FAILURE (Status))
466  {
468  "from region handler - deactivate, [%s]",
469  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
470  }
471 
472  RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
473  }
474 
475  /*
476  * Remove handler reference in the region
477  *
478  * NOTE: this doesn't mean that the region goes away, the region
479  * is just inaccessible as indicated to the _REG method
480  *
481  * If the region is on the handler's list, this must be the
482  * region's handler
483  */
484  RegionObj->Region.Handler = NULL;
485  AcpiUtRemoveReference (HandlerObj);
486 
487  return_VOID;
488  }
489 
490  /* Walk the linked list of handlers */
491 
492  LastObjPtr = &ObjDesc->Region.Next;
493  ObjDesc = ObjDesc->Region.Next;
494 
495  /* Prevent infinite loop if list is corrupted */
496 
497  if (ObjDesc == StartDesc)
498  {
500  "Circular handler list in region object %p",
501  RegionObj));
502  return_VOID;
503  }
504  }
505 
506  /* If we get here, the region was not in the handler's region list */
507 
509  "Cannot remove region %p from address handler %p\n",
510  RegionObj, HandlerObj));
511 
512  return_VOID;
513 }
514 
515 
516 /*******************************************************************************
517  *
518  * FUNCTION: AcpiEvAttachRegion
519  *
520  * PARAMETERS: HandlerObj - Handler Object
521  * RegionObj - Region Object
522  * AcpiNsIsLocked - Namespace Region Already Locked?
523  *
524  * RETURN: None
525  *
526  * DESCRIPTION: Create the association between the handler and the region
527  * this is a two way association.
528  *
529  ******************************************************************************/
530 
533  ACPI_OPERAND_OBJECT *HandlerObj,
534  ACPI_OPERAND_OBJECT *RegionObj,
535  BOOLEAN AcpiNsIsLocked)
536 {
537 
538  ACPI_FUNCTION_TRACE (EvAttachRegion);
539 
540 
541  /* Install the region's handler */
542 
543  if (RegionObj->Region.Handler)
544  {
546  }
547 
549  "Adding Region [%4.4s] %p to address handler %p [%s]\n",
550  AcpiUtGetNodeName (RegionObj->Region.Node),
551  RegionObj, HandlerObj,
552  AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
553 
554  /* Link this region to the front of the handler's list */
555 
556  RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
557  HandlerObj->AddressSpace.RegionList = RegionObj;
558  RegionObj->Region.Handler = HandlerObj;
559  AcpiUtAddReference (HandlerObj);
560 
562 }
563 
564 
565 /*******************************************************************************
566  *
567  * FUNCTION: AcpiEvExecuteRegMethod
568  *
569  * PARAMETERS: RegionObj - Region object
570  * Function - Passed to _REG: On (1) or Off (0)
571  *
572  * RETURN: Status
573  *
574  * DESCRIPTION: Execute _REG method for a region
575  *
576  ******************************************************************************/
577 
580  ACPI_OPERAND_OBJECT *RegionObj,
582 {
585  ACPI_OPERAND_OBJECT *RegionObj2;
586  const ACPI_NAME *RegNamePtr = ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__REG);
587  ACPI_NAMESPACE_NODE *MethodNode;
590 
591 
592  ACPI_FUNCTION_TRACE (EvExecuteRegMethod);
593 
594 
595  if (!AcpiGbl_NamespaceInitialized ||
596  RegionObj->Region.Handler == NULL)
597  {
599  }
600 
601  RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
602  if (!RegionObj2)
603  {
605  }
606 
607  /*
608  * Find any "_REG" method associated with this region definition.
609  * The method should always be updated as this function may be
610  * invoked after a namespace change.
611  */
612  Node = RegionObj->Region.Node->Parent;
614  *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
615  if (ACPI_SUCCESS (Status))
616  {
617  /*
618  * The _REG method is optional and there can be only one per
619  * region definition. This will be executed when the handler is
620  * attached or removed.
621  */
622  RegionObj2->Extra.Method_REG = MethodNode;
623  }
624  if (RegionObj2->Extra.Method_REG == NULL)
625  {
627  }
628 
629  /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */
630 
631  if ((Function == ACPI_REG_CONNECT &&
632  RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) ||
634  !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED)))
635  {
637  }
638 
639  /* Allocate and initialize the evaluation information block */
640 
642  if (!Info)
643  {
645  }
646 
647  Info->PrefixNode = RegionObj2->Extra.Method_REG;
648  Info->RelativePathname = NULL;
649  Info->Parameters = Args;
651 
652  /*
653  * The _REG method has two arguments:
654  *
655  * Arg0 - Integer:
656  * Operation region space ID Same value as RegionObj->Region.SpaceId
657  *
658  * Arg1 - Integer:
659  * connection status 1 for connecting the handler, 0 for disconnecting
660  * the handler (Passed as a parameter)
661  */
662  Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId);
663  if (!Args[0])
664  {
666  goto Cleanup1;
667  }
668 
670  if (!Args[1])
671  {
673  goto Cleanup2;
674  }
675 
676  Args[2] = NULL; /* Terminate list */
677 
678  /* Execute the method, no return value */
679 
681  AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL));
682 
685 
686  if (ACPI_FAILURE (Status))
687  {
688  goto Cleanup2;
689  }
690 
691  if (Function == ACPI_REG_CONNECT)
692  {
693  RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED;
694  }
695  else
696  {
697  RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED;
698  }
699 
700 Cleanup2:
702 
703 Cleanup1:
704  ACPI_FREE (Info);
706 }
707 
708 
709 /*******************************************************************************
710  *
711  * FUNCTION: AcpiEvExecuteRegMethods
712  *
713  * PARAMETERS: Node - Namespace node for the device
714  * SpaceId - The address space ID
715  * Function - Passed to _REG: On (1) or Off (0)
716  *
717  * RETURN: None
718  *
719  * DESCRIPTION: Run all _REG methods for the input Space ID;
720  * Note: assumes namespace is locked, or system init time.
721  *
722  ******************************************************************************/
723 
724 void
729 {
731 
732 
733  ACPI_FUNCTION_TRACE (EvExecuteRegMethods);
734 
735  /*
736  * These address spaces do not need a call to _REG, since the ACPI
737  * specification defines them as: "must always be accessible". Since
738  * they never change state (never become unavailable), no need to ever
739  * call _REG on them. Also, a DataTable is not a "real" address space,
740  * so do not call _REG. September 2018.
741  */
745  {
746  return_VOID;
747  }
748 
749  Info.SpaceId = SpaceId;
750  Info.Function = Function;
751  Info.RegRunCount = 0;
752 
754  " Running _REG methods for SpaceId %s\n",
755  AcpiUtGetRegionName (Info.SpaceId)));
756 
757  /*
758  * Run all _REG methods for all Operation Regions for this space ID. This
759  * is a separate walk in order to handle any interdependencies between
760  * regions and _REG methods. (i.e. handlers must be installed for all
761  * regions of this Space ID before we can run any _REG methods)
762  */
765 
766  /*
767  * Special case for EC and GPIO: handle "orphan" _REG methods with
768  * no region.
769  */
771  {
773  }
774 
776  " Executed %u _REG methods for SpaceId %s\n",
777  Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));
778 
779  return_VOID;
780 }
781 
782 
783 /*******************************************************************************
784  *
785  * FUNCTION: AcpiEvRegRun
786  *
787  * PARAMETERS: WalkNamespace callback
788  *
789  * DESCRIPTION: Run _REG method for region objects of the requested spaceID
790  *
791  ******************************************************************************/
792 
793 static ACPI_STATUS
795  ACPI_HANDLE ObjHandle,
796  UINT32 Level,
797  void *Context,
798  void **ReturnValue)
799 {
800  ACPI_OPERAND_OBJECT *ObjDesc;
804 
805 
807 
808  /* Convert and validate the device handle */
809 
810  Node = AcpiNsValidateHandle (ObjHandle);
811  if (!Node)
812  {
813  return (AE_BAD_PARAMETER);
814  }
815 
816  /*
817  * We only care about regions and objects that are allowed to have
818  * address space handlers
819  */
820  if ((Node->Type != ACPI_TYPE_REGION) &&
821  (Node != AcpiGbl_RootNode))
822  {
823  return (AE_OK);
824  }
825 
826  /* Check for an existing internal object */
827 
828  ObjDesc = AcpiNsGetAttachedObject (Node);
829  if (!ObjDesc)
830  {
831  /* No object, just exit */
832 
833  return (AE_OK);
834  }
835 
836  /* Object is a Region */
837 
838  if (ObjDesc->Region.SpaceId != Info->SpaceId)
839  {
840  /* This region is for a different address space, just ignore it */
841 
842  return (AE_OK);
843  }
844 
845  Info->RegRunCount++;
846  Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function);
847  return (Status);
848 }
849 
850 
851 /*******************************************************************************
852  *
853  * FUNCTION: AcpiEvExecuteOrphanRegMethod
854  *
855  * PARAMETERS: DeviceNode - Namespace node for an ACPI device
856  * SpaceId - The address space ID
857  *
858  * RETURN: None
859  *
860  * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
861  * device. This is a _REG method that has no corresponding region
862  * within the device's scope. ACPI tables depending on these
863  * "orphan" _REG methods have been seen for both EC and GPIO
864  * Operation Regions. Presumably the Windows ACPI implementation
865  * always calls the _REG method independent of the presence of
866  * an actual Operation Region with the correct address space ID.
867  *
868  * MUTEX: Assumes the namespace is locked
869  *
870  ******************************************************************************/
871 
872 static void
876 {
877  ACPI_HANDLE RegMethod;
878  ACPI_NAMESPACE_NODE *NextNode;
881  ACPI_OBJECT Objects[2];
882 
883 
884  ACPI_FUNCTION_TRACE (EvExecuteOrphanRegMethod);
885 
886 
887  if (!DeviceNode)
888  {
889  return_VOID;
890  }
891 
892  /* Namespace is currently locked, must release */
893 
895 
896  /* Get a handle to a _REG method immediately under the EC device */
897 
899  if (ACPI_FAILURE (Status))
900  {
901  goto Exit; /* There is no _REG method present */
902  }
903 
904  /*
905  * Execute the _REG method only if there is no Operation Region in
906  * this scope with the Embedded Controller space ID. Otherwise, it
907  * will already have been executed. Note, this allows for Regions
908  * with other space IDs to be present; but the code below will then
909  * execute the _REG method with the EmbeddedControl SpaceID argument.
910  */
911  NextNode = AcpiNsGetNextNode (DeviceNode, NULL);
912  while (NextNode)
913  {
914  if ((NextNode->Type == ACPI_TYPE_REGION) &&
915  (NextNode->Object) &&
916  (NextNode->Object->Region.SpaceId == SpaceId))
917  {
918  goto Exit; /* Do not execute the _REG */
919  }
920 
921  NextNode = AcpiNsGetNextNode (DeviceNode, NextNode);
922  }
923 
924  /* Evaluate the _REG(SpaceId,Connect) method */
925 
926  Args.Count = 2;
927  Args.Pointer = Objects;
928  Objects[0].Type = ACPI_TYPE_INTEGER;
929  Objects[0].Integer.Value = SpaceId;
930  Objects[1].Type = ACPI_TYPE_INTEGER;
931  Objects[1].Integer.Value = ACPI_REG_CONNECT;
932 
933  (void) AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
934 
935 Exit:
936  /* We ignore all errors from above, don't care */
937 
939  return_VOID;
940 }
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
#define ACPI_NUM_DEFAULT_SPACES
Definition: acconfig.h:202
#define ACPI_FREE(a)
Definition: actypes.h:386
void AcpiUtAddReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:743
union acpi_operand_object * Object
Definition: aclocal.h:187
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
union acpi_operand_object * Handler
Definition: acobject.h:204
UINT8 ACPI_ADR_SPACE_TYPE
Definition: actypes.h:850
union acpi_operand_object * Next
Definition: acobject.h:205
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
ACPI_STATUS(* ACPI_ADR_SPACE_SETUP)(ACPI_HANDLE RegionHandle, UINT32 Function, void *HandlerContext, void **RegionContext)
Definition: actypes.h:1216
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ACPI_STATUS(* ACPI_ADR_SPACE_HANDLER)(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: actypes.h:1194
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define ACPI_NS_WALK_UNLOCK
Definition: acnamesp.h:77
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_NAMESPACE_NODE * Node
Definition: acobject.h:203
#define ACPI_REG_CONNECT
Definition: actypes.h:881
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define ACPI_TYPE_INTEGER
Definition: actypes.h:680
ACPI_STATUS AcpiNsEvaluate(ACPI_EVALUATE_INFO *Info)
Definition: nseval.c:82
#define ACPI_REG_DISCONNECT
Definition: actypes.h:880
#define ACPI_ADR_SPACE_GPIO
Definition: actypes.h:860
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
UINT8 AcpiGbl_DefaultAddressSpaces[]
Definition: evhandler.c:66
ACPI_ADR_SPACE_SETUP Setup
Definition: acobject.h:416
#define ACPI_ADR_SPACE_DATA_TABLE
Definition: actypes.h:875
#define ACPI_REGION_DEACTIVATE
Definition: actypes.h:1223
#define METHOD_NAME__REG
Definition: acnames.h:69
union acpi_operand_object * RegionList
Definition: acobject.h:417
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define AE_TIME
Definition: acexcep.h:125
struct acpi_namespace_node * Parent
Definition: aclocal.h:192
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
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
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define ACPI_DEBUG_EXEC(a)
Definition: acoutput.h:477
#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED
Definition: acobject.h:424
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
ACPI_STATUS AcpiEvAddressSpaceDispatch(ACPI_OPERAND_OBJECT *RegionObj, ACPI_OPERAND_OBJECT *FieldObj, UINT32 Function, UINT32 RegionOffset, UINT32 BitWidth, UINT64 *Value)
Definition: evregion.c:150
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:828
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
UINT32 void void ** ReturnValue
Definition: acevents.h:214
ACPI_OBJECT_EXTRA Extra
Definition: acobject.h:539
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:853
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:125
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
unsigned int UINT32
union node Node
Definition: types.h:1255
#define AOPOBJ_SETUP_COMPLETE
Definition: acobject.h:99
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
void AcpiEvDetachRegion(ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:362
unsigned char BOOLEAN
#define AE_INFO
Definition: acoutput.h:230
static WCHAR Address[46]
Definition: ping.c:68
#define ACPI_DB_OPREGION
Definition: acoutput.h:167
char ** Args
Definition: acdebug.h:353
ACPI_ADR_SPACE_HANDLER Handler
Definition: acobject.h:413
ACPI_OBJECT_REGION Region
Definition: acobject.h:525
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
ACPI_STATUS AcpiNsSearchOneScope(UINT32 EntryName, ACPI_NAMESPACE_NODE *Node, ACPI_OBJECT_TYPE Type, ACPI_NAMESPACE_NODE **RetNode)
Definition: nssearch.c:98
static ACPI_STATUS AcpiEvRegRun(ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue)
Definition: evregion.c:794
#define ACPI_TYPE_METHOD
Definition: actypes.h:687
#define ACPI_ADR_SPACE_EC
Definition: actypes.h:855
static void Exit(void)
Definition: sock.c:1331
#define AE_ALREADY_EXISTS
Definition: acexcep.h:115
#define ACPI_UINT32_MAX
Definition: actypes.h:66
ACPI_OPERAND_OBJECT * AcpiUtCreateIntegerObject(UINT64 Value)
Definition: utobject.c:223
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
ACPI_STATUS AcpiGetHandle(ACPI_HANDLE Parent, ACPI_STRING Pathname, ACPI_HANDLE *RetHandle)
Definition: nsxfname.c:85
Definition: Node.h:9
#define return_VOID
Definition: acoutput.h:495
static void AcpiEvExecuteOrphanRegMethod(ACPI_NAMESPACE_NODE *DeviceNode, ACPI_ADR_SPACE_TYPE SpaceId)
Definition: evregion.c:873
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:861
#define AOPOBJ_REG_CONNECTED
Definition: acobject.h:98
#define AE_NOT_EXIST
Definition: acexcep.h:114
ACPI_OBJECT_ADDR_HANDLER AddressSpace
Definition: acobject.h:537
#define ACPI_TYPE_ANY
Definition: actypes.h:679
UINT32 ACPI_NAME
Definition: actypes.h:461
ACPI_STATUS AcpiEvAttachRegion(ACPI_OPERAND_OBJECT *HandlerObj, ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:532
ACPI_OBJECT_COMMON_HEADER ACPI_NAMESPACE_NODE * Method_REG
Definition: acobject.h:479
ACPI_STATUS AcpiEvExecuteRegMethod(ACPI_OPERAND_OBJECT *RegionObj, UINT32 Function)
Definition: evregion.c:579
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:668
void AcpiEvExecuteRegMethods(ACPI_NAMESPACE_NODE *Node, ACPI_ADR_SPACE_TYPE SpaceId, UINT32 Function)
Definition: evregion.c:725
void AcpiExExitInterpreter(void)
Definition: exutils.c:139
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
void AcpiExEnterInterpreter(void)
Definition: exutils.c:91
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
ACPI_STATUS AcpiEvaluateObject(ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer)
Definition: nsxfeval.c:217
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_DB_NAMES
Definition: acoutput.h:166
ACPI_OBJECT_COMMON Common
Definition: acobject.h:517
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:781
#define NULL
Definition: types.h:112
ACPI_STATUS AcpiEvInitializeOpRegions(void)
Definition: evregion.c:86
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO UINT16 ResourceLength
Definition: acobject.h:344
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
struct tagContext Context
Definition: acpixf.h:1034
ACPI_OBJECT_REGION_FIELD Field
Definition: acobject.h:532
ACPI_PHYSICAL_ADDRESS Address
Definition: acobject.h:206
#define ACPI_TYPE_REGION
Definition: actypes.h:689
ACPI_NAMESPACE_NODE * AcpiNsGetNextNode(ACPI_NAMESPACE_NODE *Parent, ACPI_NAMESPACE_NODE *Child)
Definition: nswalk.c:72
#define ACPI_REGION_ACTIVATE
Definition: actypes.h:1222
void * RegionContext
Definition: acobject.h:481
ACPI_NAMESPACE_NODE * AcpiNsValidateHandle(ACPI_HANDLE Handle)
Definition: nsutils.c:655
#define ACPI_IGNORE_RETURN_VALUE
Definition: acstruct.h:231
#define ACPI_ADR_SPACE_SYSTEM_MEMORY
Definition: actypes.h:852
unsigned long long UINT64
ACPI_OBJECT_TYPE Type
Definition: actypes.h:961
#define ACPI_MTX_NAMESPACE
Definition: aclocal.h:85
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
unsigned char UINT8
#define AE_OK
Definition: acexcep.h:97
BOOLEAN AcpiEvHasDefaultHandler(ACPI_NAMESPACE_NODE *Node, ACPI_ADR_SPACE_TYPE SpaceId)
Definition: evhandler.c:166
struct acpi_object::@592 Integer
ACPI_OPERAND_OBJECT * AcpiNsGetSecondaryObject(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: nsobject.c:346
Definition: dlist.c:348