167754Smsmith/******************************************************************************
267754Smsmith *
3245582Sjkim * Module Name: evregion - Operation Region support
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7316303Sjkim/******************************************************************************
8316303Sjkim *
9316303Sjkim * 1. Copyright Notice
10316303Sjkim *
11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
14316303Sjkim * 2. License
15316303Sjkim *
16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17316303Sjkim * rights. You may have additional license terms from the party that provided
18316303Sjkim * you this software, covering your right to use that party's intellectual
19316303Sjkim * property rights.
20316303Sjkim *
21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
26316303Sjkim * Code in any form, with the right to sublicense such rights; and
27316303Sjkim *
28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29316303Sjkim * license (with the right to sublicense), under only those claims of Intel
30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
33316303Sjkim * license, and in no event shall the patent license extend to any additions
34316303Sjkim * to or modifications of the Original Intel Code. No other license or right
35316303Sjkim * is granted directly or by implication, estoppel or otherwise;
36316303Sjkim *
37316303Sjkim * The above copyright and patent license is granted only if the following
38316303Sjkim * conditions are met:
39316303Sjkim *
40316303Sjkim * 3. Conditions
41316303Sjkim *
42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43316303Sjkim * Redistribution of source code of any substantial portion of the Covered
44316303Sjkim * Code or modification with rights to further distribute source must include
45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
49316303Sjkim * Code and the date of any change. Licensee must include in that file the
50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
51316303Sjkim * must include a prominent statement that the modification is derived,
52316303Sjkim * directly or indirectly, from Original Intel Code.
53316303Sjkim *
54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55316303Sjkim * Redistribution of source code of any substantial portion of the Covered
56316303Sjkim * Code or modification without rights to further distribute source must
57316303Sjkim * include the following Disclaimer and Export Compliance provision in the
58316303Sjkim * documentation and/or other materials provided with distribution. In
59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
61316303Sjkim * license from Licensee to its licensee is limited to the intellectual
62316303Sjkim * property embodied in the software Licensee provides to its licensee, and
63316303Sjkim * not to intellectual property embodied in modifications its licensee may
64316303Sjkim * make.
65316303Sjkim *
66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69316303Sjkim * provision in the documentation and/or other materials provided with the
70316303Sjkim * distribution.
71316303Sjkim *
72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73316303Sjkim * Intel Code.
74316303Sjkim *
75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77316303Sjkim * other dealings in products derived from or relating to the Covered Code
78316303Sjkim * without prior written authorization from Intel.
79316303Sjkim *
80316303Sjkim * 4. Disclaimer and Export Compliance
81316303Sjkim *
82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88316303Sjkim * PARTICULAR PURPOSE.
89316303Sjkim *
90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97316303Sjkim * LIMITED REMEDY.
98316303Sjkim *
99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100316303Sjkim * software or system incorporating such software without first obtaining any
101316303Sjkim * required license or other approval from the U. S. Department of Commerce or
102316303Sjkim * any other agency or department of the United States Government. In the
103316303Sjkim * event Licensee exports any such software from the United States or
104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
105316303Sjkim * ensure that the distribution and export/re-export of the software is in
106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109316303Sjkim * software, or service, directly or indirectly, to any country for which the
110316303Sjkim * United States government or any agency thereof requires an export license,
111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
112316303Sjkim * such license, approval or letter.
113316303Sjkim *
114316303Sjkim *****************************************************************************
115316303Sjkim *
116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
117316303Sjkim * following license:
118316303Sjkim *
119217365Sjkim * Redistribution and use in source and binary forms, with or without
120217365Sjkim * modification, are permitted provided that the following conditions
121217365Sjkim * are met:
122217365Sjkim * 1. Redistributions of source code must retain the above copyright
123217365Sjkim *    notice, this list of conditions, and the following disclaimer,
124217365Sjkim *    without modification.
125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
127217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
128217365Sjkim *    including a substantially similar Disclaimer requirement for further
129217365Sjkim *    binary redistribution.
130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
131217365Sjkim *    of any contributors may be used to endorse or promote products derived
132217365Sjkim *    from this software without specific prior written permission.
13367754Smsmith *
134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145316303Sjkim *
146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
148217365Sjkim * Software Foundation.
14967754Smsmith *
150316303Sjkim *****************************************************************************/
15167754Smsmith
152193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
153193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
154193341Sjkim#include <contrib/dev/acpica/include/acevents.h>
155193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
156193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
15767754Smsmith
15877424Smsmith#define _COMPONENT          ACPI_EVENTS
15991116Smsmith        ACPI_MODULE_NAME    ("evregion")
16067754Smsmith
16167754Smsmith
162245582Sjkimextern UINT8        AcpiGbl_DefaultAddressSpaces[];
163245582Sjkim
164151937Sjkim/* Local prototypes */
165117521Snjl
166220663Sjkimstatic void
167220663SjkimAcpiEvOrphanEcRegMethod (
168249663Sjkim    ACPI_NAMESPACE_NODE     *EcDeviceNode);
169220663Sjkim
170151937Sjkimstatic ACPI_STATUS
171151937SjkimAcpiEvRegRun (
172151937Sjkim    ACPI_HANDLE             ObjHandle,
173151937Sjkim    UINT32                  Level,
174151937Sjkim    void                    *Context,
175151937Sjkim    void                    **ReturnValue);
176151937Sjkim
177151937Sjkim
17877424Smsmith/*******************************************************************************
17967754Smsmith *
180129684Snjl * FUNCTION:    AcpiEvInitializeOpRegions
181129684Snjl *
182129684Snjl * PARAMETERS:  None
183129684Snjl *
184129684Snjl * RETURN:      Status
185129684Snjl *
186129684Snjl * DESCRIPTION: Execute _REG methods for all Operation Regions that have
187129684Snjl *              an installed default region handler.
188129684Snjl *
189129684Snjl ******************************************************************************/
190129684Snjl
191129684SnjlACPI_STATUS
192129684SnjlAcpiEvInitializeOpRegions (
193129684Snjl    void)
194129684Snjl{
195129684Snjl    ACPI_STATUS             Status;
196193267Sjkim    UINT32                  i;
197129684Snjl
198129684Snjl
199167802Sjkim    ACPI_FUNCTION_TRACE (EvInitializeOpRegions);
200129684Snjl
201129684Snjl
202129684Snjl    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
203129684Snjl    if (ACPI_FAILURE (Status))
204129684Snjl    {
205129684Snjl        return_ACPI_STATUS (Status);
206129684Snjl    }
207129684Snjl
208193267Sjkim    /* Run the _REG methods for OpRegions in each default address space */
209193267Sjkim
210129684Snjl    for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
211129684Snjl    {
212193267Sjkim        /*
213198237Sjkim         * Make sure the installed handler is the DEFAULT handler. If not the
214198237Sjkim         * default, the _REG methods will have already been run (when the
215198237Sjkim         * handler was installed)
216129684Snjl         */
217198237Sjkim        if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode,
218198237Sjkim               AcpiGbl_DefaultAddressSpaces[i]))
219198237Sjkim        {
220298714Sjkim            AcpiEvExecuteRegMethods (AcpiGbl_RootNode,
221298714Sjkim                AcpiGbl_DefaultAddressSpaces[i], ACPI_REG_CONNECT);
222198237Sjkim        }
223129684Snjl    }
224129684Snjl
225129684Snjl    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
226129684Snjl    return_ACPI_STATUS (Status);
227129684Snjl}
228129684Snjl
229129684Snjl
230129684Snjl/*******************************************************************************
231129684Snjl *
23267754Smsmith * FUNCTION:    AcpiEvAddressSpaceDispatch
23367754Smsmith *
234123315Snjl * PARAMETERS:  RegionObj           - Internal region object
235228110Sjkim *              FieldObj            - Corresponding field. Can be NULL.
23667754Smsmith *              Function            - Read or Write operation
237193267Sjkim *              RegionOffset        - Where in the region to read or write
23887031Smsmith *              BitWidth            - Field width in bits (8, 16, 32, or 64)
239167802Sjkim *              Value               - Pointer to in or out value, must be
240202771Sjkim *                                    a full 64-bit integer
24167754Smsmith *
24267754Smsmith * RETURN:      Status
24367754Smsmith *
24467754Smsmith * DESCRIPTION: Dispatch an address space or operation region access to
24567754Smsmith *              a previously installed handler.
24667754Smsmith *
247298714Sjkim * NOTE: During early initialization, we always install the default region
248298714Sjkim * handlers for Memory, I/O and PCI_Config. This ensures that these operation
249298714Sjkim * region address spaces are always available as per the ACPI specification.
250298714Sjkim * This is especially needed in order to support the execution of
251298714Sjkim * module-level AML code during loading of the ACPI tables.
252298714Sjkim *
25377424Smsmith ******************************************************************************/
25467754Smsmith
25567754SmsmithACPI_STATUS
25667754SmsmithAcpiEvAddressSpaceDispatch (
25767754Smsmith    ACPI_OPERAND_OBJECT     *RegionObj,
258228110Sjkim    ACPI_OPERAND_OBJECT     *FieldObj,
25967754Smsmith    UINT32                  Function,
260193267Sjkim    UINT32                  RegionOffset,
26167754Smsmith    UINT32                  BitWidth,
262202771Sjkim    UINT64                  *Value)
26367754Smsmith{
26467754Smsmith    ACPI_STATUS             Status;
26577424Smsmith    ACPI_ADR_SPACE_HANDLER  Handler;
26677424Smsmith    ACPI_ADR_SPACE_SETUP    RegionSetup;
26767754Smsmith    ACPI_OPERAND_OBJECT     *HandlerDesc;
26887031Smsmith    ACPI_OPERAND_OBJECT     *RegionObj2;
26967754Smsmith    void                    *RegionContext = NULL;
270228110Sjkim    ACPI_CONNECTION_INFO    *Context;
271272444Sjkim    ACPI_PHYSICAL_ADDRESS   Address;
27267754Smsmith
27367754Smsmith
274167802Sjkim    ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch);
27567754Smsmith
27667754Smsmith
27787031Smsmith    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
27887031Smsmith    if (!RegionObj2)
27987031Smsmith    {
28087031Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
28187031Smsmith    }
28287031Smsmith
283117521Snjl    /* Ensure that there is a handler associated with this region */
284117521Snjl
285123315Snjl    HandlerDesc = RegionObj->Region.Handler;
28667754Smsmith    if (!HandlerDesc)
28767754Smsmith    {
288167802Sjkim        ACPI_ERROR ((AE_INFO,
289167802Sjkim            "No handler for Region [%4.4s] (%p) [%s]",
290123315Snjl            AcpiUtGetNodeName (RegionObj->Region.Node),
29177424Smsmith            RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
29277424Smsmith
29387031Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
29467754Smsmith    }
29567754Smsmith
296228110Sjkim    Context = HandlerDesc->AddressSpace.Context;
297228110Sjkim
29867754Smsmith    /*
299193267Sjkim     * It may be the case that the region has never been initialized.
30077424Smsmith     * Some types of regions require special init code
30167754Smsmith     */
30287031Smsmith    if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
30367754Smsmith    {
304193267Sjkim        /* This region has not been initialized yet, do it */
305193267Sjkim
306117521Snjl        RegionSetup = HandlerDesc->AddressSpace.Setup;
30767754Smsmith        if (!RegionSetup)
30867754Smsmith        {
309117521Snjl            /* No initialization routine, exit with error */
310117521Snjl
311167802Sjkim            ACPI_ERROR ((AE_INFO,
312167802Sjkim                "No init routine for region(%p) [%s]",
31377424Smsmith                RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
314117521Snjl            return_ACPI_STATUS (AE_NOT_EXIST);
31567754Smsmith        }
31667754Smsmith
31767754Smsmith        /*
318193267Sjkim         * We must exit the interpreter because the region setup will
319193267Sjkim         * potentially execute control methods (for example, the _REG method
320193267Sjkim         * for this region)
32167754Smsmith         */
322193267Sjkim        AcpiExExitInterpreter ();
32367754Smsmith
32467754Smsmith        Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
325298714Sjkim            Context, &RegionContext);
32667754Smsmith
32767754Smsmith        /* Re-enter the interpreter */
32867754Smsmith
329193267Sjkim        AcpiExEnterInterpreter ();
33067754Smsmith
331117521Snjl        /* Check for failure of the Region Setup */
332117521Snjl
33367754Smsmith        if (ACPI_FAILURE (Status))
33467754Smsmith        {
335167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
336167802Sjkim                "During region initialization: [%s]",
33777424Smsmith                AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
33887031Smsmith            return_ACPI_STATUS (Status);
33967754Smsmith        }
34067754Smsmith
341193267Sjkim        /* Region initialization may have been completed by RegionSetup */
342193267Sjkim
343117521Snjl        if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
344117521Snjl        {
345117521Snjl            RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
346117521Snjl
347254745Sjkim            /*
348254745Sjkim             * Save the returned context for use in all accesses to
349254745Sjkim             * the handler for this particular region
350254745Sjkim             */
351254745Sjkim            if (!(RegionObj2->Extra.RegionContext))
352117521Snjl            {
353117521Snjl                RegionObj2->Extra.RegionContext = RegionContext;
354117521Snjl            }
355117521Snjl        }
35667754Smsmith    }
35767754Smsmith
358117521Snjl    /* We have everything we need, we can invoke the address space handler */
35967754Smsmith
360117521Snjl    Handler = HandlerDesc->AddressSpace.Handler;
361272444Sjkim    Address = (RegionObj->Region.Address + RegionOffset);
362117521Snjl
363228110Sjkim    /*
364228110Sjkim     * Special handling for GenericSerialBus and GeneralPurposeIo:
365228110Sjkim     * There are three extra parameters that must be passed to the
366228110Sjkim     * handler via the context:
367272444Sjkim     *   1) Connection buffer, a resource template from Connection() op
368272444Sjkim     *   2) Length of the above buffer
369272444Sjkim     *   3) Actual access length from the AccessAs() op
370272444Sjkim     *
371272444Sjkim     * In addition, for GeneralPurposeIo, the Address and BitWidth fields
372272444Sjkim     * are defined as follows:
373272444Sjkim     *   1) Address is the pin number index of the field (bit offset from
374272444Sjkim     *      the previous Connection)
375272444Sjkim     *   2) BitWidth is the actual bit length of the field (number of pins)
376228110Sjkim     */
377272444Sjkim    if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) &&
378228110Sjkim        Context &&
379228110Sjkim        FieldObj)
380228110Sjkim    {
381228110Sjkim        /* Get the Connection (ResourceTemplate) buffer */
382228110Sjkim
383228110Sjkim        Context->Connection = FieldObj->Field.ResourceBuffer;
384228110Sjkim        Context->Length = FieldObj->Field.ResourceLength;
385228110Sjkim        Context->AccessLength = FieldObj->Field.AccessLength;
386228110Sjkim    }
387272444Sjkim    if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) &&
388272444Sjkim        Context &&
389272444Sjkim        FieldObj)
390272444Sjkim    {
391272444Sjkim        /* Get the Connection (ResourceTemplate) buffer */
392228110Sjkim
393272444Sjkim        Context->Connection = FieldObj->Field.ResourceBuffer;
394272444Sjkim        Context->Length = FieldObj->Field.ResourceLength;
395272444Sjkim        Context->AccessLength = FieldObj->Field.AccessLength;
396272444Sjkim        Address = FieldObj->Field.PinNumberIndex;
397272444Sjkim        BitWidth = FieldObj->Field.BitLength;
398272444Sjkim    }
399272444Sjkim
400272444Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
401272444Sjkim        "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
402272444Sjkim        &RegionObj->Region.Handler->AddressSpace, Handler,
403281396Sjkim        ACPI_FORMAT_UINT64 (Address),
404272444Sjkim        AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
405272444Sjkim
406167802Sjkim    if (!(HandlerDesc->AddressSpace.HandlerFlags &
407298714Sjkim        ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
40867754Smsmith    {
40967754Smsmith        /*
410117521Snjl         * For handlers other than the default (supplied) handlers, we must
411117521Snjl         * exit the interpreter because the handler *might* block -- we don't
412117521Snjl         * know what it will do, so we can't hold the lock on the intepreter.
41367754Smsmith         */
414193267Sjkim        AcpiExExitInterpreter();
41567754Smsmith    }
41667754Smsmith
417117521Snjl    /* Call the handler */
418117521Snjl
419272444Sjkim    Status = Handler (Function, Address, BitWidth, Value, Context,
420272444Sjkim        RegionObj2->Extra.RegionContext);
42167754Smsmith
42267754Smsmith    if (ACPI_FAILURE (Status))
42367754Smsmith    {
424167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]",
425167802Sjkim            AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
426327557Sjkim
427327557Sjkim        /*
428327557Sjkim         * Special case for an EC timeout. These are seen so frequently
429327557Sjkim         * that an additional error message is helpful
430327557Sjkim         */
431327557Sjkim        if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
432327557Sjkim            (Status == AE_TIME))
433327557Sjkim        {
434327557Sjkim            ACPI_ERROR ((AE_INFO,
435327557Sjkim                "Timeout from EC hardware or EC device driver"));
436327557Sjkim        }
43767754Smsmith    }
43867754Smsmith
439167802Sjkim    if (!(HandlerDesc->AddressSpace.HandlerFlags &
440298714Sjkim        ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
44167754Smsmith    {
44283174Smsmith        /*
44383174Smsmith         * We just returned from a non-default handler, we must re-enter the
44483174Smsmith         * interpreter
44583174Smsmith         */
446298714Sjkim        AcpiExEnterInterpreter ();
44767754Smsmith    }
44867754Smsmith
44967754Smsmith    return_ACPI_STATUS (Status);
45067754Smsmith}
45167754Smsmith
452123315Snjl
45377424Smsmith/*******************************************************************************
45467754Smsmith *
45599679Siwasaki * FUNCTION:    AcpiEvDetachRegion
45667754Smsmith *
457138287Smarks * PARAMETERS:  RegionObj           - Region Object
458138287Smarks *              AcpiNsIsLocked      - Namespace Region Already Locked?
45967754Smsmith *
46067754Smsmith * RETURN:      None
46167754Smsmith *
46267754Smsmith * DESCRIPTION: Break the association between the handler and the region
46367754Smsmith *              this is a two way association.
46467754Smsmith *
46567754Smsmith ******************************************************************************/
46667754Smsmith
46767754Smsmithvoid
468298714SjkimAcpiEvDetachRegion (
46970243Smsmith    ACPI_OPERAND_OBJECT     *RegionObj,
47070243Smsmith    BOOLEAN                 AcpiNsIsLocked)
47167754Smsmith{
47267754Smsmith    ACPI_OPERAND_OBJECT     *HandlerObj;
47367754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
474272444Sjkim    ACPI_OPERAND_OBJECT     *StartDesc;
47567754Smsmith    ACPI_OPERAND_OBJECT     **LastObjPtr;
47677424Smsmith    ACPI_ADR_SPACE_SETUP    RegionSetup;
477123315Snjl    void                    **RegionContext;
47887031Smsmith    ACPI_OPERAND_OBJECT     *RegionObj2;
47967754Smsmith    ACPI_STATUS             Status;
48067754Smsmith
48167754Smsmith
482167802Sjkim    ACPI_FUNCTION_TRACE (EvDetachRegion);
48367754Smsmith
48483174Smsmith
48587031Smsmith    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
48687031Smsmith    if (!RegionObj2)
48787031Smsmith    {
48899679Siwasaki        return_VOID;
48987031Smsmith    }
490123315Snjl    RegionContext = &RegionObj2->Extra.RegionContext;
49167754Smsmith
492117521Snjl    /* Get the address handler from the region object */
493117521Snjl
494123315Snjl    HandlerObj = RegionObj->Region.Handler;
49567754Smsmith    if (!HandlerObj)
49667754Smsmith    {
497117521Snjl        /* This region has no handler, all done */
498117521Snjl
49967754Smsmith        return_VOID;
50067754Smsmith    }
50167754Smsmith
502117521Snjl    /* Find this region in the handler's list */
50367754Smsmith
504117521Snjl    ObjDesc = HandlerObj->AddressSpace.RegionList;
505272444Sjkim    StartDesc = ObjDesc;
506117521Snjl    LastObjPtr = &HandlerObj->AddressSpace.RegionList;
50767754Smsmith
50867754Smsmith    while (ObjDesc)
50967754Smsmith    {
510117521Snjl        /* Is this the correct Region? */
511117521Snjl
51267754Smsmith        if (ObjDesc == RegionObj)
51367754Smsmith        {
51482367Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
51582367Smsmith                "Removing Region %p from address handler %p\n",
51667754Smsmith                RegionObj, HandlerObj));
517117521Snjl
518117521Snjl            /* This is it, remove it from the handler's list */
519117521Snjl
52067754Smsmith            *LastObjPtr = ObjDesc->Region.Next;
521193267Sjkim            ObjDesc->Region.Next = NULL;        /* Must clear field */
52267754Smsmith
52370243Smsmith            if (AcpiNsIsLocked)
52470243Smsmith            {
52591116Smsmith                Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
52691116Smsmith                if (ACPI_FAILURE (Status))
52791116Smsmith                {
52891116Smsmith                    return_VOID;
52991116Smsmith                }
53070243Smsmith            }
53170243Smsmith
532117521Snjl            /* Now stop region accesses by executing the _REG method */
533117521Snjl
534220663Sjkim            Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
53599679Siwasaki            if (ACPI_FAILURE (Status))
53699679Siwasaki            {
537167802Sjkim                ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
53899679Siwasaki                    AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
53999679Siwasaki            }
54067754Smsmith
54170243Smsmith            if (AcpiNsIsLocked)
54270243Smsmith            {
54391116Smsmith                Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
54491116Smsmith                if (ACPI_FAILURE (Status))
54591116Smsmith                {
54691116Smsmith                    return_VOID;
54791116Smsmith                }
54870243Smsmith            }
54970243Smsmith
550167802Sjkim            /*
551193267Sjkim             * If the region has been activated, call the setup handler with
552193267Sjkim             * the deactivate notification
553167802Sjkim             */
554167802Sjkim            if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
555167802Sjkim            {
556167802Sjkim                RegionSetup = HandlerObj->AddressSpace.Setup;
557167802Sjkim                Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
558167802Sjkim                    HandlerObj->AddressSpace.Context, RegionContext);
559117521Snjl
560254745Sjkim                /*
561254745Sjkim                 * RegionContext should have been released by the deactivate
562254745Sjkim                 * operation. We don't need access to it anymore here.
563254745Sjkim                 */
564254745Sjkim                if (RegionContext)
565254745Sjkim                {
566254745Sjkim                    *RegionContext = NULL;
567254745Sjkim                }
568254745Sjkim
569167802Sjkim                /* Init routine may fail, Just ignore errors */
57067754Smsmith
571167802Sjkim                if (ACPI_FAILURE (Status))
572167802Sjkim                {
573167802Sjkim                    ACPI_EXCEPTION ((AE_INFO, Status,
574167802Sjkim                        "from region handler - deactivate, [%s]",
575167802Sjkim                        AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
576167802Sjkim                }
577117521Snjl
578167802Sjkim                RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
57967754Smsmith            }
58067754Smsmith
58167754Smsmith            /*
582117521Snjl             * Remove handler reference in the region
58367754Smsmith             *
584167802Sjkim             * NOTE: this doesn't mean that the region goes away, the region
585167802Sjkim             * is just inaccessible as indicated to the _REG method
58667754Smsmith             *
587167802Sjkim             * If the region is on the handler's list, this must be the
588167802Sjkim             * region's handler
58967754Smsmith             */
590123315Snjl            RegionObj->Region.Handler = NULL;
591117521Snjl            AcpiUtRemoveReference (HandlerObj);
59267754Smsmith
59367754Smsmith            return_VOID;
594117521Snjl        }
59567754Smsmith
596117521Snjl        /* Walk the linked list of handlers */
59767754Smsmith
59867754Smsmith        LastObjPtr = &ObjDesc->Region.Next;
59967754Smsmith        ObjDesc = ObjDesc->Region.Next;
600272444Sjkim
601272444Sjkim        /* Prevent infinite loop if list is corrupted */
602272444Sjkim
603272444Sjkim        if (ObjDesc == StartDesc)
604272444Sjkim        {
605272444Sjkim            ACPI_ERROR ((AE_INFO,
606272444Sjkim                "Circular handler list in region object %p",
607272444Sjkim                RegionObj));
608272444Sjkim            return_VOID;
609272444Sjkim        }
61067754Smsmith    }
61167754Smsmith
612117521Snjl    /* If we get here, the region was not in the handler's region list */
613117521Snjl
61482367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
61582367Smsmith        "Cannot remove region %p from address handler %p\n",
61667754Smsmith        RegionObj, HandlerObj));
61767754Smsmith
61867754Smsmith    return_VOID;
61967754Smsmith}
62067754Smsmith
62167754Smsmith
62277424Smsmith/*******************************************************************************
62367754Smsmith *
62499679Siwasaki * FUNCTION:    AcpiEvAttachRegion
62567754Smsmith *
626138287Smarks * PARAMETERS:  HandlerObj          - Handler Object
627138287Smarks *              RegionObj           - Region Object
628138287Smarks *              AcpiNsIsLocked      - Namespace Region Already Locked?
62967754Smsmith *
63067754Smsmith * RETURN:      None
63167754Smsmith *
63267754Smsmith * DESCRIPTION: Create the association between the handler and the region
63367754Smsmith *              this is a two way association.
63467754Smsmith *
63567754Smsmith ******************************************************************************/
63667754Smsmith
63767754SmsmithACPI_STATUS
63899679SiwasakiAcpiEvAttachRegion (
63967754Smsmith    ACPI_OPERAND_OBJECT     *HandlerObj,
64067754Smsmith    ACPI_OPERAND_OBJECT     *RegionObj,
64167754Smsmith    BOOLEAN                 AcpiNsIsLocked)
64267754Smsmith{
64367754Smsmith
644167802Sjkim    ACPI_FUNCTION_TRACE (EvAttachRegion);
64567754Smsmith
64667754Smsmith
647298714Sjkim    /* Install the region's handler */
648298714Sjkim
649298714Sjkim    if (RegionObj->Region.Handler)
650298714Sjkim    {
651298714Sjkim        return_ACPI_STATUS (AE_ALREADY_EXISTS);
652298714Sjkim    }
653298714Sjkim
65483174Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
655123315Snjl        "Adding Region [%4.4s] %p to address handler %p [%s]\n",
656123315Snjl        AcpiUtGetNodeName (RegionObj->Region.Node),
657126372Snjl        RegionObj, HandlerObj,
658123315Snjl        AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
65967754Smsmith
660117521Snjl    /* Link this region to the front of the handler's list */
66167754Smsmith
662117521Snjl    RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
663117521Snjl    HandlerObj->AddressSpace.RegionList = RegionObj;
664123315Snjl    RegionObj->Region.Handler = HandlerObj;
665117521Snjl    AcpiUtAddReference (HandlerObj);
666117521Snjl
667123315Snjl    return_ACPI_STATUS (AE_OK);
66867754Smsmith}
66967754Smsmith
67067754Smsmith
67177424Smsmith/*******************************************************************************
67267754Smsmith *
673245582Sjkim * FUNCTION:    AcpiEvExecuteRegMethod
67467754Smsmith *
675245582Sjkim * PARAMETERS:  RegionObj           - Region object
676245582Sjkim *              Function            - Passed to _REG: On (1) or Off (0)
67767754Smsmith *
678245582Sjkim * RETURN:      Status
67967754Smsmith *
680245582Sjkim * DESCRIPTION: Execute _REG method for a region
68167754Smsmith *
68277424Smsmith ******************************************************************************/
68367754Smsmith
684245582SjkimACPI_STATUS
685245582SjkimAcpiEvExecuteRegMethod (
686245582Sjkim    ACPI_OPERAND_OBJECT     *RegionObj,
687245582Sjkim    UINT32                  Function)
68867754Smsmith{
689245582Sjkim    ACPI_EVALUATE_INFO      *Info;
690245582Sjkim    ACPI_OPERAND_OBJECT     *Args[3];
691245582Sjkim    ACPI_OPERAND_OBJECT     *RegionObj2;
692298714Sjkim    const ACPI_NAME         *RegNamePtr = ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__REG);
693298714Sjkim    ACPI_NAMESPACE_NODE     *MethodNode;
694298714Sjkim    ACPI_NAMESPACE_NODE     *Node;
69567754Smsmith    ACPI_STATUS             Status;
69667754Smsmith
69767754Smsmith
698245582Sjkim    ACPI_FUNCTION_TRACE (EvExecuteRegMethod);
69977424Smsmith
70077424Smsmith
701298714Sjkim    if (!AcpiGbl_NamespaceInitialized ||
702298714Sjkim        RegionObj->Region.Handler == NULL)
703298714Sjkim    {
704298714Sjkim        return_ACPI_STATUS (AE_OK);
705298714Sjkim    }
706298714Sjkim
707245582Sjkim    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
708245582Sjkim    if (!RegionObj2)
70967754Smsmith    {
710245582Sjkim        return_ACPI_STATUS (AE_NOT_EXIST);
71167754Smsmith    }
71267754Smsmith
713298714Sjkim    /*
714298714Sjkim     * Find any "_REG" method associated with this region definition.
715298714Sjkim     * The method should always be updated as this function may be
716298714Sjkim     * invoked after a namespace change.
717298714Sjkim     */
718298714Sjkim    Node = RegionObj->Region.Node->Parent;
719298714Sjkim    Status = AcpiNsSearchOneScope (
720298714Sjkim        *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
721298714Sjkim    if (ACPI_SUCCESS (Status))
722298714Sjkim    {
723298714Sjkim        /*
724298714Sjkim         * The _REG method is optional and there can be only one per
725298714Sjkim         * region definition. This will be executed when the handler is
726298714Sjkim         * attached or removed.
727298714Sjkim         */
728298714Sjkim        RegionObj2->Extra.Method_REG = MethodNode;
729298714Sjkim    }
730245582Sjkim    if (RegionObj2->Extra.Method_REG == NULL)
73167754Smsmith    {
732245582Sjkim        return_ACPI_STATUS (AE_OK);
73367754Smsmith    }
73467754Smsmith
735298714Sjkim    /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */
736298714Sjkim
737298714Sjkim    if ((Function == ACPI_REG_CONNECT &&
738298714Sjkim        RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) ||
739298714Sjkim        (Function == ACPI_REG_DISCONNECT &&
740298714Sjkim         !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED)))
741298714Sjkim    {
742298714Sjkim        return_ACPI_STATUS (AE_OK);
743298714Sjkim    }
744298714Sjkim
745245582Sjkim    /* Allocate and initialize the evaluation information block */
74667754Smsmith
747245582Sjkim    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
748245582Sjkim    if (!Info)
74967754Smsmith    {
750245582Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
75167754Smsmith    }
75267754Smsmith
753245582Sjkim    Info->PrefixNode = RegionObj2->Extra.Method_REG;
754249663Sjkim    Info->RelativePathname = NULL;
755245582Sjkim    Info->Parameters = Args;
756245582Sjkim    Info->Flags = ACPI_IGNORE_RETURN_VALUE;
757117521Snjl
75867754Smsmith    /*
759245582Sjkim     * The _REG method has two arguments:
76067754Smsmith     *
761245582Sjkim     * Arg0 - Integer:
762245582Sjkim     *  Operation region space ID Same value as RegionObj->Region.SpaceId
763245582Sjkim     *
764245582Sjkim     * Arg1 - Integer:
765245582Sjkim     *  connection status 1 for connecting the handler, 0 for disconnecting
766245582Sjkim     *  the handler (Passed as a parameter)
76767754Smsmith     */
768245582Sjkim    Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId);
769245582Sjkim    if (!Args[0])
770129684Snjl    {
771245582Sjkim        Status = AE_NO_MEMORY;
772245582Sjkim        goto Cleanup1;
773129684Snjl    }
774129684Snjl
775245582Sjkim    Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function);
776245582Sjkim    if (!Args[1])
777129684Snjl    {
778129684Snjl        Status = AE_NO_MEMORY;
779245582Sjkim        goto Cleanup2;
780129684Snjl    }
781129684Snjl
782245582Sjkim    Args[2] = NULL; /* Terminate list */
783129684Snjl
784245582Sjkim    /* Execute the method, no return value */
785129684Snjl
786245582Sjkim    ACPI_DEBUG_EXEC (
787245582Sjkim        AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL));
788129684Snjl
789245582Sjkim    Status = AcpiNsEvaluate (Info);
790245582Sjkim    AcpiUtRemoveReference (Args[1]);
791129684Snjl
792298714Sjkim    if (ACPI_FAILURE (Status))
793298714Sjkim    {
794298714Sjkim        goto Cleanup2;
795298714Sjkim    }
796298714Sjkim
797298714Sjkim    if (Function == ACPI_REG_CONNECT)
798298714Sjkim    {
799298714Sjkim        RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED;
800298714Sjkim    }
801298714Sjkim    else
802298714Sjkim    {
803298714Sjkim        RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED;
804298714Sjkim    }
805298714Sjkim
806245582SjkimCleanup2:
807245582Sjkim    AcpiUtRemoveReference (Args[0]);
808129684Snjl
809245582SjkimCleanup1:
810245582Sjkim    ACPI_FREE (Info);
811129684Snjl    return_ACPI_STATUS (Status);
812129684Snjl}
813129684Snjl
814129684Snjl
815129684Snjl/*******************************************************************************
816129684Snjl *
817129684Snjl * FUNCTION:    AcpiEvExecuteRegMethods
818129684Snjl *
819129684Snjl * PARAMETERS:  Node            - Namespace node for the device
820129684Snjl *              SpaceId         - The address space ID
821298714Sjkim *              Function        - Passed to _REG: On (1) or Off (0)
822129684Snjl *
823298714Sjkim * RETURN:      None
824129684Snjl *
825138287Smarks * DESCRIPTION: Run all _REG methods for the input Space ID;
826129684Snjl *              Note: assumes namespace is locked, or system init time.
827129684Snjl *
828129684Snjl ******************************************************************************/
829129684Snjl
830298714Sjkimvoid
831129684SnjlAcpiEvExecuteRegMethods (
832129684Snjl    ACPI_NAMESPACE_NODE     *Node,
833298714Sjkim    ACPI_ADR_SPACE_TYPE     SpaceId,
834298714Sjkim    UINT32                  Function)
835129684Snjl{
836287168Sjkim    ACPI_REG_WALK_INFO      Info;
837129684Snjl
838129684Snjl
839167802Sjkim    ACPI_FUNCTION_TRACE (EvExecuteRegMethods);
840129684Snjl
841287168Sjkim    Info.SpaceId = SpaceId;
842298714Sjkim    Info.Function = Function;
843287168Sjkim    Info.RegRunCount = 0;
844129684Snjl
845287168Sjkim    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
846287168Sjkim        "    Running _REG methods for SpaceId %s\n",
847287168Sjkim        AcpiUtGetRegionName (Info.SpaceId)));
848287168Sjkim
849129684Snjl    /*
850193267Sjkim     * Run all _REG methods for all Operation Regions for this space ID. This
851193267Sjkim     * is a separate walk in order to handle any interdependencies between
852193267Sjkim     * regions and _REG methods. (i.e. handlers must be installed for all
853193267Sjkim     * regions of this Space ID before we can run any _REG methods)
854129684Snjl     */
855298714Sjkim    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
856287168Sjkim        ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL);
857129684Snjl
858220663Sjkim    /* Special case for EC: handle "orphan" _REG methods with no region */
859220663Sjkim
860220663Sjkim    if (SpaceId == ACPI_ADR_SPACE_EC)
861220663Sjkim    {
862249663Sjkim        AcpiEvOrphanEcRegMethod (Node);
863220663Sjkim    }
864220663Sjkim
865287168Sjkim    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
866287168Sjkim        "    Executed %u _REG methods for SpaceId %s\n",
867287168Sjkim        Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));
868287168Sjkim
869298714Sjkim    return_VOID;
870129684Snjl}
871129684Snjl
872129684Snjl
873129684Snjl/*******************************************************************************
874129684Snjl *
875123315Snjl * FUNCTION:    AcpiEvRegRun
876123315Snjl *
877123315Snjl * PARAMETERS:  WalkNamespace callback
878123315Snjl *
879123315Snjl * DESCRIPTION: Run _REG method for region objects of the requested spaceID
880123315Snjl *
881123315Snjl ******************************************************************************/
88267754Smsmith
883151937Sjkimstatic ACPI_STATUS
884123315SnjlAcpiEvRegRun (
885123315Snjl    ACPI_HANDLE             ObjHandle,
886123315Snjl    UINT32                  Level,
887123315Snjl    void                    *Context,
888123315Snjl    void                    **ReturnValue)
889123315Snjl{
890123315Snjl    ACPI_OPERAND_OBJECT     *ObjDesc;
891123315Snjl    ACPI_NAMESPACE_NODE     *Node;
892123315Snjl    ACPI_STATUS             Status;
893287168Sjkim    ACPI_REG_WALK_INFO      *Info;
894123315Snjl
895123315Snjl
896287168Sjkim    Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context);
897123315Snjl
898123315Snjl    /* Convert and validate the device handle */
899123315Snjl
900200553Sjkim    Node = AcpiNsValidateHandle (ObjHandle);
901123315Snjl    if (!Node)
902123315Snjl    {
903123315Snjl        return (AE_BAD_PARAMETER);
904123315Snjl    }
905123315Snjl
906123315Snjl    /*
907193267Sjkim     * We only care about regions.and objects that are allowed to have address
908193267Sjkim     * space handlers
909123315Snjl     */
910123315Snjl    if ((Node->Type != ACPI_TYPE_REGION) &&
911123315Snjl        (Node != AcpiGbl_RootNode))
912123315Snjl    {
913123315Snjl        return (AE_OK);
914123315Snjl    }
915123315Snjl
916123315Snjl    /* Check for an existing internal object */
917123315Snjl
918123315Snjl    ObjDesc = AcpiNsGetAttachedObject (Node);
919123315Snjl    if (!ObjDesc)
920123315Snjl    {
921123315Snjl        /* No object, just exit */
922123315Snjl
923123315Snjl        return (AE_OK);
924123315Snjl    }
925123315Snjl
926123315Snjl    /* Object is a Region */
927123315Snjl
928287168Sjkim    if (ObjDesc->Region.SpaceId != Info->SpaceId)
929123315Snjl    {
930193267Sjkim        /* This region is for a different address space, just ignore it */
931193267Sjkim
932123315Snjl        return (AE_OK);
933123315Snjl    }
934123315Snjl
935287168Sjkim    Info->RegRunCount++;
936298714Sjkim    Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function);
937123315Snjl    return (Status);
938123315Snjl}
939123315Snjl
940220663Sjkim
941220663Sjkim/*******************************************************************************
942220663Sjkim *
943220663Sjkim * FUNCTION:    AcpiEvOrphanEcRegMethod
944220663Sjkim *
945249663Sjkim * PARAMETERS:  EcDeviceNode        - Namespace node for an EC device
946220663Sjkim *
947220663Sjkim * RETURN:      None
948220663Sjkim *
949220663Sjkim * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
950220663Sjkim *              device. This is a _REG method that has no corresponding region
951220663Sjkim *              within the EC device scope. The orphan _REG method appears to
952220663Sjkim *              have been enabled by the description of the ECDT in the ACPI
953220663Sjkim *              specification: "The availability of the region space can be
954220663Sjkim *              detected by providing a _REG method object underneath the
955220663Sjkim *              Embedded Controller device."
956220663Sjkim *
957249663Sjkim *              To quickly access the EC device, we use the EcDeviceNode used
958249663Sjkim *              during EC handler installation. Otherwise, we would need to
959249663Sjkim *              perform a time consuming namespace walk, executing _HID
960249663Sjkim *              methods to find the EC device.
961220663Sjkim *
962249663Sjkim *  MUTEX:      Assumes the namespace is locked
963249663Sjkim *
964220663Sjkim ******************************************************************************/
965220663Sjkim
966220663Sjkimstatic void
967220663SjkimAcpiEvOrphanEcRegMethod (
968249663Sjkim    ACPI_NAMESPACE_NODE     *EcDeviceNode)
969220663Sjkim{
970249663Sjkim    ACPI_HANDLE             RegMethod;
971249663Sjkim    ACPI_NAMESPACE_NODE     *NextNode;
972220663Sjkim    ACPI_STATUS             Status;
973220663Sjkim    ACPI_OBJECT_LIST        Args;
974220663Sjkim    ACPI_OBJECT             Objects[2];
975220663Sjkim
976220663Sjkim
977220663Sjkim    ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod);
978220663Sjkim
979220663Sjkim
980249663Sjkim    if (!EcDeviceNode)
981220663Sjkim    {
982220663Sjkim        return_VOID;
983220663Sjkim    }
984220663Sjkim
985220663Sjkim    /* Namespace is currently locked, must release */
986220663Sjkim
987220663Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
988220663Sjkim
989220663Sjkim    /* Get a handle to a _REG method immediately under the EC device */
990220663Sjkim
991249663Sjkim    Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod);
992220663Sjkim    if (ACPI_FAILURE (Status))
993220663Sjkim    {
994249663Sjkim        goto Exit; /* There is no _REG method present */
995220663Sjkim    }
996220663Sjkim
997220663Sjkim    /*
998220663Sjkim     * Execute the _REG method only if there is no Operation Region in
999220663Sjkim     * this scope with the Embedded Controller space ID. Otherwise, it
1000220663Sjkim     * will already have been executed. Note, this allows for Regions
1001220663Sjkim     * with other space IDs to be present; but the code below will then
1002249663Sjkim     * execute the _REG method with the EmbeddedControl SpaceID argument.
1003220663Sjkim     */
1004220663Sjkim    NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL);
1005220663Sjkim    while (NextNode)
1006220663Sjkim    {
1007220663Sjkim        if ((NextNode->Type == ACPI_TYPE_REGION) &&
1008220663Sjkim            (NextNode->Object) &&
1009220663Sjkim            (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC))
1010220663Sjkim        {
1011249663Sjkim            goto Exit; /* Do not execute the _REG */
1012220663Sjkim        }
1013249663Sjkim
1014220663Sjkim        NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode);
1015220663Sjkim    }
1016220663Sjkim
1017249663Sjkim    /* Evaluate the _REG(EmbeddedControl,Connect) method */
1018220663Sjkim
1019220663Sjkim    Args.Count = 2;
1020220663Sjkim    Args.Pointer = Objects;
1021220663Sjkim    Objects[0].Type = ACPI_TYPE_INTEGER;
1022220663Sjkim    Objects[0].Integer.Value = ACPI_ADR_SPACE_EC;
1023220663Sjkim    Objects[1].Type = ACPI_TYPE_INTEGER;
1024220663Sjkim    Objects[1].Integer.Value = ACPI_REG_CONNECT;
1025220663Sjkim
1026220663Sjkim    Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
1027220663Sjkim
1028220663SjkimExit:
1029220663Sjkim    /* We ignore all errors from above, don't care */
1030220663Sjkim
1031220663Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1032220663Sjkim    return_VOID;
1033220663Sjkim}
1034