Linux Audio

Check our new training course

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