ReactOS  0.4.15-dev-5608-gafb953a
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 
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_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 
215  if (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM)
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 
224  if (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_FIXED_HARDWARE)
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 
320  Status = AcpiOsAcquireMutex (ContextMutex, ACPI_WAIT_FOREVER);
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 
368 ReEnterInterpreter:
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 
397 void
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  {
418  return_VOID;
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 
429  return_VOID;
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  {
458  return_VOID;
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  {
476  return_VOID;
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 
523  return_VOID;
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));
538  return_VOID;
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 
548  return_VOID;
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  */
698  Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId);
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 
727  if (Function == ACPI_REG_CONNECT)
728  {
729  RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED;
730  }
731  else
732  {
733  RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED;
734  }
735 
736 Cleanup2:
738 
739 Cleanup1:
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 
760 void
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  {
782  return_VOID;
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 
815  return_VOID;
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 
829 static ACPI_STATUS
831  ACPI_HANDLE ObjHandle,
832  UINT32 Level,
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 
908 static 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  {
925  return_VOID;
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 
971 Exit:
972  /* We ignore all errors from above, don't care */
973 
975  return_VOID;
976 }
#define ACPI_EXCEPTION(plist)
Definition: acoutput.h:239
UINT8 * InternalBuffer
Definition: actypes.h:1228
#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:752
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:859
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:1239
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:1203
_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:890
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
ACPI_MUTEX ContextMutex
Definition: acobject.h:417
#define TRUE
Definition: types.h:120
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
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
ACPI_STATUS AcpiNsEvaluate(ACPI_EVALUATE_INFO *Info)
Definition: nseval.c:82
#define ACPI_REG_DISCONNECT
Definition: actypes.h:889
#define ACPI_ADR_SPACE_GPIO
Definition: actypes.h:869
struct acpi_object::@600 Integer
ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
Definition: osl.c:306
_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:418
#define ACPI_ADR_SPACE_DATA_TABLE
Definition: actypes.h:884
#define ACPI_REGION_DEACTIVATE
Definition: actypes.h:1246
#define METHOD_NAME__REG
Definition: acnames.h:70
union acpi_operand_object * RegionList
Definition: acobject.h:419
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:426
#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_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
UINT64 Offset
Definition: actypes.h:1234
UINT32 void void ** ReturnValue
Definition: acevents.h:214
ACPI_OBJECT_EXTRA Extra
Definition: acobject.h:541
#define ACPI_ADR_SPACE_SYSTEM_IO
Definition: actypes.h:862
const char * AcpiUtGetRegionName(UINT8 SpaceId)
Definition: utdecode.c:125
#define FALSE
Definition: types.h:117
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
#define ACPI_ADR_SPACE_PLATFORM_COMM
Definition: actypes.h:871
void AcpiEvDetachRegion(ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:398
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:414
ACPI_OBJECT_REGION Region
Definition: acobject.h:527
_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:830
#define ACPI_TYPE_METHOD
Definition: actypes.h:695
#define ACPI_ADR_SPACE_EC
Definition: actypes.h:864
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
#define ACPI_WAIT_FOREVER
Definition: actypes.h:501
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:909
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:870
#define AOPOBJ_REG_CONNECTED
Definition: acobject.h:98
#define AE_NOT_EXIST
Definition: acexcep.h:114
UINT8 SubspaceId
Definition: actypes.h:1226
ACPI_OBJECT_ADDR_HANDLER AddressSpace
Definition: acobject.h:539
#define ACPI_TYPE_ANY
Definition: actypes.h:687
UINT32 ACPI_NAME
Definition: actypes.h:461
ACPI_STATUS AcpiEvAttachRegion(ACPI_OPERAND_OBJECT *HandlerObj, ACPI_OPERAND_OBJECT *RegionObj, BOOLEAN AcpiNsIsLocked)
Definition: evregion.c:568
ACPI_OBJECT_COMMON_HEADER ACPI_NAMESPACE_NODE * Method_REG
Definition: acobject.h:481
ACPI_STATUS AcpiEvExecuteRegMethod(ACPI_OPERAND_OBJECT *RegionObj, UINT32 Function)
Definition: evregion.c:615
UINT16 Length
Definition: actypes.h:1227
void AcpiEvExecuteRegMethods(ACPI_NAMESPACE_NODE *Node, ACPI_ADR_SPACE_TYPE SpaceId, UINT32 Function)
Definition: evregion.c:761
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:519
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
unsigned short UINT16
#define NULL
Definition: types.h:112
UINT64 Length
Definition: actypes.h:1235
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:345
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
struct tagContext Context
Definition: acpixf.h:1038
ACPI_OBJECT_REGION_FIELD Field
Definition: acobject.h:534
ACPI_PHYSICAL_ADDRESS Address
Definition: acobject.h:206
#define ACPI_TYPE_REGION
Definition: actypes.h:697
ACPI_NAMESPACE_NODE * AcpiNsGetNextNode(ACPI_NAMESPACE_NODE *Parent, ACPI_NAMESPACE_NODE *Child)
Definition: nswalk.c:72
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Definition: osl.c:333
#define ACPI_REGION_ACTIVATE
Definition: actypes.h:1245
#define ACPI_MUTEX
Definition: actypes.h:273
void * RegionContext
Definition: acobject.h:483
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:861
unsigned long long UINT64
ACPI_OBJECT_TYPE Type
Definition: actypes.h:970
#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
#define ACPI_ADR_SPACE_FIXED_HARDWARE
Definition: actypes.h:885
ACPI_OPERAND_OBJECT * AcpiNsGetSecondaryObject(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: nsobject.c:346
Definition: dlist.c:348