Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /******************************************************************************
0002  *
0003  * Module Name: evhandler - Support for Address Space handlers
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acevents.h"
0155 #include "acnamesp.h"
0156 #include "acinterp.h"
0157 
0158 #define _COMPONENT          ACPI_EVENTS
0159         ACPI_MODULE_NAME    ("evhandler")
0160 
0161 
0162 /* Local prototypes */
0163 
0164 static ACPI_STATUS
0165 AcpiEvInstallHandler (
0166     ACPI_HANDLE             ObjHandle,
0167     UINT32                  Level,
0168     void                    *Context,
0169     void                    **ReturnValue);
0170 
0171 
0172 /* These are the address spaces that will get default handlers */
0173 
0174 UINT8        AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] =
0175 {
0176     ACPI_ADR_SPACE_SYSTEM_MEMORY,
0177     ACPI_ADR_SPACE_SYSTEM_IO,
0178     ACPI_ADR_SPACE_PCI_CONFIG,
0179     ACPI_ADR_SPACE_DATA_TABLE
0180 };
0181 
0182 
0183 /*******************************************************************************
0184  *
0185  * FUNCTION:    AcpiEvInstallRegionHandlers
0186  *
0187  * PARAMETERS:  None
0188  *
0189  * RETURN:      Status
0190  *
0191  * DESCRIPTION: Installs the core subsystem default address space handlers.
0192  *
0193  ******************************************************************************/
0194 
0195 ACPI_STATUS
0196 AcpiEvInstallRegionHandlers (
0197     void)
0198 {
0199     ACPI_STATUS             Status;
0200     UINT32                  i;
0201 
0202 
0203     ACPI_FUNCTION_TRACE (EvInstallRegionHandlers);
0204 
0205 
0206     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0207     if (ACPI_FAILURE (Status))
0208     {
0209         return_ACPI_STATUS (Status);
0210     }
0211 
0212     /*
0213      * All address spaces (PCI Config, EC, SMBus) are scope dependent and
0214      * registration must occur for a specific device.
0215      *
0216      * In the case of the system memory and IO address spaces there is
0217      * currently no device associated with the address space. For these we
0218      * use the root.
0219      *
0220      * We install the default PCI config space handler at the root so that
0221      * this space is immediately available even though the we have not
0222      * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
0223      * specification which states that the PCI config space must be always
0224      * available -- even though we are nowhere near ready to find the PCI root
0225      * buses at this point.
0226      *
0227      * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
0228      * has already been installed (via AcpiInstallAddressSpaceHandler).
0229      * Similar for AE_SAME_HANDLER.
0230      */
0231     for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
0232     {
0233         Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode,
0234             AcpiGbl_DefaultAddressSpaces[i],
0235             ACPI_DEFAULT_HANDLER, NULL, NULL);
0236         switch (Status)
0237         {
0238         case AE_OK:
0239         case AE_SAME_HANDLER:
0240         case AE_ALREADY_EXISTS:
0241 
0242             /* These exceptions are all OK */
0243 
0244             Status = AE_OK;
0245             break;
0246 
0247         default:
0248 
0249             goto UnlockAndExit;
0250         }
0251     }
0252 
0253 UnlockAndExit:
0254     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0255     return_ACPI_STATUS (Status);
0256 }
0257 
0258 
0259 /*******************************************************************************
0260  *
0261  * FUNCTION:    AcpiEvHasDefaultHandler
0262  *
0263  * PARAMETERS:  Node                - Namespace node for the device
0264  *              SpaceId             - The address space ID
0265  *
0266  * RETURN:      TRUE if default handler is installed, FALSE otherwise
0267  *
0268  * DESCRIPTION: Check if the default handler is installed for the requested
0269  *              space ID.
0270  *
0271  ******************************************************************************/
0272 
0273 BOOLEAN
0274 AcpiEvHasDefaultHandler (
0275     ACPI_NAMESPACE_NODE     *Node,
0276     ACPI_ADR_SPACE_TYPE     SpaceId)
0277 {
0278     ACPI_OPERAND_OBJECT     *ObjDesc;
0279     ACPI_OPERAND_OBJECT     *HandlerObj;
0280 
0281 
0282     /* Must have an existing internal object */
0283 
0284     ObjDesc = AcpiNsGetAttachedObject (Node);
0285     if (ObjDesc)
0286     {
0287         HandlerObj = ObjDesc->CommonNotify.Handler;
0288 
0289         /* Walk the linked list of handlers for this object */
0290 
0291         while (HandlerObj)
0292         {
0293             if (HandlerObj->AddressSpace.SpaceId == SpaceId)
0294             {
0295                 if (HandlerObj->AddressSpace.HandlerFlags &
0296                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
0297                 {
0298                     return (TRUE);
0299                 }
0300             }
0301 
0302             HandlerObj = HandlerObj->AddressSpace.Next;
0303         }
0304     }
0305 
0306     return (FALSE);
0307 }
0308 
0309 
0310 /*******************************************************************************
0311  *
0312  * FUNCTION:    AcpiEvInstallHandler
0313  *
0314  * PARAMETERS:  WalkNamespace callback
0315  *
0316  * DESCRIPTION: This routine installs an address handler into objects that are
0317  *              of type Region or Device.
0318  *
0319  *              If the Object is a Device, and the device has a handler of
0320  *              the same type then the search is terminated in that branch.
0321  *
0322  *              This is because the existing handler is closer in proximity
0323  *              to any more regions than the one we are trying to install.
0324  *
0325  ******************************************************************************/
0326 
0327 static ACPI_STATUS
0328 AcpiEvInstallHandler (
0329     ACPI_HANDLE             ObjHandle,
0330     UINT32                  Level,
0331     void                    *Context,
0332     void                    **ReturnValue)
0333 {
0334     ACPI_OPERAND_OBJECT     *HandlerObj;
0335     ACPI_OPERAND_OBJECT     *NextHandlerObj;
0336     ACPI_OPERAND_OBJECT     *ObjDesc;
0337     ACPI_NAMESPACE_NODE     *Node;
0338     ACPI_STATUS             Status;
0339 
0340 
0341     ACPI_FUNCTION_NAME (EvInstallHandler);
0342 
0343 
0344     HandlerObj = (ACPI_OPERAND_OBJECT  *) Context;
0345 
0346     /* Parameter validation */
0347 
0348     if (!HandlerObj)
0349     {
0350         return (AE_OK);
0351     }
0352 
0353     /* Convert and validate the device handle */
0354 
0355     Node = AcpiNsValidateHandle (ObjHandle);
0356     if (!Node)
0357     {
0358         return (AE_BAD_PARAMETER);
0359     }
0360 
0361     /*
0362      * We only care about regions and objects that are allowed to have
0363      * address space handlers
0364      */
0365     if ((Node->Type != ACPI_TYPE_DEVICE) &&
0366         (Node->Type != ACPI_TYPE_REGION) &&
0367         (Node != AcpiGbl_RootNode))
0368     {
0369         return (AE_OK);
0370     }
0371 
0372     /* Check for an existing internal object */
0373 
0374     ObjDesc = AcpiNsGetAttachedObject (Node);
0375     if (!ObjDesc)
0376     {
0377         /* No object, just exit */
0378 
0379         return (AE_OK);
0380     }
0381 
0382     /* Devices are handled different than regions */
0383 
0384     if (ObjDesc->Common.Type == ACPI_TYPE_DEVICE)
0385     {
0386         /* Check if this Device already has a handler for this address space */
0387 
0388         NextHandlerObj = AcpiEvFindRegionHandler (
0389             HandlerObj->AddressSpace.SpaceId, ObjDesc->CommonNotify.Handler);
0390         if (NextHandlerObj)
0391         {
0392             /* Found a handler, is it for the same address space? */
0393 
0394             ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
0395                 "Found handler for region [%s] in device %p(%p) handler %p\n",
0396                 AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId),
0397                 ObjDesc, NextHandlerObj, HandlerObj));
0398 
0399             /*
0400              * Since the object we found it on was a device, then it means
0401              * that someone has already installed a handler for the branch
0402              * of the namespace from this device on. Just bail out telling
0403              * the walk routine to not traverse this branch. This preserves
0404              * the scoping rule for handlers.
0405              */
0406             return (AE_CTRL_DEPTH);
0407         }
0408 
0409         /*
0410          * As long as the device didn't have a handler for this space we
0411          * don't care about it. We just ignore it and proceed.
0412          */
0413         return (AE_OK);
0414     }
0415 
0416     /* Object is a Region */
0417 
0418     if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId)
0419     {
0420         /* This region is for a different address space, just ignore it */
0421 
0422         return (AE_OK);
0423     }
0424 
0425     /*
0426      * Now we have a region and it is for the handler's address space type.
0427      *
0428      * First disconnect region for any previous handler (if any)
0429      */
0430     AcpiEvDetachRegion (ObjDesc, FALSE);
0431 
0432     /* Connect the region to the new handler */
0433 
0434     Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE);
0435     return (Status);
0436 }
0437 
0438 
0439 /*******************************************************************************
0440  *
0441  * FUNCTION:    AcpiEvFindRegionHandler
0442  *
0443  * PARAMETERS:  SpaceId         - The address space ID
0444  *              HandlerObj      - Head of the handler object list
0445  *
0446  * RETURN:      Matching handler object. NULL if space ID not matched
0447  *
0448  * DESCRIPTION: Search a handler object list for a match on the address
0449  *              space ID.
0450  *
0451  ******************************************************************************/
0452 
0453 ACPI_OPERAND_OBJECT *
0454 AcpiEvFindRegionHandler (
0455     ACPI_ADR_SPACE_TYPE     SpaceId,
0456     ACPI_OPERAND_OBJECT     *HandlerObj)
0457 {
0458 
0459     /* Walk the handler list for this device */
0460 
0461     while (HandlerObj)
0462     {
0463         /* Same SpaceId indicates a handler is installed */
0464 
0465         if (HandlerObj->AddressSpace.SpaceId == SpaceId)
0466         {
0467             return (HandlerObj);
0468         }
0469 
0470         /* Next handler object */
0471 
0472         HandlerObj = HandlerObj->AddressSpace.Next;
0473     }
0474 
0475     return (NULL);
0476 }
0477 
0478 
0479 /*******************************************************************************
0480  *
0481  * FUNCTION:    AcpiEvInstallSpaceHandler
0482  *
0483  * PARAMETERS:  Node            - Namespace node for the device
0484  *              SpaceId         - The address space ID
0485  *              Handler         - Address of the handler
0486  *              Setup           - Address of the setup function
0487  *              Context         - Value passed to the handler on each access
0488  *
0489  * RETURN:      Status
0490  *
0491  * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
0492  *              Assumes namespace is locked
0493  *
0494  ******************************************************************************/
0495 
0496 ACPI_STATUS
0497 AcpiEvInstallSpaceHandler (
0498     ACPI_NAMESPACE_NODE     *Node,
0499     ACPI_ADR_SPACE_TYPE     SpaceId,
0500     ACPI_ADR_SPACE_HANDLER  Handler,
0501     ACPI_ADR_SPACE_SETUP    Setup,
0502     void                    *Context)
0503 {
0504     ACPI_OPERAND_OBJECT     *ObjDesc;
0505     ACPI_OPERAND_OBJECT     *HandlerObj;
0506     ACPI_STATUS             Status = AE_OK;
0507     ACPI_OBJECT_TYPE        Type;
0508     UINT8                   Flags = 0;
0509 
0510 
0511     ACPI_FUNCTION_TRACE (EvInstallSpaceHandler);
0512 
0513 
0514     /*
0515      * This registration is valid for only the types below and the root.
0516      * The root node is where the default handlers get installed.
0517      */
0518     if ((Node->Type != ACPI_TYPE_DEVICE)     &&
0519         (Node->Type != ACPI_TYPE_PROCESSOR)  &&
0520         (Node->Type != ACPI_TYPE_THERMAL)    &&
0521         (Node != AcpiGbl_RootNode))
0522     {
0523         Status = AE_BAD_PARAMETER;
0524         goto UnlockAndExit;
0525     }
0526 
0527     if (Handler == ACPI_DEFAULT_HANDLER)
0528     {
0529         Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
0530 
0531         switch (SpaceId)
0532         {
0533         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
0534 
0535             Handler = AcpiExSystemMemorySpaceHandler;
0536             Setup   = AcpiEvSystemMemoryRegionSetup;
0537             break;
0538 
0539         case ACPI_ADR_SPACE_SYSTEM_IO:
0540 
0541             Handler = AcpiExSystemIoSpaceHandler;
0542             Setup   = AcpiEvIoSpaceRegionSetup;
0543             break;
0544 
0545         case ACPI_ADR_SPACE_PCI_CONFIG:
0546 
0547             Handler = AcpiExPciConfigSpaceHandler;
0548             Setup   = AcpiEvPciConfigRegionSetup;
0549             break;
0550 
0551         case ACPI_ADR_SPACE_CMOS:
0552 
0553             Handler = AcpiExCmosSpaceHandler;
0554             Setup   = AcpiEvCmosRegionSetup;
0555             break;
0556 
0557         case ACPI_ADR_SPACE_PCI_BAR_TARGET:
0558 
0559             Handler = AcpiExPciBarSpaceHandler;
0560             Setup   = AcpiEvPciBarRegionSetup;
0561             break;
0562 
0563         case ACPI_ADR_SPACE_DATA_TABLE:
0564 
0565             Handler = AcpiExDataTableSpaceHandler;
0566             Setup   = AcpiEvDataTableRegionSetup;
0567             break;
0568 
0569         default:
0570 
0571             Status = AE_BAD_PARAMETER;
0572             goto UnlockAndExit;
0573         }
0574     }
0575 
0576     /* If the caller hasn't specified a setup routine, use the default */
0577 
0578     if (!Setup)
0579     {
0580         Setup = AcpiEvDefaultRegionSetup;
0581     }
0582 
0583     /* Check for an existing internal object */
0584 
0585     ObjDesc = AcpiNsGetAttachedObject (Node);
0586     if (ObjDesc)
0587     {
0588         /*
0589          * The attached device object already exists. Now make sure
0590          * the handler is not already installed.
0591          */
0592         HandlerObj = AcpiEvFindRegionHandler (SpaceId,
0593             ObjDesc->CommonNotify.Handler);
0594 
0595         if (HandlerObj)
0596         {
0597             if (HandlerObj->AddressSpace.Handler == Handler)
0598             {
0599                 /*
0600                  * It is (relatively) OK to attempt to install the SAME
0601                  * handler twice. This can easily happen with the
0602                  * PCI_Config space.
0603                  */
0604                 Status = AE_SAME_HANDLER;
0605                 goto UnlockAndExit;
0606             }
0607             else
0608             {
0609                 /* A handler is already installed */
0610 
0611                 Status = AE_ALREADY_EXISTS;
0612             }
0613 
0614             goto UnlockAndExit;
0615         }
0616     }
0617     else
0618     {
0619         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
0620             "Creating object on Device %p while installing handler\n",
0621             Node));
0622 
0623         /* ObjDesc does not exist, create one */
0624 
0625         if (Node->Type == ACPI_TYPE_ANY)
0626         {
0627             Type = ACPI_TYPE_DEVICE;
0628         }
0629         else
0630         {
0631             Type = Node->Type;
0632         }
0633 
0634         ObjDesc = AcpiUtCreateInternalObject (Type);
0635         if (!ObjDesc)
0636         {
0637             Status = AE_NO_MEMORY;
0638             goto UnlockAndExit;
0639         }
0640 
0641         /* Init new descriptor */
0642 
0643         ObjDesc->Common.Type = (UINT8) Type;
0644 
0645         /* Attach the new object to the Node */
0646 
0647         Status = AcpiNsAttachObject (Node, ObjDesc, Type);
0648 
0649         /* Remove local reference to the object */
0650 
0651         AcpiUtRemoveReference (ObjDesc);
0652 
0653         if (ACPI_FAILURE (Status))
0654         {
0655             goto UnlockAndExit;
0656         }
0657     }
0658 
0659     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
0660         "Installing address handler for region %s(%X) "
0661         "on Device %4.4s %p(%p)\n",
0662         AcpiUtGetRegionName (SpaceId), SpaceId,
0663         AcpiUtGetNodeName (Node), Node, ObjDesc));
0664 
0665     /*
0666      * Install the handler
0667      *
0668      * At this point there is no existing handler. Just allocate the object
0669      * for the handler and link it into the list.
0670      */
0671     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
0672     if (!HandlerObj)
0673     {
0674         Status = AE_NO_MEMORY;
0675         goto UnlockAndExit;
0676     }
0677 
0678     /* Init handler obj */
0679 
0680     Status = AcpiOsCreateMutex (&HandlerObj->AddressSpace.ContextMutex);
0681     if (ACPI_FAILURE (Status))
0682     {
0683         AcpiUtRemoveReference (HandlerObj);
0684         goto UnlockAndExit;
0685     }
0686 
0687     HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
0688     HandlerObj->AddressSpace.HandlerFlags = Flags;
0689     HandlerObj->AddressSpace.RegionList = NULL;
0690     HandlerObj->AddressSpace.Node = Node;
0691     HandlerObj->AddressSpace.Handler = Handler;
0692     HandlerObj->AddressSpace.Context = Context;
0693     HandlerObj->AddressSpace.Setup = Setup;
0694 
0695     /* Install at head of Device.AddressSpace list */
0696 
0697     HandlerObj->AddressSpace.Next = ObjDesc->CommonNotify.Handler;
0698 
0699     /*
0700      * The Device object is the first reference on the HandlerObj.
0701      * Each region that uses the handler adds a reference.
0702      */
0703     ObjDesc->CommonNotify.Handler = HandlerObj;
0704 
0705     /*
0706      * Walk the namespace finding all of the regions this handler will
0707      * manage.
0708      *
0709      * Start at the device and search the branch toward the leaf nodes
0710      * until either the leaf is encountered or a device is detected that
0711      * has an address handler of the same type.
0712      *
0713      * In either case, back up and search down the remainder of the branch
0714      */
0715     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node,
0716         ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
0717         AcpiEvInstallHandler, NULL, HandlerObj, NULL);
0718 
0719 UnlockAndExit:
0720     return_ACPI_STATUS (Status);
0721 }