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 17 ACPI_MODULE_NAME("evregion") 18 19 extern u8 acpi_gbl_default_address_spaces[]; 20 21 /* Local prototypes */ 22 23 static void 24 acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, 25 acpi_adr_space_type space_id); 26 27 static acpi_status 28 acpi_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 44 acpi_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_UINT32_MAX, 69 acpi_gbl_default_address_spaces 70 [i], ACPI_REG_CONNECT); 71 } 72 } 73 74 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 75 return_ACPI_STATUS(status); 76 } 77 78 /******************************************************************************* 79 * 80 * FUNCTION: acpi_ev_address_space_dispatch 81 * 82 * PARAMETERS: region_obj - Internal region object 83 * field_obj - Corresponding field. Can be NULL. 84 * function - Read or Write operation 85 * region_offset - Where in the region to read or write 86 * bit_width - Field width in bits (8, 16, 32, or 64) 87 * value - Pointer to in or out value, must be 88 * a full 64-bit integer 89 * 90 * RETURN: Status 91 * 92 * DESCRIPTION: Dispatch an address space or operation region access to 93 * a previously installed handler. 94 * 95 * NOTE: During early initialization, we always install the default region 96 * handlers for Memory, I/O and PCI_Config. This ensures that these operation 97 * region address spaces are always available as per the ACPI specification. 98 * This is especially needed in order to support the execution of 99 * module-level AML code during loading of the ACPI tables. 100 * 101 ******************************************************************************/ 102 103 acpi_status 104 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 105 union acpi_operand_object *field_obj, 106 u32 function, 107 u32 region_offset, u32 bit_width, u64 *value) 108 { 109 acpi_status status; 110 acpi_adr_space_handler handler; 111 acpi_adr_space_setup region_setup; 112 union acpi_operand_object *handler_desc; 113 union acpi_operand_object *region_obj2; 114 void *region_context = NULL; 115 struct acpi_connection_info *context; 116 acpi_mutex context_mutex; 117 u8 context_locked; 118 acpi_physical_address address; 119 120 ACPI_FUNCTION_TRACE(ev_address_space_dispatch); 121 122 region_obj2 = acpi_ns_get_secondary_object(region_obj); 123 if (!region_obj2) { 124 return_ACPI_STATUS(AE_NOT_EXIST); 125 } 126 127 /* Ensure that there is a handler associated with this region */ 128 129 handler_desc = region_obj->region.handler; 130 if (!handler_desc) { 131 ACPI_ERROR((AE_INFO, 132 "No handler for Region [%4.4s] (%p) [%s]", 133 acpi_ut_get_node_name(region_obj->region.node), 134 region_obj, 135 acpi_ut_get_region_name(region_obj->region. 136 space_id))); 137 138 return_ACPI_STATUS(AE_NOT_EXIST); 139 } 140 141 context = handler_desc->address_space.context; 142 context_mutex = handler_desc->address_space.context_mutex; 143 context_locked = FALSE; 144 145 /* 146 * It may be the case that the region has never been initialized. 147 * Some types of regions require special init code 148 */ 149 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { 150 151 /* This region has not been initialized yet, do it */ 152 153 region_setup = handler_desc->address_space.setup; 154 if (!region_setup) { 155 156 /* No initialization routine, exit with error */ 157 158 ACPI_ERROR((AE_INFO, 159 "No init routine for region(%p) [%s]", 160 region_obj, 161 acpi_ut_get_region_name(region_obj->region. 162 space_id))); 163 return_ACPI_STATUS(AE_NOT_EXIST); 164 } 165 166 if (region_obj->region.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { 167 struct acpi_pcc_info *ctx = 168 handler_desc->address_space.context; 169 170 ctx->internal_buffer = 171 field_obj->field.internal_pcc_buffer; 172 ctx->length = (u16)region_obj->region.length; 173 ctx->subspace_id = (u8)region_obj->region.address; 174 } 175 176 if (region_obj->region.space_id == 177 ACPI_ADR_SPACE_FIXED_HARDWARE) { 178 struct acpi_ffh_info *ctx = 179 handler_desc->address_space.context; 180 181 ctx->length = region_obj->region.length; 182 ctx->offset = region_obj->region.address; 183 } 184 185 /* 186 * We must exit the interpreter because the region setup will 187 * potentially execute control methods (for example, the _REG method 188 * for this region) 189 */ 190 acpi_ex_exit_interpreter(); 191 192 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 193 context, ®ion_context); 194 195 /* Re-enter the interpreter */ 196 197 acpi_ex_enter_interpreter(); 198 199 /* Check for failure of the Region Setup */ 200 201 if (ACPI_FAILURE(status)) { 202 ACPI_EXCEPTION((AE_INFO, status, 203 "During region initialization: [%s]", 204 acpi_ut_get_region_name(region_obj-> 205 region. 206 space_id))); 207 return_ACPI_STATUS(status); 208 } 209 210 /* Region initialization may have been completed by region_setup */ 211 212 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { 213 region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; 214 215 /* 216 * Save the returned context for use in all accesses to 217 * the handler for this particular region 218 */ 219 if (!(region_obj2->extra.region_context)) { 220 region_obj2->extra.region_context = 221 region_context; 222 } 223 } 224 } 225 226 /* We have everything we need, we can invoke the address space handler */ 227 228 handler = handler_desc->address_space.handler; 229 address = (region_obj->region.address + region_offset); 230 231 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 232 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 233 ®ion_obj->region.handler->address_space, handler, 234 ACPI_FORMAT_UINT64(address), 235 acpi_ut_get_region_name(region_obj->region. 236 space_id))); 237 238 if (!(handler_desc->address_space.handler_flags & 239 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { 240 /* 241 * For handlers other than the default (supplied) handlers, we must 242 * exit the interpreter because the handler *might* block -- we don't 243 * know what it will do, so we can't hold the lock on the interpreter. 244 */ 245 acpi_ex_exit_interpreter(); 246 } 247 248 /* 249 * Special handling for generic_serial_bus and general_purpose_io: 250 * There are three extra parameters that must be passed to the 251 * handler via the context: 252 * 1) Connection buffer, a resource template from Connection() op 253 * 2) Length of the above buffer 254 * 3) Actual access length from the access_as() op 255 * 256 * Since we pass these extra parameters via the context, which is 257 * shared between threads, we must lock the context to avoid these 258 * parameters being changed from another thread before the handler 259 * has completed running. 260 * 261 * In addition, for general_purpose_io, the Address and bit_width fields 262 * are defined as follows: 263 * 1) Address is the pin number index of the field (bit offset from 264 * the previous Connection) 265 * 2) bit_width is the actual bit length of the field (number of pins) 266 */ 267 if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS || 268 region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && 269 context && field_obj) { 270 271 status = 272 acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); 273 if (ACPI_FAILURE(status)) { 274 goto re_enter_interpreter; 275 } 276 277 context_locked = TRUE; 278 279 /* Get the Connection (resource_template) buffer */ 280 281 context->connection = field_obj->field.resource_buffer; 282 context->length = field_obj->field.resource_length; 283 context->access_length = field_obj->field.access_length; 284 285 if (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) { 286 address = field_obj->field.pin_number_index; 287 bit_width = field_obj->field.bit_length; 288 } 289 } 290 291 /* Call the handler */ 292 293 status = handler(function, address, bit_width, value, context, 294 region_obj2->extra.region_context); 295 296 if (context_locked) { 297 acpi_os_release_mutex(context_mutex); 298 } 299 300 if (ACPI_FAILURE(status)) { 301 ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", 302 acpi_ut_get_region_name(region_obj->region. 303 space_id))); 304 305 /* 306 * Special case for an EC timeout. These are seen so frequently 307 * that an additional error message is helpful 308 */ 309 if ((region_obj->region.space_id == ACPI_ADR_SPACE_EC) && 310 (status == AE_TIME)) { 311 ACPI_ERROR((AE_INFO, 312 "Timeout from EC hardware or EC device driver")); 313 } 314 } 315 316 re_enter_interpreter: 317 if (!(handler_desc->address_space.handler_flags & 318 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { 319 /* 320 * We just returned from a non-default handler, we must re-enter the 321 * interpreter 322 */ 323 acpi_ex_enter_interpreter(); 324 } 325 326 return_ACPI_STATUS(status); 327 } 328 329 /******************************************************************************* 330 * 331 * FUNCTION: acpi_ev_detach_region 332 * 333 * PARAMETERS: region_obj - Region Object 334 * acpi_ns_is_locked - Namespace Region Already Locked? 335 * 336 * RETURN: None 337 * 338 * DESCRIPTION: Break the association between the handler and the region 339 * this is a two way association. 340 * 341 ******************************************************************************/ 342 343 void 344 acpi_ev_detach_region(union acpi_operand_object *region_obj, 345 u8 acpi_ns_is_locked) 346 { 347 union acpi_operand_object *handler_obj; 348 union acpi_operand_object *obj_desc; 349 union acpi_operand_object *start_desc; 350 union acpi_operand_object **last_obj_ptr; 351 acpi_adr_space_setup region_setup; 352 void **region_context; 353 union acpi_operand_object *region_obj2; 354 acpi_status status; 355 356 ACPI_FUNCTION_TRACE(ev_detach_region); 357 358 region_obj2 = acpi_ns_get_secondary_object(region_obj); 359 if (!region_obj2) { 360 return_VOID; 361 } 362 region_context = ®ion_obj2->extra.region_context; 363 364 /* Get the address handler from the region object */ 365 366 handler_obj = region_obj->region.handler; 367 if (!handler_obj) { 368 369 /* This region has no handler, all done */ 370 371 return_VOID; 372 } 373 374 /* Find this region in the handler's list */ 375 376 obj_desc = handler_obj->address_space.region_list; 377 start_desc = obj_desc; 378 last_obj_ptr = &handler_obj->address_space.region_list; 379 380 while (obj_desc) { 381 382 /* Is this the correct Region? */ 383 384 if (obj_desc == region_obj) { 385 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 386 "Removing Region %p from address handler %p\n", 387 region_obj, handler_obj)); 388 389 /* This is it, remove it from the handler's list */ 390 391 *last_obj_ptr = obj_desc->region.next; 392 obj_desc->region.next = NULL; /* Must clear field */ 393 394 if (acpi_ns_is_locked) { 395 status = 396 acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 397 if (ACPI_FAILURE(status)) { 398 return_VOID; 399 } 400 } 401 402 /* Now stop region accesses by executing the _REG method */ 403 404 status = 405 acpi_ev_execute_reg_method(region_obj, 406 ACPI_REG_DISCONNECT); 407 if (ACPI_FAILURE(status)) { 408 ACPI_EXCEPTION((AE_INFO, status, 409 "from region _REG, [%s]", 410 acpi_ut_get_region_name 411 (region_obj->region.space_id))); 412 } 413 414 if (acpi_ns_is_locked) { 415 status = 416 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 417 if (ACPI_FAILURE(status)) { 418 return_VOID; 419 } 420 } 421 422 /* 423 * If the region has been activated, call the setup handler with 424 * the deactivate notification 425 */ 426 if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { 427 region_setup = handler_obj->address_space.setup; 428 status = 429 region_setup(region_obj, 430 ACPI_REGION_DEACTIVATE, 431 handler_obj->address_space. 432 context, region_context); 433 434 /* 435 * region_context should have been released by the deactivate 436 * operation. We don't need access to it anymore here. 437 */ 438 if (region_context) { 439 *region_context = NULL; 440 } 441 442 /* Init routine may fail, Just ignore errors */ 443 444 if (ACPI_FAILURE(status)) { 445 ACPI_EXCEPTION((AE_INFO, status, 446 "from region handler - deactivate, [%s]", 447 acpi_ut_get_region_name 448 (region_obj->region. 449 space_id))); 450 } 451 452 region_obj->region.flags &= 453 ~(AOPOBJ_SETUP_COMPLETE); 454 } 455 456 /* 457 * Remove handler reference in the region 458 * 459 * NOTE: this doesn't mean that the region goes away, the region 460 * is just inaccessible as indicated to the _REG method 461 * 462 * If the region is on the handler's list, this must be the 463 * region's handler 464 */ 465 region_obj->region.handler = NULL; 466 acpi_ut_remove_reference(handler_obj); 467 468 return_VOID; 469 } 470 471 /* Walk the linked list of handlers */ 472 473 last_obj_ptr = &obj_desc->region.next; 474 obj_desc = obj_desc->region.next; 475 476 /* Prevent infinite loop if list is corrupted */ 477 478 if (obj_desc == start_desc) { 479 ACPI_ERROR((AE_INFO, 480 "Circular handler list in region object %p", 481 region_obj)); 482 return_VOID; 483 } 484 } 485 486 /* If we get here, the region was not in the handler's region list */ 487 488 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 489 "Cannot remove region %p from address handler %p\n", 490 region_obj, handler_obj)); 491 492 return_VOID; 493 } 494 495 /******************************************************************************* 496 * 497 * FUNCTION: acpi_ev_attach_region 498 * 499 * PARAMETERS: handler_obj - Handler Object 500 * region_obj - Region Object 501 * acpi_ns_is_locked - Namespace Region Already Locked? 502 * 503 * RETURN: None 504 * 505 * DESCRIPTION: Create the association between the handler and the region 506 * this is a two way association. 507 * 508 ******************************************************************************/ 509 510 acpi_status 511 acpi_ev_attach_region(union acpi_operand_object *handler_obj, 512 union acpi_operand_object *region_obj, 513 u8 acpi_ns_is_locked) 514 { 515 516 ACPI_FUNCTION_TRACE(ev_attach_region); 517 518 /* Install the region's handler */ 519 520 if (region_obj->region.handler) { 521 return_ACPI_STATUS(AE_ALREADY_EXISTS); 522 } 523 524 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 525 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 526 acpi_ut_get_node_name(region_obj->region.node), 527 region_obj, handler_obj, 528 acpi_ut_get_region_name(region_obj->region. 529 space_id))); 530 531 /* Link this region to the front of the handler's list */ 532 533 region_obj->region.next = handler_obj->address_space.region_list; 534 handler_obj->address_space.region_list = region_obj; 535 region_obj->region.handler = handler_obj; 536 acpi_ut_add_reference(handler_obj); 537 538 return_ACPI_STATUS(AE_OK); 539 } 540 541 /******************************************************************************* 542 * 543 * FUNCTION: acpi_ev_execute_reg_method 544 * 545 * PARAMETERS: region_obj - Region object 546 * function - Passed to _REG: On (1) or Off (0) 547 * 548 * RETURN: Status 549 * 550 * DESCRIPTION: Execute _REG method for a region 551 * 552 ******************************************************************************/ 553 554 acpi_status 555 acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) 556 { 557 struct acpi_evaluate_info *info; 558 union acpi_operand_object *args[3]; 559 union acpi_operand_object *region_obj2; 560 const acpi_name *reg_name_ptr = 561 ACPI_CAST_PTR(acpi_name, METHOD_NAME__REG); 562 struct acpi_namespace_node *method_node; 563 struct acpi_namespace_node *node; 564 acpi_status status; 565 566 ACPI_FUNCTION_TRACE(ev_execute_reg_method); 567 568 if (!acpi_gbl_namespace_initialized || 569 region_obj->region.handler == NULL) { 570 return_ACPI_STATUS(AE_OK); 571 } 572 573 region_obj2 = acpi_ns_get_secondary_object(region_obj); 574 if (!region_obj2) { 575 return_ACPI_STATUS(AE_NOT_EXIST); 576 } 577 578 /* 579 * Find any "_REG" method associated with this region definition. 580 * The method should always be updated as this function may be 581 * invoked after a namespace change. 582 */ 583 node = region_obj->region.node->parent; 584 status = 585 acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD, 586 &method_node); 587 if (ACPI_SUCCESS(status)) { 588 /* 589 * The _REG method is optional and there can be only one per 590 * region definition. This will be executed when the handler is 591 * attached or removed. 592 */ 593 region_obj2->extra.method_REG = method_node; 594 } 595 if (region_obj2->extra.method_REG == NULL) { 596 return_ACPI_STATUS(AE_OK); 597 } 598 599 /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */ 600 601 if ((function == ACPI_REG_CONNECT && 602 region_obj->common.flags & AOPOBJ_REG_CONNECTED) || 603 (function == ACPI_REG_DISCONNECT && 604 !(region_obj->common.flags & AOPOBJ_REG_CONNECTED))) { 605 return_ACPI_STATUS(AE_OK); 606 } 607 608 /* Allocate and initialize the evaluation information block */ 609 610 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 611 if (!info) { 612 return_ACPI_STATUS(AE_NO_MEMORY); 613 } 614 615 info->prefix_node = region_obj2->extra.method_REG; 616 info->relative_pathname = NULL; 617 info->parameters = args; 618 info->flags = ACPI_IGNORE_RETURN_VALUE; 619 620 /* 621 * The _REG method has two arguments: 622 * 623 * arg0 - Integer: 624 * Operation region space ID Same value as region_obj->Region.space_id 625 * 626 * arg1 - Integer: 627 * connection status 1 for connecting the handler, 0 for disconnecting 628 * the handler (Passed as a parameter) 629 */ 630 args[0] = 631 acpi_ut_create_integer_object((u64)region_obj->region.space_id); 632 if (!args[0]) { 633 status = AE_NO_MEMORY; 634 goto cleanup1; 635 } 636 637 args[1] = acpi_ut_create_integer_object((u64)function); 638 if (!args[1]) { 639 status = AE_NO_MEMORY; 640 goto cleanup2; 641 } 642 643 args[2] = NULL; /* Terminate list */ 644 645 /* Execute the method, no return value */ 646 647 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 648 (ACPI_TYPE_METHOD, info->prefix_node, NULL)); 649 650 status = acpi_ns_evaluate(info); 651 acpi_ut_remove_reference(args[1]); 652 653 if (ACPI_FAILURE(status)) { 654 goto cleanup2; 655 } 656 657 if (function == ACPI_REG_CONNECT) { 658 region_obj->common.flags |= AOPOBJ_REG_CONNECTED; 659 } else { 660 region_obj->common.flags &= ~AOPOBJ_REG_CONNECTED; 661 } 662 663 cleanup2: 664 acpi_ut_remove_reference(args[0]); 665 666 cleanup1: 667 ACPI_FREE(info); 668 return_ACPI_STATUS(status); 669 } 670 671 /******************************************************************************* 672 * 673 * FUNCTION: acpi_ev_execute_reg_methods 674 * 675 * PARAMETERS: node - Namespace node for the device 676 * max_depth - Depth to which search for _REG 677 * space_id - The address space ID 678 * function - Passed to _REG: On (1) or Off (0) 679 * 680 * RETURN: None 681 * 682 * DESCRIPTION: Run all _REG methods for the input Space ID; 683 * Note: assumes namespace is locked, or system init time. 684 * 685 ******************************************************************************/ 686 687 void 688 acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth, 689 acpi_adr_space_type space_id, u32 function) 690 { 691 struct acpi_reg_walk_info info; 692 693 ACPI_FUNCTION_TRACE(ev_execute_reg_methods); 694 695 /* 696 * These address spaces do not need a call to _REG, since the ACPI 697 * specification defines them as: "must always be accessible". Since 698 * they never change state (never become unavailable), no need to ever 699 * call _REG on them. Also, a data_table is not a "real" address space, 700 * so do not call _REG. September 2018. 701 */ 702 if ((space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) || 703 (space_id == ACPI_ADR_SPACE_SYSTEM_IO) || 704 (space_id == ACPI_ADR_SPACE_DATA_TABLE)) { 705 return_VOID; 706 } 707 708 info.space_id = space_id; 709 info.function = function; 710 info.reg_run_count = 0; 711 712 ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, 713 " Running _REG methods for SpaceId %s\n", 714 acpi_ut_get_region_name(info.space_id))); 715 716 /* 717 * Run all _REG methods for all Operation Regions for this space ID. This 718 * is a separate walk in order to handle any interdependencies between 719 * regions and _REG methods. (i.e. handlers must be installed for all 720 * regions of this Space ID before we can run any _REG methods) 721 */ 722 (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, max_depth, 723 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL, 724 &info, NULL); 725 726 /* 727 * Special case for EC and GPIO: handle "orphan" _REG methods with 728 * no region. 729 */ 730 if (space_id == ACPI_ADR_SPACE_EC || space_id == ACPI_ADR_SPACE_GPIO) { 731 acpi_ev_execute_orphan_reg_method(node, space_id); 732 } 733 734 ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, 735 " Executed %u _REG methods for SpaceId %s\n", 736 info.reg_run_count, 737 acpi_ut_get_region_name(info.space_id))); 738 739 return_VOID; 740 } 741 742 /******************************************************************************* 743 * 744 * FUNCTION: acpi_ev_reg_run 745 * 746 * PARAMETERS: walk_namespace callback 747 * 748 * DESCRIPTION: Run _REG method for region objects of the requested spaceID 749 * 750 ******************************************************************************/ 751 752 static acpi_status 753 acpi_ev_reg_run(acpi_handle obj_handle, 754 u32 level, void *context, void **return_value) 755 { 756 union acpi_operand_object *obj_desc; 757 struct acpi_namespace_node *node; 758 acpi_status status; 759 struct acpi_reg_walk_info *info; 760 761 info = ACPI_CAST_PTR(struct acpi_reg_walk_info, context); 762 763 /* Convert and validate the device handle */ 764 765 node = acpi_ns_validate_handle(obj_handle); 766 if (!node) { 767 return (AE_BAD_PARAMETER); 768 } 769 770 /* 771 * We only care about regions and objects that are allowed to have 772 * address space handlers 773 */ 774 if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) { 775 return (AE_OK); 776 } 777 778 /* Check for an existing internal object */ 779 780 obj_desc = acpi_ns_get_attached_object(node); 781 if (!obj_desc) { 782 783 /* No object, just exit */ 784 785 return (AE_OK); 786 } 787 788 /* Object is a Region */ 789 790 if (obj_desc->region.space_id != info->space_id) { 791 792 /* This region is for a different address space, just ignore it */ 793 794 return (AE_OK); 795 } 796 797 info->reg_run_count++; 798 status = acpi_ev_execute_reg_method(obj_desc, info->function); 799 return (status); 800 } 801 802 /******************************************************************************* 803 * 804 * FUNCTION: acpi_ev_execute_orphan_reg_method 805 * 806 * PARAMETERS: device_node - Namespace node for an ACPI device 807 * space_id - The address space ID 808 * 809 * RETURN: None 810 * 811 * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI 812 * device. This is a _REG method that has no corresponding region 813 * within the device's scope. ACPI tables depending on these 814 * "orphan" _REG methods have been seen for both EC and GPIO 815 * Operation Regions. Presumably the Windows ACPI implementation 816 * always calls the _REG method independent of the presence of 817 * an actual Operation Region with the correct address space ID. 818 * 819 * MUTEX: Assumes the namespace is locked 820 * 821 ******************************************************************************/ 822 823 static void 824 acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, 825 acpi_adr_space_type space_id) 826 { 827 acpi_handle reg_method; 828 struct acpi_namespace_node *next_node; 829 acpi_status status; 830 struct acpi_object_list args; 831 union acpi_object objects[2]; 832 833 ACPI_FUNCTION_TRACE(ev_execute_orphan_reg_method); 834 835 if (!device_node) { 836 return_VOID; 837 } 838 839 /* Namespace is currently locked, must release */ 840 841 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 842 843 /* Get a handle to a _REG method immediately under the EC device */ 844 845 status = acpi_get_handle(device_node, METHOD_NAME__REG, ®_method); 846 if (ACPI_FAILURE(status)) { 847 goto exit; /* There is no _REG method present */ 848 } 849 850 /* 851 * Execute the _REG method only if there is no Operation Region in 852 * this scope with the Embedded Controller space ID. Otherwise, it 853 * will already have been executed. Note, this allows for Regions 854 * with other space IDs to be present; but the code below will then 855 * execute the _REG method with the embedded_control space_ID argument. 856 */ 857 next_node = acpi_ns_get_next_node(device_node, NULL); 858 while (next_node) { 859 if ((next_node->type == ACPI_TYPE_REGION) && 860 (next_node->object) && 861 (next_node->object->region.space_id == space_id)) { 862 goto exit; /* Do not execute the _REG */ 863 } 864 865 next_node = acpi_ns_get_next_node(device_node, next_node); 866 } 867 868 /* Evaluate the _REG(space_id,Connect) method */ 869 870 args.count = 2; 871 args.pointer = objects; 872 objects[0].type = ACPI_TYPE_INTEGER; 873 objects[0].integer.value = space_id; 874 objects[1].type = ACPI_TYPE_INTEGER; 875 objects[1].integer.value = ACPI_REG_CONNECT; 876 877 (void)acpi_evaluate_object(reg_method, NULL, &args, NULL); 878 879 exit: 880 /* We ignore all errors from above, don't care */ 881 882 (void)acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 883 return_VOID; 884 } 885