1 /******************************************************************************
2  *
3  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
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    ("evrgnini")
52 
53 
54 /*******************************************************************************
55  *
56  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
57  *
58  * PARAMETERS:  Handle              - Region we are interested in
59  *              Function            - Start or stop
60  *              HandlerContext      - Address space handler context
61  *              RegionContext       - Region specific context
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: Setup a SystemMemory operation region
66  *
67  ******************************************************************************/
68 
69 ACPI_STATUS
AcpiEvSystemMemoryRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)70 AcpiEvSystemMemoryRegionSetup (
71     ACPI_HANDLE             Handle,
72     UINT32                  Function,
73     void                    *HandlerContext,
74     void                    **RegionContext)
75 {
76     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
77     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
78     ACPI_MEM_MAPPING        *Mm;
79 
80 
81     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
82 
83 
84     if (Function == ACPI_REGION_DEACTIVATE)
85     {
86         if (*RegionContext)
87         {
88             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
89 
90             /* Delete memory mappings if present */
91 
92             while (LocalRegionContext->FirstMm)
93             {
94                 Mm = LocalRegionContext->FirstMm;
95                 LocalRegionContext->FirstMm = Mm->NextMm;
96                 AcpiOsUnmapMemory(Mm->LogicalAddress, Mm->Length);
97                 ACPI_FREE(Mm);
98             }
99             ACPI_FREE (LocalRegionContext);
100             *RegionContext = NULL;
101         }
102         return_ACPI_STATUS (AE_OK);
103     }
104 
105     /* Create a new context */
106 
107     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
108     if (!(LocalRegionContext))
109     {
110         return_ACPI_STATUS (AE_NO_MEMORY);
111     }
112 
113     /* Save the region length and address for use in the handler */
114 
115     LocalRegionContext->Length  = RegionDesc->Region.Length;
116     LocalRegionContext->Address = RegionDesc->Region.Address;
117 
118     *RegionContext = LocalRegionContext;
119     return_ACPI_STATUS (AE_OK);
120 }
121 
122 
123 /*******************************************************************************
124  *
125  * FUNCTION:    AcpiEvIoSpaceRegionSetup
126  *
127  * PARAMETERS:  Handle              - Region we are interested in
128  *              Function            - Start or stop
129  *              HandlerContext      - Address space handler context
130  *              RegionContext       - Region specific context
131  *
132  * RETURN:      Status
133  *
134  * DESCRIPTION: Setup a IO operation region
135  *
136  ******************************************************************************/
137 
138 ACPI_STATUS
AcpiEvIoSpaceRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)139 AcpiEvIoSpaceRegionSetup (
140     ACPI_HANDLE             Handle,
141     UINT32                  Function,
142     void                    *HandlerContext,
143     void                    **RegionContext)
144 {
145     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
146 
147 
148     if (Function == ACPI_REGION_DEACTIVATE)
149     {
150         *RegionContext = NULL;
151     }
152     else
153     {
154         *RegionContext = HandlerContext;
155     }
156 
157     return_ACPI_STATUS (AE_OK);
158 }
159 
160 
161 /*******************************************************************************
162  *
163  * FUNCTION:    AcpiEvPciConfigRegionSetup
164  *
165  * PARAMETERS:  Handle              - Region we are interested in
166  *              Function            - Start or stop
167  *              HandlerContext      - Address space handler context
168  *              RegionContext       - Region specific context
169  *
170  * RETURN:      Status
171  *
172  * DESCRIPTION: Setup a PCI_Config operation region
173  *
174  * MUTEX:       Assumes namespace is not locked
175  *
176  ******************************************************************************/
177 
178 ACPI_STATUS
AcpiEvPciConfigRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)179 AcpiEvPciConfigRegionSetup (
180     ACPI_HANDLE             Handle,
181     UINT32                  Function,
182     void                    *HandlerContext,
183     void                    **RegionContext)
184 {
185     ACPI_STATUS             Status = AE_OK;
186     UINT64                  PciValue;
187     ACPI_PCI_ID             *PciId = *RegionContext;
188     ACPI_OPERAND_OBJECT     *HandlerObj;
189     ACPI_NAMESPACE_NODE     *ParentNode;
190     ACPI_NAMESPACE_NODE     *PciRootNode;
191     ACPI_NAMESPACE_NODE     *PciDeviceNode;
192     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
193 
194 
195     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
196 
197 
198     HandlerObj = RegionObj->Region.Handler;
199     if (!HandlerObj)
200     {
201         /*
202          * No installed handler. This shouldn't happen because the dispatch
203          * routine checks before we get here, but we check again just in case.
204          */
205         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
206             "Attempting to init a region %p, with no handler\n", RegionObj));
207         return_ACPI_STATUS (AE_NOT_EXIST);
208     }
209 
210     *RegionContext = NULL;
211     if (Function == ACPI_REGION_DEACTIVATE)
212     {
213         if (PciId)
214         {
215             ACPI_FREE (PciId);
216         }
217         return_ACPI_STATUS (Status);
218     }
219 
220     ParentNode = RegionObj->Region.Node->Parent;
221 
222     /*
223      * Get the _SEG and _BBN values from the device upon which the handler
224      * is installed.
225      *
226      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
227      * This is the device the handler has been registered to handle.
228      */
229 
230     /*
231      * If the AddressSpace.Node is still pointing to the root, we need
232      * to scan upward for a PCI Root bridge and re-associate the OpRegion
233      * handlers with that device.
234      */
235     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
236     {
237         /* Start search from the parent object */
238 
239         PciRootNode = ParentNode;
240         while (PciRootNode != AcpiGbl_RootNode)
241         {
242             /* Get the _HID/_CID in order to detect a RootBridge */
243 
244             if (AcpiEvIsPciRootBridge (PciRootNode))
245             {
246                 /* Install a handler for this PCI root bridge */
247 
248                 Status = AcpiInstallAddressSpaceHandler (
249                     (ACPI_HANDLE) PciRootNode,
250                     ACPI_ADR_SPACE_PCI_CONFIG,
251                     ACPI_DEFAULT_HANDLER, NULL, NULL);
252                 if (ACPI_FAILURE (Status))
253                 {
254                     if (Status == AE_SAME_HANDLER)
255                     {
256                         /*
257                          * It is OK if the handler is already installed on the
258                          * root bridge. Still need to return a context object
259                          * for the new PCI_Config operation region, however.
260                          */
261                     }
262                     else
263                     {
264                         ACPI_EXCEPTION ((AE_INFO, Status,
265                             "Could not install PciConfig handler "
266                             "for Root Bridge %4.4s",
267                             AcpiUtGetNodeName (PciRootNode)));
268                     }
269                 }
270                 break;
271             }
272 
273             PciRootNode = PciRootNode->Parent;
274         }
275 
276         /* PCI root bridge not found, use namespace root node */
277     }
278     else
279     {
280         PciRootNode = HandlerObj->AddressSpace.Node;
281     }
282 
283     /*
284      * If this region is now initialized, we are done.
285      * (InstallAddressSpaceHandler could have initialized it)
286      */
287     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
288     {
289         return_ACPI_STATUS (AE_OK);
290     }
291 
292     /* Region is still not initialized. Create a new context */
293 
294     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
295     if (!PciId)
296     {
297         return_ACPI_STATUS (AE_NO_MEMORY);
298     }
299 
300     /*
301      * For PCI_Config space access, we need the segment, bus, device and
302      * function numbers. Acquire them here.
303      *
304      * Find the parent device object. (This allows the operation region to be
305      * within a subscope under the device, such as a control method.)
306      */
307     PciDeviceNode = RegionObj->Region.Node;
308     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
309     {
310         PciDeviceNode = PciDeviceNode->Parent;
311     }
312 
313     if (!PciDeviceNode)
314     {
315         ACPI_FREE (PciId);
316         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
317     }
318 
319     /*
320      * Get the PCI device and function numbers from the _ADR object
321      * contained in the parent's scope.
322      */
323     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
324         PciDeviceNode, &PciValue);
325 
326     /*
327      * The default is zero, and since the allocation above zeroed the data,
328      * just do nothing on failure.
329      */
330     if (ACPI_SUCCESS (Status))
331     {
332         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
333         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
334     }
335 
336     /* The PCI segment number comes from the _SEG method */
337 
338     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
339         PciRootNode, &PciValue);
340     if (ACPI_SUCCESS (Status))
341     {
342         PciId->Segment = ACPI_LOWORD (PciValue);
343     }
344 
345     /* The PCI bus number comes from the _BBN method */
346 
347     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
348         PciRootNode, &PciValue);
349     if (ACPI_SUCCESS (Status))
350     {
351         PciId->Bus = ACPI_LOWORD (PciValue);
352     }
353 
354     /* Complete/update the PCI ID for this device */
355 
356     Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
357     if (ACPI_FAILURE (Status))
358     {
359         ACPI_FREE (PciId);
360         return_ACPI_STATUS (Status);
361     }
362 
363     *RegionContext = PciId;
364     return_ACPI_STATUS (AE_OK);
365 }
366 
367 
368 /*******************************************************************************
369  *
370  * FUNCTION:    AcpiEvIsPciRootBridge
371  *
372  * PARAMETERS:  Node            - Device node being examined
373  *
374  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
375  *
376  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
377  *              examining the _HID and _CID for the device.
378  *
379  ******************************************************************************/
380 
381 BOOLEAN
AcpiEvIsPciRootBridge(ACPI_NAMESPACE_NODE * Node)382 AcpiEvIsPciRootBridge (
383     ACPI_NAMESPACE_NODE     *Node)
384 {
385     ACPI_STATUS             Status;
386     ACPI_PNP_DEVICE_ID      *Hid;
387     ACPI_PNP_DEVICE_ID_LIST *Cid;
388     UINT32                  i;
389     BOOLEAN                 Match;
390 
391 
392     /* Get the _HID and check for a PCI Root Bridge */
393 
394     Status = AcpiUtExecute_HID (Node, &Hid);
395     if (ACPI_FAILURE (Status))
396     {
397         return (FALSE);
398     }
399 
400     Match = AcpiUtIsPciRootBridge (Hid->String);
401     ACPI_FREE (Hid);
402 
403     if (Match)
404     {
405         return (TRUE);
406     }
407 
408     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
409 
410     Status = AcpiUtExecute_CID (Node, &Cid);
411     if (ACPI_FAILURE (Status))
412     {
413         return (FALSE);
414     }
415 
416     /* Check all _CIDs in the returned list */
417 
418     for (i = 0; i < Cid->Count; i++)
419     {
420         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
421         {
422             ACPI_FREE (Cid);
423             return (TRUE);
424         }
425     }
426 
427     ACPI_FREE (Cid);
428     return (FALSE);
429 }
430 
431 
432 /*******************************************************************************
433  *
434  * FUNCTION:    AcpiEvPciBarRegionSetup
435  *
436  * PARAMETERS:  Handle              - Region we are interested in
437  *              Function            - Start or stop
438  *              HandlerContext      - Address space handler context
439  *              RegionContext       - Region specific context
440  *
441  * RETURN:      Status
442  *
443  * DESCRIPTION: Setup a PciBAR operation region
444  *
445  * MUTEX:       Assumes namespace is not locked
446  *
447  ******************************************************************************/
448 
449 ACPI_STATUS
AcpiEvPciBarRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)450 AcpiEvPciBarRegionSetup (
451     ACPI_HANDLE             Handle,
452     UINT32                  Function,
453     void                    *HandlerContext,
454     void                    **RegionContext)
455 {
456     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
457 
458 
459     return_ACPI_STATUS (AE_OK);
460 }
461 
462 
463 /*******************************************************************************
464  *
465  * FUNCTION:    AcpiEvCmosRegionSetup
466  *
467  * PARAMETERS:  Handle              - Region we are interested in
468  *              Function            - Start or stop
469  *              HandlerContext      - Address space handler context
470  *              RegionContext       - Region specific context
471  *
472  * RETURN:      Status
473  *
474  * DESCRIPTION: Setup a CMOS operation region
475  *
476  * MUTEX:       Assumes namespace is not locked
477  *
478  ******************************************************************************/
479 
480 ACPI_STATUS
AcpiEvCmosRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)481 AcpiEvCmosRegionSetup (
482     ACPI_HANDLE             Handle,
483     UINT32                  Function,
484     void                    *HandlerContext,
485     void                    **RegionContext)
486 {
487     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
488 
489 
490     return_ACPI_STATUS (AE_OK);
491 }
492 
493 
494 /*******************************************************************************
495  *
496  * FUNCTION:    AcpiEvDataTableRegionSetup
497  *
498  * PARAMETERS:  Handle              - Region we are interested in
499  *              Function            - Start or stop
500  *              HandlerContext      - Address space handler context
501  *              RegionContext       - Region specific context
502  *
503  * RETURN:      Status
504  *
505  * DESCRIPTION: Setup a DataTableRegion
506  *
507  * MUTEX:       Assumes namespace is not locked
508  *
509  ******************************************************************************/
510 
511 ACPI_STATUS
AcpiEvDataTableRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)512 AcpiEvDataTableRegionSetup (
513     ACPI_HANDLE             Handle,
514     UINT32                  Function,
515     void                    *HandlerContext,
516     void                    **RegionContext)
517 {
518     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
519     ACPI_DATA_TABLE_MAPPING *LocalRegionContext;
520 
521 
522     ACPI_FUNCTION_TRACE (EvDataTableRegionSetup);
523 
524 
525     if (Function == ACPI_REGION_DEACTIVATE)
526     {
527         if (*RegionContext)
528         {
529             ACPI_FREE (*RegionContext);
530             *RegionContext = NULL;
531         }
532         return_ACPI_STATUS (AE_OK);
533     }
534 
535     /* Create a new context */
536 
537     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DATA_TABLE_MAPPING));
538     if (!(LocalRegionContext))
539     {
540         return_ACPI_STATUS (AE_NO_MEMORY);
541     }
542 
543     /* Save the data table pointer for use in the handler */
544 
545     LocalRegionContext->Pointer = RegionDesc->Region.Pointer;
546 
547     *RegionContext = LocalRegionContext;
548     return_ACPI_STATUS (AE_OK);
549 }
550 
551 
552 /*******************************************************************************
553  *
554  * FUNCTION:    AcpiEvDefaultRegionSetup
555  *
556  * PARAMETERS:  Handle              - Region we are interested in
557  *              Function            - Start or stop
558  *              HandlerContext      - Address space handler context
559  *              RegionContext       - Region specific context
560  *
561  * RETURN:      Status
562  *
563  * DESCRIPTION: Default region initialization
564  *
565  ******************************************************************************/
566 
567 ACPI_STATUS
AcpiEvDefaultRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)568 AcpiEvDefaultRegionSetup (
569     ACPI_HANDLE             Handle,
570     UINT32                  Function,
571     void                    *HandlerContext,
572     void                    **RegionContext)
573 {
574     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
575 
576 
577     if (Function == ACPI_REGION_DEACTIVATE)
578     {
579         *RegionContext = NULL;
580     }
581     else
582     {
583         *RegionContext = HandlerContext;
584     }
585 
586     return_ACPI_STATUS (AE_OK);
587 }
588 
589 
590 /*******************************************************************************
591  *
592  * FUNCTION:    AcpiEvInitializeRegion
593  *
594  * PARAMETERS:  RegionObj       - Region we are initializing
595  *
596  * RETURN:      Status
597  *
598  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
599  *              for execution at a later time
600  *
601  *              Get the appropriate address space handler for a newly
602  *              created region.
603  *
604  *              This also performs address space specific initialization. For
605  *              example, PCI regions must have an _ADR object that contains
606  *              a PCI address in the scope of the definition. This address is
607  *              required to perform an access to PCI config space.
608  *
609  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
610  *              method for this region.
611  *
612  * NOTE:        Possible incompliance:
613  *              There is a behavior conflict in automatic _REG execution:
614  *              1. When the interpreter is evaluating a method, we can only
615  *                 automatically run _REG for the following case:
616  *                   Method(_REG, 2) {}
617  *                   OperationRegion (OPR1, 0x80, 0x1000010, 0x4)
618  *              2. When the interpreter is loading a table, we can also
619  *                 automatically run _REG for the following case:
620  *                   OperationRegion (OPR1, 0x80, 0x1000010, 0x4)
621  *                   Method(_REG, 2) {}
622  *              Though this may not be compliant to the de-facto standard, the
623  *              logic is kept in order not to trigger regressions. And keeping
624  *              this logic should be taken care by the caller of this function.
625  *
626  ******************************************************************************/
627 
628 ACPI_STATUS
AcpiEvInitializeRegion(ACPI_OPERAND_OBJECT * RegionObj)629 AcpiEvInitializeRegion (
630     ACPI_OPERAND_OBJECT     *RegionObj)
631 {
632     ACPI_OPERAND_OBJECT     *HandlerObj;
633     ACPI_OPERAND_OBJECT     *ObjDesc;
634     ACPI_ADR_SPACE_TYPE     SpaceId;
635     ACPI_NAMESPACE_NODE     *Node;
636 
637 
638     ACPI_FUNCTION_TRACE (EvInitializeRegion);
639 
640 
641     if (!RegionObj)
642     {
643         return_ACPI_STATUS (AE_BAD_PARAMETER);
644     }
645 
646     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
647     {
648         return_ACPI_STATUS (AE_OK);
649     }
650 
651     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
652 
653     Node = RegionObj->Region.Node->Parent;
654     SpaceId = RegionObj->Region.SpaceId;
655 
656     /*
657      * The following loop depends upon the root Node having no parent
658      * ie: AcpiGbl_RootNode->Parent being set to NULL
659      */
660     while (Node)
661     {
662         /* Check to see if a handler exists */
663 
664         HandlerObj = NULL;
665         ObjDesc = AcpiNsGetAttachedObject (Node);
666         if (ObjDesc)
667         {
668             /* Can only be a handler if the object exists */
669 
670             switch (Node->Type)
671             {
672             case ACPI_TYPE_DEVICE:
673             case ACPI_TYPE_PROCESSOR:
674             case ACPI_TYPE_THERMAL:
675 
676                 HandlerObj = ObjDesc->CommonNotify.Handler;
677                 break;
678 
679             default:
680 
681                 /* Ignore other objects */
682 
683                 break;
684             }
685 
686             HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
687             if (HandlerObj)
688             {
689                 /* Found correct handler */
690 
691                 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
692                     "Found handler %p for region %p in obj %p\n",
693                     HandlerObj, RegionObj, ObjDesc));
694 
695                 (void) AcpiEvAttachRegion (HandlerObj, RegionObj, FALSE);
696 
697                 /*
698                  * Tell all users that this region is usable by
699                  * running the _REG method
700                  */
701                 AcpiExExitInterpreter ();
702                 (void) AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
703                 AcpiExEnterInterpreter ();
704                 return_ACPI_STATUS (AE_OK);
705             }
706         }
707 
708         /* This node does not have the handler we need; Pop up one level */
709 
710         Node = Node->Parent;
711     }
712 
713     /*
714      * If we get here, there is no handler for this region. This is not
715      * fatal because many regions get created before a handler is installed
716      * for said region.
717      */
718     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
719         "No handler for RegionType %s(%X) (RegionObj %p)\n",
720         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
721 
722     return_ACPI_STATUS (AE_OK);
723 }
724