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