167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and 467754Smsmith * Address Spaces. 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9281075Sdim * Copyright (C) 2000 - 2015, Intel Corp. 1070243Smsmith * All rights reserved. 1167754Smsmith * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 2667754Smsmith * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 3067754Smsmith * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 4467754Smsmith 45281075Sdim#define EXPORT_ACPI_INTERFACES 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 5167754Smsmith 5277424Smsmith#define _COMPONENT ACPI_EVENTS 5391116Smsmith ACPI_MODULE_NAME ("evxfregn") 5467754Smsmith 5567754Smsmith 5677424Smsmith/******************************************************************************* 5767754Smsmith * 5867754Smsmith * FUNCTION: AcpiInstallAddressSpaceHandler 5967754Smsmith * 6067754Smsmith * PARAMETERS: Device - Handle for the device 6167754Smsmith * SpaceId - The address space ID 6267754Smsmith * Handler - Address of the handler 6367754Smsmith * Setup - Address of the setup function 6467754Smsmith * Context - Value passed to the handler on each access 6567754Smsmith * 6667754Smsmith * RETURN: Status 6767754Smsmith * 6867754Smsmith * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. 6967754Smsmith * 70213806Sjkim * NOTE: This function should only be called after AcpiEnableSubsystem has 71213806Sjkim * been called. This is because any _REG methods associated with the Space ID 72213806Sjkim * are executed here, and these methods can only be safely executed after 73213806Sjkim * the default handlers have been installed and the hardware has been 74213806Sjkim * initialized (via AcpiEnableSubsystem.) 75213806Sjkim * 7667754Smsmith ******************************************************************************/ 7767754Smsmith 7867754SmsmithACPI_STATUS 7967754SmsmithAcpiInstallAddressSpaceHandler ( 8067754Smsmith ACPI_HANDLE Device, 8177424Smsmith ACPI_ADR_SPACE_TYPE SpaceId, 8277424Smsmith ACPI_ADR_SPACE_HANDLER Handler, 8377424Smsmith ACPI_ADR_SPACE_SETUP Setup, 8467754Smsmith void *Context) 8567754Smsmith{ 8667754Smsmith ACPI_NAMESPACE_NODE *Node; 8791116Smsmith ACPI_STATUS Status; 8867754Smsmith 8967754Smsmith 90167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallAddressSpaceHandler); 9167754Smsmith 9277424Smsmith 9367754Smsmith /* Parameter validation */ 9467754Smsmith 9591116Smsmith if (!Device) 9667754Smsmith { 9767754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 9867754Smsmith } 9967754Smsmith 10091116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 10191116Smsmith if (ACPI_FAILURE (Status)) 10291116Smsmith { 10391116Smsmith return_ACPI_STATUS (Status); 10491116Smsmith } 10567754Smsmith 10667754Smsmith /* Convert and validate the device handle */ 10767754Smsmith 108200553Sjkim Node = AcpiNsValidateHandle (Device); 10967754Smsmith if (!Node) 11067754Smsmith { 11167754Smsmith Status = AE_BAD_PARAMETER; 11267754Smsmith goto UnlockAndExit; 11367754Smsmith } 11467754Smsmith 115129684Snjl /* Install the handler for all Regions for this Space ID */ 11667754Smsmith 117129684Snjl Status = AcpiEvInstallSpaceHandler (Node, SpaceId, Handler, Setup, Context); 118129684Snjl if (ACPI_FAILURE (Status)) 11967754Smsmith { 12067754Smsmith goto UnlockAndExit; 12167754Smsmith } 12267754Smsmith 123218590Sjkim /* 124218590Sjkim * For the default SpaceIDs, (the IDs for which there are default region handlers 125218590Sjkim * installed) Only execute the _REG methods if the global initialization _REG 126218590Sjkim * methods have already been run (via AcpiInitializeObjects). In other words, 127218590Sjkim * we will defer the execution of the _REG methods for these SpaceIDs until 128218590Sjkim * execution of AcpiInitializeObjects. This is done because we need the handlers 129218590Sjkim * for the default spaces (mem/io/pci/table) to be installed before we can run 130218590Sjkim * any control methods (or _REG methods). There is known BIOS code that depends 131218590Sjkim * on this. 132218590Sjkim * 133218590Sjkim * For all other SpaceIDs, we can safely execute the _REG methods immediately. 134218590Sjkim * This means that for IDs like EmbeddedController, this function should be called 135218590Sjkim * only after AcpiEnableSubsystem has been called. 136218590Sjkim */ 137218590Sjkim switch (SpaceId) 138218590Sjkim { 139218590Sjkim case ACPI_ADR_SPACE_SYSTEM_MEMORY: 140218590Sjkim case ACPI_ADR_SPACE_SYSTEM_IO: 141218590Sjkim case ACPI_ADR_SPACE_PCI_CONFIG: 142218590Sjkim case ACPI_ADR_SPACE_DATA_TABLE: 14367754Smsmith 144220663Sjkim if (!AcpiGbl_RegMethodsExecuted) 145218590Sjkim { 146220663Sjkim /* We will defer execution of the _REG methods for this space */ 147220663Sjkim goto UnlockAndExit; 148218590Sjkim } 149218590Sjkim break; 150218590Sjkim 151218590Sjkim default: 152250838Sjkim 153218590Sjkim break; 154218590Sjkim } 155218590Sjkim 156220663Sjkim /* Run all _REG methods for this address space */ 157218590Sjkim 158220663Sjkim Status = AcpiEvExecuteRegMethods (Node, SpaceId); 159220663Sjkim 160220663Sjkim 16167754SmsmithUnlockAndExit: 16291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 16367754Smsmith return_ACPI_STATUS (Status); 16467754Smsmith} 16567754Smsmith 166167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler) 16767754Smsmith 168167802Sjkim 16977424Smsmith/******************************************************************************* 17067754Smsmith * 17167754Smsmith * FUNCTION: AcpiRemoveAddressSpaceHandler 17267754Smsmith * 173117521Snjl * PARAMETERS: Device - Handle for the device 174117521Snjl * SpaceId - The address space ID 17567754Smsmith * Handler - Address of the handler 17667754Smsmith * 17767754Smsmith * RETURN: Status 17867754Smsmith * 179117521Snjl * DESCRIPTION: Remove a previously installed handler. 18067754Smsmith * 18167754Smsmith ******************************************************************************/ 18267754Smsmith 18367754SmsmithACPI_STATUS 18467754SmsmithAcpiRemoveAddressSpaceHandler ( 18567754Smsmith ACPI_HANDLE Device, 18677424Smsmith ACPI_ADR_SPACE_TYPE SpaceId, 18777424Smsmith ACPI_ADR_SPACE_HANDLER Handler) 18867754Smsmith{ 18967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 19067754Smsmith ACPI_OPERAND_OBJECT *HandlerObj; 19167754Smsmith ACPI_OPERAND_OBJECT *RegionObj; 19267754Smsmith ACPI_OPERAND_OBJECT **LastObjPtr; 19367754Smsmith ACPI_NAMESPACE_NODE *Node; 19491116Smsmith ACPI_STATUS Status; 19567754Smsmith 19667754Smsmith 197167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveAddressSpaceHandler); 19867754Smsmith 19967754Smsmith 20067754Smsmith /* Parameter validation */ 20167754Smsmith 20291116Smsmith if (!Device) 20367754Smsmith { 20467754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 20567754Smsmith } 20667754Smsmith 20791116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 20891116Smsmith if (ACPI_FAILURE (Status)) 20991116Smsmith { 21091116Smsmith return_ACPI_STATUS (Status); 21191116Smsmith } 21267754Smsmith 21367754Smsmith /* Convert and validate the device handle */ 21467754Smsmith 215200553Sjkim Node = AcpiNsValidateHandle (Device); 216167802Sjkim if (!Node || 217167802Sjkim ((Node->Type != ACPI_TYPE_DEVICE) && 218167802Sjkim (Node->Type != ACPI_TYPE_PROCESSOR) && 219167802Sjkim (Node->Type != ACPI_TYPE_THERMAL) && 220167802Sjkim (Node != AcpiGbl_RootNode))) 22167754Smsmith { 22267754Smsmith Status = AE_BAD_PARAMETER; 22367754Smsmith goto UnlockAndExit; 22467754Smsmith } 22567754Smsmith 22667754Smsmith /* Make sure the internal object exists */ 22767754Smsmith 22877424Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 22967754Smsmith if (!ObjDesc) 23067754Smsmith { 23167754Smsmith Status = AE_NOT_EXIST; 23267754Smsmith goto UnlockAndExit; 23367754Smsmith } 23467754Smsmith 235117521Snjl /* Find the address handler the user requested */ 236117521Snjl 237123315Snjl HandlerObj = ObjDesc->Device.Handler; 238123315Snjl LastObjPtr = &ObjDesc->Device.Handler; 23967754Smsmith while (HandlerObj) 24067754Smsmith { 241117521Snjl /* We have a handler, see if user requested this one */ 242117521Snjl 243117521Snjl if (HandlerObj->AddressSpace.SpaceId == SpaceId) 24467754Smsmith { 245167802Sjkim /* Handler must be the same as the installed handler */ 246167802Sjkim 247167802Sjkim if (HandlerObj->AddressSpace.Handler != Handler) 248167802Sjkim { 249167802Sjkim Status = AE_BAD_PARAMETER; 250167802Sjkim goto UnlockAndExit; 251167802Sjkim } 252167802Sjkim 253117521Snjl /* Matched SpaceId, first dereference this in the Regions */ 254117521Snjl 25582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 256193267Sjkim "Removing address handler %p(%p) for region %s " 257193267Sjkim "on Device %p(%p)\n", 25877424Smsmith HandlerObj, Handler, AcpiUtGetRegionName (SpaceId), 25967754Smsmith Node, ObjDesc)); 26067754Smsmith 261117521Snjl RegionObj = HandlerObj->AddressSpace.RegionList; 26267754Smsmith 26367754Smsmith /* Walk the handler's region list */ 26467754Smsmith 26567754Smsmith while (RegionObj) 26667754Smsmith { 26767754Smsmith /* 26885756Smsmith * First disassociate the handler from the region. 26967754Smsmith * 27085756Smsmith * NOTE: this doesn't mean that the region goes away 27185756Smsmith * The region is just inaccessible as indicated to 27285756Smsmith * the _REG method 27367754Smsmith */ 27499679Siwasaki AcpiEvDetachRegion (RegionObj, TRUE); 27567754Smsmith 27667754Smsmith /* 277117521Snjl * Walk the list: Just grab the head because the 278117521Snjl * DetachRegion removed the previous head. 27967754Smsmith */ 280117521Snjl RegionObj = HandlerObj->AddressSpace.RegionList; 28167754Smsmith 28267754Smsmith } 28367754Smsmith 284117521Snjl /* Remove this Handler object from the list */ 28567754Smsmith 286117521Snjl *LastObjPtr = HandlerObj->AddressSpace.Next; 287117521Snjl 288117521Snjl /* Now we can delete the handler object */ 289117521Snjl 29077424Smsmith AcpiUtRemoveReference (HandlerObj); 29167754Smsmith goto UnlockAndExit; 29267754Smsmith } 29367754Smsmith 294117521Snjl /* Walk the linked list of handlers */ 295117521Snjl 296117521Snjl LastObjPtr = &HandlerObj->AddressSpace.Next; 297117521Snjl HandlerObj = HandlerObj->AddressSpace.Next; 29867754Smsmith } 29967754Smsmith 300117521Snjl /* The handler does not exist */ 30167754Smsmith 30282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 30382367Smsmith "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", 30477424Smsmith Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc)); 30567754Smsmith 30667754Smsmith Status = AE_NOT_EXIST; 30767754Smsmith 30867754SmsmithUnlockAndExit: 30991116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 31067754Smsmith return_ACPI_STATUS (Status); 31167754Smsmith} 31267754Smsmith 313167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler) 314