1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and 4ae115bc7Smrj * Address Spaces. 5ae115bc7Smrj * 6ae115bc7Smrj *****************************************************************************/ 7ae115bc7Smrj 826f3cdf0SGordon Ross /* 9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 10ae115bc7Smrj * All rights reserved. 11ae115bc7Smrj * 1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1426f3cdf0SGordon Ross * are met: 1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1726f3cdf0SGordon Ross * without modification. 1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2226f3cdf0SGordon Ross * binary redistribution. 2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2526f3cdf0SGordon Ross * from this software without specific prior written permission. 26ae115bc7Smrj * 2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2926f3cdf0SGordon Ross * Software Foundation. 30ae115bc7Smrj * 3126f3cdf0SGordon Ross * NO WARRANTY 3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4326f3cdf0SGordon Ross */ 44ae115bc7Smrj 45*385cc6b4SJerry Jelinek #define EXPORT_ACPI_INTERFACES 46ae115bc7Smrj 47ae115bc7Smrj #include "acpi.h" 48aa2aa9a6SDana Myers #include "accommon.h" 49ae115bc7Smrj #include "acnamesp.h" 50ae115bc7Smrj #include "acevents.h" 51ae115bc7Smrj 52ae115bc7Smrj #define _COMPONENT ACPI_EVENTS 53ae115bc7Smrj ACPI_MODULE_NAME ("evxfregn") 54ae115bc7Smrj 55ae115bc7Smrj 56ae115bc7Smrj /******************************************************************************* 57ae115bc7Smrj * 58ae115bc7Smrj * FUNCTION: AcpiInstallAddressSpaceHandler 59ae115bc7Smrj * 60ae115bc7Smrj * PARAMETERS: Device - Handle for the device 61ae115bc7Smrj * SpaceId - The address space ID 62ae115bc7Smrj * Handler - Address of the handler 63ae115bc7Smrj * Setup - Address of the setup function 64ae115bc7Smrj * Context - Value passed to the handler on each access 65ae115bc7Smrj * 66ae115bc7Smrj * RETURN: Status 67ae115bc7Smrj * 68ae115bc7Smrj * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. 69ae115bc7Smrj * 7026f3cdf0SGordon Ross * NOTE: This function should only be called after AcpiEnableSubsystem has 7126f3cdf0SGordon Ross * been called. This is because any _REG methods associated with the Space ID 7226f3cdf0SGordon Ross * are executed here, and these methods can only be safely executed after 7326f3cdf0SGordon Ross * the default handlers have been installed and the hardware has been 7426f3cdf0SGordon Ross * initialized (via AcpiEnableSubsystem.) 7526f3cdf0SGordon Ross * 76ae115bc7Smrj ******************************************************************************/ 77ae115bc7Smrj 78ae115bc7Smrj ACPI_STATUS 79ae115bc7Smrj AcpiInstallAddressSpaceHandler ( 80ae115bc7Smrj ACPI_HANDLE Device, 81ae115bc7Smrj ACPI_ADR_SPACE_TYPE SpaceId, 82ae115bc7Smrj ACPI_ADR_SPACE_HANDLER Handler, 83ae115bc7Smrj ACPI_ADR_SPACE_SETUP Setup, 84ae115bc7Smrj void *Context) 85ae115bc7Smrj { 86ae115bc7Smrj ACPI_NAMESPACE_NODE *Node; 87ae115bc7Smrj ACPI_STATUS Status; 88ae115bc7Smrj 89ae115bc7Smrj 90ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiInstallAddressSpaceHandler); 91ae115bc7Smrj 92ae115bc7Smrj 93ae115bc7Smrj /* Parameter validation */ 94ae115bc7Smrj 95ae115bc7Smrj if (!Device) 96ae115bc7Smrj { 97ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 98ae115bc7Smrj } 99ae115bc7Smrj 100ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 101ae115bc7Smrj if (ACPI_FAILURE (Status)) 102ae115bc7Smrj { 103ae115bc7Smrj return_ACPI_STATUS (Status); 104ae115bc7Smrj } 105ae115bc7Smrj 106ae115bc7Smrj /* Convert and validate the device handle */ 107ae115bc7Smrj 10826f3cdf0SGordon Ross Node = AcpiNsValidateHandle (Device); 109ae115bc7Smrj if (!Node) 110ae115bc7Smrj { 111ae115bc7Smrj Status = AE_BAD_PARAMETER; 112ae115bc7Smrj goto UnlockAndExit; 113ae115bc7Smrj } 114ae115bc7Smrj 115ae115bc7Smrj /* Install the handler for all Regions for this Space ID */ 116ae115bc7Smrj 117*385cc6b4SJerry Jelinek Status = AcpiEvInstallSpaceHandler ( 118*385cc6b4SJerry Jelinek Node, SpaceId, Handler, Setup, Context); 119ae115bc7Smrj if (ACPI_FAILURE (Status)) 120ae115bc7Smrj { 121ae115bc7Smrj goto UnlockAndExit; 122ae115bc7Smrj } 123ae115bc7Smrj 124ae115bc7Smrj /* Run all _REG methods for this address space */ 125ae115bc7Smrj 126*385cc6b4SJerry Jelinek AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT); 127ae115bc7Smrj 12826f3cdf0SGordon Ross 129ae115bc7Smrj UnlockAndExit: 130ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 131ae115bc7Smrj return_ACPI_STATUS (Status); 132ae115bc7Smrj } 133ae115bc7Smrj 134ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler) 135ae115bc7Smrj 136ae115bc7Smrj 137ae115bc7Smrj /******************************************************************************* 138ae115bc7Smrj * 139ae115bc7Smrj * FUNCTION: AcpiRemoveAddressSpaceHandler 140ae115bc7Smrj * 141ae115bc7Smrj * PARAMETERS: Device - Handle for the device 142ae115bc7Smrj * SpaceId - The address space ID 143ae115bc7Smrj * Handler - Address of the handler 144ae115bc7Smrj * 145ae115bc7Smrj * RETURN: Status 146ae115bc7Smrj * 147ae115bc7Smrj * DESCRIPTION: Remove a previously installed handler. 148ae115bc7Smrj * 149ae115bc7Smrj ******************************************************************************/ 150ae115bc7Smrj 151ae115bc7Smrj ACPI_STATUS 152ae115bc7Smrj AcpiRemoveAddressSpaceHandler ( 153ae115bc7Smrj ACPI_HANDLE Device, 154ae115bc7Smrj ACPI_ADR_SPACE_TYPE SpaceId, 155ae115bc7Smrj ACPI_ADR_SPACE_HANDLER Handler) 156ae115bc7Smrj { 157ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc; 158ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj; 159ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj; 160ae115bc7Smrj ACPI_OPERAND_OBJECT **LastObjPtr; 161ae115bc7Smrj ACPI_NAMESPACE_NODE *Node; 162ae115bc7Smrj ACPI_STATUS Status; 163ae115bc7Smrj 164ae115bc7Smrj 165ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiRemoveAddressSpaceHandler); 166ae115bc7Smrj 167ae115bc7Smrj 168ae115bc7Smrj /* Parameter validation */ 169ae115bc7Smrj 170ae115bc7Smrj if (!Device) 171ae115bc7Smrj { 172ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 173ae115bc7Smrj } 174ae115bc7Smrj 175ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 176ae115bc7Smrj if (ACPI_FAILURE (Status)) 177ae115bc7Smrj { 178ae115bc7Smrj return_ACPI_STATUS (Status); 179ae115bc7Smrj } 180ae115bc7Smrj 181ae115bc7Smrj /* Convert and validate the device handle */ 182ae115bc7Smrj 18326f3cdf0SGordon Ross Node = AcpiNsValidateHandle (Device); 184ae115bc7Smrj if (!Node || 185ae115bc7Smrj ((Node->Type != ACPI_TYPE_DEVICE) && 186ae115bc7Smrj (Node->Type != ACPI_TYPE_PROCESSOR) && 187ae115bc7Smrj (Node->Type != ACPI_TYPE_THERMAL) && 188ae115bc7Smrj (Node != AcpiGbl_RootNode))) 189ae115bc7Smrj { 190ae115bc7Smrj Status = AE_BAD_PARAMETER; 191ae115bc7Smrj goto UnlockAndExit; 192ae115bc7Smrj } 193ae115bc7Smrj 194ae115bc7Smrj /* Make sure the internal object exists */ 195ae115bc7Smrj 196ae115bc7Smrj ObjDesc = AcpiNsGetAttachedObject (Node); 197ae115bc7Smrj if (!ObjDesc) 198ae115bc7Smrj { 199ae115bc7Smrj Status = AE_NOT_EXIST; 200ae115bc7Smrj goto UnlockAndExit; 201ae115bc7Smrj } 202ae115bc7Smrj 203ae115bc7Smrj /* Find the address handler the user requested */ 204ae115bc7Smrj 205*385cc6b4SJerry Jelinek HandlerObj = ObjDesc->CommonNotify.Handler; 206*385cc6b4SJerry Jelinek LastObjPtr = &ObjDesc->CommonNotify.Handler; 207ae115bc7Smrj while (HandlerObj) 208ae115bc7Smrj { 209ae115bc7Smrj /* We have a handler, see if user requested this one */ 210ae115bc7Smrj 211ae115bc7Smrj if (HandlerObj->AddressSpace.SpaceId == SpaceId) 212ae115bc7Smrj { 213ae115bc7Smrj /* Handler must be the same as the installed handler */ 214ae115bc7Smrj 215ae115bc7Smrj if (HandlerObj->AddressSpace.Handler != Handler) 216ae115bc7Smrj { 217ae115bc7Smrj Status = AE_BAD_PARAMETER; 218ae115bc7Smrj goto UnlockAndExit; 219ae115bc7Smrj } 220ae115bc7Smrj 221ae115bc7Smrj /* Matched SpaceId, first dereference this in the Regions */ 222ae115bc7Smrj 223ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 224aa2aa9a6SDana Myers "Removing address handler %p(%p) for region %s " 225aa2aa9a6SDana Myers "on Device %p(%p)\n", 226ae115bc7Smrj HandlerObj, Handler, AcpiUtGetRegionName (SpaceId), 227ae115bc7Smrj Node, ObjDesc)); 228ae115bc7Smrj 229ae115bc7Smrj RegionObj = HandlerObj->AddressSpace.RegionList; 230ae115bc7Smrj 231ae115bc7Smrj /* Walk the handler's region list */ 232ae115bc7Smrj 233ae115bc7Smrj while (RegionObj) 234ae115bc7Smrj { 235ae115bc7Smrj /* 236ae115bc7Smrj * First disassociate the handler from the region. 237ae115bc7Smrj * 238ae115bc7Smrj * NOTE: this doesn't mean that the region goes away 239ae115bc7Smrj * The region is just inaccessible as indicated to 240ae115bc7Smrj * the _REG method 241ae115bc7Smrj */ 242ae115bc7Smrj AcpiEvDetachRegion (RegionObj, TRUE); 243ae115bc7Smrj 244ae115bc7Smrj /* 245ae115bc7Smrj * Walk the list: Just grab the head because the 246ae115bc7Smrj * DetachRegion removed the previous head. 247ae115bc7Smrj */ 248ae115bc7Smrj RegionObj = HandlerObj->AddressSpace.RegionList; 249ae115bc7Smrj 250ae115bc7Smrj } 251ae115bc7Smrj 252ae115bc7Smrj /* Remove this Handler object from the list */ 253ae115bc7Smrj 254ae115bc7Smrj *LastObjPtr = HandlerObj->AddressSpace.Next; 255ae115bc7Smrj 256ae115bc7Smrj /* Now we can delete the handler object */ 257ae115bc7Smrj 258ae115bc7Smrj AcpiUtRemoveReference (HandlerObj); 259ae115bc7Smrj goto UnlockAndExit; 260ae115bc7Smrj } 261ae115bc7Smrj 262ae115bc7Smrj /* Walk the linked list of handlers */ 263ae115bc7Smrj 264ae115bc7Smrj LastObjPtr = &HandlerObj->AddressSpace.Next; 265ae115bc7Smrj HandlerObj = HandlerObj->AddressSpace.Next; 266ae115bc7Smrj } 267ae115bc7Smrj 268ae115bc7Smrj /* The handler does not exist */ 269ae115bc7Smrj 270ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 271ae115bc7Smrj "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", 272ae115bc7Smrj Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc)); 273ae115bc7Smrj 274ae115bc7Smrj Status = AE_NOT_EXIST; 275ae115bc7Smrj 276ae115bc7Smrj UnlockAndExit: 277ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 278ae115bc7Smrj return_ACPI_STATUS (Status); 279ae115bc7Smrj } 280ae115bc7Smrj 281ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler) 282