167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and 467754Smsmith * Address Spaces. 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 8217365Sjkim/* 9217365Sjkim * Copyright (C) 2000 - 2011, 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 4567754Smsmith#define __EVXFREGN_C__ 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: 152218590Sjkim break; 153218590Sjkim } 154218590Sjkim 155220663Sjkim /* Run all _REG methods for this address space */ 156218590Sjkim 157220663Sjkim Status = AcpiEvExecuteRegMethods (Node, SpaceId); 158220663Sjkim 159220663Sjkim 16067754SmsmithUnlockAndExit: 16191116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 16267754Smsmith return_ACPI_STATUS (Status); 16367754Smsmith} 16467754Smsmith 165167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler) 16667754Smsmith 167167802Sjkim 16877424Smsmith/******************************************************************************* 16967754Smsmith * 17067754Smsmith * FUNCTION: AcpiRemoveAddressSpaceHandler 17167754Smsmith * 172117521Snjl * PARAMETERS: Device - Handle for the device 173117521Snjl * SpaceId - The address space ID 17467754Smsmith * Handler - Address of the handler 17567754Smsmith * 17667754Smsmith * RETURN: Status 17767754Smsmith * 178117521Snjl * DESCRIPTION: Remove a previously installed handler. 17967754Smsmith * 18067754Smsmith ******************************************************************************/ 18167754Smsmith 18267754SmsmithACPI_STATUS 18367754SmsmithAcpiRemoveAddressSpaceHandler ( 18467754Smsmith ACPI_HANDLE Device, 18577424Smsmith ACPI_ADR_SPACE_TYPE SpaceId, 18677424Smsmith ACPI_ADR_SPACE_HANDLER Handler) 18767754Smsmith{ 18867754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 18967754Smsmith ACPI_OPERAND_OBJECT *HandlerObj; 19067754Smsmith ACPI_OPERAND_OBJECT *RegionObj; 19167754Smsmith ACPI_OPERAND_OBJECT **LastObjPtr; 19267754Smsmith ACPI_NAMESPACE_NODE *Node; 19391116Smsmith ACPI_STATUS Status; 19467754Smsmith 19567754Smsmith 196167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveAddressSpaceHandler); 19767754Smsmith 19867754Smsmith 19967754Smsmith /* Parameter validation */ 20067754Smsmith 20191116Smsmith if (!Device) 20267754Smsmith { 20367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 20467754Smsmith } 20567754Smsmith 20691116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 20791116Smsmith if (ACPI_FAILURE (Status)) 20891116Smsmith { 20991116Smsmith return_ACPI_STATUS (Status); 21091116Smsmith } 21167754Smsmith 21267754Smsmith /* Convert and validate the device handle */ 21367754Smsmith 214200553Sjkim Node = AcpiNsValidateHandle (Device); 215167802Sjkim if (!Node || 216167802Sjkim ((Node->Type != ACPI_TYPE_DEVICE) && 217167802Sjkim (Node->Type != ACPI_TYPE_PROCESSOR) && 218167802Sjkim (Node->Type != ACPI_TYPE_THERMAL) && 219167802Sjkim (Node != AcpiGbl_RootNode))) 22067754Smsmith { 22167754Smsmith Status = AE_BAD_PARAMETER; 22267754Smsmith goto UnlockAndExit; 22367754Smsmith } 22467754Smsmith 22567754Smsmith /* Make sure the internal object exists */ 22667754Smsmith 22777424Smsmith ObjDesc = AcpiNsGetAttachedObject (Node); 22867754Smsmith if (!ObjDesc) 22967754Smsmith { 23067754Smsmith Status = AE_NOT_EXIST; 23167754Smsmith goto UnlockAndExit; 23267754Smsmith } 23367754Smsmith 234117521Snjl /* Find the address handler the user requested */ 235117521Snjl 236123315Snjl HandlerObj = ObjDesc->Device.Handler; 237123315Snjl LastObjPtr = &ObjDesc->Device.Handler; 23867754Smsmith while (HandlerObj) 23967754Smsmith { 240117521Snjl /* We have a handler, see if user requested this one */ 241117521Snjl 242117521Snjl if (HandlerObj->AddressSpace.SpaceId == SpaceId) 24367754Smsmith { 244167802Sjkim /* Handler must be the same as the installed handler */ 245167802Sjkim 246167802Sjkim if (HandlerObj->AddressSpace.Handler != Handler) 247167802Sjkim { 248167802Sjkim Status = AE_BAD_PARAMETER; 249167802Sjkim goto UnlockAndExit; 250167802Sjkim } 251167802Sjkim 252117521Snjl /* Matched SpaceId, first dereference this in the Regions */ 253117521Snjl 25482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 255193267Sjkim "Removing address handler %p(%p) for region %s " 256193267Sjkim "on Device %p(%p)\n", 25777424Smsmith HandlerObj, Handler, AcpiUtGetRegionName (SpaceId), 25867754Smsmith Node, ObjDesc)); 25967754Smsmith 260117521Snjl RegionObj = HandlerObj->AddressSpace.RegionList; 26167754Smsmith 26267754Smsmith /* Walk the handler's region list */ 26367754Smsmith 26467754Smsmith while (RegionObj) 26567754Smsmith { 26667754Smsmith /* 26785756Smsmith * First disassociate the handler from the region. 26867754Smsmith * 26985756Smsmith * NOTE: this doesn't mean that the region goes away 27085756Smsmith * The region is just inaccessible as indicated to 27185756Smsmith * the _REG method 27267754Smsmith */ 27399679Siwasaki AcpiEvDetachRegion (RegionObj, TRUE); 27467754Smsmith 27567754Smsmith /* 276117521Snjl * Walk the list: Just grab the head because the 277117521Snjl * DetachRegion removed the previous head. 27867754Smsmith */ 279117521Snjl RegionObj = HandlerObj->AddressSpace.RegionList; 28067754Smsmith 28167754Smsmith } 28267754Smsmith 283117521Snjl /* Remove this Handler object from the list */ 28467754Smsmith 285117521Snjl *LastObjPtr = HandlerObj->AddressSpace.Next; 286117521Snjl 287117521Snjl /* Now we can delete the handler object */ 288117521Snjl 28977424Smsmith AcpiUtRemoveReference (HandlerObj); 29067754Smsmith goto UnlockAndExit; 29167754Smsmith } 29267754Smsmith 293117521Snjl /* Walk the linked list of handlers */ 294117521Snjl 295117521Snjl LastObjPtr = &HandlerObj->AddressSpace.Next; 296117521Snjl HandlerObj = HandlerObj->AddressSpace.Next; 29767754Smsmith } 29867754Smsmith 299117521Snjl /* The handler does not exist */ 30067754Smsmith 30182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 30282367Smsmith "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", 30377424Smsmith Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc)); 30467754Smsmith 30567754Smsmith Status = AE_NOT_EXIST; 30667754Smsmith 30767754SmsmithUnlockAndExit: 30891116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 30967754Smsmith return_ACPI_STATUS (Status); 31067754Smsmith} 31167754Smsmith 312167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler) 31367754Smsmith 314