1 /******************************************************************************
3 * Module Name: evregion - ACPI AddressSpace (OpRegion) handler dispatch
6 *****************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
38 * The above copyright and patent license is granted only if the following
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
73 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
81 * 4. Disclaimer and Export Compliance
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
115 *****************************************************************************/
118 #define __EVREGION_C__
120 #include <contrib/dev/acpica/acpi.h>
121 #include <contrib/dev/acpica/acevents.h>
122 #include <contrib/dev/acpica/acnamesp.h>
123 #include <contrib/dev/acpica/acinterp.h>
125 #define _COMPONENT ACPI_EVENTS
126 ACPI_MODULE_NAME ("evregion")
128 #define ACPI_NUM_DEFAULT_SPACES 4
130 static UINT8 AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] = {
131 ACPI_ADR_SPACE_SYSTEM_MEMORY,
132 ACPI_ADR_SPACE_SYSTEM_IO,
133 ACPI_ADR_SPACE_PCI_CONFIG,
134 ACPI_ADR_SPACE_DATA_TABLE};
136 /* Local prototypes */
140 ACPI_HANDLE ObjHandle,
146 AcpiEvInstallHandler (
147 ACPI_HANDLE ObjHandle,
153 /*******************************************************************************
155 * FUNCTION: AcpiEvInstallRegionHandlers
161 * DESCRIPTION: Installs the core subsystem default address space handlers.
163 ******************************************************************************/
166 AcpiEvInstallRegionHandlers (
173 ACPI_FUNCTION_TRACE ("EvInstallRegionHandlers");
176 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
177 if (ACPI_FAILURE (Status))
179 return_ACPI_STATUS (Status);
183 * All address spaces (PCI Config, EC, SMBus) are scope dependent
184 * and registration must occur for a specific device.
186 * In the case of the system memory and IO address spaces there is currently
187 * no device associated with the address space. For these we use the root.
189 * We install the default PCI config space handler at the root so
190 * that this space is immediately available even though the we have
191 * not enumerated all the PCI Root Buses yet. This is to conform
192 * to the ACPI specification which states that the PCI config
193 * space must be always available -- even though we are nowhere
194 * near ready to find the PCI root buses at this point.
196 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
197 * has already been installed (via AcpiInstallAddressSpaceHandler).
198 * Similar for AE_SAME_HANDLER.
200 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
202 Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode,
203 AcpiGbl_DefaultAddressSpaces[i],
204 ACPI_DEFAULT_HANDLER, NULL, NULL);
208 case AE_SAME_HANDLER:
209 case AE_ALREADY_EXISTS:
211 /* These exceptions are all OK */
223 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
224 return_ACPI_STATUS (Status);
228 /*******************************************************************************
230 * FUNCTION: AcpiEvInitializeOpRegions
236 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
237 * an installed default region handler.
239 ******************************************************************************/
242 AcpiEvInitializeOpRegions (
249 ACPI_FUNCTION_TRACE ("EvInitializeOpRegions");
252 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
253 if (ACPI_FAILURE (Status))
255 return_ACPI_STATUS (Status);
259 * Run the _REG methods for OpRegions in each default address space
261 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
263 /* TBD: Make sure handler is the DEFAULT handler, otherwise
264 * _REG will have already been run.
266 Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode,
267 AcpiGbl_DefaultAddressSpaces[i]);
270 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
271 return_ACPI_STATUS (Status);
275 /*******************************************************************************
277 * FUNCTION: AcpiEvExecuteRegMethod
279 * PARAMETERS: RegionObj - Region object
280 * Function - Passed to _REG: On (1) or Off (0)
284 * DESCRIPTION: Execute _REG method for a region
286 ******************************************************************************/
289 AcpiEvExecuteRegMethod (
290 ACPI_OPERAND_OBJECT *RegionObj,
293 ACPI_PARAMETER_INFO Info;
294 ACPI_OPERAND_OBJECT *Params[3];
295 ACPI_OPERAND_OBJECT *RegionObj2;
299 ACPI_FUNCTION_TRACE ("EvExecuteRegMethod");
302 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
305 return_ACPI_STATUS (AE_NOT_EXIST);
308 if (RegionObj2->Extra.Method_REG == NULL)
310 return_ACPI_STATUS (AE_OK);
314 * The _REG method has two arguments:
316 * Arg0, Integer: Operation region space ID
317 * Same value as RegionObj->Region.SpaceId
318 * Arg1, Integer: connection status
319 * 1 for connecting the handler,
320 * 0 for disconnecting the handler
321 * Passed as a parameter
323 Params[0] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
326 return_ACPI_STATUS (AE_NO_MEMORY);
329 Params[1] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
332 Status = AE_NO_MEMORY;
336 /* Setup the parameter objects */
338 Params[0]->Integer.Value = RegionObj->Region.SpaceId;
339 Params[1]->Integer.Value = Function;
342 Info.Node = RegionObj2->Extra.Method_REG;
343 Info.Parameters = Params;
344 Info.ParameterType = ACPI_PARAM_ARGS;
346 /* Execute the method, no return value */
348 ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
349 ACPI_TYPE_METHOD, Info.Node, NULL));
350 Status = AcpiNsEvaluateByHandle (&Info);
352 AcpiUtRemoveReference (Params[1]);
355 AcpiUtRemoveReference (Params[0]);
357 return_ACPI_STATUS (Status);
361 /*******************************************************************************
363 * FUNCTION: AcpiEvAddressSpaceDispatch
365 * PARAMETERS: RegionObj - Internal region object
366 * Function - Read or Write operation
367 * Address - Where in the space to read or write
368 * BitWidth - Field width in bits (8, 16, 32, or 64)
369 * Value - Pointer to in or out value
373 * DESCRIPTION: Dispatch an address space or operation region access to
374 * a previously installed handler.
376 ******************************************************************************/
379 AcpiEvAddressSpaceDispatch (
380 ACPI_OPERAND_OBJECT *RegionObj,
382 ACPI_PHYSICAL_ADDRESS Address,
388 ACPI_ADR_SPACE_HANDLER Handler;
389 ACPI_ADR_SPACE_SETUP RegionSetup;
390 ACPI_OPERAND_OBJECT *HandlerDesc;
391 ACPI_OPERAND_OBJECT *RegionObj2;
392 void *RegionContext = NULL;
395 ACPI_FUNCTION_TRACE ("EvAddressSpaceDispatch");
398 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
401 return_ACPI_STATUS (AE_NOT_EXIST);
404 /* Ensure that there is a handler associated with this region */
406 HandlerDesc = RegionObj->Region.Handler;
409 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
410 "No handler for Region [%4.4s] (%p) [%s]\n",
411 AcpiUtGetNodeName (RegionObj->Region.Node),
412 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
414 return_ACPI_STATUS (AE_NOT_EXIST);
418 * It may be the case that the region has never been initialized
419 * Some types of regions require special init code
421 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
424 * This region has not been initialized yet, do it
426 RegionSetup = HandlerDesc->AddressSpace.Setup;
429 /* No initialization routine, exit with error */
431 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
432 "No init routine for region(%p) [%s]\n",
433 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
434 return_ACPI_STATUS (AE_NOT_EXIST);
438 * We must exit the interpreter because the region
439 * setup will potentially execute control methods
440 * (e.g., _REG method for this region)
442 AcpiExExitInterpreter ();
444 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE,
445 HandlerDesc->AddressSpace.Context, &RegionContext);
447 /* Re-enter the interpreter */
449 Status2 = AcpiExEnterInterpreter ();
450 if (ACPI_FAILURE (Status2))
452 return_ACPI_STATUS (Status2);
455 /* Check for failure of the Region Setup */
457 if (ACPI_FAILURE (Status))
459 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
460 AcpiFormatException (Status),
461 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
462 return_ACPI_STATUS (Status);
466 * Region initialization may have been completed by RegionSetup
468 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE))
470 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
472 if (RegionObj2->Extra.RegionContext)
474 /* The handler for this region was already installed */
476 ACPI_MEM_FREE (RegionContext);
481 * Save the returned context for use in all accesses to
482 * this particular region
484 RegionObj2->Extra.RegionContext = RegionContext;
489 /* We have everything we need, we can invoke the address space handler */
491 Handler = HandlerDesc->AddressSpace.Handler;
493 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
494 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
495 &RegionObj->Region.Handler->AddressSpace, Handler,
496 ACPI_FORMAT_UINT64 (Address),
497 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
499 if (!(HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
502 * For handlers other than the default (supplied) handlers, we must
503 * exit the interpreter because the handler *might* block -- we don't
504 * know what it will do, so we can't hold the lock on the intepreter.
506 AcpiExExitInterpreter();
509 /* Call the handler */
511 Status = Handler (Function, Address, BitWidth, Value,
512 HandlerDesc->AddressSpace.Context,
513 RegionObj2->Extra.RegionContext);
515 if (ACPI_FAILURE (Status))
517 ACPI_REPORT_ERROR (("Handler for [%s] returned %s\n",
518 AcpiUtGetRegionName (RegionObj->Region.SpaceId),
519 AcpiFormatException (Status)));
522 if (!(HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED))
525 * We just returned from a non-default handler, we must re-enter the
528 Status2 = AcpiExEnterInterpreter ();
529 if (ACPI_FAILURE (Status2))
531 return_ACPI_STATUS (Status2);
535 return_ACPI_STATUS (Status);
539 /*******************************************************************************
541 * FUNCTION: AcpiEvDetachRegion
543 * PARAMETERS: RegionObj - Region Object
544 * AcpiNsIsLocked - Namespace Region Already Locked?
548 * DESCRIPTION: Break the association between the handler and the region
549 * this is a two way association.
551 ******************************************************************************/
555 ACPI_OPERAND_OBJECT *RegionObj,
556 BOOLEAN AcpiNsIsLocked)
558 ACPI_OPERAND_OBJECT *HandlerObj;
559 ACPI_OPERAND_OBJECT *ObjDesc;
560 ACPI_OPERAND_OBJECT **LastObjPtr;
561 ACPI_ADR_SPACE_SETUP RegionSetup;
562 void **RegionContext;
563 ACPI_OPERAND_OBJECT *RegionObj2;
567 ACPI_FUNCTION_TRACE ("EvDetachRegion");
570 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
575 RegionContext = &RegionObj2->Extra.RegionContext;
577 /* Get the address handler from the region object */
579 HandlerObj = RegionObj->Region.Handler;
582 /* This region has no handler, all done */
587 /* Find this region in the handler's list */
589 ObjDesc = HandlerObj->AddressSpace.RegionList;
590 LastObjPtr = &HandlerObj->AddressSpace.RegionList;
594 /* Is this the correct Region? */
596 if (ObjDesc == RegionObj)
598 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
599 "Removing Region %p from address handler %p\n",
600 RegionObj, HandlerObj));
602 /* This is it, remove it from the handler's list */
604 *LastObjPtr = ObjDesc->Region.Next;
605 ObjDesc->Region.Next = NULL; /* Must clear field */
609 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
610 if (ACPI_FAILURE (Status))
616 /* Now stop region accesses by executing the _REG method */
618 Status = AcpiEvExecuteRegMethod (RegionObj, 0);
619 if (ACPI_FAILURE (Status))
621 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
622 AcpiFormatException (Status),
623 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
628 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
629 if (ACPI_FAILURE (Status))
635 /* Call the setup handler with the deactivate notification */
637 RegionSetup = HandlerObj->AddressSpace.Setup;
638 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
639 HandlerObj->AddressSpace.Context, RegionContext);
641 /* Init routine may fail, Just ignore errors */
643 if (ACPI_FAILURE (Status))
645 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
646 AcpiFormatException (Status),
647 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
650 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
653 * Remove handler reference in the region
655 * NOTE: this doesn't mean that the region goes away
656 * The region is just inaccessible as indicated to
659 * If the region is on the handler's list
660 * this better be the region's handler
662 RegionObj->Region.Handler = NULL;
663 AcpiUtRemoveReference (HandlerObj);
668 /* Walk the linked list of handlers */
670 LastObjPtr = &ObjDesc->Region.Next;
671 ObjDesc = ObjDesc->Region.Next;
674 /* If we get here, the region was not in the handler's region list */
676 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
677 "Cannot remove region %p from address handler %p\n",
678 RegionObj, HandlerObj));
684 /*******************************************************************************
686 * FUNCTION: AcpiEvAttachRegion
688 * PARAMETERS: HandlerObj - Handler Object
689 * RegionObj - Region Object
690 * AcpiNsIsLocked - Namespace Region Already Locked?
694 * DESCRIPTION: Create the association between the handler and the region
695 * this is a two way association.
697 ******************************************************************************/
701 ACPI_OPERAND_OBJECT *HandlerObj,
702 ACPI_OPERAND_OBJECT *RegionObj,
703 BOOLEAN AcpiNsIsLocked)
706 ACPI_FUNCTION_TRACE ("EvAttachRegion");
709 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
710 "Adding Region [%4.4s] %p to address handler %p [%s]\n",
711 AcpiUtGetNodeName (RegionObj->Region.Node),
712 RegionObj, HandlerObj,
713 AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
715 /* Link this region to the front of the handler's list */
717 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList;
718 HandlerObj->AddressSpace.RegionList = RegionObj;
720 /* Install the region's handler */
722 if (RegionObj->Region.Handler)
724 return_ACPI_STATUS (AE_ALREADY_EXISTS);
727 RegionObj->Region.Handler = HandlerObj;
728 AcpiUtAddReference (HandlerObj);
730 return_ACPI_STATUS (AE_OK);
734 /*******************************************************************************
736 * FUNCTION: AcpiEvInstallHandler
738 * PARAMETERS: WalkNamespace callback
740 * DESCRIPTION: This routine installs an address handler into objects that are
741 * of type Region or Device.
743 * If the Object is a Device, and the device has a handler of
744 * the same type then the search is terminated in that branch.
746 * This is because the existing handler is closer in proximity
747 * to any more regions than the one we are trying to install.
749 ******************************************************************************/
752 AcpiEvInstallHandler (
753 ACPI_HANDLE ObjHandle,
758 ACPI_OPERAND_OBJECT *HandlerObj;
759 ACPI_OPERAND_OBJECT *NextHandlerObj;
760 ACPI_OPERAND_OBJECT *ObjDesc;
761 ACPI_NAMESPACE_NODE *Node;
765 ACPI_FUNCTION_NAME ("EvInstallHandler");
768 HandlerObj = (ACPI_OPERAND_OBJECT *) Context;
770 /* Parameter validation */
777 /* Convert and validate the device handle */
779 Node = AcpiNsMapHandleToNode (ObjHandle);
782 return (AE_BAD_PARAMETER);
786 * We only care about regions.and objects
787 * that are allowed to have address space handlers
789 if ((Node->Type != ACPI_TYPE_DEVICE) &&
790 (Node->Type != ACPI_TYPE_REGION) &&
791 (Node != AcpiGbl_RootNode))
796 /* Check for an existing internal object */
798 ObjDesc = AcpiNsGetAttachedObject (Node);
801 /* No object, just exit */
806 /* Devices are handled different than regions */
808 if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_DEVICE)
810 /* Check if this Device already has a handler for this address space */
812 NextHandlerObj = ObjDesc->Device.Handler;
813 while (NextHandlerObj)
815 /* Found a handler, is it for the same address space? */
817 if (NextHandlerObj->AddressSpace.SpaceId == HandlerObj->AddressSpace.SpaceId)
819 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
820 "Found handler for region [%s] in device %p(%p) handler %p\n",
821 AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId),
822 ObjDesc, NextHandlerObj, HandlerObj));
825 * Since the object we found it on was a device, then it
826 * means that someone has already installed a handler for
827 * the branch of the namespace from this device on. Just
828 * bail out telling the walk routine to not traverse this
829 * branch. This preserves the scoping rule for handlers.
831 return (AE_CTRL_DEPTH);
834 /* Walk the linked list of handlers attached to this device */
836 NextHandlerObj = NextHandlerObj->AddressSpace.Next;
840 * As long as the device didn't have a handler for this
841 * space we don't care about it. We just ignore it and
847 /* Object is a Region */
849 if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId)
852 * This region is for a different address space
859 * Now we have a region and it is for the handler's address
862 * First disconnect region for any previous handler (if any)
864 AcpiEvDetachRegion (ObjDesc, FALSE);
866 /* Connect the region to the new handler */
868 Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE);
873 /*******************************************************************************
875 * FUNCTION: AcpiEvInstallSpaceHandler
877 * PARAMETERS: Node - Namespace node for the device
878 * SpaceId - The address space ID
879 * Handler - Address of the handler
880 * Setup - Address of the setup function
881 * Context - Value passed to the handler on each access
885 * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
886 * Assumes namespace is locked
888 ******************************************************************************/
891 AcpiEvInstallSpaceHandler (
892 ACPI_NAMESPACE_NODE *Node,
893 ACPI_ADR_SPACE_TYPE SpaceId,
894 ACPI_ADR_SPACE_HANDLER Handler,
895 ACPI_ADR_SPACE_SETUP Setup,
898 ACPI_OPERAND_OBJECT *ObjDesc;
899 ACPI_OPERAND_OBJECT *HandlerObj;
901 ACPI_OBJECT_TYPE Type;
905 ACPI_FUNCTION_TRACE ("EvInstallSpaceHandler");
909 * This registration is valid for only the types below
910 * and the root. This is where the default handlers
913 if ((Node->Type != ACPI_TYPE_DEVICE) &&
914 (Node->Type != ACPI_TYPE_PROCESSOR) &&
915 (Node->Type != ACPI_TYPE_THERMAL) &&
916 (Node != AcpiGbl_RootNode))
918 Status = AE_BAD_PARAMETER;
922 if (Handler == ACPI_DEFAULT_HANDLER)
924 Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
928 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
929 Handler = AcpiExSystemMemorySpaceHandler;
930 Setup = AcpiEvSystemMemoryRegionSetup;
933 case ACPI_ADR_SPACE_SYSTEM_IO:
934 Handler = AcpiExSystemIoSpaceHandler;
935 Setup = AcpiEvIoSpaceRegionSetup;
938 case ACPI_ADR_SPACE_PCI_CONFIG:
939 Handler = AcpiExPciConfigSpaceHandler;
940 Setup = AcpiEvPciConfigRegionSetup;
943 case ACPI_ADR_SPACE_CMOS:
944 Handler = AcpiExCmosSpaceHandler;
945 Setup = AcpiEvCmosRegionSetup;
948 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
949 Handler = AcpiExPciBarSpaceHandler;
950 Setup = AcpiEvPciBarRegionSetup;
953 case ACPI_ADR_SPACE_DATA_TABLE:
954 Handler = AcpiExDataTableSpaceHandler;
959 Status = AE_BAD_PARAMETER;
964 /* If the caller hasn't specified a setup routine, use the default */
968 Setup = AcpiEvDefaultRegionSetup;
971 /* Check for an existing internal object */
973 ObjDesc = AcpiNsGetAttachedObject (Node);
977 * The attached device object already exists.
978 * Make sure the handler is not already installed.
980 HandlerObj = ObjDesc->Device.Handler;
982 /* Walk the handler list for this device */
986 /* Same SpaceId indicates a handler already installed */
988 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
990 if (HandlerObj->AddressSpace.Handler == Handler)
993 * It is (relatively) OK to attempt to install the SAME
994 * handler twice. This can easily happen
995 * with PCI_Config space.
997 Status = AE_SAME_HANDLER;
1002 /* A handler is already installed */
1004 Status = AE_ALREADY_EXISTS;
1009 /* Walk the linked list of handlers */
1011 HandlerObj = HandlerObj->AddressSpace.Next;
1016 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
1017 "Creating object on Device %p while installing handler\n", Node));
1019 /* ObjDesc does not exist, create one */
1021 if (Node->Type == ACPI_TYPE_ANY)
1023 Type = ACPI_TYPE_DEVICE;
1030 ObjDesc = AcpiUtCreateInternalObject (Type);
1033 Status = AE_NO_MEMORY;
1037 /* Init new descriptor */
1039 ObjDesc->Common.Type = (UINT8) Type;
1041 /* Attach the new object to the Node */
1043 Status = AcpiNsAttachObject (Node, ObjDesc, Type);
1045 /* Remove local reference to the object */
1047 AcpiUtRemoveReference (ObjDesc);
1049 if (ACPI_FAILURE (Status))
1055 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
1056 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
1057 AcpiUtGetRegionName (SpaceId), SpaceId,
1058 AcpiUtGetNodeName (Node), Node, ObjDesc));
1061 * Install the handler
1063 * At this point there is no existing handler.
1064 * Just allocate the object for the handler and link it
1067 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
1070 Status = AE_NO_MEMORY;
1074 /* Init handler obj */
1076 HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
1077 HandlerObj->AddressSpace.Hflags = Flags;
1078 HandlerObj->AddressSpace.RegionList = NULL;
1079 HandlerObj->AddressSpace.Node = Node;
1080 HandlerObj->AddressSpace.Handler = Handler;
1081 HandlerObj->AddressSpace.Context = Context;
1082 HandlerObj->AddressSpace.Setup = Setup;
1084 /* Install at head of Device.AddressSpace list */
1086 HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler;
1089 * The Device object is the first reference on the HandlerObj.
1090 * Each region that uses the handler adds a reference.
1092 ObjDesc->Device.Handler = HandlerObj;
1095 * Walk the namespace finding all of the regions this
1096 * handler will manage.
1098 * Start at the device and search the branch toward
1099 * the leaf nodes until either the leaf is encountered or
1100 * a device is detected that has an address handler of the
1103 * In either case, back up and search down the remainder
1106 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
1107 ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler,
1111 return_ACPI_STATUS (Status);
1115 /*******************************************************************************
1117 * FUNCTION: AcpiEvExecuteRegMethods
1119 * PARAMETERS: Node - Namespace node for the device
1120 * SpaceId - The address space ID
1124 * DESCRIPTION: Run all _REG methods for the input Space ID;
1125 * Note: assumes namespace is locked, or system init time.
1127 ******************************************************************************/
1130 AcpiEvExecuteRegMethods (
1131 ACPI_NAMESPACE_NODE *Node,
1132 ACPI_ADR_SPACE_TYPE SpaceId)
1137 ACPI_FUNCTION_TRACE ("EvExecuteRegMethods");
1141 * Run all _REG methods for all Operation Regions for this
1142 * space ID. This is a separate walk in order to handle any
1143 * interdependencies between regions and _REG methods. (i.e. handlers
1144 * must be installed for all regions of this Space ID before we
1145 * can run any _REG methods)
1147 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
1148 ACPI_NS_WALK_UNLOCK, AcpiEvRegRun,
1151 return_ACPI_STATUS (Status);
1155 /*******************************************************************************
1157 * FUNCTION: AcpiEvRegRun
1159 * PARAMETERS: WalkNamespace callback
1161 * DESCRIPTION: Run _REG method for region objects of the requested spaceID
1163 ******************************************************************************/
1167 ACPI_HANDLE ObjHandle,
1172 ACPI_OPERAND_OBJECT *ObjDesc;
1173 ACPI_NAMESPACE_NODE *Node;
1174 ACPI_ADR_SPACE_TYPE SpaceId;
1178 SpaceId = *ACPI_CAST_PTR (ACPI_ADR_SPACE_TYPE, Context);
1180 /* Convert and validate the device handle */
1182 Node = AcpiNsMapHandleToNode (ObjHandle);
1185 return (AE_BAD_PARAMETER);
1189 * We only care about regions.and objects
1190 * that are allowed to have address space handlers
1192 if ((Node->Type != ACPI_TYPE_REGION) &&
1193 (Node != AcpiGbl_RootNode))
1198 /* Check for an existing internal object */
1200 ObjDesc = AcpiNsGetAttachedObject (Node);
1203 /* No object, just exit */
1208 /* Object is a Region */
1210 if (ObjDesc->Region.SpaceId != SpaceId)
1213 * This region is for a different address space
1219 Status = AcpiEvExecuteRegMethod (ObjDesc, 1);