Linux Audio

Check our new training course

Loading...
v3.1
   1/******************************************************************************
   2 *
   3 * Module Name: evregion - ACPI address_space (op_region) handler dispatch
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2011, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acevents.h"
  47#include "acnamesp.h"
  48#include "acinterp.h"
  49
  50#define _COMPONENT          ACPI_EVENTS
  51ACPI_MODULE_NAME("evregion")
  52
 
 
  53/* Local prototypes */
  54static u8
  55acpi_ev_has_default_handler(struct acpi_namespace_node *node,
  56			    acpi_adr_space_type space_id);
  57
  58static void acpi_ev_orphan_ec_reg_method(void);
 
  59
  60static acpi_status
  61acpi_ev_reg_run(acpi_handle obj_handle,
  62		u32 level, void *context, void **return_value);
  63
  64static acpi_status
  65acpi_ev_install_handler(acpi_handle obj_handle,
  66			u32 level, void *context, void **return_value);
  67
  68/* These are the address spaces that will get default handlers */
  69
  70#define ACPI_NUM_DEFAULT_SPACES     4
  71
  72static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
  73	ACPI_ADR_SPACE_SYSTEM_MEMORY,
  74	ACPI_ADR_SPACE_SYSTEM_IO,
  75	ACPI_ADR_SPACE_PCI_CONFIG,
  76	ACPI_ADR_SPACE_DATA_TABLE
  77};
  78
  79/*******************************************************************************
  80 *
  81 * FUNCTION:    acpi_ev_install_region_handlers
  82 *
  83 * PARAMETERS:  None
  84 *
  85 * RETURN:      Status
  86 *
  87 * DESCRIPTION: Installs the core subsystem default address space handlers.
  88 *
  89 ******************************************************************************/
  90
  91acpi_status acpi_ev_install_region_handlers(void)
  92{
  93	acpi_status status;
  94	u32 i;
  95
  96	ACPI_FUNCTION_TRACE(ev_install_region_handlers);
  97
  98	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  99	if (ACPI_FAILURE(status)) {
 100		return_ACPI_STATUS(status);
 101	}
 102
 103	/*
 104	 * All address spaces (PCI Config, EC, SMBus) are scope dependent and
 105	 * registration must occur for a specific device.
 106	 *
 107	 * In the case of the system memory and IO address spaces there is
 108	 * currently no device associated with the address space. For these we
 109	 * use the root.
 110	 *
 111	 * We install the default PCI config space handler at the root so that
 112	 * this space is immediately available even though the we have not
 113	 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
 114	 * specification which states that the PCI config space must be always
 115	 * available -- even though we are nowhere near ready to find the PCI root
 116	 * buses at this point.
 117	 *
 118	 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
 119	 * has already been installed (via acpi_install_address_space_handler).
 120	 * Similar for AE_SAME_HANDLER.
 121	 */
 122	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 123		status = acpi_ev_install_space_handler(acpi_gbl_root_node,
 124						       acpi_gbl_default_address_spaces
 125						       [i],
 126						       ACPI_DEFAULT_HANDLER,
 127						       NULL, NULL);
 128		switch (status) {
 129		case AE_OK:
 130		case AE_SAME_HANDLER:
 131		case AE_ALREADY_EXISTS:
 132
 133			/* These exceptions are all OK */
 134
 135			status = AE_OK;
 136			break;
 137
 138		default:
 139
 140			goto unlock_and_exit;
 141		}
 142	}
 143
 144      unlock_and_exit:
 145	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 146	return_ACPI_STATUS(status);
 147}
 148
 149/*******************************************************************************
 150 *
 151 * FUNCTION:    acpi_ev_has_default_handler
 152 *
 153 * PARAMETERS:  Node                - Namespace node for the device
 154 *              space_id            - The address space ID
 155 *
 156 * RETURN:      TRUE if default handler is installed, FALSE otherwise
 157 *
 158 * DESCRIPTION: Check if the default handler is installed for the requested
 159 *              space ID.
 160 *
 161 ******************************************************************************/
 162
 163static u8
 164acpi_ev_has_default_handler(struct acpi_namespace_node *node,
 165			    acpi_adr_space_type space_id)
 166{
 167	union acpi_operand_object *obj_desc;
 168	union acpi_operand_object *handler_obj;
 169
 170	/* Must have an existing internal object */
 171
 172	obj_desc = acpi_ns_get_attached_object(node);
 173	if (obj_desc) {
 174		handler_obj = obj_desc->device.handler;
 175
 176		/* Walk the linked list of handlers for this object */
 177
 178		while (handler_obj) {
 179			if (handler_obj->address_space.space_id == space_id) {
 180				if (handler_obj->address_space.handler_flags &
 181				    ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
 182					return (TRUE);
 183				}
 184			}
 185
 186			handler_obj = handler_obj->address_space.next;
 187		}
 188	}
 189
 190	return (FALSE);
 191}
 192
 193/*******************************************************************************
 194 *
 195 * FUNCTION:    acpi_ev_initialize_op_regions
 196 *
 197 * PARAMETERS:  None
 198 *
 199 * RETURN:      Status
 200 *
 201 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
 202 *              an installed default region handler.
 203 *
 204 ******************************************************************************/
 205
 206acpi_status acpi_ev_initialize_op_regions(void)
 207{
 208	acpi_status status;
 209	u32 i;
 210
 211	ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
 212
 213	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 214	if (ACPI_FAILURE(status)) {
 215		return_ACPI_STATUS(status);
 216	}
 217
 218	/* Run the _REG methods for op_regions in each default address space */
 219
 220	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 221		/*
 222		 * Make sure the installed handler is the DEFAULT handler. If not the
 223		 * default, the _REG methods will have already been run (when the
 224		 * handler was installed)
 225		 */
 226		if (acpi_ev_has_default_handler(acpi_gbl_root_node,
 227						acpi_gbl_default_address_spaces
 228						[i])) {
 229			status =
 230			    acpi_ev_execute_reg_methods(acpi_gbl_root_node,
 231							acpi_gbl_default_address_spaces
 232							[i]);
 233		}
 234	}
 235
 236	acpi_gbl_reg_methods_executed = TRUE;
 237
 238	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 239	return_ACPI_STATUS(status);
 240}
 241
 242/*******************************************************************************
 243 *
 244 * FUNCTION:    acpi_ev_execute_reg_method
 245 *
 246 * PARAMETERS:  region_obj          - Region object
 247 *              Function            - Passed to _REG: On (1) or Off (0)
 248 *
 249 * RETURN:      Status
 250 *
 251 * DESCRIPTION: Execute _REG method for a region
 252 *
 253 ******************************************************************************/
 254
 255acpi_status
 256acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
 257{
 258	struct acpi_evaluate_info *info;
 259	union acpi_operand_object *args[3];
 260	union acpi_operand_object *region_obj2;
 261	acpi_status status;
 262
 263	ACPI_FUNCTION_TRACE(ev_execute_reg_method);
 264
 265	region_obj2 = acpi_ns_get_secondary_object(region_obj);
 266	if (!region_obj2) {
 267		return_ACPI_STATUS(AE_NOT_EXIST);
 268	}
 269
 270	if (region_obj2->extra.method_REG == NULL) {
 271		return_ACPI_STATUS(AE_OK);
 272	}
 273
 274	/* Allocate and initialize the evaluation information block */
 275
 276	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
 277	if (!info) {
 278		return_ACPI_STATUS(AE_NO_MEMORY);
 279	}
 280
 281	info->prefix_node = region_obj2->extra.method_REG;
 282	info->pathname = NULL;
 283	info->parameters = args;
 284	info->flags = ACPI_IGNORE_RETURN_VALUE;
 285
 286	/*
 287	 * The _REG method has two arguments:
 288	 *
 289	 * Arg0 - Integer:
 290	 *  Operation region space ID Same value as region_obj->Region.space_id
 291	 *
 292	 * Arg1 - Integer:
 293	 *  connection status 1 for connecting the handler, 0 for disconnecting
 294	 *  the handler (Passed as a parameter)
 295	 */
 296	args[0] =
 297	    acpi_ut_create_integer_object((u64) region_obj->region.space_id);
 298	if (!args[0]) {
 299		status = AE_NO_MEMORY;
 300		goto cleanup1;
 301	}
 302
 303	args[1] = acpi_ut_create_integer_object((u64) function);
 304	if (!args[1]) {
 305		status = AE_NO_MEMORY;
 306		goto cleanup2;
 307	}
 308
 309	args[2] = NULL;		/* Terminate list */
 310
 311	/* Execute the method, no return value */
 312
 313	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 314			(ACPI_TYPE_METHOD, info->prefix_node, NULL));
 315
 316	status = acpi_ns_evaluate(info);
 317	acpi_ut_remove_reference(args[1]);
 318
 319      cleanup2:
 320	acpi_ut_remove_reference(args[0]);
 321
 322      cleanup1:
 323	ACPI_FREE(info);
 324	return_ACPI_STATUS(status);
 325}
 326
 327/*******************************************************************************
 328 *
 329 * FUNCTION:    acpi_ev_address_space_dispatch
 330 *
 331 * PARAMETERS:  region_obj          - Internal region object
 332 *              Function            - Read or Write operation
 
 333 *              region_offset       - Where in the region to read or write
 334 *              bit_width           - Field width in bits (8, 16, 32, or 64)
 335 *              Value               - Pointer to in or out value, must be
 336 *                                    a full 64-bit integer
 337 *
 338 * RETURN:      Status
 339 *
 340 * DESCRIPTION: Dispatch an address space or operation region access to
 341 *              a previously installed handler.
 342 *
 
 
 
 
 
 
 343 ******************************************************************************/
 344
 345acpi_status
 346acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 
 347			       u32 function,
 348			       u32 region_offset, u32 bit_width, u64 *value)
 349{
 350	acpi_status status;
 351	acpi_adr_space_handler handler;
 352	acpi_adr_space_setup region_setup;
 353	union acpi_operand_object *handler_desc;
 354	union acpi_operand_object *region_obj2;
 355	void *region_context = NULL;
 
 
 356
 357	ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
 358
 359	region_obj2 = acpi_ns_get_secondary_object(region_obj);
 360	if (!region_obj2) {
 361		return_ACPI_STATUS(AE_NOT_EXIST);
 362	}
 363
 364	/* Ensure that there is a handler associated with this region */
 365
 366	handler_desc = region_obj->region.handler;
 367	if (!handler_desc) {
 368		ACPI_ERROR((AE_INFO,
 369			    "No handler for Region [%4.4s] (%p) [%s]",
 370			    acpi_ut_get_node_name(region_obj->region.node),
 371			    region_obj,
 372			    acpi_ut_get_region_name(region_obj->region.
 373						    space_id)));
 374
 375		return_ACPI_STATUS(AE_NOT_EXIST);
 376	}
 377
 
 
 378	/*
 379	 * It may be the case that the region has never been initialized.
 380	 * Some types of regions require special init code
 381	 */
 382	if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
 383
 384		/* This region has not been initialized yet, do it */
 385
 386		region_setup = handler_desc->address_space.setup;
 387		if (!region_setup) {
 388
 389			/* No initialization routine, exit with error */
 390
 391			ACPI_ERROR((AE_INFO,
 392				    "No init routine for region(%p) [%s]",
 393				    region_obj,
 394				    acpi_ut_get_region_name(region_obj->region.
 395							    space_id)));
 396			return_ACPI_STATUS(AE_NOT_EXIST);
 397		}
 398
 399		/*
 400		 * We must exit the interpreter because the region setup will
 401		 * potentially execute control methods (for example, the _REG method
 402		 * for this region)
 403		 */
 404		acpi_ex_exit_interpreter();
 405
 406		status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
 407				      handler_desc->address_space.context,
 408				      &region_context);
 409
 410		/* Re-enter the interpreter */
 411
 412		acpi_ex_enter_interpreter();
 413
 414		/* Check for failure of the Region Setup */
 415
 416		if (ACPI_FAILURE(status)) {
 417			ACPI_EXCEPTION((AE_INFO, status,
 418					"During region initialization: [%s]",
 419					acpi_ut_get_region_name(region_obj->
 420								region.
 421								space_id)));
 422			return_ACPI_STATUS(status);
 423		}
 424
 425		/* Region initialization may have been completed by region_setup */
 426
 427		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
 428			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
 429
 430			if (region_obj2->extra.region_context) {
 431
 432				/* The handler for this region was already installed */
 433
 434				ACPI_FREE(region_context);
 435			} else {
 436				/*
 437				 * Save the returned context for use in all accesses to
 438				 * this particular region
 439				 */
 440				region_obj2->extra.region_context =
 441				    region_context;
 442			}
 443		}
 444	}
 445
 446	/* We have everything we need, we can invoke the address space handler */
 447
 448	handler = handler_desc->address_space.handler;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 449
 450	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 451			  "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
 452			  &region_obj->region.handler->address_space, handler,
 453			  ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
 454						  region_offset),
 455			  acpi_ut_get_region_name(region_obj->region.
 456						  space_id)));
 457
 458	if (!(handler_desc->address_space.handler_flags &
 459	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 460		/*
 461		 * For handlers other than the default (supplied) handlers, we must
 462		 * exit the interpreter because the handler *might* block -- we don't
 463		 * know what it will do, so we can't hold the lock on the intepreter.
 464		 */
 465		acpi_ex_exit_interpreter();
 466	}
 467
 468	/* Call the handler */
 469
 470	status = handler(function,
 471			 (region_obj->region.address + region_offset),
 472			 bit_width, value, handler_desc->address_space.context,
 473			 region_obj2->extra.region_context);
 474
 475	if (ACPI_FAILURE(status)) {
 476		ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
 477				acpi_ut_get_region_name(region_obj->region.
 478							space_id)));
 479	}
 480
 481	if (!(handler_desc->address_space.handler_flags &
 482	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 483		/*
 484		 * We just returned from a non-default handler, we must re-enter the
 485		 * interpreter
 486		 */
 487		acpi_ex_enter_interpreter();
 488	}
 489
 490	return_ACPI_STATUS(status);
 491}
 492
 493/*******************************************************************************
 494 *
 495 * FUNCTION:    acpi_ev_detach_region
 496 *
 497 * PARAMETERS:  region_obj          - Region Object
 498 *              acpi_ns_is_locked   - Namespace Region Already Locked?
 499 *
 500 * RETURN:      None
 501 *
 502 * DESCRIPTION: Break the association between the handler and the region
 503 *              this is a two way association.
 504 *
 505 ******************************************************************************/
 506
 507void
 508acpi_ev_detach_region(union acpi_operand_object *region_obj,
 509		      u8 acpi_ns_is_locked)
 510{
 511	union acpi_operand_object *handler_obj;
 512	union acpi_operand_object *obj_desc;
 
 513	union acpi_operand_object **last_obj_ptr;
 514	acpi_adr_space_setup region_setup;
 515	void **region_context;
 516	union acpi_operand_object *region_obj2;
 517	acpi_status status;
 518
 519	ACPI_FUNCTION_TRACE(ev_detach_region);
 520
 521	region_obj2 = acpi_ns_get_secondary_object(region_obj);
 522	if (!region_obj2) {
 523		return_VOID;
 524	}
 525	region_context = &region_obj2->extra.region_context;
 526
 527	/* Get the address handler from the region object */
 528
 529	handler_obj = region_obj->region.handler;
 530	if (!handler_obj) {
 531
 532		/* This region has no handler, all done */
 533
 534		return_VOID;
 535	}
 536
 537	/* Find this region in the handler's list */
 538
 539	obj_desc = handler_obj->address_space.region_list;
 
 540	last_obj_ptr = &handler_obj->address_space.region_list;
 541
 542	while (obj_desc) {
 543
 544		/* Is this the correct Region? */
 545
 546		if (obj_desc == region_obj) {
 547			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 548					  "Removing Region %p from address handler %p\n",
 549					  region_obj, handler_obj));
 550
 551			/* This is it, remove it from the handler's list */
 552
 553			*last_obj_ptr = obj_desc->region.next;
 554			obj_desc->region.next = NULL;	/* Must clear field */
 555
 556			if (acpi_ns_is_locked) {
 557				status =
 558				    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 559				if (ACPI_FAILURE(status)) {
 560					return_VOID;
 561				}
 562			}
 563
 564			/* Now stop region accesses by executing the _REG method */
 565
 566			status =
 567			    acpi_ev_execute_reg_method(region_obj,
 568						       ACPI_REG_DISCONNECT);
 569			if (ACPI_FAILURE(status)) {
 570				ACPI_EXCEPTION((AE_INFO, status,
 571						"from region _REG, [%s]",
 572						acpi_ut_get_region_name
 573						(region_obj->region.space_id)));
 574			}
 575
 576			if (acpi_ns_is_locked) {
 577				status =
 578				    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 579				if (ACPI_FAILURE(status)) {
 580					return_VOID;
 581				}
 582			}
 583
 584			/*
 585			 * If the region has been activated, call the setup handler with
 586			 * the deactivate notification
 587			 */
 588			if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
 589				region_setup = handler_obj->address_space.setup;
 590				status =
 591				    region_setup(region_obj,
 592						 ACPI_REGION_DEACTIVATE,
 593						 handler_obj->address_space.
 594						 context, region_context);
 595
 
 
 
 
 
 
 
 
 596				/* Init routine may fail, Just ignore errors */
 597
 598				if (ACPI_FAILURE(status)) {
 599					ACPI_EXCEPTION((AE_INFO, status,
 600							"from region handler - deactivate, [%s]",
 601							acpi_ut_get_region_name
 602							(region_obj->region.
 603							 space_id)));
 604				}
 605
 606				region_obj->region.flags &=
 607				    ~(AOPOBJ_SETUP_COMPLETE);
 608			}
 609
 610			/*
 611			 * Remove handler reference in the region
 612			 *
 613			 * NOTE: this doesn't mean that the region goes away, the region
 614			 * is just inaccessible as indicated to the _REG method
 615			 *
 616			 * If the region is on the handler's list, this must be the
 617			 * region's handler
 618			 */
 619			region_obj->region.handler = NULL;
 620			acpi_ut_remove_reference(handler_obj);
 621
 622			return_VOID;
 623		}
 624
 625		/* Walk the linked list of handlers */
 626
 627		last_obj_ptr = &obj_desc->region.next;
 628		obj_desc = obj_desc->region.next;
 
 
 
 
 
 
 
 
 
 629	}
 630
 631	/* If we get here, the region was not in the handler's region list */
 632
 633	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 634			  "Cannot remove region %p from address handler %p\n",
 635			  region_obj, handler_obj));
 636
 637	return_VOID;
 638}
 639
 640/*******************************************************************************
 641 *
 642 * FUNCTION:    acpi_ev_attach_region
 643 *
 644 * PARAMETERS:  handler_obj         - Handler Object
 645 *              region_obj          - Region Object
 646 *              acpi_ns_is_locked   - Namespace Region Already Locked?
 647 *
 648 * RETURN:      None
 649 *
 650 * DESCRIPTION: Create the association between the handler and the region
 651 *              this is a two way association.
 652 *
 653 ******************************************************************************/
 654
 655acpi_status
 656acpi_ev_attach_region(union acpi_operand_object *handler_obj,
 657		      union acpi_operand_object *region_obj,
 658		      u8 acpi_ns_is_locked)
 659{
 660
 661	ACPI_FUNCTION_TRACE(ev_attach_region);
 662
 
 
 
 
 
 
 663	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 664			  "Adding Region [%4.4s] %p to address handler %p [%s]\n",
 665			  acpi_ut_get_node_name(region_obj->region.node),
 666			  region_obj, handler_obj,
 667			  acpi_ut_get_region_name(region_obj->region.
 668						  space_id)));
 669
 670	/* Link this region to the front of the handler's list */
 671
 672	region_obj->region.next = handler_obj->address_space.region_list;
 673	handler_obj->address_space.region_list = region_obj;
 674
 675	/* Install the region's handler */
 676
 677	if (region_obj->region.handler) {
 678		return_ACPI_STATUS(AE_ALREADY_EXISTS);
 679	}
 680
 681	region_obj->region.handler = handler_obj;
 682	acpi_ut_add_reference(handler_obj);
 683
 684	return_ACPI_STATUS(AE_OK);
 685}
 686
 687/*******************************************************************************
 688 *
 689 * FUNCTION:    acpi_ev_install_handler
 690 *
 691 * PARAMETERS:  walk_namespace callback
 692 *
 693 * DESCRIPTION: This routine installs an address handler into objects that are
 694 *              of type Region or Device.
 695 *
 696 *              If the Object is a Device, and the device has a handler of
 697 *              the same type then the search is terminated in that branch.
 698 *
 699 *              This is because the existing handler is closer in proximity
 700 *              to any more regions than the one we are trying to install.
 701 *
 702 ******************************************************************************/
 703
 704static acpi_status
 705acpi_ev_install_handler(acpi_handle obj_handle,
 706			u32 level, void *context, void **return_value)
 707{
 708	union acpi_operand_object *handler_obj;
 709	union acpi_operand_object *next_handler_obj;
 710	union acpi_operand_object *obj_desc;
 711	struct acpi_namespace_node *node;
 
 712	acpi_status status;
 713
 714	ACPI_FUNCTION_NAME(ev_install_handler);
 715
 716	handler_obj = (union acpi_operand_object *)context;
 717
 718	/* Parameter validation */
 719
 720	if (!handler_obj) {
 721		return (AE_OK);
 722	}
 723
 724	/* Convert and validate the device handle */
 725
 726	node = acpi_ns_validate_handle(obj_handle);
 727	if (!node) {
 728		return (AE_BAD_PARAMETER);
 729	}
 730
 731	/*
 732	 * We only care about regions and objects that are allowed to have
 733	 * address space handlers
 734	 */
 735	if ((node->type != ACPI_TYPE_DEVICE) &&
 736	    (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
 737		return (AE_OK);
 738	}
 739
 740	/* Check for an existing internal object */
 741
 742	obj_desc = acpi_ns_get_attached_object(node);
 743	if (!obj_desc) {
 744
 745		/* No object, just exit */
 746
 747		return (AE_OK);
 748	}
 749
 750	/* Devices are handled different than regions */
 751
 752	if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
 753
 754		/* Check if this Device already has a handler for this address space */
 755
 756		next_handler_obj = obj_desc->device.handler;
 757		while (next_handler_obj) {
 758
 759			/* Found a handler, is it for the same address space? */
 760
 761			if (next_handler_obj->address_space.space_id ==
 762			    handler_obj->address_space.space_id) {
 763				ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 764						  "Found handler for region [%s] in device %p(%p) "
 765						  "handler %p\n",
 766						  acpi_ut_get_region_name
 767						  (handler_obj->address_space.
 768						   space_id), obj_desc,
 769						  next_handler_obj,
 770						  handler_obj));
 771
 772				/*
 773				 * Since the object we found it on was a device, then it
 774				 * means that someone has already installed a handler for
 775				 * the branch of the namespace from this device on. Just
 776				 * bail out telling the walk routine to not traverse this
 777				 * branch. This preserves the scoping rule for handlers.
 778				 */
 779				return (AE_CTRL_DEPTH);
 780			}
 781
 782			/* Walk the linked list of handlers attached to this device */
 783
 784			next_handler_obj = next_handler_obj->address_space.next;
 785		}
 786
 
 
 
 
 787		/*
 788		 * As long as the device didn't have a handler for this space we
 789		 * don't care about it. We just ignore it and proceed.
 
 790		 */
 791		return (AE_OK);
 792	}
 793
 794	/* Object is a Region */
 795
 796	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
 797
 798		/* This region is for a different address space, just ignore it */
 799
 800		return (AE_OK);
 801	}
 802
 803	/*
 804	 * Now we have a region and it is for the handler's address space type.
 805	 *
 806	 * First disconnect region for any previous handler (if any)
 807	 */
 808	acpi_ev_detach_region(obj_desc, FALSE);
 809
 810	/* Connect the region to the new handler */
 811
 812	status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
 813	return (status);
 814}
 815
 816/*******************************************************************************
 817 *
 818 * FUNCTION:    acpi_ev_install_space_handler
 819 *
 820 * PARAMETERS:  Node            - Namespace node for the device
 821 *              space_id        - The address space ID
 822 *              Handler         - Address of the handler
 823 *              Setup           - Address of the setup function
 824 *              Context         - Value passed to the handler on each access
 825 *
 826 * RETURN:      Status
 827 *
 828 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
 829 *              Assumes namespace is locked
 830 *
 831 ******************************************************************************/
 832
 833acpi_status
 834acpi_ev_install_space_handler(struct acpi_namespace_node * node,
 835			      acpi_adr_space_type space_id,
 836			      acpi_adr_space_handler handler,
 837			      acpi_adr_space_setup setup, void *context)
 838{
 839	union acpi_operand_object *obj_desc;
 840	union acpi_operand_object *handler_obj;
 
 841	acpi_status status;
 842	acpi_object_type type;
 843	u8 flags = 0;
 844
 845	ACPI_FUNCTION_TRACE(ev_install_space_handler);
 846
 847	/*
 848	 * This registration is valid for only the types below and the root. This
 849	 * is where the default handlers get placed.
 850	 */
 851	if ((node->type != ACPI_TYPE_DEVICE) &&
 852	    (node->type != ACPI_TYPE_PROCESSOR) &&
 853	    (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
 854		status = AE_BAD_PARAMETER;
 855		goto unlock_and_exit;
 856	}
 857
 858	if (handler == ACPI_DEFAULT_HANDLER) {
 859		flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
 860
 861		switch (space_id) {
 862		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 863			handler = acpi_ex_system_memory_space_handler;
 864			setup = acpi_ev_system_memory_region_setup;
 865			break;
 866
 867		case ACPI_ADR_SPACE_SYSTEM_IO:
 868			handler = acpi_ex_system_io_space_handler;
 869			setup = acpi_ev_io_space_region_setup;
 870			break;
 871
 872		case ACPI_ADR_SPACE_PCI_CONFIG:
 873			handler = acpi_ex_pci_config_space_handler;
 874			setup = acpi_ev_pci_config_region_setup;
 875			break;
 876
 877		case ACPI_ADR_SPACE_CMOS:
 878			handler = acpi_ex_cmos_space_handler;
 879			setup = acpi_ev_cmos_region_setup;
 880			break;
 881
 882		case ACPI_ADR_SPACE_PCI_BAR_TARGET:
 883			handler = acpi_ex_pci_bar_space_handler;
 884			setup = acpi_ev_pci_bar_region_setup;
 885			break;
 886
 887		case ACPI_ADR_SPACE_DATA_TABLE:
 888			handler = acpi_ex_data_table_space_handler;
 889			setup = NULL;
 890			break;
 891
 892		default:
 893			status = AE_BAD_PARAMETER;
 894			goto unlock_and_exit;
 895		}
 896	}
 897
 898	/* If the caller hasn't specified a setup routine, use the default */
 899
 900	if (!setup) {
 901		setup = acpi_ev_default_region_setup;
 902	}
 903
 904	/* Check for an existing internal object */
 905
 906	obj_desc = acpi_ns_get_attached_object(node);
 907	if (obj_desc) {
 908		/*
 909		 * The attached device object already exists. Make sure the handler
 910		 * is not already installed.
 911		 */
 912		handler_obj = obj_desc->device.handler;
 913
 914		/* Walk the handler list for this device */
 915
 916		while (handler_obj) {
 917
 918			/* Same space_id indicates a handler already installed */
 919
 920			if (handler_obj->address_space.space_id == space_id) {
 921				if (handler_obj->address_space.handler ==
 922				    handler) {
 923					/*
 924					 * It is (relatively) OK to attempt to install the SAME
 925					 * handler twice. This can easily happen with the
 926					 * PCI_Config space.
 927					 */
 928					status = AE_SAME_HANDLER;
 929					goto unlock_and_exit;
 930				} else {
 931					/* A handler is already installed */
 932
 933					status = AE_ALREADY_EXISTS;
 934				}
 935				goto unlock_and_exit;
 936			}
 937
 938			/* Walk the linked list of handlers */
 939
 940			handler_obj = handler_obj->address_space.next;
 941		}
 942	} else {
 943		ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 944				  "Creating object on Device %p while installing handler\n",
 945				  node));
 946
 947		/* obj_desc does not exist, create one */
 948
 949		if (node->type == ACPI_TYPE_ANY) {
 950			type = ACPI_TYPE_DEVICE;
 951		} else {
 952			type = node->type;
 953		}
 954
 955		obj_desc = acpi_ut_create_internal_object(type);
 956		if (!obj_desc) {
 957			status = AE_NO_MEMORY;
 958			goto unlock_and_exit;
 959		}
 960
 961		/* Init new descriptor */
 962
 963		obj_desc->common.type = (u8) type;
 964
 965		/* Attach the new object to the Node */
 966
 967		status = acpi_ns_attach_object(node, obj_desc, type);
 968
 969		/* Remove local reference to the object */
 970
 971		acpi_ut_remove_reference(obj_desc);
 972
 973		if (ACPI_FAILURE(status)) {
 974			goto unlock_and_exit;
 975		}
 976	}
 977
 978	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 979			  "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
 980			  acpi_ut_get_region_name(space_id), space_id,
 981			  acpi_ut_get_node_name(node), node, obj_desc));
 982
 983	/*
 984	 * Install the handler
 
 
 
 985	 *
 986	 * At this point there is no existing handler. Just allocate the object
 987	 * for the handler and link it into the list.
 
 988	 */
 989	handler_obj =
 990	    acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
 991	if (!handler_obj) {
 992		status = AE_NO_MEMORY;
 993		goto unlock_and_exit;
 
 
 
 
 
 
 994	}
 995
 996	/* Init handler obj */
 997
 998	handler_obj->address_space.space_id = (u8) space_id;
 999	handler_obj->address_space.handler_flags = flags;
1000	handler_obj->address_space.region_list = NULL;
1001	handler_obj->address_space.node = node;
1002	handler_obj->address_space.handler = handler;
1003	handler_obj->address_space.context = context;
1004	handler_obj->address_space.setup = setup;
1005
1006	/* Install at head of Device.address_space list */
 
1007
1008	handler_obj->address_space.next = obj_desc->device.handler;
 
1009
1010	/*
1011	 * The Device object is the first reference on the handler_obj.
1012	 * Each region that uses the handler adds a reference.
1013	 */
1014	obj_desc->device.handler = handler_obj;
1015
1016	/*
1017	 * Walk the namespace finding all of the regions this
1018	 * handler will manage.
1019	 *
1020	 * Start at the device and search the branch toward
1021	 * the leaf nodes until either the leaf is encountered or
1022	 * a device is detected that has an address handler of the
1023	 * same type.
1024	 *
1025	 * In either case, back up and search down the remainder
1026	 * of the branch
1027	 */
1028	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1029					ACPI_NS_WALK_UNLOCK,
1030					acpi_ev_install_handler, NULL,
1031					handler_obj, NULL);
1032
1033      unlock_and_exit:
 
 
 
 
1034	return_ACPI_STATUS(status);
1035}
1036
1037/*******************************************************************************
1038 *
1039 * FUNCTION:    acpi_ev_execute_reg_methods
1040 *
1041 * PARAMETERS:  Node            - Namespace node for the device
1042 *              space_id        - The address space ID
 
1043 *
1044 * RETURN:      Status
1045 *
1046 * DESCRIPTION: Run all _REG methods for the input Space ID;
1047 *              Note: assumes namespace is locked, or system init time.
1048 *
1049 ******************************************************************************/
1050
1051acpi_status
1052acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
1053			    acpi_adr_space_type space_id)
1054{
1055	acpi_status status;
1056
1057	ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
1058
 
 
 
 
 
 
 
 
1059	/*
1060	 * Run all _REG methods for all Operation Regions for this space ID. This
1061	 * is a separate walk in order to handle any interdependencies between
1062	 * regions and _REG methods. (i.e. handlers must be installed for all
1063	 * regions of this Space ID before we can run any _REG methods)
1064	 */
1065	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1066					ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1067					NULL, &space_id, NULL);
1068
1069	/* Special case for EC: handle "orphan" _REG methods with no region */
1070
1071	if (space_id == ACPI_ADR_SPACE_EC) {
1072		acpi_ev_orphan_ec_reg_method();
1073	}
1074
1075	return_ACPI_STATUS(status);
 
 
 
 
 
1076}
1077
1078/*******************************************************************************
1079 *
1080 * FUNCTION:    acpi_ev_reg_run
1081 *
1082 * PARAMETERS:  walk_namespace callback
1083 *
1084 * DESCRIPTION: Run _REG method for region objects of the requested space_iD
1085 *
1086 ******************************************************************************/
1087
1088static acpi_status
1089acpi_ev_reg_run(acpi_handle obj_handle,
1090		u32 level, void *context, void **return_value)
1091{
1092	union acpi_operand_object *obj_desc;
1093	struct acpi_namespace_node *node;
1094	acpi_adr_space_type space_id;
1095	acpi_status status;
 
1096
1097	space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
1098
1099	/* Convert and validate the device handle */
1100
1101	node = acpi_ns_validate_handle(obj_handle);
1102	if (!node) {
1103		return (AE_BAD_PARAMETER);
1104	}
1105
1106	/*
1107	 * We only care about regions.and objects that are allowed to have address
1108	 * space handlers
1109	 */
1110	if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
1111		return (AE_OK);
1112	}
1113
1114	/* Check for an existing internal object */
1115
1116	obj_desc = acpi_ns_get_attached_object(node);
1117	if (!obj_desc) {
1118
1119		/* No object, just exit */
1120
1121		return (AE_OK);
1122	}
1123
1124	/* Object is a Region */
1125
1126	if (obj_desc->region.space_id != space_id) {
1127
1128		/* This region is for a different address space, just ignore it */
1129
1130		return (AE_OK);
1131	}
1132
1133	status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
 
1134	return (status);
1135}
1136
1137/*******************************************************************************
1138 *
1139 * FUNCTION:    acpi_ev_orphan_ec_reg_method
1140 *
1141 * PARAMETERS:  None
1142 *
1143 * RETURN:      None
1144 *
1145 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
1146 *              device. This is a _REG method that has no corresponding region
1147 *              within the EC device scope. The orphan _REG method appears to
1148 *              have been enabled by the description of the ECDT in the ACPI
1149 *              specification: "The availability of the region space can be
1150 *              detected by providing a _REG method object underneath the
1151 *              Embedded Controller device."
1152 *
1153 *              To quickly access the EC device, we use the EC_ID that appears
1154 *              within the ECDT. Otherwise, we would need to perform a time-
1155 *              consuming namespace walk, executing _HID methods to find the
1156 *              EC device.
 
 
1157 *
1158 ******************************************************************************/
1159
1160static void acpi_ev_orphan_ec_reg_method(void)
 
1161{
1162	struct acpi_table_ecdt *table;
 
1163	acpi_status status;
1164	struct acpi_object_list args;
1165	union acpi_object objects[2];
1166	struct acpi_namespace_node *ec_device_node;
1167	struct acpi_namespace_node *reg_method;
1168	struct acpi_namespace_node *next_node;
1169
1170	ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
1171
1172	/* Get the ECDT (if present in system) */
1173
1174	status = acpi_get_table(ACPI_SIG_ECDT, 0,
1175				ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
1176						       &table));
1177	if (ACPI_FAILURE(status)) {
1178		return_VOID;
1179	}
1180
1181	/* We need a valid EC_ID string */
1182
1183	if (!(*table->id)) {
1184		return_VOID;
1185	}
1186
1187	/* Namespace is currently locked, must release */
1188
1189	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
1190
1191	/* Get a handle to the EC device referenced in the ECDT */
1192
1193	status = acpi_get_handle(NULL,
1194				 ACPI_CAST_PTR(char, table->id),
1195				 ACPI_CAST_PTR(acpi_handle, &ec_device_node));
1196	if (ACPI_FAILURE(status)) {
1197		goto exit;
1198	}
1199
1200	/* Get a handle to a _REG method immediately under the EC device */
1201
1202	status = acpi_get_handle(ec_device_node,
1203				 METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
1204								 &reg_method));
1205	if (ACPI_FAILURE(status)) {
1206		goto exit;
1207	}
1208
1209	/*
1210	 * Execute the _REG method only if there is no Operation Region in
1211	 * this scope with the Embedded Controller space ID. Otherwise, it
1212	 * will already have been executed. Note, this allows for Regions
1213	 * with other space IDs to be present; but the code below will then
1214	 * execute the _REG method with the EC space ID argument.
1215	 */
1216	next_node = acpi_ns_get_next_node(ec_device_node, NULL);
1217	while (next_node) {
1218		if ((next_node->type == ACPI_TYPE_REGION) &&
1219		    (next_node->object) &&
1220		    (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
1221			goto exit;	/* Do not execute _REG */
1222		}
 
1223		next_node = acpi_ns_get_next_node(ec_device_node, next_node);
1224	}
1225
1226	/* Evaluate the _REG(EC,Connect) method */
1227
1228	args.count = 2;
1229	args.pointer = objects;
1230	objects[0].type = ACPI_TYPE_INTEGER;
1231	objects[0].integer.value = ACPI_ADR_SPACE_EC;
1232	objects[1].type = ACPI_TYPE_INTEGER;
1233	objects[1].integer.value = ACPI_REG_CONNECT;
1234
1235	status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
1236
1237      exit:
1238	/* We ignore all errors from above, don't care */
1239
1240	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
1241	return_VOID;
1242}
v4.6
  1/******************************************************************************
  2 *
  3 * Module Name: evregion - Operation Region support
  4 *
  5 *****************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2016, Intel Corp.
  9 * All rights reserved.
 10 *
 11 * Redistribution and use in source and binary forms, with or without
 12 * modification, are permitted provided that the following conditions
 13 * are met:
 14 * 1. Redistributions of source code must retain the above copyright
 15 *    notice, this list of conditions, and the following disclaimer,
 16 *    without modification.
 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 18 *    substantially similar to the "NO WARRANTY" disclaimer below
 19 *    ("Disclaimer") and any redistribution must be conditioned upon
 20 *    including a substantially similar Disclaimer requirement for further
 21 *    binary redistribution.
 22 * 3. Neither the names of the above-listed copyright holders nor the names
 23 *    of any contributors may be used to endorse or promote products derived
 24 *    from this software without specific prior written permission.
 25 *
 26 * Alternatively, this software may be distributed under the terms of the
 27 * GNU General Public License ("GPL") version 2 as published by the Free
 28 * Software Foundation.
 29 *
 30 * NO WARRANTY
 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 41 * POSSIBILITY OF SUCH DAMAGES.
 42 */
 43
 44#include <acpi/acpi.h>
 45#include "accommon.h"
 46#include "acevents.h"
 47#include "acnamesp.h"
 48#include "acinterp.h"
 49
 50#define _COMPONENT          ACPI_EVENTS
 51ACPI_MODULE_NAME("evregion")
 52
 53extern u8 acpi_gbl_default_address_spaces[];
 54
 55/* Local prototypes */
 
 
 
 56
 57static void
 58acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node);
 59
 60static acpi_status
 61acpi_ev_reg_run(acpi_handle obj_handle,
 62		u32 level, void *context, void **return_value);
 63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 64/*******************************************************************************
 65 *
 66 * FUNCTION:    acpi_ev_initialize_op_regions
 67 *
 68 * PARAMETERS:  None
 69 *
 70 * RETURN:      Status
 71 *
 72 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
 73 *              an installed default region handler.
 74 *
 75 ******************************************************************************/
 76
 77acpi_status acpi_ev_initialize_op_regions(void)
 78{
 79	acpi_status status;
 80	u32 i;
 81
 82	ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
 83
 84	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 85	if (ACPI_FAILURE(status)) {
 86		return_ACPI_STATUS(status);
 87	}
 88
 89	/* Run the _REG methods for op_regions in each default address space */
 90
 91	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 92		/*
 93		 * Make sure the installed handler is the DEFAULT handler. If not the
 94		 * default, the _REG methods will have already been run (when the
 95		 * handler was installed)
 96		 */
 97		if (acpi_ev_has_default_handler(acpi_gbl_root_node,
 98						acpi_gbl_default_address_spaces
 99						[i])) {
100			acpi_ev_execute_reg_methods(acpi_gbl_root_node,
101						    acpi_gbl_default_address_spaces
102						    [i], ACPI_REG_CONNECT);
 
103		}
104	}
105
 
 
106	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
107	return_ACPI_STATUS(status);
108}
109
110/*******************************************************************************
111 *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112 * FUNCTION:    acpi_ev_address_space_dispatch
113 *
114 * PARAMETERS:  region_obj          - Internal region object
115 *              field_obj           - Corresponding field. Can be NULL.
116 *              function            - Read or Write operation
117 *              region_offset       - Where in the region to read or write
118 *              bit_width           - Field width in bits (8, 16, 32, or 64)
119 *              value               - Pointer to in or out value, must be
120 *                                    a full 64-bit integer
121 *
122 * RETURN:      Status
123 *
124 * DESCRIPTION: Dispatch an address space or operation region access to
125 *              a previously installed handler.
126 *
127 * NOTE: During early initialization, we always install the default region
128 * handlers for Memory, I/O and PCI_Config. This ensures that these operation
129 * region address spaces are always available as per the ACPI specification.
130 * This is especially needed in order to support the execution of
131 * module-level AML code during loading of the ACPI tables.
132 *
133 ******************************************************************************/
134
135acpi_status
136acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
137			       union acpi_operand_object *field_obj,
138			       u32 function,
139			       u32 region_offset, u32 bit_width, u64 *value)
140{
141	acpi_status status;
142	acpi_adr_space_handler handler;
143	acpi_adr_space_setup region_setup;
144	union acpi_operand_object *handler_desc;
145	union acpi_operand_object *region_obj2;
146	void *region_context = NULL;
147	struct acpi_connection_info *context;
148	acpi_physical_address address;
149
150	ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
151
152	region_obj2 = acpi_ns_get_secondary_object(region_obj);
153	if (!region_obj2) {
154		return_ACPI_STATUS(AE_NOT_EXIST);
155	}
156
157	/* Ensure that there is a handler associated with this region */
158
159	handler_desc = region_obj->region.handler;
160	if (!handler_desc) {
161		ACPI_ERROR((AE_INFO,
162			    "No handler for Region [%4.4s] (%p) [%s]",
163			    acpi_ut_get_node_name(region_obj->region.node),
164			    region_obj,
165			    acpi_ut_get_region_name(region_obj->region.
166						    space_id)));
167
168		return_ACPI_STATUS(AE_NOT_EXIST);
169	}
170
171	context = handler_desc->address_space.context;
172
173	/*
174	 * It may be the case that the region has never been initialized.
175	 * Some types of regions require special init code
176	 */
177	if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
178
179		/* This region has not been initialized yet, do it */
180
181		region_setup = handler_desc->address_space.setup;
182		if (!region_setup) {
183
184			/* No initialization routine, exit with error */
185
186			ACPI_ERROR((AE_INFO,
187				    "No init routine for region(%p) [%s]",
188				    region_obj,
189				    acpi_ut_get_region_name(region_obj->region.
190							    space_id)));
191			return_ACPI_STATUS(AE_NOT_EXIST);
192		}
193
194		/*
195		 * We must exit the interpreter because the region setup will
196		 * potentially execute control methods (for example, the _REG method
197		 * for this region)
198		 */
199		acpi_ex_exit_interpreter();
200
201		status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
202				      context, &region_context);
 
203
204		/* Re-enter the interpreter */
205
206		acpi_ex_enter_interpreter();
207
208		/* Check for failure of the Region Setup */
209
210		if (ACPI_FAILURE(status)) {
211			ACPI_EXCEPTION((AE_INFO, status,
212					"During region initialization: [%s]",
213					acpi_ut_get_region_name(region_obj->
214								region.
215								space_id)));
216			return_ACPI_STATUS(status);
217		}
218
219		/* Region initialization may have been completed by region_setup */
220
221		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
222			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
223
224			/*
225			 * Save the returned context for use in all accesses to
226			 * the handler for this particular region
227			 */
228			if (!(region_obj2->extra.region_context)) {
 
 
 
 
 
229				region_obj2->extra.region_context =
230				    region_context;
231			}
232		}
233	}
234
235	/* We have everything we need, we can invoke the address space handler */
236
237	handler = handler_desc->address_space.handler;
238	address = (region_obj->region.address + region_offset);
239
240	/*
241	 * Special handling for generic_serial_bus and general_purpose_io:
242	 * There are three extra parameters that must be passed to the
243	 * handler via the context:
244	 *   1) Connection buffer, a resource template from Connection() op
245	 *   2) Length of the above buffer
246	 *   3) Actual access length from the access_as() op
247	 *
248	 * In addition, for general_purpose_io, the Address and bit_width fields
249	 * are defined as follows:
250	 *   1) Address is the pin number index of the field (bit offset from
251	 *      the previous Connection)
252	 *   2) bit_width is the actual bit length of the field (number of pins)
253	 */
254	if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) &&
255	    context && field_obj) {
256
257		/* Get the Connection (resource_template) buffer */
258
259		context->connection = field_obj->field.resource_buffer;
260		context->length = field_obj->field.resource_length;
261		context->access_length = field_obj->field.access_length;
262	}
263	if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) &&
264	    context && field_obj) {
265
266		/* Get the Connection (resource_template) buffer */
267
268		context->connection = field_obj->field.resource_buffer;
269		context->length = field_obj->field.resource_length;
270		context->access_length = field_obj->field.access_length;
271		address = field_obj->field.pin_number_index;
272		bit_width = field_obj->field.bit_length;
273	}
274
275	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
276			  "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
277			  &region_obj->region.handler->address_space, handler,
278			  ACPI_FORMAT_UINT64(address),
 
279			  acpi_ut_get_region_name(region_obj->region.
280						  space_id)));
281
282	if (!(handler_desc->address_space.handler_flags &
283	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
284		/*
285		 * For handlers other than the default (supplied) handlers, we must
286		 * exit the interpreter because the handler *might* block -- we don't
287		 * know what it will do, so we can't hold the lock on the intepreter.
288		 */
289		acpi_ex_exit_interpreter();
290	}
291
292	/* Call the handler */
293
294	status = handler(function, address, bit_width, value, context,
 
 
295			 region_obj2->extra.region_context);
296
297	if (ACPI_FAILURE(status)) {
298		ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
299				acpi_ut_get_region_name(region_obj->region.
300							space_id)));
301	}
302
303	if (!(handler_desc->address_space.handler_flags &
304	      ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
305		/*
306		 * We just returned from a non-default handler, we must re-enter the
307		 * interpreter
308		 */
309		acpi_ex_enter_interpreter();
310	}
311
312	return_ACPI_STATUS(status);
313}
314
315/*******************************************************************************
316 *
317 * FUNCTION:    acpi_ev_detach_region
318 *
319 * PARAMETERS:  region_obj          - Region Object
320 *              acpi_ns_is_locked   - Namespace Region Already Locked?
321 *
322 * RETURN:      None
323 *
324 * DESCRIPTION: Break the association between the handler and the region
325 *              this is a two way association.
326 *
327 ******************************************************************************/
328
329void
330acpi_ev_detach_region(union acpi_operand_object *region_obj,
331		      u8 acpi_ns_is_locked)
332{
333	union acpi_operand_object *handler_obj;
334	union acpi_operand_object *obj_desc;
335	union acpi_operand_object *start_desc;
336	union acpi_operand_object **last_obj_ptr;
337	acpi_adr_space_setup region_setup;
338	void **region_context;
339	union acpi_operand_object *region_obj2;
340	acpi_status status;
341
342	ACPI_FUNCTION_TRACE(ev_detach_region);
343
344	region_obj2 = acpi_ns_get_secondary_object(region_obj);
345	if (!region_obj2) {
346		return_VOID;
347	}
348	region_context = &region_obj2->extra.region_context;
349
350	/* Get the address handler from the region object */
351
352	handler_obj = region_obj->region.handler;
353	if (!handler_obj) {
354
355		/* This region has no handler, all done */
356
357		return_VOID;
358	}
359
360	/* Find this region in the handler's list */
361
362	obj_desc = handler_obj->address_space.region_list;
363	start_desc = obj_desc;
364	last_obj_ptr = &handler_obj->address_space.region_list;
365
366	while (obj_desc) {
367
368		/* Is this the correct Region? */
369
370		if (obj_desc == region_obj) {
371			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
372					  "Removing Region %p from address handler %p\n",
373					  region_obj, handler_obj));
374
375			/* This is it, remove it from the handler's list */
376
377			*last_obj_ptr = obj_desc->region.next;
378			obj_desc->region.next = NULL;	/* Must clear field */
379
380			if (acpi_ns_is_locked) {
381				status =
382				    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
383				if (ACPI_FAILURE(status)) {
384					return_VOID;
385				}
386			}
387
388			/* Now stop region accesses by executing the _REG method */
389
390			status =
391			    acpi_ev_execute_reg_method(region_obj,
392						       ACPI_REG_DISCONNECT);
393			if (ACPI_FAILURE(status)) {
394				ACPI_EXCEPTION((AE_INFO, status,
395						"from region _REG, [%s]",
396						acpi_ut_get_region_name
397						(region_obj->region.space_id)));
398			}
399
400			if (acpi_ns_is_locked) {
401				status =
402				    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
403				if (ACPI_FAILURE(status)) {
404					return_VOID;
405				}
406			}
407
408			/*
409			 * If the region has been activated, call the setup handler with
410			 * the deactivate notification
411			 */
412			if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
413				region_setup = handler_obj->address_space.setup;
414				status =
415				    region_setup(region_obj,
416						 ACPI_REGION_DEACTIVATE,
417						 handler_obj->address_space.
418						 context, region_context);
419
420				/*
421				 * region_context should have been released by the deactivate
422				 * operation. We don't need access to it anymore here.
423				 */
424				if (region_context) {
425					*region_context = NULL;
426				}
427
428				/* Init routine may fail, Just ignore errors */
429
430				if (ACPI_FAILURE(status)) {
431					ACPI_EXCEPTION((AE_INFO, status,
432							"from region handler - deactivate, [%s]",
433							acpi_ut_get_region_name
434							(region_obj->region.
435							 space_id)));
436				}
437
438				region_obj->region.flags &=
439				    ~(AOPOBJ_SETUP_COMPLETE);
440			}
441
442			/*
443			 * Remove handler reference in the region
444			 *
445			 * NOTE: this doesn't mean that the region goes away, the region
446			 * is just inaccessible as indicated to the _REG method
447			 *
448			 * If the region is on the handler's list, this must be the
449			 * region's handler
450			 */
451			region_obj->region.handler = NULL;
452			acpi_ut_remove_reference(handler_obj);
453
454			return_VOID;
455		}
456
457		/* Walk the linked list of handlers */
458
459		last_obj_ptr = &obj_desc->region.next;
460		obj_desc = obj_desc->region.next;
461
462		/* Prevent infinite loop if list is corrupted */
463
464		if (obj_desc == start_desc) {
465			ACPI_ERROR((AE_INFO,
466				    "Circular handler list in region object %p",
467				    region_obj));
468			return_VOID;
469		}
470	}
471
472	/* If we get here, the region was not in the handler's region list */
473
474	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
475			  "Cannot remove region %p from address handler %p\n",
476			  region_obj, handler_obj));
477
478	return_VOID;
479}
480
481/*******************************************************************************
482 *
483 * FUNCTION:    acpi_ev_attach_region
484 *
485 * PARAMETERS:  handler_obj         - Handler Object
486 *              region_obj          - Region Object
487 *              acpi_ns_is_locked   - Namespace Region Already Locked?
488 *
489 * RETURN:      None
490 *
491 * DESCRIPTION: Create the association between the handler and the region
492 *              this is a two way association.
493 *
494 ******************************************************************************/
495
496acpi_status
497acpi_ev_attach_region(union acpi_operand_object *handler_obj,
498		      union acpi_operand_object *region_obj,
499		      u8 acpi_ns_is_locked)
500{
501
502	ACPI_FUNCTION_TRACE(ev_attach_region);
503
504	/* Install the region's handler */
505
506	if (region_obj->region.handler) {
507		return_ACPI_STATUS(AE_ALREADY_EXISTS);
508	}
509
510	ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
511			  "Adding Region [%4.4s] %p to address handler %p [%s]\n",
512			  acpi_ut_get_node_name(region_obj->region.node),
513			  region_obj, handler_obj,
514			  acpi_ut_get_region_name(region_obj->region.
515						  space_id)));
516
517	/* Link this region to the front of the handler's list */
518
519	region_obj->region.next = handler_obj->address_space.region_list;
520	handler_obj->address_space.region_list = region_obj;
 
 
 
 
 
 
 
521	region_obj->region.handler = handler_obj;
522	acpi_ut_add_reference(handler_obj);
523
524	return_ACPI_STATUS(AE_OK);
525}
526
527/*******************************************************************************
528 *
529 * FUNCTION:    acpi_ev_associate_reg_method
 
 
530 *
531 * PARAMETERS:  region_obj          - Region object
 
532 *
533 * RETURN:      Status
 
534 *
535 * DESCRIPTION: Find and associate _REG method to a region
 
536 *
537 ******************************************************************************/
538
539void acpi_ev_associate_reg_method(union acpi_operand_object *region_obj)
 
 
540{
541	acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
542	struct acpi_namespace_node *method_node;
 
543	struct acpi_namespace_node *node;
544	union acpi_operand_object *region_obj2;
545	acpi_status status;
546
547	ACPI_FUNCTION_TRACE(ev_associate_reg_method);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
549	region_obj2 = acpi_ns_get_secondary_object(region_obj);
550	if (!region_obj2) {
551		return_VOID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552	}
553
554	node = region_obj->region.node->parent;
 
 
555
556	/* Find any "_REG" method associated with this region definition */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
558	status =
559	    acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
560				     &method_node);
561	if (ACPI_SUCCESS(status)) {
562		/*
563		 * The _REG method is optional and there can be only one per region
564		 * definition. This will be executed when the handler is attached
565		 * or removed
566		 */
567		region_obj2->extra.method_REG = method_node;
 
 
 
 
 
 
 
 
 
568	}
569
570	return_VOID;
 
 
 
 
 
 
 
 
 
 
571}
572
573/*******************************************************************************
574 *
575 * FUNCTION:    acpi_ev_execute_reg_method
576 *
577 * PARAMETERS:  region_obj          - Region object
578 *              function            - Passed to _REG: On (1) or Off (0)
 
 
 
579 *
580 * RETURN:      Status
581 *
582 * DESCRIPTION: Execute _REG method for a region
 
583 *
584 ******************************************************************************/
585
586acpi_status
587acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
 
 
 
588{
589	struct acpi_evaluate_info *info;
590	union acpi_operand_object *args[3];
591	union acpi_operand_object *region_obj2;
592	acpi_status status;
 
 
593
594	ACPI_FUNCTION_TRACE(ev_execute_reg_method);
595
596	region_obj2 = acpi_ns_get_secondary_object(region_obj);
597	if (!region_obj2) {
598		return_ACPI_STATUS(AE_NOT_EXIST);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599	}
600
601	if (region_obj2->extra.method_REG == NULL ||
602	    region_obj->region.handler == NULL ||
603	    !acpi_gbl_namespace_initialized) {
604		return_ACPI_STATUS(AE_OK);
605	}
606
607	/* _REG(DISCONNECT) should be paired with _REG(CONNECT) */
 
 
 
 
 
 
 
 
608
609	if ((function == ACPI_REG_CONNECT &&
610	     region_obj->common.flags & AOPOBJ_REG_CONNECTED) ||
611	    (function == ACPI_REG_DISCONNECT &&
612	     !(region_obj->common.flags & AOPOBJ_REG_CONNECTED))) {
613		return_ACPI_STATUS(AE_OK);
614	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
616	/* Allocate and initialize the evaluation information block */
617
618	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
619	if (!info) {
620		return_ACPI_STATUS(AE_NO_MEMORY);
621	}
622
623	info->prefix_node = region_obj2->extra.method_REG;
624	info->relative_pathname = NULL;
625	info->parameters = args;
626	info->flags = ACPI_IGNORE_RETURN_VALUE;
627
628	/*
629	 * The _REG method has two arguments:
630	 *
631	 * arg0 - Integer:
632	 *  Operation region space ID Same value as region_obj->Region.space_id
633	 *
634	 * arg1 - Integer:
635	 *  connection status 1 for connecting the handler, 0 for disconnecting
636	 *  the handler (Passed as a parameter)
637	 */
638	args[0] =
639	    acpi_ut_create_integer_object((u64)region_obj->region.space_id);
640	if (!args[0]) {
641		status = AE_NO_MEMORY;
642		goto cleanup1;
643	}
644
645	args[1] = acpi_ut_create_integer_object((u64)function);
646	if (!args[1]) {
647		status = AE_NO_MEMORY;
648		goto cleanup2;
649	}
650
651	args[2] = NULL;		/* Terminate list */
652
653	/* Execute the method, no return value */
 
 
 
 
 
 
654
655	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
656			(ACPI_TYPE_METHOD, info->prefix_node, NULL));
657
658	status = acpi_ns_evaluate(info);
659	acpi_ut_remove_reference(args[1]);
660
661	if (ACPI_FAILURE(status)) {
662		goto cleanup2;
663	}
 
 
664
665	if (function == ACPI_REG_CONNECT) {
666		region_obj->common.flags |= AOPOBJ_REG_CONNECTED;
667	} else {
668		region_obj->common.flags &= ~AOPOBJ_REG_CONNECTED;
669	}
 
 
 
 
 
 
 
 
 
 
 
670
671cleanup2:
672	acpi_ut_remove_reference(args[0]);
673
674cleanup1:
675	ACPI_FREE(info);
676	return_ACPI_STATUS(status);
677}
678
679/*******************************************************************************
680 *
681 * FUNCTION:    acpi_ev_execute_reg_methods
682 *
683 * PARAMETERS:  node            - Namespace node for the device
684 *              space_id        - The address space ID
685 *              function        - Passed to _REG: On (1) or Off (0)
686 *
687 * RETURN:      None
688 *
689 * DESCRIPTION: Run all _REG methods for the input Space ID;
690 *              Note: assumes namespace is locked, or system init time.
691 *
692 ******************************************************************************/
693
694void
695acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
696			    acpi_adr_space_type space_id, u32 function)
697{
698	struct acpi_reg_walk_info info;
699
700	ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
701
702	info.space_id = space_id;
703	info.function = function;
704	info.reg_run_count = 0;
705
706	ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES,
707			      "    Running _REG methods for SpaceId %s\n",
708			      acpi_ut_get_region_name(info.space_id)));
709
710	/*
711	 * Run all _REG methods for all Operation Regions for this space ID. This
712	 * is a separate walk in order to handle any interdependencies between
713	 * regions and _REG methods. (i.e. handlers must be installed for all
714	 * regions of this Space ID before we can run any _REG methods)
715	 */
716	(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
717				     ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL,
718				     &info, NULL);
719
720	/* Special case for EC: handle "orphan" _REG methods with no region */
721
722	if (space_id == ACPI_ADR_SPACE_EC) {
723		acpi_ev_orphan_ec_reg_method(node);
724	}
725
726	ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES,
727			      "    Executed %u _REG methods for SpaceId %s\n",
728			      info.reg_run_count,
729			      acpi_ut_get_region_name(info.space_id)));
730
731	return_VOID;
732}
733
734/*******************************************************************************
735 *
736 * FUNCTION:    acpi_ev_reg_run
737 *
738 * PARAMETERS:  walk_namespace callback
739 *
740 * DESCRIPTION: Run _REG method for region objects of the requested spaceID
741 *
742 ******************************************************************************/
743
744static acpi_status
745acpi_ev_reg_run(acpi_handle obj_handle,
746		u32 level, void *context, void **return_value)
747{
748	union acpi_operand_object *obj_desc;
749	struct acpi_namespace_node *node;
 
750	acpi_status status;
751	struct acpi_reg_walk_info *info;
752
753	info = ACPI_CAST_PTR(struct acpi_reg_walk_info, context);
754
755	/* Convert and validate the device handle */
756
757	node = acpi_ns_validate_handle(obj_handle);
758	if (!node) {
759		return (AE_BAD_PARAMETER);
760	}
761
762	/*
763	 * We only care about regions.and objects that are allowed to have address
764	 * space handlers
765	 */
766	if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
767		return (AE_OK);
768	}
769
770	/* Check for an existing internal object */
771
772	obj_desc = acpi_ns_get_attached_object(node);
773	if (!obj_desc) {
774
775		/* No object, just exit */
776
777		return (AE_OK);
778	}
779
780	/* Object is a Region */
781
782	if (obj_desc->region.space_id != info->space_id) {
783
784		/* This region is for a different address space, just ignore it */
785
786		return (AE_OK);
787	}
788
789	info->reg_run_count++;
790	status = acpi_ev_execute_reg_method(obj_desc, info->function);
791	return (status);
792}
793
794/*******************************************************************************
795 *
796 * FUNCTION:    acpi_ev_orphan_ec_reg_method
797 *
798 * PARAMETERS:  ec_device_node      - Namespace node for an EC device
799 *
800 * RETURN:      None
801 *
802 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
803 *              device. This is a _REG method that has no corresponding region
804 *              within the EC device scope. The orphan _REG method appears to
805 *              have been enabled by the description of the ECDT in the ACPI
806 *              specification: "The availability of the region space can be
807 *              detected by providing a _REG method object underneath the
808 *              Embedded Controller device."
809 *
810 *              To quickly access the EC device, we use the ec_device_node used
811 *              during EC handler installation. Otherwise, we would need to
812 *              perform a time consuming namespace walk, executing _HID
813 *              methods to find the EC device.
814 *
815 *  MUTEX:      Assumes the namespace is locked
816 *
817 ******************************************************************************/
818
819static void
820acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
821{
822	acpi_handle reg_method;
823	struct acpi_namespace_node *next_node;
824	acpi_status status;
825	struct acpi_object_list args;
826	union acpi_object objects[2];
 
 
 
827
828	ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
829
830	if (!ec_device_node) {
 
 
 
 
 
 
 
 
 
 
 
831		return_VOID;
832	}
833
834	/* Namespace is currently locked, must release */
835
836	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
837
 
 
 
 
 
 
 
 
 
838	/* Get a handle to a _REG method immediately under the EC device */
839
840	status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, &reg_method);
 
 
841	if (ACPI_FAILURE(status)) {
842		goto exit;	/* There is no _REG method present */
843	}
844
845	/*
846	 * Execute the _REG method only if there is no Operation Region in
847	 * this scope with the Embedded Controller space ID. Otherwise, it
848	 * will already have been executed. Note, this allows for Regions
849	 * with other space IDs to be present; but the code below will then
850	 * execute the _REG method with the embedded_control space_ID argument.
851	 */
852	next_node = acpi_ns_get_next_node(ec_device_node, NULL);
853	while (next_node) {
854		if ((next_node->type == ACPI_TYPE_REGION) &&
855		    (next_node->object) &&
856		    (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
857			goto exit;	/* Do not execute the _REG */
858		}
859
860		next_node = acpi_ns_get_next_node(ec_device_node, next_node);
861	}
862
863	/* Evaluate the _REG(embedded_control,Connect) method */
864
865	args.count = 2;
866	args.pointer = objects;
867	objects[0].type = ACPI_TYPE_INTEGER;
868	objects[0].integer.value = ACPI_ADR_SPACE_EC;
869	objects[1].type = ACPI_TYPE_INTEGER;
870	objects[1].integer.value = ACPI_REG_CONNECT;
871
872	status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
873
874exit:
875	/* We ignore all errors from above, don't care */
876
877	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
878	return_VOID;
879}