1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3*385cc6b4SJerry Jelinek * Module Name: evregion - Operation Region support 4ae115bc7Smrj * 5ae115bc7Smrj *****************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46ae115bc7Smrj #include "acevents.h" 47ae115bc7Smrj #include "acnamesp.h" 48ae115bc7Smrj #include "acinterp.h" 49ae115bc7Smrj 50ae115bc7Smrj #define _COMPONENT ACPI_EVENTS 51ae115bc7Smrj ACPI_MODULE_NAME ("evregion") 52ae115bc7Smrj 53ae115bc7Smrj 54*385cc6b4SJerry Jelinek extern UINT8 AcpiGbl_DefaultAddressSpaces[]; 55ae115bc7Smrj 56*385cc6b4SJerry Jelinek /* Local prototypes */ 5757190917SDana Myers 5826f3cdf0SGordon Ross static void 5926f3cdf0SGordon Ross AcpiEvOrphanEcRegMethod ( 60*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *EcDeviceNode); 6126f3cdf0SGordon Ross 62ae115bc7Smrj static ACPI_STATUS 63ae115bc7Smrj AcpiEvRegRun ( 64ae115bc7Smrj ACPI_HANDLE ObjHandle, 65ae115bc7Smrj UINT32 Level, 66ae115bc7Smrj void *Context, 67ae115bc7Smrj void **ReturnValue); 68ae115bc7Smrj 6957190917SDana Myers 7057190917SDana Myers /******************************************************************************* 7157190917SDana Myers * 72ae115bc7Smrj * FUNCTION: AcpiEvInitializeOpRegions 73ae115bc7Smrj * 74ae115bc7Smrj * PARAMETERS: None 75ae115bc7Smrj * 76ae115bc7Smrj * RETURN: Status 77ae115bc7Smrj * 78ae115bc7Smrj * DESCRIPTION: Execute _REG methods for all Operation Regions that have 79ae115bc7Smrj * an installed default region handler. 80ae115bc7Smrj * 81ae115bc7Smrj ******************************************************************************/ 82ae115bc7Smrj 83ae115bc7Smrj ACPI_STATUS 84ae115bc7Smrj AcpiEvInitializeOpRegions ( 85ae115bc7Smrj void) 86ae115bc7Smrj { 87ae115bc7Smrj ACPI_STATUS Status; 88db2bae30SDana Myers UINT32 i; 89ae115bc7Smrj 90ae115bc7Smrj 91ae115bc7Smrj ACPI_FUNCTION_TRACE (EvInitializeOpRegions); 92ae115bc7Smrj 93ae115bc7Smrj 94ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 95ae115bc7Smrj if (ACPI_FAILURE (Status)) 96ae115bc7Smrj { 97ae115bc7Smrj return_ACPI_STATUS (Status); 98ae115bc7Smrj } 99ae115bc7Smrj 100aa2aa9a6SDana Myers /* Run the _REG methods for OpRegions in each default address space */ 101aa2aa9a6SDana Myers 102ae115bc7Smrj for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 103ae115bc7Smrj { 104aa2aa9a6SDana Myers /* 10557190917SDana Myers * Make sure the installed handler is the DEFAULT handler. If not the 10657190917SDana Myers * default, the _REG methods will have already been run (when the 10757190917SDana Myers * handler was installed) 108ae115bc7Smrj */ 10957190917SDana Myers if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, 11057190917SDana Myers AcpiGbl_DefaultAddressSpaces[i])) 11157190917SDana Myers { 112*385cc6b4SJerry Jelinek AcpiEvExecuteRegMethods (AcpiGbl_RootNode, 113*385cc6b4SJerry Jelinek AcpiGbl_DefaultAddressSpaces[i], ACPI_REG_CONNECT); 114ae115bc7Smrj } 11557190917SDana Myers } 116ae115bc7Smrj 117ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 118ae115bc7Smrj return_ACPI_STATUS (Status); 119ae115bc7Smrj } 120ae115bc7Smrj 121ae115bc7Smrj 122ae115bc7Smrj /******************************************************************************* 123ae115bc7Smrj * 124ae115bc7Smrj * FUNCTION: AcpiEvAddressSpaceDispatch 125ae115bc7Smrj * 126ae115bc7Smrj * PARAMETERS: RegionObj - Internal region object 127*385cc6b4SJerry Jelinek * FieldObj - Corresponding field. Can be NULL. 128ae115bc7Smrj * Function - Read or Write operation 129aa2aa9a6SDana Myers * RegionOffset - Where in the region to read or write 130ae115bc7Smrj * BitWidth - Field width in bits (8, 16, 32, or 64) 131ae115bc7Smrj * Value - Pointer to in or out value, must be 13226f3cdf0SGordon Ross * a full 64-bit integer 133ae115bc7Smrj * 134ae115bc7Smrj * RETURN: Status 135ae115bc7Smrj * 136ae115bc7Smrj * DESCRIPTION: Dispatch an address space or operation region access to 137ae115bc7Smrj * a previously installed handler. 138ae115bc7Smrj * 139*385cc6b4SJerry Jelinek * NOTE: During early initialization, we always install the default region 140*385cc6b4SJerry Jelinek * handlers for Memory, I/O and PCI_Config. This ensures that these operation 141*385cc6b4SJerry Jelinek * region address spaces are always available as per the ACPI specification. 142*385cc6b4SJerry Jelinek * This is especially needed in order to support the execution of 143*385cc6b4SJerry Jelinek * module-level AML code during loading of the ACPI tables. 144*385cc6b4SJerry Jelinek * 145ae115bc7Smrj ******************************************************************************/ 146ae115bc7Smrj 147ae115bc7Smrj ACPI_STATUS 148ae115bc7Smrj AcpiEvAddressSpaceDispatch ( 149ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj, 150*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *FieldObj, 151ae115bc7Smrj UINT32 Function, 152aa2aa9a6SDana Myers UINT32 RegionOffset, 153ae115bc7Smrj UINT32 BitWidth, 15426f3cdf0SGordon Ross UINT64 *Value) 155ae115bc7Smrj { 156ae115bc7Smrj ACPI_STATUS Status; 157ae115bc7Smrj ACPI_ADR_SPACE_HANDLER Handler; 158ae115bc7Smrj ACPI_ADR_SPACE_SETUP RegionSetup; 159ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerDesc; 160ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj2; 161ae115bc7Smrj void *RegionContext = NULL; 162*385cc6b4SJerry Jelinek ACPI_CONNECTION_INFO *Context; 163*385cc6b4SJerry Jelinek ACPI_PHYSICAL_ADDRESS Address; 164ae115bc7Smrj 165ae115bc7Smrj 166ae115bc7Smrj ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); 167ae115bc7Smrj 168ae115bc7Smrj 169ae115bc7Smrj RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 170ae115bc7Smrj if (!RegionObj2) 171ae115bc7Smrj { 172ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST); 173ae115bc7Smrj } 174ae115bc7Smrj 175ae115bc7Smrj /* Ensure that there is a handler associated with this region */ 176ae115bc7Smrj 177ae115bc7Smrj HandlerDesc = RegionObj->Region.Handler; 178ae115bc7Smrj if (!HandlerDesc) 179ae115bc7Smrj { 180ae115bc7Smrj ACPI_ERROR ((AE_INFO, 181ae115bc7Smrj "No handler for Region [%4.4s] (%p) [%s]", 182ae115bc7Smrj AcpiUtGetNodeName (RegionObj->Region.Node), 183ae115bc7Smrj RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 184ae115bc7Smrj 185ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST); 186ae115bc7Smrj } 187ae115bc7Smrj 188*385cc6b4SJerry Jelinek Context = HandlerDesc->AddressSpace.Context; 189*385cc6b4SJerry Jelinek 190ae115bc7Smrj /* 191aa2aa9a6SDana Myers * It may be the case that the region has never been initialized. 192ae115bc7Smrj * Some types of regions require special init code 193ae115bc7Smrj */ 194ae115bc7Smrj if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 195ae115bc7Smrj { 196aa2aa9a6SDana Myers /* This region has not been initialized yet, do it */ 197aa2aa9a6SDana Myers 198ae115bc7Smrj RegionSetup = HandlerDesc->AddressSpace.Setup; 199ae115bc7Smrj if (!RegionSetup) 200ae115bc7Smrj { 201ae115bc7Smrj /* No initialization routine, exit with error */ 202ae115bc7Smrj 203ae115bc7Smrj ACPI_ERROR ((AE_INFO, 204ae115bc7Smrj "No init routine for region(%p) [%s]", 205ae115bc7Smrj RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 206ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST); 207ae115bc7Smrj } 208ae115bc7Smrj 209ae115bc7Smrj /* 210aa2aa9a6SDana Myers * We must exit the interpreter because the region setup will 211aa2aa9a6SDana Myers * potentially execute control methods (for example, the _REG method 212aa2aa9a6SDana Myers * for this region) 213ae115bc7Smrj */ 214ae115bc7Smrj AcpiExExitInterpreter (); 215ae115bc7Smrj 216ae115bc7Smrj Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, 217*385cc6b4SJerry Jelinek Context, &RegionContext); 218ae115bc7Smrj 219ae115bc7Smrj /* Re-enter the interpreter */ 220ae115bc7Smrj 221db2bae30SDana Myers AcpiExEnterInterpreter (); 222ae115bc7Smrj 223ae115bc7Smrj /* Check for failure of the Region Setup */ 224ae115bc7Smrj 225ae115bc7Smrj if (ACPI_FAILURE (Status)) 226ae115bc7Smrj { 227ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, 228ae115bc7Smrj "During region initialization: [%s]", 229ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 230ae115bc7Smrj return_ACPI_STATUS (Status); 231ae115bc7Smrj } 232ae115bc7Smrj 233aa2aa9a6SDana Myers /* Region initialization may have been completed by RegionSetup */ 234aa2aa9a6SDana Myers 235ae115bc7Smrj if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 236ae115bc7Smrj { 237ae115bc7Smrj RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; 238ae115bc7Smrj 239ae115bc7Smrj /* 240ae115bc7Smrj * Save the returned context for use in all accesses to 241*385cc6b4SJerry Jelinek * the handler for this particular region 242ae115bc7Smrj */ 243*385cc6b4SJerry Jelinek if (!(RegionObj2->Extra.RegionContext)) 244*385cc6b4SJerry Jelinek { 245ae115bc7Smrj RegionObj2->Extra.RegionContext = RegionContext; 246ae115bc7Smrj } 247ae115bc7Smrj } 248ae115bc7Smrj } 249ae115bc7Smrj 250ae115bc7Smrj /* We have everything we need, we can invoke the address space handler */ 251ae115bc7Smrj 252ae115bc7Smrj Handler = HandlerDesc->AddressSpace.Handler; 253*385cc6b4SJerry Jelinek Address = (RegionObj->Region.Address + RegionOffset); 254*385cc6b4SJerry Jelinek 255*385cc6b4SJerry Jelinek /* 256*385cc6b4SJerry Jelinek * Special handling for GenericSerialBus and GeneralPurposeIo: 257*385cc6b4SJerry Jelinek * There are three extra parameters that must be passed to the 258*385cc6b4SJerry Jelinek * handler via the context: 259*385cc6b4SJerry Jelinek * 1) Connection buffer, a resource template from Connection() op 260*385cc6b4SJerry Jelinek * 2) Length of the above buffer 261*385cc6b4SJerry Jelinek * 3) Actual access length from the AccessAs() op 262*385cc6b4SJerry Jelinek * 263*385cc6b4SJerry Jelinek * In addition, for GeneralPurposeIo, the Address and BitWidth fields 264*385cc6b4SJerry Jelinek * are defined as follows: 265*385cc6b4SJerry Jelinek * 1) Address is the pin number index of the field (bit offset from 266*385cc6b4SJerry Jelinek * the previous Connection) 267*385cc6b4SJerry Jelinek * 2) BitWidth is the actual bit length of the field (number of pins) 268*385cc6b4SJerry Jelinek */ 269*385cc6b4SJerry Jelinek if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) && 270*385cc6b4SJerry Jelinek Context && 271*385cc6b4SJerry Jelinek FieldObj) 272*385cc6b4SJerry Jelinek { 273*385cc6b4SJerry Jelinek /* Get the Connection (ResourceTemplate) buffer */ 274*385cc6b4SJerry Jelinek 275*385cc6b4SJerry Jelinek Context->Connection = FieldObj->Field.ResourceBuffer; 276*385cc6b4SJerry Jelinek Context->Length = FieldObj->Field.ResourceLength; 277*385cc6b4SJerry Jelinek Context->AccessLength = FieldObj->Field.AccessLength; 278*385cc6b4SJerry Jelinek } 279*385cc6b4SJerry Jelinek if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) && 280*385cc6b4SJerry Jelinek Context && 281*385cc6b4SJerry Jelinek FieldObj) 282*385cc6b4SJerry Jelinek { 283*385cc6b4SJerry Jelinek /* Get the Connection (ResourceTemplate) buffer */ 284*385cc6b4SJerry Jelinek 285*385cc6b4SJerry Jelinek Context->Connection = FieldObj->Field.ResourceBuffer; 286*385cc6b4SJerry Jelinek Context->Length = FieldObj->Field.ResourceLength; 287*385cc6b4SJerry Jelinek Context->AccessLength = FieldObj->Field.AccessLength; 288*385cc6b4SJerry Jelinek Address = FieldObj->Field.PinNumberIndex; 289*385cc6b4SJerry Jelinek BitWidth = FieldObj->Field.BitLength; 290*385cc6b4SJerry Jelinek } 291ae115bc7Smrj 292ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 293ae115bc7Smrj "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 294ae115bc7Smrj &RegionObj->Region.Handler->AddressSpace, Handler, 295*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (Address), 296ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 297ae115bc7Smrj 298ae115bc7Smrj if (!(HandlerDesc->AddressSpace.HandlerFlags & 299ae115bc7Smrj ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 300ae115bc7Smrj { 301ae115bc7Smrj /* 302ae115bc7Smrj * For handlers other than the default (supplied) handlers, we must 303ae115bc7Smrj * exit the interpreter because the handler *might* block -- we don't 304ae115bc7Smrj * know what it will do, so we can't hold the lock on the intepreter. 305ae115bc7Smrj */ 306ae115bc7Smrj AcpiExExitInterpreter(); 307ae115bc7Smrj } 308ae115bc7Smrj 309ae115bc7Smrj /* Call the handler */ 310ae115bc7Smrj 311*385cc6b4SJerry Jelinek Status = Handler (Function, Address, BitWidth, Value, Context, 312*385cc6b4SJerry Jelinek RegionObj2->Extra.RegionContext); 313ae115bc7Smrj 314ae115bc7Smrj if (ACPI_FAILURE (Status)) 315ae115bc7Smrj { 316ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", 317ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 318ae115bc7Smrj } 319ae115bc7Smrj 320ae115bc7Smrj if (!(HandlerDesc->AddressSpace.HandlerFlags & 321ae115bc7Smrj ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 322ae115bc7Smrj { 323ae115bc7Smrj /* 324ae115bc7Smrj * We just returned from a non-default handler, we must re-enter the 325ae115bc7Smrj * interpreter 326ae115bc7Smrj */ 327db2bae30SDana Myers AcpiExEnterInterpreter (); 328ae115bc7Smrj } 329ae115bc7Smrj 330ae115bc7Smrj return_ACPI_STATUS (Status); 331ae115bc7Smrj } 332ae115bc7Smrj 333ae115bc7Smrj 334ae115bc7Smrj /******************************************************************************* 335ae115bc7Smrj * 336ae115bc7Smrj * FUNCTION: AcpiEvDetachRegion 337ae115bc7Smrj * 338ae115bc7Smrj * PARAMETERS: RegionObj - Region Object 339ae115bc7Smrj * AcpiNsIsLocked - Namespace Region Already Locked? 340ae115bc7Smrj * 341ae115bc7Smrj * RETURN: None 342ae115bc7Smrj * 343ae115bc7Smrj * DESCRIPTION: Break the association between the handler and the region 344ae115bc7Smrj * this is a two way association. 345ae115bc7Smrj * 346ae115bc7Smrj ******************************************************************************/ 347ae115bc7Smrj 348ae115bc7Smrj void 349ae115bc7Smrj AcpiEvDetachRegion ( 350ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj, 351ae115bc7Smrj BOOLEAN AcpiNsIsLocked) 352ae115bc7Smrj { 353ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj; 354ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc; 355*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *StartDesc; 356ae115bc7Smrj ACPI_OPERAND_OBJECT **LastObjPtr; 357ae115bc7Smrj ACPI_ADR_SPACE_SETUP RegionSetup; 358ae115bc7Smrj void **RegionContext; 359ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj2; 360ae115bc7Smrj ACPI_STATUS Status; 361ae115bc7Smrj 362ae115bc7Smrj 363ae115bc7Smrj ACPI_FUNCTION_TRACE (EvDetachRegion); 364ae115bc7Smrj 365ae115bc7Smrj 366ae115bc7Smrj RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 367ae115bc7Smrj if (!RegionObj2) 368ae115bc7Smrj { 369ae115bc7Smrj return_VOID; 370ae115bc7Smrj } 371ae115bc7Smrj RegionContext = &RegionObj2->Extra.RegionContext; 372ae115bc7Smrj 373ae115bc7Smrj /* Get the address handler from the region object */ 374ae115bc7Smrj 375ae115bc7Smrj HandlerObj = RegionObj->Region.Handler; 376ae115bc7Smrj if (!HandlerObj) 377ae115bc7Smrj { 378ae115bc7Smrj /* This region has no handler, all done */ 379ae115bc7Smrj 380ae115bc7Smrj return_VOID; 381ae115bc7Smrj } 382ae115bc7Smrj 383ae115bc7Smrj /* Find this region in the handler's list */ 384ae115bc7Smrj 385ae115bc7Smrj ObjDesc = HandlerObj->AddressSpace.RegionList; 386*385cc6b4SJerry Jelinek StartDesc = ObjDesc; 387ae115bc7Smrj LastObjPtr = &HandlerObj->AddressSpace.RegionList; 388ae115bc7Smrj 389ae115bc7Smrj while (ObjDesc) 390ae115bc7Smrj { 391ae115bc7Smrj /* Is this the correct Region? */ 392ae115bc7Smrj 393ae115bc7Smrj if (ObjDesc == RegionObj) 394ae115bc7Smrj { 395ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 396ae115bc7Smrj "Removing Region %p from address handler %p\n", 397ae115bc7Smrj RegionObj, HandlerObj)); 398ae115bc7Smrj 399ae115bc7Smrj /* This is it, remove it from the handler's list */ 400ae115bc7Smrj 401ae115bc7Smrj *LastObjPtr = ObjDesc->Region.Next; 402ae115bc7Smrj ObjDesc->Region.Next = NULL; /* Must clear field */ 403ae115bc7Smrj 404ae115bc7Smrj if (AcpiNsIsLocked) 405ae115bc7Smrj { 406ae115bc7Smrj Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 407ae115bc7Smrj if (ACPI_FAILURE (Status)) 408ae115bc7Smrj { 409ae115bc7Smrj return_VOID; 410ae115bc7Smrj } 411ae115bc7Smrj } 412ae115bc7Smrj 413ae115bc7Smrj /* Now stop region accesses by executing the _REG method */ 414ae115bc7Smrj 41526f3cdf0SGordon Ross Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT); 416ae115bc7Smrj if (ACPI_FAILURE (Status)) 417ae115bc7Smrj { 418ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", 419ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 420ae115bc7Smrj } 421ae115bc7Smrj 422ae115bc7Smrj if (AcpiNsIsLocked) 423ae115bc7Smrj { 424ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 425ae115bc7Smrj if (ACPI_FAILURE (Status)) 426ae115bc7Smrj { 427ae115bc7Smrj return_VOID; 428ae115bc7Smrj } 429ae115bc7Smrj } 430ae115bc7Smrj 431ae115bc7Smrj /* 432aa2aa9a6SDana Myers * If the region has been activated, call the setup handler with 433aa2aa9a6SDana Myers * the deactivate notification 434ae115bc7Smrj */ 435ae115bc7Smrj if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 436ae115bc7Smrj { 437ae115bc7Smrj RegionSetup = HandlerObj->AddressSpace.Setup; 438ae115bc7Smrj Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, 439ae115bc7Smrj HandlerObj->AddressSpace.Context, RegionContext); 440ae115bc7Smrj 441*385cc6b4SJerry Jelinek /* 442*385cc6b4SJerry Jelinek * RegionContext should have been released by the deactivate 443*385cc6b4SJerry Jelinek * operation. We don't need access to it anymore here. 444*385cc6b4SJerry Jelinek */ 445*385cc6b4SJerry Jelinek if (RegionContext) 446*385cc6b4SJerry Jelinek { 447*385cc6b4SJerry Jelinek *RegionContext = NULL; 448*385cc6b4SJerry Jelinek } 449*385cc6b4SJerry Jelinek 450ae115bc7Smrj /* Init routine may fail, Just ignore errors */ 451ae115bc7Smrj 452ae115bc7Smrj if (ACPI_FAILURE (Status)) 453ae115bc7Smrj { 454ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, 455ae115bc7Smrj "from region handler - deactivate, [%s]", 456ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 457ae115bc7Smrj } 458ae115bc7Smrj 459ae115bc7Smrj RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 460ae115bc7Smrj } 461ae115bc7Smrj 462ae115bc7Smrj /* 463ae115bc7Smrj * Remove handler reference in the region 464ae115bc7Smrj * 465ae115bc7Smrj * NOTE: this doesn't mean that the region goes away, the region 466ae115bc7Smrj * is just inaccessible as indicated to the _REG method 467ae115bc7Smrj * 468ae115bc7Smrj * If the region is on the handler's list, this must be the 469ae115bc7Smrj * region's handler 470ae115bc7Smrj */ 471ae115bc7Smrj RegionObj->Region.Handler = NULL; 472ae115bc7Smrj AcpiUtRemoveReference (HandlerObj); 473ae115bc7Smrj 474ae115bc7Smrj return_VOID; 475ae115bc7Smrj } 476ae115bc7Smrj 477ae115bc7Smrj /* Walk the linked list of handlers */ 478ae115bc7Smrj 479ae115bc7Smrj LastObjPtr = &ObjDesc->Region.Next; 480ae115bc7Smrj ObjDesc = ObjDesc->Region.Next; 481*385cc6b4SJerry Jelinek 482*385cc6b4SJerry Jelinek /* Prevent infinite loop if list is corrupted */ 483*385cc6b4SJerry Jelinek 484*385cc6b4SJerry Jelinek if (ObjDesc == StartDesc) 485*385cc6b4SJerry Jelinek { 486*385cc6b4SJerry Jelinek ACPI_ERROR ((AE_INFO, 487*385cc6b4SJerry Jelinek "Circular handler list in region object %p", 488*385cc6b4SJerry Jelinek RegionObj)); 489*385cc6b4SJerry Jelinek return_VOID; 490*385cc6b4SJerry Jelinek } 491ae115bc7Smrj } 492ae115bc7Smrj 493ae115bc7Smrj /* If we get here, the region was not in the handler's region list */ 494ae115bc7Smrj 495ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 496ae115bc7Smrj "Cannot remove region %p from address handler %p\n", 497ae115bc7Smrj RegionObj, HandlerObj)); 498ae115bc7Smrj 499ae115bc7Smrj return_VOID; 500ae115bc7Smrj } 501ae115bc7Smrj 502ae115bc7Smrj 503ae115bc7Smrj /******************************************************************************* 504ae115bc7Smrj * 505ae115bc7Smrj * FUNCTION: AcpiEvAttachRegion 506ae115bc7Smrj * 507ae115bc7Smrj * PARAMETERS: HandlerObj - Handler Object 508ae115bc7Smrj * RegionObj - Region Object 509ae115bc7Smrj * AcpiNsIsLocked - Namespace Region Already Locked? 510ae115bc7Smrj * 511ae115bc7Smrj * RETURN: None 512ae115bc7Smrj * 513ae115bc7Smrj * DESCRIPTION: Create the association between the handler and the region 514ae115bc7Smrj * this is a two way association. 515ae115bc7Smrj * 516ae115bc7Smrj ******************************************************************************/ 517ae115bc7Smrj 518ae115bc7Smrj ACPI_STATUS 519ae115bc7Smrj AcpiEvAttachRegion ( 520ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj, 521ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj, 522ae115bc7Smrj BOOLEAN AcpiNsIsLocked) 523ae115bc7Smrj { 524ae115bc7Smrj 525ae115bc7Smrj ACPI_FUNCTION_TRACE (EvAttachRegion); 526ae115bc7Smrj 527ae115bc7Smrj 528*385cc6b4SJerry Jelinek /* Install the region's handler */ 529*385cc6b4SJerry Jelinek 530*385cc6b4SJerry Jelinek if (RegionObj->Region.Handler) 531*385cc6b4SJerry Jelinek { 532*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_ALREADY_EXISTS); 533*385cc6b4SJerry Jelinek } 534*385cc6b4SJerry Jelinek 535ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 536ae115bc7Smrj "Adding Region [%4.4s] %p to address handler %p [%s]\n", 537ae115bc7Smrj AcpiUtGetNodeName (RegionObj->Region.Node), 538ae115bc7Smrj RegionObj, HandlerObj, 539ae115bc7Smrj AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 540ae115bc7Smrj 541ae115bc7Smrj /* Link this region to the front of the handler's list */ 542ae115bc7Smrj 543ae115bc7Smrj RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; 544ae115bc7Smrj HandlerObj->AddressSpace.RegionList = RegionObj; 545ae115bc7Smrj RegionObj->Region.Handler = HandlerObj; 546ae115bc7Smrj AcpiUtAddReference (HandlerObj); 547ae115bc7Smrj 548ae115bc7Smrj return_ACPI_STATUS (AE_OK); 549ae115bc7Smrj } 550ae115bc7Smrj 551ae115bc7Smrj 552ae115bc7Smrj /******************************************************************************* 553ae115bc7Smrj * 554*385cc6b4SJerry Jelinek * FUNCTION: AcpiEvExecuteRegMethod 555ae115bc7Smrj * 556*385cc6b4SJerry Jelinek * PARAMETERS: RegionObj - Region object 557*385cc6b4SJerry Jelinek * Function - Passed to _REG: On (1) or Off (0) 558ae115bc7Smrj * 559ae115bc7Smrj * RETURN: Status 560ae115bc7Smrj * 561*385cc6b4SJerry Jelinek * DESCRIPTION: Execute _REG method for a region 562ae115bc7Smrj * 563ae115bc7Smrj ******************************************************************************/ 564ae115bc7Smrj 565ae115bc7Smrj ACPI_STATUS 566*385cc6b4SJerry Jelinek AcpiEvExecuteRegMethod ( 567*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *RegionObj, 568*385cc6b4SJerry Jelinek UINT32 Function) 569ae115bc7Smrj { 570*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info; 571*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *Args[3]; 572*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *RegionObj2; 573*385cc6b4SJerry Jelinek const ACPI_NAME *RegNamePtr = ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__REG); 574*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *MethodNode; 575*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node; 576ae115bc7Smrj ACPI_STATUS Status; 577ae115bc7Smrj 578ae115bc7Smrj 579*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (EvExecuteRegMethod); 580ae115bc7Smrj 581ae115bc7Smrj 582*385cc6b4SJerry Jelinek if (!AcpiGbl_NamespaceInitialized || 583*385cc6b4SJerry Jelinek RegionObj->Region.Handler == NULL) 584*385cc6b4SJerry Jelinek { 585*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 586*385cc6b4SJerry Jelinek } 587*385cc6b4SJerry Jelinek 588*385cc6b4SJerry Jelinek RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 589*385cc6b4SJerry Jelinek if (!RegionObj2) 590*385cc6b4SJerry Jelinek { 591*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NOT_EXIST); 592*385cc6b4SJerry Jelinek } 593*385cc6b4SJerry Jelinek 594ae115bc7Smrj /* 595*385cc6b4SJerry Jelinek * Find any "_REG" method associated with this region definition. 596*385cc6b4SJerry Jelinek * The method should always be updated as this function may be 597*385cc6b4SJerry Jelinek * invoked after a namespace change. 598ae115bc7Smrj */ 599*385cc6b4SJerry Jelinek Node = RegionObj->Region.Node->Parent; 600*385cc6b4SJerry Jelinek Status = AcpiNsSearchOneScope ( 601*385cc6b4SJerry Jelinek *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); 602*385cc6b4SJerry Jelinek if (ACPI_SUCCESS (Status)) 603ae115bc7Smrj { 604ae115bc7Smrj /* 605*385cc6b4SJerry Jelinek * The _REG method is optional and there can be only one per 606*385cc6b4SJerry Jelinek * region definition. This will be executed when the handler is 607*385cc6b4SJerry Jelinek * attached or removed. 608ae115bc7Smrj */ 609*385cc6b4SJerry Jelinek RegionObj2->Extra.Method_REG = MethodNode; 610*385cc6b4SJerry Jelinek } 611*385cc6b4SJerry Jelinek if (RegionObj2->Extra.Method_REG == NULL) 612ae115bc7Smrj { 613*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 614*385cc6b4SJerry Jelinek } 615ae115bc7Smrj 616*385cc6b4SJerry Jelinek /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */ 617*385cc6b4SJerry Jelinek 618*385cc6b4SJerry Jelinek if ((Function == ACPI_REG_CONNECT && 619*385cc6b4SJerry Jelinek RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) || 620*385cc6b4SJerry Jelinek (Function == ACPI_REG_DISCONNECT && 621*385cc6b4SJerry Jelinek !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED))) 622ae115bc7Smrj { 623*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 624*385cc6b4SJerry Jelinek } 625*385cc6b4SJerry Jelinek 626*385cc6b4SJerry Jelinek /* Allocate and initialize the evaluation information block */ 627*385cc6b4SJerry Jelinek 628*385cc6b4SJerry Jelinek Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 629*385cc6b4SJerry Jelinek if (!Info) 630ae115bc7Smrj { 631*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NO_MEMORY); 632*385cc6b4SJerry Jelinek } 633*385cc6b4SJerry Jelinek 634*385cc6b4SJerry Jelinek Info->PrefixNode = RegionObj2->Extra.Method_REG; 635*385cc6b4SJerry Jelinek Info->RelativePathname = NULL; 636*385cc6b4SJerry Jelinek Info->Parameters = Args; 637*385cc6b4SJerry Jelinek Info->Flags = ACPI_IGNORE_RETURN_VALUE; 638*385cc6b4SJerry Jelinek 639ae115bc7Smrj /* 640*385cc6b4SJerry Jelinek * The _REG method has two arguments: 641*385cc6b4SJerry Jelinek * 642*385cc6b4SJerry Jelinek * Arg0 - Integer: 643*385cc6b4SJerry Jelinek * Operation region space ID Same value as RegionObj->Region.SpaceId 644*385cc6b4SJerry Jelinek * 645*385cc6b4SJerry Jelinek * Arg1 - Integer: 646*385cc6b4SJerry Jelinek * connection status 1 for connecting the handler, 0 for disconnecting 647*385cc6b4SJerry Jelinek * the handler (Passed as a parameter) 648ae115bc7Smrj */ 649*385cc6b4SJerry Jelinek Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); 650*385cc6b4SJerry Jelinek if (!Args[0]) 651ae115bc7Smrj { 652ae115bc7Smrj Status = AE_NO_MEMORY; 653*385cc6b4SJerry Jelinek goto Cleanup1; 654ae115bc7Smrj } 655ae115bc7Smrj 656*385cc6b4SJerry Jelinek Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); 657*385cc6b4SJerry Jelinek if (!Args[1]) 658*385cc6b4SJerry Jelinek { 659*385cc6b4SJerry Jelinek Status = AE_NO_MEMORY; 660*385cc6b4SJerry Jelinek goto Cleanup2; 661*385cc6b4SJerry Jelinek } 662ae115bc7Smrj 663*385cc6b4SJerry Jelinek Args[2] = NULL; /* Terminate list */ 664ae115bc7Smrj 665*385cc6b4SJerry Jelinek /* Execute the method, no return value */ 666ae115bc7Smrj 667*385cc6b4SJerry Jelinek ACPI_DEBUG_EXEC ( 668*385cc6b4SJerry Jelinek AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL)); 669ae115bc7Smrj 670*385cc6b4SJerry Jelinek Status = AcpiNsEvaluate (Info); 671*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Args[1]); 672ae115bc7Smrj 673ae115bc7Smrj if (ACPI_FAILURE (Status)) 674ae115bc7Smrj { 675*385cc6b4SJerry Jelinek goto Cleanup2; 676ae115bc7Smrj } 677ae115bc7Smrj 678*385cc6b4SJerry Jelinek if (Function == ACPI_REG_CONNECT) 679ae115bc7Smrj { 680*385cc6b4SJerry Jelinek RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED; 681*385cc6b4SJerry Jelinek } 682*385cc6b4SJerry Jelinek else 683*385cc6b4SJerry Jelinek { 684*385cc6b4SJerry Jelinek RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED; 685ae115bc7Smrj } 686ae115bc7Smrj 687*385cc6b4SJerry Jelinek Cleanup2: 688*385cc6b4SJerry Jelinek AcpiUtRemoveReference (Args[0]); 689ae115bc7Smrj 690*385cc6b4SJerry Jelinek Cleanup1: 691*385cc6b4SJerry Jelinek ACPI_FREE (Info); 692ae115bc7Smrj return_ACPI_STATUS (Status); 693ae115bc7Smrj } 694ae115bc7Smrj 695ae115bc7Smrj 696ae115bc7Smrj /******************************************************************************* 697ae115bc7Smrj * 698ae115bc7Smrj * FUNCTION: AcpiEvExecuteRegMethods 699ae115bc7Smrj * 700ae115bc7Smrj * PARAMETERS: Node - Namespace node for the device 701ae115bc7Smrj * SpaceId - The address space ID 702*385cc6b4SJerry Jelinek * Function - Passed to _REG: On (1) or Off (0) 703ae115bc7Smrj * 704*385cc6b4SJerry Jelinek * RETURN: None 705ae115bc7Smrj * 706ae115bc7Smrj * DESCRIPTION: Run all _REG methods for the input Space ID; 707ae115bc7Smrj * Note: assumes namespace is locked, or system init time. 708ae115bc7Smrj * 709ae115bc7Smrj ******************************************************************************/ 710ae115bc7Smrj 711*385cc6b4SJerry Jelinek void 712ae115bc7Smrj AcpiEvExecuteRegMethods ( 713ae115bc7Smrj ACPI_NAMESPACE_NODE *Node, 714*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_TYPE SpaceId, 715*385cc6b4SJerry Jelinek UINT32 Function) 716ae115bc7Smrj { 717*385cc6b4SJerry Jelinek ACPI_REG_WALK_INFO Info; 718ae115bc7Smrj 719ae115bc7Smrj 720ae115bc7Smrj ACPI_FUNCTION_TRACE (EvExecuteRegMethods); 721ae115bc7Smrj 722*385cc6b4SJerry Jelinek Info.SpaceId = SpaceId; 723*385cc6b4SJerry Jelinek Info.Function = Function; 724*385cc6b4SJerry Jelinek Info.RegRunCount = 0; 725*385cc6b4SJerry Jelinek 726*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 727*385cc6b4SJerry Jelinek " Running _REG methods for SpaceId %s\n", 728*385cc6b4SJerry Jelinek AcpiUtGetRegionName (Info.SpaceId))); 729ae115bc7Smrj 730ae115bc7Smrj /* 731aa2aa9a6SDana Myers * Run all _REG methods for all Operation Regions for this space ID. This 732aa2aa9a6SDana Myers * is a separate walk in order to handle any interdependencies between 733aa2aa9a6SDana Myers * regions and _REG methods. (i.e. handlers must be installed for all 734aa2aa9a6SDana Myers * regions of this Space ID before we can run any _REG methods) 735ae115bc7Smrj */ 736*385cc6b4SJerry Jelinek (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 737*385cc6b4SJerry Jelinek ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL); 738ae115bc7Smrj 73926f3cdf0SGordon Ross /* Special case for EC: handle "orphan" _REG methods with no region */ 74026f3cdf0SGordon Ross 74126f3cdf0SGordon Ross if (SpaceId == ACPI_ADR_SPACE_EC) 74226f3cdf0SGordon Ross { 743*385cc6b4SJerry Jelinek AcpiEvOrphanEcRegMethod (Node); 74426f3cdf0SGordon Ross } 74526f3cdf0SGordon Ross 746*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 747*385cc6b4SJerry Jelinek " Executed %u _REG methods for SpaceId %s\n", 748*385cc6b4SJerry Jelinek Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId))); 749*385cc6b4SJerry Jelinek 750*385cc6b4SJerry Jelinek return_VOID; 751ae115bc7Smrj } 752ae115bc7Smrj 753ae115bc7Smrj 754ae115bc7Smrj /******************************************************************************* 755ae115bc7Smrj * 756ae115bc7Smrj * FUNCTION: AcpiEvRegRun 757ae115bc7Smrj * 758ae115bc7Smrj * PARAMETERS: WalkNamespace callback 759ae115bc7Smrj * 760ae115bc7Smrj * DESCRIPTION: Run _REG method for region objects of the requested spaceID 761ae115bc7Smrj * 762ae115bc7Smrj ******************************************************************************/ 763ae115bc7Smrj 764ae115bc7Smrj static ACPI_STATUS 765ae115bc7Smrj AcpiEvRegRun ( 766ae115bc7Smrj ACPI_HANDLE ObjHandle, 767ae115bc7Smrj UINT32 Level, 768ae115bc7Smrj void *Context, 769ae115bc7Smrj void **ReturnValue) 770ae115bc7Smrj { 771ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc; 772ae115bc7Smrj ACPI_NAMESPACE_NODE *Node; 773ae115bc7Smrj ACPI_STATUS Status; 774*385cc6b4SJerry Jelinek ACPI_REG_WALK_INFO *Info; 775ae115bc7Smrj 776ae115bc7Smrj 777*385cc6b4SJerry Jelinek Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context); 778ae115bc7Smrj 779ae115bc7Smrj /* Convert and validate the device handle */ 780ae115bc7Smrj 78126f3cdf0SGordon Ross Node = AcpiNsValidateHandle (ObjHandle); 782ae115bc7Smrj if (!Node) 783ae115bc7Smrj { 784ae115bc7Smrj return (AE_BAD_PARAMETER); 785ae115bc7Smrj } 786ae115bc7Smrj 787ae115bc7Smrj /* 788aa2aa9a6SDana Myers * We only care about regions.and objects that are allowed to have address 789aa2aa9a6SDana Myers * space handlers 790ae115bc7Smrj */ 791ae115bc7Smrj if ((Node->Type != ACPI_TYPE_REGION) && 792ae115bc7Smrj (Node != AcpiGbl_RootNode)) 793ae115bc7Smrj { 794ae115bc7Smrj return (AE_OK); 795ae115bc7Smrj } 796ae115bc7Smrj 797ae115bc7Smrj /* Check for an existing internal object */ 798ae115bc7Smrj 799ae115bc7Smrj ObjDesc = AcpiNsGetAttachedObject (Node); 800ae115bc7Smrj if (!ObjDesc) 801ae115bc7Smrj { 802ae115bc7Smrj /* No object, just exit */ 803ae115bc7Smrj 804ae115bc7Smrj return (AE_OK); 805ae115bc7Smrj } 806ae115bc7Smrj 807ae115bc7Smrj /* Object is a Region */ 808ae115bc7Smrj 809*385cc6b4SJerry Jelinek if (ObjDesc->Region.SpaceId != Info->SpaceId) 810ae115bc7Smrj { 811aa2aa9a6SDana Myers /* This region is for a different address space, just ignore it */ 812aa2aa9a6SDana Myers 813ae115bc7Smrj return (AE_OK); 814ae115bc7Smrj } 815ae115bc7Smrj 816*385cc6b4SJerry Jelinek Info->RegRunCount++; 817*385cc6b4SJerry Jelinek Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function); 818ae115bc7Smrj return (Status); 819ae115bc7Smrj } 820ae115bc7Smrj 82126f3cdf0SGordon Ross 82226f3cdf0SGordon Ross /******************************************************************************* 82326f3cdf0SGordon Ross * 82426f3cdf0SGordon Ross * FUNCTION: AcpiEvOrphanEcRegMethod 82526f3cdf0SGordon Ross * 826*385cc6b4SJerry Jelinek * PARAMETERS: EcDeviceNode - Namespace node for an EC device 82726f3cdf0SGordon Ross * 82826f3cdf0SGordon Ross * RETURN: None 82926f3cdf0SGordon Ross * 83026f3cdf0SGordon Ross * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 83126f3cdf0SGordon Ross * device. This is a _REG method that has no corresponding region 83226f3cdf0SGordon Ross * within the EC device scope. The orphan _REG method appears to 83326f3cdf0SGordon Ross * have been enabled by the description of the ECDT in the ACPI 83426f3cdf0SGordon Ross * specification: "The availability of the region space can be 83526f3cdf0SGordon Ross * detected by providing a _REG method object underneath the 83626f3cdf0SGordon Ross * Embedded Controller device." 83726f3cdf0SGordon Ross * 838*385cc6b4SJerry Jelinek * To quickly access the EC device, we use the EcDeviceNode used 839*385cc6b4SJerry Jelinek * during EC handler installation. Otherwise, we would need to 840*385cc6b4SJerry Jelinek * perform a time consuming namespace walk, executing _HID 841*385cc6b4SJerry Jelinek * methods to find the EC device. 842*385cc6b4SJerry Jelinek * 843*385cc6b4SJerry Jelinek * MUTEX: Assumes the namespace is locked 84426f3cdf0SGordon Ross * 84526f3cdf0SGordon Ross ******************************************************************************/ 84626f3cdf0SGordon Ross 84726f3cdf0SGordon Ross static void 84826f3cdf0SGordon Ross AcpiEvOrphanEcRegMethod ( 849*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *EcDeviceNode) 85026f3cdf0SGordon Ross { 851*385cc6b4SJerry Jelinek ACPI_HANDLE RegMethod; 852*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *NextNode; 85326f3cdf0SGordon Ross ACPI_STATUS Status; 85426f3cdf0SGordon Ross ACPI_OBJECT_LIST Args; 85526f3cdf0SGordon Ross ACPI_OBJECT Objects[2]; 85626f3cdf0SGordon Ross 85726f3cdf0SGordon Ross 85826f3cdf0SGordon Ross ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); 85926f3cdf0SGordon Ross 86026f3cdf0SGordon Ross 861*385cc6b4SJerry Jelinek if (!EcDeviceNode) 86226f3cdf0SGordon Ross { 86326f3cdf0SGordon Ross return_VOID; 86426f3cdf0SGordon Ross } 86526f3cdf0SGordon Ross 86626f3cdf0SGordon Ross /* Namespace is currently locked, must release */ 86726f3cdf0SGordon Ross 86826f3cdf0SGordon Ross (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 86926f3cdf0SGordon Ross 87026f3cdf0SGordon Ross /* Get a handle to a _REG method immediately under the EC device */ 87126f3cdf0SGordon Ross 872*385cc6b4SJerry Jelinek Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod); 87326f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 87426f3cdf0SGordon Ross { 875*385cc6b4SJerry Jelinek goto Exit; /* There is no _REG method present */ 87626f3cdf0SGordon Ross } 87726f3cdf0SGordon Ross 87826f3cdf0SGordon Ross /* 87926f3cdf0SGordon Ross * Execute the _REG method only if there is no Operation Region in 88026f3cdf0SGordon Ross * this scope with the Embedded Controller space ID. Otherwise, it 88126f3cdf0SGordon Ross * will already have been executed. Note, this allows for Regions 88226f3cdf0SGordon Ross * with other space IDs to be present; but the code below will then 883*385cc6b4SJerry Jelinek * execute the _REG method with the EmbeddedControl SpaceID argument. 88426f3cdf0SGordon Ross */ 88526f3cdf0SGordon Ross NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); 88626f3cdf0SGordon Ross while (NextNode) 88726f3cdf0SGordon Ross { 88826f3cdf0SGordon Ross if ((NextNode->Type == ACPI_TYPE_REGION) && 88926f3cdf0SGordon Ross (NextNode->Object) && 89026f3cdf0SGordon Ross (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) 89126f3cdf0SGordon Ross { 892*385cc6b4SJerry Jelinek goto Exit; /* Do not execute the _REG */ 89326f3cdf0SGordon Ross } 894*385cc6b4SJerry Jelinek 89526f3cdf0SGordon Ross NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); 89626f3cdf0SGordon Ross } 89726f3cdf0SGordon Ross 898*385cc6b4SJerry Jelinek /* Evaluate the _REG(EmbeddedControl,Connect) method */ 89926f3cdf0SGordon Ross 90026f3cdf0SGordon Ross Args.Count = 2; 90126f3cdf0SGordon Ross Args.Pointer = Objects; 90226f3cdf0SGordon Ross Objects[0].Type = ACPI_TYPE_INTEGER; 90326f3cdf0SGordon Ross Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; 90426f3cdf0SGordon Ross Objects[1].Type = ACPI_TYPE_INTEGER; 90526f3cdf0SGordon Ross Objects[1].Integer.Value = ACPI_REG_CONNECT; 90626f3cdf0SGordon Ross 90726f3cdf0SGordon Ross Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); 90826f3cdf0SGordon Ross 90926f3cdf0SGordon Ross Exit: 91026f3cdf0SGordon Ross /* We ignore all errors from above, don't care */ 91126f3cdf0SGordon Ross 91226f3cdf0SGordon Ross Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 91326f3cdf0SGordon Ross return_VOID; 91426f3cdf0SGordon Ross } 915