evrgnini.c revision 44f6c01242da4e162f28d8e1216a8c7a91174605
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/****************************************************************************** 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: evrgnini- ACPI address_space (op_region) init 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 - 2005, R. Byron Moore 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met: 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * notice, this list of conditions, and the following disclaimer, 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * without modification. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * substantially similar to the "NO WARRANTY" disclaimer below 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ("Disclaimer") and any redistribution must be conditioned upon 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * including a substantially similar Disclaimer requirement for further 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * binary redistribution. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of any contributors may be used to endorse or promote products derived 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * from this software without specific prior written permission. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation. 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES. 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acevents.h> 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acnamesp.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT ACPI_EVENTS 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_MODULE_NAME ("evrgnini") 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_system_memory_region_setup 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: Handle - Region we are interested in 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a system_memory operation region 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_system_memory_region_setup ( 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *region_desc = (union acpi_operand_object *) handle; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_mem_space_context *local_region_context; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup"); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (function == ACPI_REGION_DEACTIVATE) { 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*region_context) { 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_MEM_FREE (*region_context); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = NULL; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Create a new context */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context)); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(local_region_context)) { 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_NO_MEMORY); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Save the region length and address for use in the handler */ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_region_context->length = region_desc->region.length; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_region_context->address = region_desc->region.address; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = local_region_context; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_io_space_region_setup 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: Handle - Region we are interested in 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a IO operation region 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_io_space_region_setup ( 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_io_space_region_setup"); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (function == ACPI_REGION_DEACTIVATE) { 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = NULL; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = handler_context; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_pci_config_region_setup 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 14744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * PARAMETERS: Handle - Region we are interested in 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 15444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a PCI_Config operation region 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX: Assumes namespace is not locked 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_pci_config_region_setup ( 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_status status = AE_OK; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_integer pci_value; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_pci_id *pci_id = *region_context; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *handler_obj; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_namespace_node *parent_node; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_namespace_node *pci_root_node; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *region_obj = (union acpi_operand_object *) handle; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_device_id object_hID; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = region_obj->region.handler; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!handler_obj) { 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * No installed handler. This shouldn't happen because the dispatch 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * routine checks before we get here, but we check again just in case. 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Attempting to init a region %p, with no handler\n", region_obj)); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_NOT_EXIST); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = NULL; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (function == ACPI_REGION_DEACTIVATE) { 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pci_id) { 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_MEM_FREE (pci_id); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (status); 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds parent_node = acpi_ns_get_parent_node (region_obj->region.node); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the _SEG and _BBN values from the device upon which the handler 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is installed. 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We need to get the _SEG and _BBN objects relative to the PCI BUS device. 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is the device the handler has been registered to handle. 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the address_space.Node is still pointing to the root, we need 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to scan upward for a PCI Root bridge and re-associate the op_region 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handlers with that device. 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (handler_obj->address_space.node == acpi_gbl_root_node) { 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start search from the parent object */ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_root_node = parent_node; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (pci_root_node != acpi_gbl_root_node) { 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_execute_HID (pci_root_node, &object_hID); 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_SUCCESS (status)) { 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Got a valid _HID, check if this is a PCI root */ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING, 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof (PCI_ROOT_HID_STRING)))) { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Install a handler for this PCI root bridge */ 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_install_address_space_handler ((acpi_handle) pci_root_node, 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_ADR_SPACE_PCI_CONFIG, 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_DEFAULT_HANDLER, NULL, NULL); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE (status)) { 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status == AE_SAME_HANDLER) { 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It is OK if the handler is already installed on the root 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bridge. Still need to return a context object for the 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * new PCI_Config operation region, however. 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = AE_OK; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_REPORT_ERROR (( 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Could not install pci_config handler for Root Bridge %4.4s, %s\n", 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status))); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_root_node = acpi_ns_get_parent_node (pci_root_node); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* PCI root bridge not found, use namespace root node */ 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_root_node = handler_obj->address_space.node; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If this region is now initialized, we are done. 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (install_address_space_handler could have initialized it) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Region is still not initialized. Create a new context */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id)); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!pci_id) { 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_NO_MEMORY); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For PCI_Config space access, we need the segment, bus, 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device and function numbers. Acquire them here. 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the PCI device and function numbers from the _ADR object 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * contained in the parent's scope. 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The default is zero, and since the allocation above zeroed 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the data, just do nothing on failure. 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_SUCCESS (status)) { 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value)); 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value)); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The PCI segment number comes from the _SEG method */ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_SUCCESS (status)) { 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_id->segment = ACPI_LOWORD (pci_value); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The PCI bus number comes from the _BBN method */ 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_SUCCESS (status)) { 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_id->bus = ACPI_LOWORD (pci_value); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Complete this device's pci_id */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = pci_id; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_pci_bar_region_setup 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: Handle - Region we are interested in 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 32744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a pci_bAR operation region 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX: Assumes namespace is not locked 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_pci_bar_region_setup ( 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_pci_bar_region_setup"); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_cmos_region_setup 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: Handle - Region we are interested in 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 35844f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Setup a CMOS operation region 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MUTEX: Assumes namespace is not locked 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_cmos_region_setup ( 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_cmos_region_setup"); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_default_region_setup 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: Handle - Region we are interested in 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function - Start or stop 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handler_context - Address space handler context 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_context - Region specific context 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 38944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore * DESCRIPTION: Default region initialization 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_default_region_setup ( 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_handle handle, 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 function, 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *handler_context, 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void **region_context) 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE ("ev_default_region_setup"); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (function == ACPI_REGION_DEACTIVATE) { 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = NULL; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *region_context = handler_context; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_ev_initialize_region 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: region_obj - Region we are initializing 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * acpi_ns_locked - Is namespace locked? 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Initializes the region, finds any _REG methods and saves them 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for execution at a later time 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the appropriate address space handler for a newly 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * created region. 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This also performs address space specific initialization. For 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * example, PCI regions must have an _ADR object that contains 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a PCI address in the scope of the definition. This address is 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * required to perform an access to PCI config space. 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_ev_initialize_region ( 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *region_obj, 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 acpi_ns_locked) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *handler_obj; 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *obj_desc; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_adr_space_type space_id; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_namespace_node *node; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_status status; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct acpi_namespace_node *method_node; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union acpi_operand_object *region_obj2; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_FUNCTION_TRACE_U32 ("ev_initialize_region", acpi_ns_locked); 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!region_obj) { 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_BAD_PARAMETER); 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) { 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj2 = acpi_ns_get_secondary_object (region_obj); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!region_obj2) { 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_NOT_EXIST); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds node = acpi_ns_get_parent_node (region_obj->region.node); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds space_id = region_obj->region.space_id; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Setup defaults */ 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj->region.handler = NULL; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj2->extra.method_REG = NULL; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Find any "_REG" method associated with this region definition */ 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ns_search_node (*reg_name_ptr, node, 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_TYPE_METHOD, &method_node); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_SUCCESS (status)) { 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The _REG method is optional and there can be only one per region 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * definition. This will be executed when the handler is attached 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or removed 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_obj2->extra.method_REG = method_node; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The following loop depends upon the root Node having no parent 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ie: acpi_gbl_root_node->parent_entry being set to NULL 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (node) { 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check to see if a handler exists */ 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = NULL; 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj_desc = acpi_ns_get_attached_object (node); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (obj_desc) { 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Can only be a handler if the object exists */ 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (node->type) { 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_TYPE_DEVICE: 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = obj_desc->device.handler; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_TYPE_PROCESSOR: 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = obj_desc->processor.handler; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_TYPE_THERMAL: 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = obj_desc->thermal_zone.handler; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Ignore other objects */ 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (handler_obj) { 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Is this handler of the correct type? */ 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (handler_obj->address_space.space_id == space_id) { 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Found correct handler */ 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Found handler %p for region %p in obj %p\n", 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj, region_obj, obj_desc)); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ev_attach_region (handler_obj, region_obj, 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ns_locked); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Tell all users that this region is usable by running the _REG 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * method 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_ns_locked) { 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE (status)) { 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (status); 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ev_execute_reg_method (region_obj, 1); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_ns_locked) { 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE (status)) { 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (status); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_OK); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Try next handler in the list */ 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds handler_obj = handler_obj->address_space.next; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This node does not have the handler we need; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Pop up one level 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds node = acpi_ns_get_parent_node (node); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* If we get here, there is no handler for this region */ 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "No handler for region_type %s(%X) (region_obj %p)\n", 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ut_get_region_name (space_id), space_id, region_obj)); 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return_ACPI_STATUS (AE_NOT_EXIST); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581