xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/events/evrgnini.c (revision aa3083e086e5a929c061c72983e09d916c548a38)
1 /******************************************************************************
2  *
3  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #include "acpi.h"
117 #include "accommon.h"
118 #include "acevents.h"
119 #include "acnamesp.h"
120 
121 #define _COMPONENT          ACPI_EVENTS
122         ACPI_MODULE_NAME    ("evrgnini")
123 
124 /* Local prototypes */
125 
126 static BOOLEAN
127 AcpiEvIsPciRootBridge (
128     ACPI_NAMESPACE_NODE     *Node);
129 
130 
131 /*******************************************************************************
132  *
133  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
134  *
135  * PARAMETERS:  Handle              - Region we are interested in
136  *              Function            - Start or stop
137  *              HandlerContext      - Address space handler context
138  *              RegionContext       - Region specific context
139  *
140  * RETURN:      Status
141  *
142  * DESCRIPTION: Setup a SystemMemory operation region
143  *
144  ******************************************************************************/
145 
146 ACPI_STATUS
147 AcpiEvSystemMemoryRegionSetup (
148     ACPI_HANDLE             Handle,
149     UINT32                  Function,
150     void                    *HandlerContext,
151     void                    **RegionContext)
152 {
153     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
154     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
155 
156 
157     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
158 
159 
160     if (Function == ACPI_REGION_DEACTIVATE)
161     {
162         if (*RegionContext)
163         {
164             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
165 
166             /* Delete a cached mapping if present */
167 
168             if (LocalRegionContext->MappedLength)
169             {
170                 AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
171                     LocalRegionContext->MappedLength);
172             }
173             ACPI_FREE (LocalRegionContext);
174             *RegionContext = NULL;
175         }
176         return_ACPI_STATUS (AE_OK);
177     }
178 
179     /* Create a new context */
180 
181     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
182     if (!(LocalRegionContext))
183     {
184         return_ACPI_STATUS (AE_NO_MEMORY);
185     }
186 
187     /* Save the region length and address for use in the handler */
188 
189     LocalRegionContext->Length  = RegionDesc->Region.Length;
190     LocalRegionContext->Address = RegionDesc->Region.Address;
191 
192     *RegionContext = LocalRegionContext;
193     return_ACPI_STATUS (AE_OK);
194 }
195 
196 
197 /*******************************************************************************
198  *
199  * FUNCTION:    AcpiEvIoSpaceRegionSetup
200  *
201  * PARAMETERS:  Handle              - Region we are interested in
202  *              Function            - Start or stop
203  *              HandlerContext      - Address space handler context
204  *              RegionContext       - Region specific context
205  *
206  * RETURN:      Status
207  *
208  * DESCRIPTION: Setup a IO operation region
209  *
210  ******************************************************************************/
211 
212 ACPI_STATUS
213 AcpiEvIoSpaceRegionSetup (
214     ACPI_HANDLE             Handle,
215     UINT32                  Function,
216     void                    *HandlerContext,
217     void                    **RegionContext)
218 {
219     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
220 
221 
222     if (Function == ACPI_REGION_DEACTIVATE)
223     {
224         *RegionContext = NULL;
225     }
226     else
227     {
228         *RegionContext = HandlerContext;
229     }
230 
231     return_ACPI_STATUS (AE_OK);
232 }
233 
234 
235 /*******************************************************************************
236  *
237  * FUNCTION:    AcpiEvPciConfigRegionSetup
238  *
239  * PARAMETERS:  Handle              - Region we are interested in
240  *              Function            - Start or stop
241  *              HandlerContext      - Address space handler context
242  *              RegionContext       - Region specific context
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: Setup a PCI_Config operation region
247  *
248  * MUTEX:       Assumes namespace is not locked
249  *
250  ******************************************************************************/
251 
252 ACPI_STATUS
253 AcpiEvPciConfigRegionSetup (
254     ACPI_HANDLE             Handle,
255     UINT32                  Function,
256     void                    *HandlerContext,
257     void                    **RegionContext)
258 {
259     ACPI_STATUS             Status = AE_OK;
260     UINT64                  PciValue;
261     ACPI_PCI_ID             *PciId = *RegionContext;
262     ACPI_OPERAND_OBJECT     *HandlerObj;
263     ACPI_NAMESPACE_NODE     *ParentNode;
264     ACPI_NAMESPACE_NODE     *PciRootNode;
265     ACPI_NAMESPACE_NODE     *PciDeviceNode;
266     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
267 
268 
269     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
270 
271 
272     HandlerObj = RegionObj->Region.Handler;
273     if (!HandlerObj)
274     {
275         /*
276          * No installed handler. This shouldn't happen because the dispatch
277          * routine checks before we get here, but we check again just in case.
278          */
279         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
280             "Attempting to init a region %p, with no handler\n", RegionObj));
281         return_ACPI_STATUS (AE_NOT_EXIST);
282     }
283 
284     *RegionContext = NULL;
285     if (Function == ACPI_REGION_DEACTIVATE)
286     {
287         if (PciId)
288         {
289             ACPI_FREE (PciId);
290         }
291         return_ACPI_STATUS (Status);
292     }
293 
294     ParentNode = RegionObj->Region.Node->Parent;
295 
296     /*
297      * Get the _SEG and _BBN values from the device upon which the handler
298      * is installed.
299      *
300      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
301      * This is the device the handler has been registered to handle.
302      */
303 
304     /*
305      * If the AddressSpace.Node is still pointing to the root, we need
306      * to scan upward for a PCI Root bridge and re-associate the OpRegion
307      * handlers with that device.
308      */
309     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
310     {
311         /* Start search from the parent object */
312 
313         PciRootNode = ParentNode;
314         while (PciRootNode != AcpiGbl_RootNode)
315         {
316             /* Get the _HID/_CID in order to detect a RootBridge */
317 
318             if (AcpiEvIsPciRootBridge (PciRootNode))
319             {
320                 /* Install a handler for this PCI root bridge */
321 
322                 Status = AcpiInstallAddressSpaceHandler (
323                     (ACPI_HANDLE) PciRootNode,
324                     ACPI_ADR_SPACE_PCI_CONFIG,
325                     ACPI_DEFAULT_HANDLER, NULL, NULL);
326                 if (ACPI_FAILURE (Status))
327                 {
328                     if (Status == AE_SAME_HANDLER)
329                     {
330                         /*
331                          * It is OK if the handler is already installed on the
332                          * root bridge. Still need to return a context object
333                          * for the new PCI_Config operation region, however.
334                          */
335                         Status = AE_OK;
336                     }
337                     else
338                     {
339                         ACPI_EXCEPTION ((AE_INFO, Status,
340                             "Could not install PciConfig handler "
341                             "for Root Bridge %4.4s",
342                             AcpiUtGetNodeName (PciRootNode)));
343                     }
344                 }
345                 break;
346             }
347 
348             PciRootNode = PciRootNode->Parent;
349         }
350 
351         /* PCI root bridge not found, use namespace root node */
352     }
353     else
354     {
355         PciRootNode = HandlerObj->AddressSpace.Node;
356     }
357 
358     /*
359      * If this region is now initialized, we are done.
360      * (InstallAddressSpaceHandler could have initialized it)
361      */
362     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
363     {
364         return_ACPI_STATUS (AE_OK);
365     }
366 
367     /* Region is still not initialized. Create a new context */
368 
369     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
370     if (!PciId)
371     {
372         return_ACPI_STATUS (AE_NO_MEMORY);
373     }
374 
375     /*
376      * For PCI_Config space access, we need the segment, bus, device and
377      * function numbers. Acquire them here.
378      *
379      * Find the parent device object. (This allows the operation region to be
380      * within a subscope under the device, such as a control method.)
381      */
382     PciDeviceNode = RegionObj->Region.Node;
383     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
384     {
385         PciDeviceNode = PciDeviceNode->Parent;
386     }
387 
388     if (!PciDeviceNode)
389     {
390         ACPI_FREE (PciId);
391         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
392     }
393 
394     /*
395      * Get the PCI device and function numbers from the _ADR object
396      * contained in the parent's scope.
397      */
398     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
399         PciDeviceNode, &PciValue);
400 
401     /*
402      * The default is zero, and since the allocation above zeroed the data,
403      * just do nothing on failure.
404      */
405     if (ACPI_SUCCESS (Status))
406     {
407         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
408         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
409     }
410 
411     /* The PCI segment number comes from the _SEG method */
412 
413     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
414         PciRootNode, &PciValue);
415     if (ACPI_SUCCESS (Status))
416     {
417         PciId->Segment = ACPI_LOWORD (PciValue);
418     }
419 
420     /* The PCI bus number comes from the _BBN method */
421 
422     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
423         PciRootNode, &PciValue);
424     if (ACPI_SUCCESS (Status))
425     {
426         PciId->Bus = ACPI_LOWORD (PciValue);
427     }
428 
429     /* Complete/update the PCI ID for this device */
430 
431     Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
432     if (ACPI_FAILURE (Status))
433     {
434         ACPI_FREE (PciId);
435         return_ACPI_STATUS (Status);
436     }
437 
438     *RegionContext = PciId;
439     return_ACPI_STATUS (AE_OK);
440 }
441 
442 
443 /*******************************************************************************
444  *
445  * FUNCTION:    AcpiEvIsPciRootBridge
446  *
447  * PARAMETERS:  Node            - Device node being examined
448  *
449  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
450  *
451  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
452  *              examining the _HID and _CID for the device.
453  *
454  ******************************************************************************/
455 
456 static BOOLEAN
457 AcpiEvIsPciRootBridge (
458     ACPI_NAMESPACE_NODE     *Node)
459 {
460     ACPI_STATUS             Status;
461     ACPI_PNP_DEVICE_ID      *Hid;
462     ACPI_PNP_DEVICE_ID_LIST *Cid;
463     UINT32                  i;
464     BOOLEAN                 Match;
465 
466 
467     /* Get the _HID and check for a PCI Root Bridge */
468 
469     Status = AcpiUtExecute_HID (Node, &Hid);
470     if (ACPI_FAILURE (Status))
471     {
472         return (FALSE);
473     }
474 
475     Match = AcpiUtIsPciRootBridge (Hid->String);
476     ACPI_FREE (Hid);
477 
478     if (Match)
479     {
480         return (TRUE);
481     }
482 
483     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
484 
485     Status = AcpiUtExecute_CID (Node, &Cid);
486     if (ACPI_FAILURE (Status))
487     {
488         return (FALSE);
489     }
490 
491     /* Check all _CIDs in the returned list */
492 
493     for (i = 0; i < Cid->Count; i++)
494     {
495         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
496         {
497             ACPI_FREE (Cid);
498             return (TRUE);
499         }
500     }
501 
502     ACPI_FREE (Cid);
503     return (FALSE);
504 }
505 
506 
507 /*******************************************************************************
508  *
509  * FUNCTION:    AcpiEvPciBarRegionSetup
510  *
511  * PARAMETERS:  Handle              - Region we are interested in
512  *              Function            - Start or stop
513  *              HandlerContext      - Address space handler context
514  *              RegionContext       - Region specific context
515  *
516  * RETURN:      Status
517  *
518  * DESCRIPTION: Setup a PciBAR operation region
519  *
520  * MUTEX:       Assumes namespace is not locked
521  *
522  ******************************************************************************/
523 
524 ACPI_STATUS
525 AcpiEvPciBarRegionSetup (
526     ACPI_HANDLE             Handle,
527     UINT32                  Function,
528     void                    *HandlerContext,
529     void                    **RegionContext)
530 {
531     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
532 
533 
534     return_ACPI_STATUS (AE_OK);
535 }
536 
537 
538 /*******************************************************************************
539  *
540  * FUNCTION:    AcpiEvCmosRegionSetup
541  *
542  * PARAMETERS:  Handle              - Region we are interested in
543  *              Function            - Start or stop
544  *              HandlerContext      - Address space handler context
545  *              RegionContext       - Region specific context
546  *
547  * RETURN:      Status
548  *
549  * DESCRIPTION: Setup a CMOS operation region
550  *
551  * MUTEX:       Assumes namespace is not locked
552  *
553  ******************************************************************************/
554 
555 ACPI_STATUS
556 AcpiEvCmosRegionSetup (
557     ACPI_HANDLE             Handle,
558     UINT32                  Function,
559     void                    *HandlerContext,
560     void                    **RegionContext)
561 {
562     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
563 
564 
565     return_ACPI_STATUS (AE_OK);
566 }
567 
568 
569 /*******************************************************************************
570  *
571  * FUNCTION:    AcpiEvDefaultRegionSetup
572  *
573  * PARAMETERS:  Handle              - Region we are interested in
574  *              Function            - Start or stop
575  *              HandlerContext      - Address space handler context
576  *              RegionContext       - Region specific context
577  *
578  * RETURN:      Status
579  *
580  * DESCRIPTION: Default region initialization
581  *
582  ******************************************************************************/
583 
584 ACPI_STATUS
585 AcpiEvDefaultRegionSetup (
586     ACPI_HANDLE             Handle,
587     UINT32                  Function,
588     void                    *HandlerContext,
589     void                    **RegionContext)
590 {
591     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
592 
593 
594     if (Function == ACPI_REGION_DEACTIVATE)
595     {
596         *RegionContext = NULL;
597     }
598     else
599     {
600         *RegionContext = HandlerContext;
601     }
602 
603     return_ACPI_STATUS (AE_OK);
604 }
605 
606 
607 /*******************************************************************************
608  *
609  * FUNCTION:    AcpiEvInitializeRegion
610  *
611  * PARAMETERS:  RegionObj       - Region we are initializing
612  *              AcpiNsLocked    - Is namespace locked?
613  *
614  * RETURN:      Status
615  *
616  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
617  *              for execution at a later time
618  *
619  *              Get the appropriate address space handler for a newly
620  *              created region.
621  *
622  *              This also performs address space specific initialization. For
623  *              example, PCI regions must have an _ADR object that contains
624  *              a PCI address in the scope of the definition. This address is
625  *              required to perform an access to PCI config space.
626  *
627  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
628  *              method for this region.
629  *
630  ******************************************************************************/
631 
632 ACPI_STATUS
633 AcpiEvInitializeRegion (
634     ACPI_OPERAND_OBJECT     *RegionObj,
635     BOOLEAN                 AcpiNsLocked)
636 {
637     ACPI_OPERAND_OBJECT     *HandlerObj;
638     ACPI_OPERAND_OBJECT     *ObjDesc;
639     ACPI_ADR_SPACE_TYPE     SpaceId;
640     ACPI_NAMESPACE_NODE     *Node;
641     ACPI_STATUS             Status;
642 
643 
644     ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
645 
646 
647     if (!RegionObj)
648     {
649         return_ACPI_STATUS (AE_BAD_PARAMETER);
650     }
651 
652     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
653     {
654         return_ACPI_STATUS (AE_OK);
655     }
656 
657     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
658 
659     Node = RegionObj->Region.Node->Parent;
660     SpaceId = RegionObj->Region.SpaceId;
661 
662     /*
663      * The following loop depends upon the root Node having no parent
664      * ie: AcpiGbl_RootNode->Parent being set to NULL
665      */
666     while (Node)
667     {
668         /* Check to see if a handler exists */
669 
670         HandlerObj = NULL;
671         ObjDesc = AcpiNsGetAttachedObject (Node);
672         if (ObjDesc)
673         {
674             /* Can only be a handler if the object exists */
675 
676             switch (Node->Type)
677             {
678             case ACPI_TYPE_DEVICE:
679             case ACPI_TYPE_PROCESSOR:
680             case ACPI_TYPE_THERMAL:
681 
682                 HandlerObj = ObjDesc->CommonNotify.Handler;
683                 break;
684 
685             case ACPI_TYPE_METHOD:
686                 /*
687                  * If we are executing module level code, the original
688                  * Node's object was replaced by this Method object and we
689                  * saved the handler in the method object.
690                  *
691                  * See AcpiNsExecModuleCode
692                  */
693                 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
694                 {
695                     HandlerObj = ObjDesc->Method.Dispatch.Handler;
696                 }
697                 break;
698 
699             default:
700 
701                 /* Ignore other objects */
702 
703                 break;
704             }
705 
706             HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
707             if (HandlerObj)
708             {
709                 /* Found correct handler */
710 
711                 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
712                     "Found handler %p for region %p in obj %p\n",
713                     HandlerObj, RegionObj, ObjDesc));
714 
715                 Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
716                     AcpiNsLocked);
717 
718                 /*
719                  * Tell all users that this region is usable by
720                  * running the _REG method
721                  */
722                 if (AcpiNsLocked)
723                 {
724                     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
725                     if (ACPI_FAILURE (Status))
726                     {
727                         return_ACPI_STATUS (Status);
728                     }
729                 }
730 
731                 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
732 
733                 if (AcpiNsLocked)
734                 {
735                     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
736                     if (ACPI_FAILURE (Status))
737                     {
738                         return_ACPI_STATUS (Status);
739                     }
740                 }
741 
742                 return_ACPI_STATUS (AE_OK);
743             }
744         }
745 
746         /* This node does not have the handler we need; Pop up one level */
747 
748         Node = Node->Parent;
749     }
750 
751     /* If we get here, there is no handler for this region */
752 
753     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
754         "No handler for RegionType %s(%X) (RegionObj %p)\n",
755         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
756 
757     return_ACPI_STATUS (AE_NOT_EXIST);
758 }
759