linux/drivers/acpi/acpica/evregion.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: evregion - ACPI address_space (op_region) handler dispatch
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2008, 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 acpi_status
  55acpi_ev_reg_run(acpi_handle obj_handle,
  56                u32 level, void *context, void **return_value);
  57
  58static acpi_status
  59acpi_ev_install_handler(acpi_handle obj_handle,
  60                        u32 level, void *context, void **return_value);
  61
  62/* These are the address spaces that will get default handlers */
  63
  64#define ACPI_NUM_DEFAULT_SPACES     4
  65
  66static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
  67        ACPI_ADR_SPACE_SYSTEM_MEMORY,
  68        ACPI_ADR_SPACE_SYSTEM_IO,
  69        ACPI_ADR_SPACE_PCI_CONFIG,
  70        ACPI_ADR_SPACE_DATA_TABLE
  71};
  72
  73/*******************************************************************************
  74 *
  75 * FUNCTION:    acpi_ev_install_region_handlers
  76 *
  77 * PARAMETERS:  None
  78 *
  79 * RETURN:      Status
  80 *
  81 * DESCRIPTION: Installs the core subsystem default address space handlers.
  82 *
  83 ******************************************************************************/
  84
  85acpi_status acpi_ev_install_region_handlers(void)
  86{
  87        acpi_status status;
  88        u32 i;
  89
  90        ACPI_FUNCTION_TRACE(ev_install_region_handlers);
  91
  92        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  93        if (ACPI_FAILURE(status)) {
  94                return_ACPI_STATUS(status);
  95        }
  96
  97        /*
  98         * All address spaces (PCI Config, EC, SMBus) are scope dependent and
  99         * registration must occur for a specific device.
 100         *
 101         * In the case of the system memory and IO address spaces there is
 102         * currently no device associated with the address space. For these we
 103         * use the root.
 104         *
 105         * We install the default PCI config space handler at the root so that
 106         * this space is immediately available even though the we have not
 107         * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
 108         * specification which states that the PCI config space must be always
 109         * available -- even though we are nowhere near ready to find the PCI root
 110         * buses at this point.
 111         *
 112         * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
 113         * has already been installed (via acpi_install_address_space_handler).
 114         * Similar for AE_SAME_HANDLER.
 115         */
 116        for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 117                status = acpi_ev_install_space_handler(acpi_gbl_root_node,
 118                                                       acpi_gbl_default_address_spaces
 119                                                       [i],
 120                                                       ACPI_DEFAULT_HANDLER,
 121                                                       NULL, NULL);
 122                switch (status) {
 123                case AE_OK:
 124                case AE_SAME_HANDLER:
 125                case AE_ALREADY_EXISTS:
 126
 127                        /* These exceptions are all OK */
 128
 129                        status = AE_OK;
 130                        break;
 131
 132                default:
 133
 134                        goto unlock_and_exit;
 135                }
 136        }
 137
 138      unlock_and_exit:
 139        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 140        return_ACPI_STATUS(status);
 141}
 142
 143/*******************************************************************************
 144 *
 145 * FUNCTION:    acpi_ev_initialize_op_regions
 146 *
 147 * PARAMETERS:  None
 148 *
 149 * RETURN:      Status
 150 *
 151 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
 152 *              an installed default region handler.
 153 *
 154 ******************************************************************************/
 155
 156acpi_status acpi_ev_initialize_op_regions(void)
 157{
 158        acpi_status status;
 159        u32 i;
 160
 161        ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
 162
 163        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 164        if (ACPI_FAILURE(status)) {
 165                return_ACPI_STATUS(status);
 166        }
 167
 168        /* Run the _REG methods for op_regions in each default address space */
 169
 170        for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
 171                /*
 172                 * TBD: Make sure handler is the DEFAULT handler, otherwise
 173                 * _REG will have already been run.
 174                 */
 175                status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
 176                                                     acpi_gbl_default_address_spaces
 177                                                     [i]);
 178        }
 179
 180        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 181        return_ACPI_STATUS(status);
 182}
 183
 184/*******************************************************************************
 185 *
 186 * FUNCTION:    acpi_ev_execute_reg_method
 187 *
 188 * PARAMETERS:  region_obj          - Region object
 189 *              Function            - Passed to _REG: On (1) or Off (0)
 190 *
 191 * RETURN:      Status
 192 *
 193 * DESCRIPTION: Execute _REG method for a region
 194 *
 195 ******************************************************************************/
 196
 197acpi_status
 198acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
 199{
 200        struct acpi_evaluate_info *info;
 201        union acpi_operand_object *args[3];
 202        union acpi_operand_object *region_obj2;
 203        acpi_status status;
 204
 205        ACPI_FUNCTION_TRACE(ev_execute_reg_method);
 206
 207        region_obj2 = acpi_ns_get_secondary_object(region_obj);
 208        if (!region_obj2) {
 209                return_ACPI_STATUS(AE_NOT_EXIST);
 210        }
 211
 212        if (region_obj2->extra.method_REG == NULL) {
 213                return_ACPI_STATUS(AE_OK);
 214        }
 215
 216        /* Allocate and initialize the evaluation information block */
 217
 218        info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
 219        if (!info) {
 220                return_ACPI_STATUS(AE_NO_MEMORY);
 221        }
 222
 223        info->prefix_node = region_obj2->extra.method_REG;
 224        info->pathname = NULL;
 225        info->parameters = args;
 226        info->flags = ACPI_IGNORE_RETURN_VALUE;
 227
 228        /*
 229         * The _REG method has two arguments:
 230         *
 231         * Arg0 - Integer:
 232         *  Operation region space ID Same value as region_obj->Region.space_id
 233         *
 234         * Arg1 - Integer:
 235         *  connection status 1 for connecting the handler, 0 for disconnecting
 236         *  the handler (Passed as a parameter)
 237         */
 238        args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
 239        if (!args[0]) {
 240                status = AE_NO_MEMORY;
 241                goto cleanup1;
 242        }
 243
 244        args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
 245        if (!args[1]) {
 246                status = AE_NO_MEMORY;
 247                goto cleanup2;
 248        }
 249
 250        /* Setup the parameter objects */
 251
 252        args[0]->integer.value = region_obj->region.space_id;
 253        args[1]->integer.value = function;
 254        args[2] = NULL;
 255
 256        /* Execute the method, no return value */
 257
 258        ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 259                        (ACPI_TYPE_METHOD, info->prefix_node, NULL));
 260
 261        status = acpi_ns_evaluate(info);
 262        acpi_ut_remove_reference(args[1]);
 263
 264      cleanup2:
 265        acpi_ut_remove_reference(args[0]);
 266
 267      cleanup1:
 268        ACPI_FREE(info);
 269        return_ACPI_STATUS(status);
 270}
 271
 272/*******************************************************************************
 273 *
 274 * FUNCTION:    acpi_ev_address_space_dispatch
 275 *
 276 * PARAMETERS:  region_obj          - Internal region object
 277 *              Function            - Read or Write operation
 278 *              region_offset       - Where in the region to read or write
 279 *              bit_width           - Field width in bits (8, 16, 32, or 64)
 280 *              Value               - Pointer to in or out value, must be
 281 *                                    full 64-bit acpi_integer
 282 *
 283 * RETURN:      Status
 284 *
 285 * DESCRIPTION: Dispatch an address space or operation region access to
 286 *              a previously installed handler.
 287 *
 288 ******************************************************************************/
 289
 290acpi_status
 291acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 292                               u32 function,
 293                               u32 region_offset,
 294                               u32 bit_width, acpi_integer * value)
 295{
 296        acpi_status status;
 297        acpi_adr_space_handler handler;
 298        acpi_adr_space_setup region_setup;
 299        union acpi_operand_object *handler_desc;
 300        union acpi_operand_object *region_obj2;
 301        void *region_context = NULL;
 302
 303        ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
 304
 305        region_obj2 = acpi_ns_get_secondary_object(region_obj);
 306        if (!region_obj2) {
 307                return_ACPI_STATUS(AE_NOT_EXIST);
 308        }
 309
 310        /* Ensure that there is a handler associated with this region */
 311
 312        handler_desc = region_obj->region.handler;
 313        if (!handler_desc) {
 314                ACPI_ERROR((AE_INFO,
 315                            "No handler for Region [%4.4s] (%p) [%s]",
 316                            acpi_ut_get_node_name(region_obj->region.node),
 317                            region_obj,
 318                            acpi_ut_get_region_name(region_obj->region.
 319                                                    space_id)));
 320
 321                return_ACPI_STATUS(AE_NOT_EXIST);
 322        }
 323
 324        /*
 325         * It may be the case that the region has never been initialized.
 326         * Some types of regions require special init code
 327         */
 328        if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
 329
 330                /* This region has not been initialized yet, do it */
 331
 332                region_setup = handler_desc->address_space.setup;
 333                if (!region_setup) {
 334
 335                        /* No initialization routine, exit with error */
 336
 337                        ACPI_ERROR((AE_INFO,
 338                                    "No init routine for region(%p) [%s]",
 339                                    region_obj,
 340                                    acpi_ut_get_region_name(region_obj->region.
 341                                                            space_id)));
 342                        return_ACPI_STATUS(AE_NOT_EXIST);
 343                }
 344
 345                /*
 346                 * We must exit the interpreter because the region setup will
 347                 * potentially execute control methods (for example, the _REG method
 348                 * for this region)
 349                 */
 350                acpi_ex_exit_interpreter();
 351
 352                status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
 353                                      handler_desc->address_space.context,
 354                                      &region_context);
 355
 356                /* Re-enter the interpreter */
 357
 358                acpi_ex_enter_interpreter();
 359
 360                /* Check for failure of the Region Setup */
 361
 362                if (ACPI_FAILURE(status)) {
 363                        ACPI_EXCEPTION((AE_INFO, status,
 364                                        "During region initialization: [%s]",
 365                                        acpi_ut_get_region_name(region_obj->
 366                                                                region.
 367                                                                space_id)));
 368                        return_ACPI_STATUS(status);
 369                }
 370
 371                /* Region initialization may have been completed by region_setup */
 372
 373                if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
 374                        region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
 375
 376                        if (region_obj2->extra.region_context) {
 377
 378                                /* The handler for this region was already installed */
 379
 380                                ACPI_FREE(region_context);
 381                        } else {
 382                                /*
 383                                 * Save the returned context for use in all accesses to
 384                                 * this particular region
 385                                 */
 386                                region_obj2->extra.region_context =
 387                                    region_context;
 388                        }
 389                }
 390        }
 391
 392        /* We have everything we need, we can invoke the address space handler */
 393
 394        handler = handler_desc->address_space.handler;
 395
 396        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 397                          "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
 398                          &region_obj->region.handler->address_space, handler,
 399                          ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
 400                                                  region_offset),
 401                          acpi_ut_get_region_name(region_obj->region.
 402                                                  space_id)));
 403
 404        if (!(handler_desc->address_space.handler_flags &
 405              ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 406                /*
 407                 * For handlers other than the default (supplied) handlers, we must
 408                 * exit the interpreter because the handler *might* block -- we don't
 409                 * know what it will do, so we can't hold the lock on the intepreter.
 410                 */
 411                acpi_ex_exit_interpreter();
 412        }
 413
 414        /* Call the handler */
 415
 416        status = handler(function,
 417                         (region_obj->region.address + region_offset),
 418                         bit_width, value, handler_desc->address_space.context,
 419                         region_obj2->extra.region_context);
 420
 421        if (ACPI_FAILURE(status)) {
 422                ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
 423                                acpi_ut_get_region_name(region_obj->region.
 424                                                        space_id)));
 425        }
 426
 427        if (!(handler_desc->address_space.handler_flags &
 428              ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 429                /*
 430                 * We just returned from a non-default handler, we must re-enter the
 431                 * interpreter
 432                 */
 433                acpi_ex_enter_interpreter();
 434        }
 435
 436        return_ACPI_STATUS(status);
 437}
 438
 439/*******************************************************************************
 440 *
 441 * FUNCTION:    acpi_ev_detach_region
 442 *
 443 * PARAMETERS:  region_obj          - Region Object
 444 *              acpi_ns_is_locked   - Namespace Region Already Locked?
 445 *
 446 * RETURN:      None
 447 *
 448 * DESCRIPTION: Break the association between the handler and the region
 449 *              this is a two way association.
 450 *
 451 ******************************************************************************/
 452
 453void
 454acpi_ev_detach_region(union acpi_operand_object *region_obj,
 455                      u8 acpi_ns_is_locked)
 456{
 457        union acpi_operand_object *handler_obj;
 458        union acpi_operand_object *obj_desc;
 459        union acpi_operand_object **last_obj_ptr;
 460        acpi_adr_space_setup region_setup;
 461        void **region_context;
 462        union acpi_operand_object *region_obj2;
 463        acpi_status status;
 464
 465        ACPI_FUNCTION_TRACE(ev_detach_region);
 466
 467        region_obj2 = acpi_ns_get_secondary_object(region_obj);
 468        if (!region_obj2) {
 469                return_VOID;
 470        }
 471        region_context = &region_obj2->extra.region_context;
 472
 473        /* Get the address handler from the region object */
 474
 475        handler_obj = region_obj->region.handler;
 476        if (!handler_obj) {
 477
 478                /* This region has no handler, all done */
 479
 480                return_VOID;
 481        }
 482
 483        /* Find this region in the handler's list */
 484
 485        obj_desc = handler_obj->address_space.region_list;
 486        last_obj_ptr = &handler_obj->address_space.region_list;
 487
 488        while (obj_desc) {
 489
 490                /* Is this the correct Region? */
 491
 492                if (obj_desc == region_obj) {
 493                        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 494                                          "Removing Region %p from address handler %p\n",
 495                                          region_obj, handler_obj));
 496
 497                        /* This is it, remove it from the handler's list */
 498
 499                        *last_obj_ptr = obj_desc->region.next;
 500                        obj_desc->region.next = NULL;   /* Must clear field */
 501
 502                        if (acpi_ns_is_locked) {
 503                                status =
 504                                    acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 505                                if (ACPI_FAILURE(status)) {
 506                                        return_VOID;
 507                                }
 508                        }
 509
 510                        /* Now stop region accesses by executing the _REG method */
 511
 512                        status = acpi_ev_execute_reg_method(region_obj, 0);
 513                        if (ACPI_FAILURE(status)) {
 514                                ACPI_EXCEPTION((AE_INFO, status,
 515                                                "from region _REG, [%s]",
 516                                                acpi_ut_get_region_name
 517                                                (region_obj->region.space_id)));
 518                        }
 519
 520                        if (acpi_ns_is_locked) {
 521                                status =
 522                                    acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 523                                if (ACPI_FAILURE(status)) {
 524                                        return_VOID;
 525                                }
 526                        }
 527
 528                        /*
 529                         * If the region has been activated, call the setup handler with
 530                         * the deactivate notification
 531                         */
 532                        if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
 533                                region_setup = handler_obj->address_space.setup;
 534                                status =
 535                                    region_setup(region_obj,
 536                                                 ACPI_REGION_DEACTIVATE,
 537                                                 handler_obj->address_space.
 538                                                 context, region_context);
 539
 540                                /* Init routine may fail, Just ignore errors */
 541
 542                                if (ACPI_FAILURE(status)) {
 543                                        ACPI_EXCEPTION((AE_INFO, status,
 544                                                        "from region handler - deactivate, [%s]",
 545                                                        acpi_ut_get_region_name
 546                                                        (region_obj->region.
 547                                                         space_id)));
 548                                }
 549
 550                                region_obj->region.flags &=
 551                                    ~(AOPOBJ_SETUP_COMPLETE);
 552                        }
 553
 554                        /*
 555                         * Remove handler reference in the region
 556                         *
 557                         * NOTE: this doesn't mean that the region goes away, the region
 558                         * is just inaccessible as indicated to the _REG method
 559                         *
 560                         * If the region is on the handler's list, this must be the
 561                         * region's handler
 562                         */
 563                        region_obj->region.handler = NULL;
 564                        acpi_ut_remove_reference(handler_obj);
 565
 566                        return_VOID;
 567                }
 568
 569                /* Walk the linked list of handlers */
 570
 571                last_obj_ptr = &obj_desc->region.next;
 572                obj_desc = obj_desc->region.next;
 573        }
 574
 575        /* If we get here, the region was not in the handler's region list */
 576
 577        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 578                          "Cannot remove region %p from address handler %p\n",
 579                          region_obj, handler_obj));
 580
 581        return_VOID;
 582}
 583
 584/*******************************************************************************
 585 *
 586 * FUNCTION:    acpi_ev_attach_region
 587 *
 588 * PARAMETERS:  handler_obj         - Handler Object
 589 *              region_obj          - Region Object
 590 *              acpi_ns_is_locked   - Namespace Region Already Locked?
 591 *
 592 * RETURN:      None
 593 *
 594 * DESCRIPTION: Create the association between the handler and the region
 595 *              this is a two way association.
 596 *
 597 ******************************************************************************/
 598
 599acpi_status
 600acpi_ev_attach_region(union acpi_operand_object *handler_obj,
 601                      union acpi_operand_object *region_obj,
 602                      u8 acpi_ns_is_locked)
 603{
 604
 605        ACPI_FUNCTION_TRACE(ev_attach_region);
 606
 607        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 608                          "Adding Region [%4.4s] %p to address handler %p [%s]\n",
 609                          acpi_ut_get_node_name(region_obj->region.node),
 610                          region_obj, handler_obj,
 611                          acpi_ut_get_region_name(region_obj->region.
 612                                                  space_id)));
 613
 614        /* Link this region to the front of the handler's list */
 615
 616        region_obj->region.next = handler_obj->address_space.region_list;
 617        handler_obj->address_space.region_list = region_obj;
 618
 619        /* Install the region's handler */
 620
 621        if (region_obj->region.handler) {
 622                return_ACPI_STATUS(AE_ALREADY_EXISTS);
 623        }
 624
 625        region_obj->region.handler = handler_obj;
 626        acpi_ut_add_reference(handler_obj);
 627
 628        return_ACPI_STATUS(AE_OK);
 629}
 630
 631/*******************************************************************************
 632 *
 633 * FUNCTION:    acpi_ev_install_handler
 634 *
 635 * PARAMETERS:  walk_namespace callback
 636 *
 637 * DESCRIPTION: This routine installs an address handler into objects that are
 638 *              of type Region or Device.
 639 *
 640 *              If the Object is a Device, and the device has a handler of
 641 *              the same type then the search is terminated in that branch.
 642 *
 643 *              This is because the existing handler is closer in proximity
 644 *              to any more regions than the one we are trying to install.
 645 *
 646 ******************************************************************************/
 647
 648static acpi_status
 649acpi_ev_install_handler(acpi_handle obj_handle,
 650                        u32 level, void *context, void **return_value)
 651{
 652        union acpi_operand_object *handler_obj;
 653        union acpi_operand_object *next_handler_obj;
 654        union acpi_operand_object *obj_desc;
 655        struct acpi_namespace_node *node;
 656        acpi_status status;
 657
 658        ACPI_FUNCTION_NAME(ev_install_handler);
 659
 660        handler_obj = (union acpi_operand_object *)context;
 661
 662        /* Parameter validation */
 663
 664        if (!handler_obj) {
 665                return (AE_OK);
 666        }
 667
 668        /* Convert and validate the device handle */
 669
 670        node = acpi_ns_map_handle_to_node(obj_handle);
 671        if (!node) {
 672                return (AE_BAD_PARAMETER);
 673        }
 674
 675        /*
 676         * We only care about regions and objects that are allowed to have
 677         * address space handlers
 678         */
 679        if ((node->type != ACPI_TYPE_DEVICE) &&
 680            (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
 681                return (AE_OK);
 682        }
 683
 684        /* Check for an existing internal object */
 685
 686        obj_desc = acpi_ns_get_attached_object(node);
 687        if (!obj_desc) {
 688
 689                /* No object, just exit */
 690
 691                return (AE_OK);
 692        }
 693
 694        /* Devices are handled different than regions */
 695
 696        if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
 697
 698                /* Check if this Device already has a handler for this address space */
 699
 700                next_handler_obj = obj_desc->device.handler;
 701                while (next_handler_obj) {
 702
 703                        /* Found a handler, is it for the same address space? */
 704
 705                        if (next_handler_obj->address_space.space_id ==
 706                            handler_obj->address_space.space_id) {
 707                                ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 708                                                  "Found handler for region [%s] in device %p(%p) "
 709                                                  "handler %p\n",
 710                                                  acpi_ut_get_region_name
 711                                                  (handler_obj->address_space.
 712                                                   space_id), obj_desc,
 713                                                  next_handler_obj,
 714                                                  handler_obj));
 715
 716                                /*
 717                                 * Since the object we found it on was a device, then it
 718                                 * means that someone has already installed a handler for
 719                                 * the branch of the namespace from this device on. Just
 720                                 * bail out telling the walk routine to not traverse this
 721                                 * branch. This preserves the scoping rule for handlers.
 722                                 */
 723                                return (AE_CTRL_DEPTH);
 724                        }
 725
 726                        /* Walk the linked list of handlers attached to this device */
 727
 728                        next_handler_obj = next_handler_obj->address_space.next;
 729                }
 730
 731                /*
 732                 * As long as the device didn't have a handler for this space we
 733                 * don't care about it. We just ignore it and proceed.
 734                 */
 735                return (AE_OK);
 736        }
 737
 738        /* Object is a Region */
 739
 740        if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
 741
 742                /* This region is for a different address space, just ignore it */
 743
 744                return (AE_OK);
 745        }
 746
 747        /*
 748         * Now we have a region and it is for the handler's address space type.
 749         *
 750         * First disconnect region for any previous handler (if any)
 751         */
 752        acpi_ev_detach_region(obj_desc, FALSE);
 753
 754        /* Connect the region to the new handler */
 755
 756        status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
 757        return (status);
 758}
 759
 760/*******************************************************************************
 761 *
 762 * FUNCTION:    acpi_ev_install_space_handler
 763 *
 764 * PARAMETERS:  Node            - Namespace node for the device
 765 *              space_id        - The address space ID
 766 *              Handler         - Address of the handler
 767 *              Setup           - Address of the setup function
 768 *              Context         - Value passed to the handler on each access
 769 *
 770 * RETURN:      Status
 771 *
 772 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
 773 *              Assumes namespace is locked
 774 *
 775 ******************************************************************************/
 776
 777acpi_status
 778acpi_ev_install_space_handler(struct acpi_namespace_node * node,
 779                              acpi_adr_space_type space_id,
 780                              acpi_adr_space_handler handler,
 781                              acpi_adr_space_setup setup, void *context)
 782{
 783        union acpi_operand_object *obj_desc;
 784        union acpi_operand_object *handler_obj;
 785        acpi_status status;
 786        acpi_object_type type;
 787        u8 flags = 0;
 788
 789        ACPI_FUNCTION_TRACE(ev_install_space_handler);
 790
 791        /*
 792         * This registration is valid for only the types below and the root. This
 793         * is where the default handlers get placed.
 794         */
 795        if ((node->type != ACPI_TYPE_DEVICE) &&
 796            (node->type != ACPI_TYPE_PROCESSOR) &&
 797            (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
 798                status = AE_BAD_PARAMETER;
 799                goto unlock_and_exit;
 800        }
 801
 802        if (handler == ACPI_DEFAULT_HANDLER) {
 803                flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
 804
 805                switch (space_id) {
 806                case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 807                        handler = acpi_ex_system_memory_space_handler;
 808                        setup = acpi_ev_system_memory_region_setup;
 809                        break;
 810
 811                case ACPI_ADR_SPACE_SYSTEM_IO:
 812                        handler = acpi_ex_system_io_space_handler;
 813                        setup = acpi_ev_io_space_region_setup;
 814                        break;
 815
 816                case ACPI_ADR_SPACE_PCI_CONFIG:
 817                        handler = acpi_ex_pci_config_space_handler;
 818                        setup = acpi_ev_pci_config_region_setup;
 819                        break;
 820
 821                case ACPI_ADR_SPACE_CMOS:
 822                        handler = acpi_ex_cmos_space_handler;
 823                        setup = acpi_ev_cmos_region_setup;
 824                        break;
 825
 826                case ACPI_ADR_SPACE_PCI_BAR_TARGET:
 827                        handler = acpi_ex_pci_bar_space_handler;
 828                        setup = acpi_ev_pci_bar_region_setup;
 829                        break;
 830
 831                case ACPI_ADR_SPACE_DATA_TABLE:
 832                        handler = acpi_ex_data_table_space_handler;
 833                        setup = NULL;
 834                        break;
 835
 836                default:
 837                        status = AE_BAD_PARAMETER;
 838                        goto unlock_and_exit;
 839                }
 840        }
 841
 842        /* If the caller hasn't specified a setup routine, use the default */
 843
 844        if (!setup) {
 845                setup = acpi_ev_default_region_setup;
 846        }
 847
 848        /* Check for an existing internal object */
 849
 850        obj_desc = acpi_ns_get_attached_object(node);
 851        if (obj_desc) {
 852                /*
 853                 * The attached device object already exists. Make sure the handler
 854                 * is not already installed.
 855                 */
 856                handler_obj = obj_desc->device.handler;
 857
 858                /* Walk the handler list for this device */
 859
 860                while (handler_obj) {
 861
 862                        /* Same space_id indicates a handler already installed */
 863
 864                        if (handler_obj->address_space.space_id == space_id) {
 865                                if (handler_obj->address_space.handler ==
 866                                    handler) {
 867                                        /*
 868                                         * It is (relatively) OK to attempt to install the SAME
 869                                         * handler twice. This can easily happen with the
 870                                         * PCI_Config space.
 871                                         */
 872                                        status = AE_SAME_HANDLER;
 873                                        goto unlock_and_exit;
 874                                } else {
 875                                        /* A handler is already installed */
 876
 877                                        status = AE_ALREADY_EXISTS;
 878                                }
 879                                goto unlock_and_exit;
 880                        }
 881
 882                        /* Walk the linked list of handlers */
 883
 884                        handler_obj = handler_obj->address_space.next;
 885                }
 886        } else {
 887                ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 888                                  "Creating object on Device %p while installing handler\n",
 889                                  node));
 890
 891                /* obj_desc does not exist, create one */
 892
 893                if (node->type == ACPI_TYPE_ANY) {
 894                        type = ACPI_TYPE_DEVICE;
 895                } else {
 896                        type = node->type;
 897                }
 898
 899                obj_desc = acpi_ut_create_internal_object(type);
 900                if (!obj_desc) {
 901                        status = AE_NO_MEMORY;
 902                        goto unlock_and_exit;
 903                }
 904
 905                /* Init new descriptor */
 906
 907                obj_desc->common.type = (u8) type;
 908
 909                /* Attach the new object to the Node */
 910
 911                status = acpi_ns_attach_object(node, obj_desc, type);
 912
 913                /* Remove local reference to the object */
 914
 915                acpi_ut_remove_reference(obj_desc);
 916
 917                if (ACPI_FAILURE(status)) {
 918                        goto unlock_and_exit;
 919                }
 920        }
 921
 922        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
 923                          "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
 924                          acpi_ut_get_region_name(space_id), space_id,
 925                          acpi_ut_get_node_name(node), node, obj_desc));
 926
 927        /*
 928         * Install the handler
 929         *
 930         * At this point there is no existing handler. Just allocate the object
 931         * for the handler and link it into the list.
 932         */
 933        handler_obj =
 934            acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
 935        if (!handler_obj) {
 936                status = AE_NO_MEMORY;
 937                goto unlock_and_exit;
 938        }
 939
 940        /* Init handler obj */
 941
 942        handler_obj->address_space.space_id = (u8) space_id;
 943        handler_obj->address_space.handler_flags = flags;
 944        handler_obj->address_space.region_list = NULL;
 945        handler_obj->address_space.node = node;
 946        handler_obj->address_space.handler = handler;
 947        handler_obj->address_space.context = context;
 948        handler_obj->address_space.setup = setup;
 949
 950        /* Install at head of Device.address_space list */
 951
 952        handler_obj->address_space.next = obj_desc->device.handler;
 953
 954        /*
 955         * The Device object is the first reference on the handler_obj.
 956         * Each region that uses the handler adds a reference.
 957         */
 958        obj_desc->device.handler = handler_obj;
 959
 960        /*
 961         * Walk the namespace finding all of the regions this
 962         * handler will manage.
 963         *
 964         * Start at the device and search the branch toward
 965         * the leaf nodes until either the leaf is encountered or
 966         * a device is detected that has an address handler of the
 967         * same type.
 968         *
 969         * In either case, back up and search down the remainder
 970         * of the branch
 971         */
 972        status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
 973                                        ACPI_NS_WALK_UNLOCK,
 974                                        acpi_ev_install_handler, handler_obj,
 975                                        NULL);
 976
 977      unlock_and_exit:
 978        return_ACPI_STATUS(status);
 979}
 980
 981/*******************************************************************************
 982 *
 983 * FUNCTION:    acpi_ev_execute_reg_methods
 984 *
 985 * PARAMETERS:  Node            - Namespace node for the device
 986 *              space_id        - The address space ID
 987 *
 988 * RETURN:      Status
 989 *
 990 * DESCRIPTION: Run all _REG methods for the input Space ID;
 991 *              Note: assumes namespace is locked, or system init time.
 992 *
 993 ******************************************************************************/
 994
 995acpi_status
 996acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
 997                            acpi_adr_space_type space_id)
 998{
 999        acpi_status status;
1000
1001        ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
1002
1003        /*
1004         * Run all _REG methods for all Operation Regions for this space ID. This
1005         * is a separate walk in order to handle any interdependencies between
1006         * regions and _REG methods. (i.e. handlers must be installed for all
1007         * regions of this Space ID before we can run any _REG methods)
1008         */
1009        status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1010                                        ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1011                                        &space_id, NULL);
1012
1013        return_ACPI_STATUS(status);
1014}
1015
1016/*******************************************************************************
1017 *
1018 * FUNCTION:    acpi_ev_reg_run
1019 *
1020 * PARAMETERS:  walk_namespace callback
1021 *
1022 * DESCRIPTION: Run _REG method for region objects of the requested space_iD
1023 *
1024 ******************************************************************************/
1025
1026static acpi_status
1027acpi_ev_reg_run(acpi_handle obj_handle,
1028                u32 level, void *context, void **return_value)
1029{
1030        union acpi_operand_object *obj_desc;
1031        struct acpi_namespace_node *node;
1032        acpi_adr_space_type space_id;
1033        acpi_status status;
1034
1035        space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
1036
1037        /* Convert and validate the device handle */
1038
1039        node = acpi_ns_map_handle_to_node(obj_handle);
1040        if (!node) {
1041                return (AE_BAD_PARAMETER);
1042        }
1043
1044        /*
1045         * We only care about regions.and objects that are allowed to have address
1046         * space handlers
1047         */
1048        if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
1049                return (AE_OK);
1050        }
1051
1052        /* Check for an existing internal object */
1053
1054        obj_desc = acpi_ns_get_attached_object(node);
1055        if (!obj_desc) {
1056
1057                /* No object, just exit */
1058
1059                return (AE_OK);
1060        }
1061
1062        /* Object is a Region */
1063
1064        if (obj_desc->region.space_id != space_id) {
1065
1066                /* This region is for a different address space, just ignore it */
1067
1068                return (AE_OK);
1069        }
1070
1071        status = acpi_ev_execute_reg_method(obj_desc, 1);
1072        return (status);
1073}
1074