evrgnini.c revision 151937
1316722Sdelphij/******************************************************************************
2316722Sdelphij *
3316722Sdelphij * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4316722Sdelphij *              $Revision: 1.78 $
5316722Sdelphij *
6316722Sdelphij *****************************************************************************/
7316722Sdelphij
8316722Sdelphij/******************************************************************************
9316722Sdelphij *
10316722Sdelphij * 1. Copyright Notice
11316722Sdelphij *
12316722Sdelphij * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13316722Sdelphij * All rights reserved.
14316722Sdelphij *
15316722Sdelphij * 2. License
16316722Sdelphij *
17316722Sdelphij * 2.1. This is your license from Intel Corp. under its intellectual property
18316722Sdelphij * rights.  You may have additional license terms from the party that provided
19316722Sdelphij * you this software, covering your right to use that party's intellectual
20316722Sdelphij * property rights.
21316722Sdelphij *
22316722Sdelphij * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23316722Sdelphij * copy of the source code appearing in this file ("Covered Code") an
24316722Sdelphij * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25316722Sdelphij * base code distributed originally by Intel ("Original Intel Code") to copy,
26316722Sdelphij * make derivatives, distribute, use and display any portion of the Covered
27316722Sdelphij * Code in any form, with the right to sublicense such rights; and
28316722Sdelphij *
29316722Sdelphij * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30316722Sdelphij * license (with the right to sublicense), under only those claims of Intel
31316722Sdelphij * patents that are infringed by the Original Intel Code, to make, use, sell,
32316722Sdelphij * offer to sell, and import the Covered Code and derivative works thereof
33316722Sdelphij * solely to the minimum extent necessary to exercise the above copyright
34316722Sdelphij * license, and in no event shall the patent license extend to any additions
35316722Sdelphij * to or modifications of the Original Intel Code.  No other license or right
36316722Sdelphij * is granted directly or by implication, estoppel or otherwise;
37316722Sdelphij *
38316722Sdelphij * The above copyright and patent license is granted only if the following
39316722Sdelphij * conditions are met:
40316722Sdelphij *
41316722Sdelphij * 3. Conditions
42316722Sdelphij *
43316722Sdelphij * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44316722Sdelphij * Redistribution of source code of any substantial portion of the Covered
45316722Sdelphij * Code or modification with rights to further distribute source must include
46316722Sdelphij * the above Copyright Notice, the above License, this list of Conditions,
47316722Sdelphij * and the following Disclaimer and Export Compliance provision.  In addition,
48316722Sdelphij * Licensee must cause all Covered Code to which Licensee contributes to
49316722Sdelphij * contain a file documenting the changes Licensee made to create that Covered
50316722Sdelphij * Code and the date of any change.  Licensee must include in that file the
51316722Sdelphij * documentation of any changes made by any predecessor Licensee.  Licensee
52316722Sdelphij * must include a prominent statement that the modification is derived,
53316722Sdelphij * directly or indirectly, from Original Intel Code.
54316722Sdelphij *
55316722Sdelphij * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56316722Sdelphij * Redistribution of source code of any substantial portion of the Covered
57316722Sdelphij * Code or modification without rights to further distribute source must
58316722Sdelphij * include the following Disclaimer and Export Compliance provision in the
59316722Sdelphij * documentation and/or other materials provided with distribution.  In
60316722Sdelphij * addition, Licensee may not authorize further sublicense of source of any
61316722Sdelphij * portion of the Covered Code, and must include terms to the effect that the
62316722Sdelphij * license from Licensee to its licensee is limited to the intellectual
63316722Sdelphij * property embodied in the software Licensee provides to its licensee, and
64316722Sdelphij * not to intellectual property embodied in modifications its licensee may
65316722Sdelphij * make.
66316722Sdelphij *
67316722Sdelphij * 3.3. Redistribution of Executable. Redistribution in executable form of any
68316722Sdelphij * substantial portion of the Covered Code or modification must reproduce the
69316722Sdelphij * above Copyright Notice, and the following Disclaimer and Export Compliance
70316722Sdelphij * provision in the documentation and/or other materials provided with the
71316722Sdelphij * distribution.
72316722Sdelphij *
73316722Sdelphij * 3.4. Intel retains all right, title, and interest in and to the Original
74316722Sdelphij * Intel Code.
75316722Sdelphij *
76316722Sdelphij * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77316722Sdelphij * Intel shall be used in advertising or otherwise to promote the sale, use or
78316722Sdelphij * other dealings in products derived from or relating to the Covered Code
79316722Sdelphij * without prior written authorization from Intel.
80316722Sdelphij *
81316722Sdelphij * 4. Disclaimer and Export Compliance
82316722Sdelphij *
83316722Sdelphij * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84316722Sdelphij * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85316722Sdelphij * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86316722Sdelphij * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87316722Sdelphij * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88316722Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89316722Sdelphij * PARTICULAR PURPOSE.
90316722Sdelphij *
91316722Sdelphij * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92316722Sdelphij * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93316722Sdelphij * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94316722Sdelphij * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95316722Sdelphij * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96316722Sdelphij * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97316722Sdelphij * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98316722Sdelphij * LIMITED REMEDY.
99316722Sdelphij *
100316722Sdelphij * 4.3. Licensee shall not export, either directly or indirectly, any of this
101316722Sdelphij * software or system incorporating such software without first obtaining any
102316722Sdelphij * required license or other approval from the U. S. Department of Commerce or
103316722Sdelphij * any other agency or department of the United States Government.  In the
104316722Sdelphij * event Licensee exports any such software from the United States or
105316722Sdelphij * re-exports any such software from a foreign destination, Licensee shall
106316722Sdelphij * ensure that the distribution and export/re-export of the software is in
107316722Sdelphij * compliance with all laws, regulations, orders, or other restrictions of the
108316722Sdelphij * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109316722Sdelphij * any of its subsidiaries will export/re-export any technical data, process,
110316722Sdelphij * software, or service, directly or indirectly, to any country for which the
111316722Sdelphij * United States government or any agency thereof requires an export license,
112316722Sdelphij * other governmental approval, or letter of assurance, without first obtaining
113316722Sdelphij * such license, approval or letter.
114316722Sdelphij *
115316722Sdelphij *****************************************************************************/
116316722Sdelphij
117316722Sdelphij
118316722Sdelphij#define __EVRGNINI_C__
119316722Sdelphij
120316722Sdelphij#include <contrib/dev/acpica/acpi.h>
121316722Sdelphij#include <contrib/dev/acpica/acevents.h>
122316722Sdelphij#include <contrib/dev/acpica/acnamesp.h>
123316722Sdelphij
124316722Sdelphij#define _COMPONENT          ACPI_EVENTS
125316722Sdelphij        ACPI_MODULE_NAME    ("evrgnini")
126316722Sdelphij
127316722Sdelphij
128316722Sdelphij/*******************************************************************************
129316722Sdelphij *
130316722Sdelphij * FUNCTION:    AcpiEvSystemMemoryRegionSetup
131316722Sdelphij *
132316722Sdelphij * PARAMETERS:  Handle              - Region we are interested in
133316722Sdelphij *              Function            - Start or stop
134316722Sdelphij *              HandlerContext      - Address space handler context
135316722Sdelphij *              RegionContext       - Region specific context
136316722Sdelphij *
137316722Sdelphij * RETURN:      Status
138316722Sdelphij *
139316722Sdelphij * DESCRIPTION: Setup a SystemMemory operation region
140316722Sdelphij *
141316722Sdelphij ******************************************************************************/
142316722Sdelphij
143316722SdelphijACPI_STATUS
144316722SdelphijAcpiEvSystemMemoryRegionSetup (
145316722Sdelphij    ACPI_HANDLE             Handle,
146316722Sdelphij    UINT32                  Function,
147316722Sdelphij    void                    *HandlerContext,
148316722Sdelphij    void                    **RegionContext)
149316722Sdelphij{
150316722Sdelphij    ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
151316722Sdelphij    ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
152316722Sdelphij
153316722Sdelphij
154316722Sdelphij    ACPI_FUNCTION_TRACE ("EvSystemMemoryRegionSetup");
155316722Sdelphij
156316722Sdelphij
157316722Sdelphij    if (Function == ACPI_REGION_DEACTIVATE)
158316722Sdelphij    {
159316722Sdelphij        if (*RegionContext)
160316722Sdelphij        {
161316722Sdelphij            ACPI_MEM_FREE (*RegionContext);
162316722Sdelphij            *RegionContext = NULL;
163316722Sdelphij        }
164316722Sdelphij        return_ACPI_STATUS (AE_OK);
165316722Sdelphij    }
166316722Sdelphij
167316722Sdelphij    /* Create a new context */
168316722Sdelphij
169316722Sdelphij    LocalRegionContext = ACPI_MEM_CALLOCATE (sizeof (ACPI_MEM_SPACE_CONTEXT));
170316722Sdelphij    if (!(LocalRegionContext))
171316722Sdelphij    {
172316722Sdelphij        return_ACPI_STATUS (AE_NO_MEMORY);
173316722Sdelphij    }
174316722Sdelphij
175316722Sdelphij    /* Save the region length and address for use in the handler */
176316722Sdelphij
177316722Sdelphij    LocalRegionContext->Length  = RegionDesc->Region.Length;
178316722Sdelphij    LocalRegionContext->Address = RegionDesc->Region.Address;
179316722Sdelphij
180316722Sdelphij    *RegionContext = LocalRegionContext;
181316722Sdelphij    return_ACPI_STATUS (AE_OK);
182316722Sdelphij}
183316722Sdelphij
184316722Sdelphij
185316722Sdelphij/*******************************************************************************
186316722Sdelphij *
187316722Sdelphij * FUNCTION:    AcpiEvIoSpaceRegionSetup
188316722Sdelphij *
189316722Sdelphij * PARAMETERS:  Handle              - Region we are interested in
190316722Sdelphij *              Function            - Start or stop
191316722Sdelphij *              HandlerContext      - Address space handler context
192316722Sdelphij *              RegionContext       - Region specific context
193316722Sdelphij *
194316722Sdelphij * RETURN:      Status
195316722Sdelphij *
196316722Sdelphij * DESCRIPTION: Setup a IO operation region
197316722Sdelphij *
198316722Sdelphij ******************************************************************************/
199316722Sdelphij
200316722SdelphijACPI_STATUS
201316722SdelphijAcpiEvIoSpaceRegionSetup (
202316722Sdelphij    ACPI_HANDLE             Handle,
203316722Sdelphij    UINT32                  Function,
204316722Sdelphij    void                    *HandlerContext,
205316722Sdelphij    void                    **RegionContext)
206316722Sdelphij{
207316722Sdelphij    ACPI_FUNCTION_TRACE ("EvIoSpaceRegionSetup");
208316722Sdelphij
209316722Sdelphij
210316722Sdelphij    if (Function == ACPI_REGION_DEACTIVATE)
211316722Sdelphij    {
212316722Sdelphij        *RegionContext = NULL;
213316722Sdelphij    }
214316722Sdelphij    else
215316722Sdelphij    {
216316722Sdelphij        *RegionContext = HandlerContext;
217316722Sdelphij    }
218316722Sdelphij
219316722Sdelphij    return_ACPI_STATUS (AE_OK);
220316722Sdelphij}
221316722Sdelphij
222316722Sdelphij
223316722Sdelphij/*******************************************************************************
224316722Sdelphij *
225316722Sdelphij * FUNCTION:    AcpiEvPciConfigRegionSetup
226316722Sdelphij *
227316722Sdelphij * PARAMETERS:  Handle              - Region we are interested in
228316722Sdelphij *              Function            - Start or stop
229316722Sdelphij *              HandlerContext      - Address space handler context
230316722Sdelphij *              RegionContext       - Region specific context
231316722Sdelphij *
232316722Sdelphij * RETURN:      Status
233316722Sdelphij *
234316722Sdelphij * DESCRIPTION: Setup a PCI_Config operation region
235316722Sdelphij *
236316722Sdelphij * MUTEX:       Assumes namespace is not locked
237316722Sdelphij *
238316722Sdelphij ******************************************************************************/
239316722Sdelphij
240316722SdelphijACPI_STATUS
241316722SdelphijAcpiEvPciConfigRegionSetup (
242316722Sdelphij    ACPI_HANDLE             Handle,
243316722Sdelphij    UINT32                  Function,
244316722Sdelphij    void                    *HandlerContext,
245316722Sdelphij    void                    **RegionContext)
246316722Sdelphij{
247316722Sdelphij    ACPI_STATUS             Status = AE_OK;
248316722Sdelphij    ACPI_INTEGER            PciValue;
249316722Sdelphij    ACPI_PCI_ID             *PciId = *RegionContext;
250316722Sdelphij    ACPI_OPERAND_OBJECT     *HandlerObj;
251316722Sdelphij    ACPI_NAMESPACE_NODE     *ParentNode;
252316722Sdelphij    ACPI_NAMESPACE_NODE     *PciRootNode;
253316722Sdelphij    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
254316722Sdelphij    ACPI_DEVICE_ID          ObjectHID;
255316722Sdelphij
256316722Sdelphij
257316722Sdelphij    ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");
258316722Sdelphij
259316722Sdelphij
260316722Sdelphij    HandlerObj = RegionObj->Region.Handler;
261316722Sdelphij    if (!HandlerObj)
262316722Sdelphij    {
263316722Sdelphij        /*
264316722Sdelphij         * No installed handler. This shouldn't happen because the dispatch
265316722Sdelphij         * routine checks before we get here, but we check again just in case.
266316722Sdelphij         */
267316722Sdelphij        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
268316722Sdelphij            "Attempting to init a region %p, with no handler\n", RegionObj));
269316722Sdelphij        return_ACPI_STATUS (AE_NOT_EXIST);
270316722Sdelphij    }
271316722Sdelphij
272316722Sdelphij    *RegionContext = NULL;
273316722Sdelphij    if (Function == ACPI_REGION_DEACTIVATE)
274316722Sdelphij    {
275316722Sdelphij        if (PciId)
276316722Sdelphij        {
277316722Sdelphij            ACPI_MEM_FREE (PciId);
278316722Sdelphij        }
279316722Sdelphij        return_ACPI_STATUS (Status);
280316722Sdelphij    }
281316722Sdelphij
282316722Sdelphij    ParentNode = AcpiNsGetParentNode (RegionObj->Region.Node);
283316722Sdelphij
284316722Sdelphij    /*
285316722Sdelphij     * Get the _SEG and _BBN values from the device upon which the handler
286316722Sdelphij     * is installed.
287316722Sdelphij     *
288316722Sdelphij     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
289316722Sdelphij     * This is the device the handler has been registered to handle.
290316722Sdelphij     */
291316722Sdelphij
292316722Sdelphij    /*
293316722Sdelphij     * If the AddressSpace.Node is still pointing to the root, we need
294316722Sdelphij     * to scan upward for a PCI Root bridge and re-associate the OpRegion
295316722Sdelphij     * handlers with that device.
296316722Sdelphij     */
297316722Sdelphij    if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
298316722Sdelphij    {
299316722Sdelphij        /* Start search from the parent object */
300316722Sdelphij
301316722Sdelphij        PciRootNode = ParentNode;
302316722Sdelphij        while (PciRootNode != AcpiGbl_RootNode)
303316722Sdelphij        {
304316722Sdelphij            Status = AcpiUtExecute_HID (PciRootNode, &ObjectHID);
305316722Sdelphij            if (ACPI_SUCCESS (Status))
306316722Sdelphij            {
307316722Sdelphij                /*
308316722Sdelphij                 * Got a valid _HID string, check if this is a PCI root.
309316722Sdelphij                 * New for ACPI 3.0: check for a PCI Express root also.
310316722Sdelphij                 */
311316722Sdelphij                if (!(ACPI_STRNCMP (ObjectHID.Value, PCI_ROOT_HID_STRING,
312316722Sdelphij                                    sizeof (PCI_ROOT_HID_STRING))           ||
313316722Sdelphij                    !(ACPI_STRNCMP (ObjectHID.Value, PCI_EXPRESS_ROOT_HID_STRING,
314316722Sdelphij                                    sizeof (PCI_EXPRESS_ROOT_HID_STRING)))))
315316722Sdelphij                {
316316722Sdelphij                    /* Install a handler for this PCI root bridge */
317316722Sdelphij
318316722Sdelphij                    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) PciRootNode,
319316722Sdelphij                                        ACPI_ADR_SPACE_PCI_CONFIG,
320316722Sdelphij                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
321316722Sdelphij                    if (ACPI_FAILURE (Status))
322316722Sdelphij                    {
323316722Sdelphij                        if (Status == AE_SAME_HANDLER)
324316722Sdelphij                        {
325316722Sdelphij                            /*
326316722Sdelphij                             * It is OK if the handler is already installed on the root
327316722Sdelphij                             * bridge.  Still need to return a context object for the
328316722Sdelphij                             * new PCI_Config operation region, however.
329316722Sdelphij                             */
330316722Sdelphij                            Status = AE_OK;
331316722Sdelphij                        }
332316722Sdelphij                        else
333316722Sdelphij                        {
334316722Sdelphij                            ACPI_REPORT_ERROR ((
335316722Sdelphij                                "Could not install PciConfig handler for Root Bridge %4.4s, %s\n",
336316722Sdelphij                                AcpiUtGetNodeName (PciRootNode), AcpiFormatException (Status)));
337316722Sdelphij                        }
338316722Sdelphij                    }
339316722Sdelphij                    break;
340316722Sdelphij                }
341316722Sdelphij            }
342316722Sdelphij
343316722Sdelphij            PciRootNode = AcpiNsGetParentNode (PciRootNode);
344316722Sdelphij        }
345316722Sdelphij
346316722Sdelphij        /* PCI root bridge not found, use namespace root node */
347316722Sdelphij    }
348316722Sdelphij    else
349316722Sdelphij    {
350316722Sdelphij        PciRootNode = HandlerObj->AddressSpace.Node;
351316722Sdelphij    }
352316722Sdelphij
353316722Sdelphij    /*
354316722Sdelphij     * If this region is now initialized, we are done.
355316722Sdelphij     * (InstallAddressSpaceHandler could have initialized it)
356316722Sdelphij     */
357316722Sdelphij    if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
358316722Sdelphij    {
359316722Sdelphij        return_ACPI_STATUS (AE_OK);
360316722Sdelphij    }
361316722Sdelphij
362316722Sdelphij    /* Region is still not initialized. Create a new context */
363316722Sdelphij
364316722Sdelphij    PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
365316722Sdelphij    if (!PciId)
366316722Sdelphij    {
367316722Sdelphij        return_ACPI_STATUS (AE_NO_MEMORY);
368316722Sdelphij    }
369316722Sdelphij
370316722Sdelphij    /*
371316722Sdelphij     * For PCI_Config space access, we need the segment, bus,
372316722Sdelphij     * device and function numbers.  Acquire them here.
373316722Sdelphij     */
374316722Sdelphij
375316722Sdelphij    /*
376316722Sdelphij     * Get the PCI device and function numbers from the _ADR object
377316722Sdelphij     * contained in the parent's scope.
378316722Sdelphij     */
379316722Sdelphij    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, ParentNode, &PciValue);
380316722Sdelphij
381316722Sdelphij    /*
382316722Sdelphij     * The default is zero, and since the allocation above zeroed
383316722Sdelphij     * the data, just do nothing on failure.
384316722Sdelphij     */
385316722Sdelphij    if (ACPI_SUCCESS (Status))
386316722Sdelphij    {
387316722Sdelphij        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
388316722Sdelphij        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
389316722Sdelphij    }
390316722Sdelphij
391316722Sdelphij    /* The PCI segment number comes from the _SEG method */
392316722Sdelphij
393316722Sdelphij    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, PciRootNode, &PciValue);
394316722Sdelphij    if (ACPI_SUCCESS (Status))
395316722Sdelphij    {
396316722Sdelphij        PciId->Segment = ACPI_LOWORD (PciValue);
397316722Sdelphij    }
398316722Sdelphij
399316722Sdelphij    /* The PCI bus number comes from the _BBN method */
400316722Sdelphij
401316722Sdelphij    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, PciRootNode, &PciValue);
402316722Sdelphij    if (ACPI_SUCCESS (Status))
403316722Sdelphij    {
404316722Sdelphij        PciId->Bus = ACPI_LOWORD (PciValue);
405316722Sdelphij    }
406316722Sdelphij
407316722Sdelphij    /* Complete this device's PciId */
408316722Sdelphij
409316722Sdelphij    AcpiOsDerivePciId (PciRootNode, RegionObj->Region.Node, &PciId);
410316722Sdelphij
411316722Sdelphij    *RegionContext = PciId;
412316722Sdelphij    return_ACPI_STATUS (AE_OK);
413316722Sdelphij}
414316722Sdelphij
415316722Sdelphij
416316722Sdelphij/*******************************************************************************
417316722Sdelphij *
418316722Sdelphij * FUNCTION:    AcpiEvPciBarRegionSetup
419316722Sdelphij *
420316722Sdelphij * PARAMETERS:  Handle              - Region we are interested in
421316722Sdelphij *              Function            - Start or stop
422316722Sdelphij *              HandlerContext      - Address space handler context
423316722Sdelphij *              RegionContext       - Region specific context
424316722Sdelphij *
425316722Sdelphij * RETURN:      Status
426316722Sdelphij *
427316722Sdelphij * DESCRIPTION: Setup a PciBAR operation region
428316722Sdelphij *
429316722Sdelphij * MUTEX:       Assumes namespace is not locked
430316722Sdelphij *
431316722Sdelphij ******************************************************************************/
432316722Sdelphij
433316722SdelphijACPI_STATUS
434316722SdelphijAcpiEvPciBarRegionSetup (
435316722Sdelphij    ACPI_HANDLE             Handle,
436316722Sdelphij    UINT32                  Function,
437316722Sdelphij    void                    *HandlerContext,
438316722Sdelphij    void                    **RegionContext)
439310419Sdelphij{
440310419Sdelphij    ACPI_FUNCTION_TRACE ("EvPciBarRegionSetup");
441310419Sdelphij
442310419Sdelphij
443310419Sdelphij    return_ACPI_STATUS (AE_OK);
444310419Sdelphij}
445310419Sdelphij
446310419Sdelphij
447310419Sdelphij/*******************************************************************************
448310419Sdelphij *
449310419Sdelphij * FUNCTION:    AcpiEvCmosRegionSetup
450310419Sdelphij *
451310419Sdelphij * PARAMETERS:  Handle              - Region we are interested in
452310419Sdelphij *              Function            - Start or stop
453310419Sdelphij *              HandlerContext      - Address space handler context
454310419Sdelphij *              RegionContext       - Region specific context
455310419Sdelphij *
456310419Sdelphij * RETURN:      Status
457310419Sdelphij *
458310419Sdelphij * DESCRIPTION: Setup a CMOS operation region
459310419Sdelphij *
460310419Sdelphij * MUTEX:       Assumes namespace is not locked
461310419Sdelphij *
462310419Sdelphij ******************************************************************************/
463310419Sdelphij
464310419SdelphijACPI_STATUS
465310419SdelphijAcpiEvCmosRegionSetup (
466310419Sdelphij    ACPI_HANDLE             Handle,
467310419Sdelphij    UINT32                  Function,
468310419Sdelphij    void                    *HandlerContext,
469310419Sdelphij    void                    **RegionContext)
470310419Sdelphij{
471310419Sdelphij    ACPI_FUNCTION_TRACE ("EvCmosRegionSetup");
472310419Sdelphij
473310419Sdelphij
474310419Sdelphij    return_ACPI_STATUS (AE_OK);
475310419Sdelphij}
476310419Sdelphij
477310419Sdelphij
478310419Sdelphij/*******************************************************************************
479310419Sdelphij *
480310419Sdelphij * FUNCTION:    AcpiEvDefaultRegionSetup
481310419Sdelphij *
482310419Sdelphij * PARAMETERS:  Handle              - Region we are interested in
483310419Sdelphij *              Function            - Start or stop
484310419Sdelphij *              HandlerContext      - Address space handler context
485310419Sdelphij *              RegionContext       - Region specific context
486310419Sdelphij *
487310419Sdelphij * RETURN:      Status
488310419Sdelphij *
489310419Sdelphij * DESCRIPTION: Default region initialization
490310419Sdelphij *
491310419Sdelphij ******************************************************************************/
492310419Sdelphij
493310419SdelphijACPI_STATUS
494310419SdelphijAcpiEvDefaultRegionSetup (
495310419Sdelphij    ACPI_HANDLE             Handle,
496310419Sdelphij    UINT32                  Function,
497310419Sdelphij    void                    *HandlerContext,
498310419Sdelphij    void                    **RegionContext)
499310419Sdelphij{
500310419Sdelphij    ACPI_FUNCTION_TRACE ("EvDefaultRegionSetup");
501310419Sdelphij
502310419Sdelphij
503310419Sdelphij    if (Function == ACPI_REGION_DEACTIVATE)
504310419Sdelphij    {
505310419Sdelphij        *RegionContext = NULL;
506310419Sdelphij    }
507310419Sdelphij    else
508310419Sdelphij    {
509310419Sdelphij        *RegionContext = HandlerContext;
510310419Sdelphij    }
511310419Sdelphij
512310419Sdelphij    return_ACPI_STATUS (AE_OK);
513310419Sdelphij}
514310419Sdelphij
515310419Sdelphij
516310419Sdelphij/*******************************************************************************
517310419Sdelphij *
518310419Sdelphij * FUNCTION:    AcpiEvInitializeRegion
519310419Sdelphij *
520310419Sdelphij * PARAMETERS:  RegionObj       - Region we are initializing
521310419Sdelphij *              AcpiNsLocked    - Is namespace locked?
522310419Sdelphij *
523310419Sdelphij * RETURN:      Status
524310419Sdelphij *
525310419Sdelphij * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
526310419Sdelphij *              for execution at a later time
527310419Sdelphij *
528310419Sdelphij *              Get the appropriate address space handler for a newly
529310419Sdelphij *              created region.
530310419Sdelphij *
531310419Sdelphij *              This also performs address space specific initialization.  For
532310419Sdelphij *              example, PCI regions must have an _ADR object that contains
533310419Sdelphij *              a PCI address in the scope of the definition.  This address is
534310419Sdelphij *              required to perform an access to PCI config space.
535310419Sdelphij *
536310419Sdelphij ******************************************************************************/
537310419Sdelphij
538310419SdelphijACPI_STATUS
539310419SdelphijAcpiEvInitializeRegion (
540310419Sdelphij    ACPI_OPERAND_OBJECT     *RegionObj,
541310419Sdelphij    BOOLEAN                 AcpiNsLocked)
542310419Sdelphij{
543310419Sdelphij    ACPI_OPERAND_OBJECT     *HandlerObj;
544310419Sdelphij    ACPI_OPERAND_OBJECT     *ObjDesc;
545310419Sdelphij    ACPI_ADR_SPACE_TYPE     SpaceId;
546310419Sdelphij    ACPI_NAMESPACE_NODE     *Node;
547310419Sdelphij    ACPI_STATUS             Status;
548310419Sdelphij    ACPI_NAMESPACE_NODE     *MethodNode;
549310419Sdelphij    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
550310419Sdelphij    ACPI_OPERAND_OBJECT     *RegionObj2;
551310419Sdelphij
552310419Sdelphij
553310419Sdelphij    ACPI_FUNCTION_TRACE_U32 ("EvInitializeRegion", AcpiNsLocked);
554310419Sdelphij
555310419Sdelphij
556310419Sdelphij    if (!RegionObj)
557310419Sdelphij    {
558310419Sdelphij        return_ACPI_STATUS (AE_BAD_PARAMETER);
559310419Sdelphij    }
560310419Sdelphij
561310419Sdelphij    if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
562310419Sdelphij    {
563310419Sdelphij        return_ACPI_STATUS (AE_OK);
564310419Sdelphij    }
565310419Sdelphij
566310419Sdelphij    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
567310419Sdelphij    if (!RegionObj2)
568310419Sdelphij    {
569310419Sdelphij        return_ACPI_STATUS (AE_NOT_EXIST);
570310419Sdelphij    }
571310419Sdelphij
572310419Sdelphij    Node = AcpiNsGetParentNode (RegionObj->Region.Node);
573310419Sdelphij    SpaceId = RegionObj->Region.SpaceId;
574310419Sdelphij
575310419Sdelphij    /* Setup defaults */
576310419Sdelphij
577310419Sdelphij    RegionObj->Region.Handler = NULL;
578310419Sdelphij    RegionObj2->Extra.Method_REG = NULL;
579310419Sdelphij    RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
580310419Sdelphij    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
581310419Sdelphij
582310419Sdelphij    /* Find any "_REG" method associated with this region definition */
583310419Sdelphij
584310419Sdelphij    Status = AcpiNsSearchNode (*RegNamePtr, Node,
585310419Sdelphij                                ACPI_TYPE_METHOD, &MethodNode);
586310419Sdelphij    if (ACPI_SUCCESS (Status))
587310419Sdelphij    {
588310419Sdelphij        /*
589310419Sdelphij         * The _REG method is optional and there can be only one per region
590310419Sdelphij         * definition.  This will be executed when the handler is attached
591310419Sdelphij         * or removed
592310419Sdelphij         */
593310419Sdelphij        RegionObj2->Extra.Method_REG = MethodNode;
594310419Sdelphij    }
595310419Sdelphij
596310419Sdelphij    /*
597310419Sdelphij     * The following loop depends upon the root Node having no parent
598310419Sdelphij     * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
599310419Sdelphij     */
600310419Sdelphij    while (Node)
601310419Sdelphij    {
602310419Sdelphij        /* Check to see if a handler exists */
603310419Sdelphij
604310419Sdelphij        HandlerObj = NULL;
605310419Sdelphij        ObjDesc = AcpiNsGetAttachedObject (Node);
606310419Sdelphij        if (ObjDesc)
607310419Sdelphij        {
608310419Sdelphij            /* Can only be a handler if the object exists */
609310419Sdelphij
610310419Sdelphij            switch (Node->Type)
611310419Sdelphij            {
612310419Sdelphij            case ACPI_TYPE_DEVICE:
613310419Sdelphij
614310419Sdelphij                HandlerObj = ObjDesc->Device.Handler;
615310419Sdelphij                break;
616310419Sdelphij
617310419Sdelphij            case ACPI_TYPE_PROCESSOR:
618310419Sdelphij
619310419Sdelphij                HandlerObj = ObjDesc->Processor.Handler;
620310419Sdelphij                break;
621310419Sdelphij
622310419Sdelphij            case ACPI_TYPE_THERMAL:
623310419Sdelphij
624310419Sdelphij                HandlerObj = ObjDesc->ThermalZone.Handler;
625310419Sdelphij                break;
626310419Sdelphij
627310419Sdelphij            default:
628310419Sdelphij                /* Ignore other objects */
629310419Sdelphij                break;
630310419Sdelphij            }
631310419Sdelphij
632310419Sdelphij            while (HandlerObj)
633310419Sdelphij            {
634310419Sdelphij                /* Is this handler of the correct type? */
635310419Sdelphij
636310419Sdelphij                if (HandlerObj->AddressSpace.SpaceId == SpaceId)
637310419Sdelphij                {
638310419Sdelphij                    /* Found correct handler */
639310419Sdelphij
640310419Sdelphij                    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
641310419Sdelphij                        "Found handler %p for region %p in obj %p\n",
642310419Sdelphij                        HandlerObj, RegionObj, ObjDesc));
643310419Sdelphij
644310419Sdelphij                    Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
645310419Sdelphij                                AcpiNsLocked);
646310419Sdelphij
647310419Sdelphij                    /*
648310419Sdelphij                     * Tell all users that this region is usable by running the _REG
649310419Sdelphij                     * method
650310419Sdelphij                     */
651310419Sdelphij                    if (AcpiNsLocked)
652310419Sdelphij                    {
653310419Sdelphij                        Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
654310419Sdelphij                        if (ACPI_FAILURE (Status))
655310419Sdelphij                        {
656310419Sdelphij                            return_ACPI_STATUS (Status);
657310419Sdelphij                        }
658310419Sdelphij                    }
659310419Sdelphij
660310419Sdelphij                    Status = AcpiEvExecuteRegMethod (RegionObj, 1);
661310419Sdelphij
662310419Sdelphij                    if (AcpiNsLocked)
663310419Sdelphij                    {
664310419Sdelphij                        Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
665310419Sdelphij                        if (ACPI_FAILURE (Status))
666310419Sdelphij                        {
667310419Sdelphij                            return_ACPI_STATUS (Status);
668310419Sdelphij                        }
669310419Sdelphij                    }
670310419Sdelphij
671310419Sdelphij                    return_ACPI_STATUS (AE_OK);
672310419Sdelphij                }
673310419Sdelphij
674310419Sdelphij                /* Try next handler in the list */
675310419Sdelphij
676310419Sdelphij                HandlerObj = HandlerObj->AddressSpace.Next;
677310419Sdelphij            }
678310419Sdelphij        }
679310419Sdelphij
680310419Sdelphij        /*
681310419Sdelphij         * This node does not have the handler we need;
682310419Sdelphij         * Pop up one level
683310419Sdelphij         */
684310419Sdelphij        Node = AcpiNsGetParentNode (Node);
685310419Sdelphij    }
686310419Sdelphij
687310419Sdelphij    /* If we get here, there is no handler for this region */
688310419Sdelphij
689310419Sdelphij    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
690310419Sdelphij        "No handler for RegionType %s(%X) (RegionObj %p)\n",
691310419Sdelphij        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
692310419Sdelphij
693310419Sdelphij    return_ACPI_STATUS (AE_NOT_EXIST);
694310419Sdelphij}
695310419Sdelphij
696310419Sdelphij