LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - evxfregn.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 16 62 25.8 %
Date: 2022-04-01 14:58:12 Functions: 1 2 50.0 %
Branches: 4 30 13.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
       5                 :            :  *                         Address Spaces.
       6                 :            :  *
       7                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       8                 :            :  *
       9                 :            :  *****************************************************************************/
      10                 :            : 
      11                 :            : #define EXPORT_ACPI_INTERFACES
      12                 :            : 
      13                 :            : #include <acpi/acpi.h>
      14                 :            : #include "accommon.h"
      15                 :            : #include "acnamesp.h"
      16                 :            : #include "acevents.h"
      17                 :            : 
      18                 :            : #define _COMPONENT          ACPI_EVENTS
      19                 :            : ACPI_MODULE_NAME("evxfregn")
      20                 :            : 
      21                 :            : /*******************************************************************************
      22                 :            :  *
      23                 :            :  * FUNCTION:    acpi_install_address_space_handler
      24                 :            :  *
      25                 :            :  * PARAMETERS:  device          - Handle for the device
      26                 :            :  *              space_id        - The address space ID
      27                 :            :  *              handler         - Address of the handler
      28                 :            :  *              setup           - Address of the setup function
      29                 :            :  *              context         - Value passed to the handler on each access
      30                 :            :  *
      31                 :            :  * RETURN:      Status
      32                 :            :  *
      33                 :            :  * DESCRIPTION: Install a handler for all op_regions of a given space_id.
      34                 :            :  *
      35                 :            :  * NOTE: This function should only be called after acpi_enable_subsystem has
      36                 :            :  * been called. This is because any _REG methods associated with the Space ID
      37                 :            :  * are executed here, and these methods can only be safely executed after
      38                 :            :  * the default handlers have been installed and the hardware has been
      39                 :            :  * initialized (via acpi_enable_subsystem.)
      40                 :            :  *
      41                 :            :  ******************************************************************************/
      42                 :            : acpi_status
      43                 :          6 : acpi_install_address_space_handler(acpi_handle device,
      44                 :            :                                    acpi_adr_space_type space_id,
      45                 :            :                                    acpi_adr_space_handler handler,
      46                 :            :                                    acpi_adr_space_setup setup, void *context)
      47                 :            : {
      48                 :          6 :         struct acpi_namespace_node *node;
      49                 :          6 :         acpi_status status;
      50                 :            : 
      51                 :          6 :         ACPI_FUNCTION_TRACE(acpi_install_address_space_handler);
      52                 :            : 
      53                 :            :         /* Parameter validation */
      54                 :            : 
      55         [ +  - ]:          6 :         if (!device) {
      56                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      57                 :            :         }
      58                 :            : 
      59                 :          6 :         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
      60         [ +  - ]:          6 :         if (ACPI_FAILURE(status)) {
      61                 :            :                 return_ACPI_STATUS(status);
      62                 :            :         }
      63                 :            : 
      64                 :            :         /* Convert and validate the device handle */
      65                 :            : 
      66                 :          6 :         node = acpi_ns_validate_handle(device);
      67         [ -  + ]:          6 :         if (!node) {
      68                 :          0 :                 status = AE_BAD_PARAMETER;
      69                 :          0 :                 goto unlock_and_exit;
      70                 :            :         }
      71                 :            : 
      72                 :            :         /* Install the handler for all Regions for this Space ID */
      73                 :            : 
      74                 :          6 :         status =
      75                 :          6 :             acpi_ev_install_space_handler(node, space_id, handler, setup,
      76                 :            :                                           context);
      77         [ -  + ]:          6 :         if (ACPI_FAILURE(status)) {
      78                 :          0 :                 goto unlock_and_exit;
      79                 :            :         }
      80                 :            : 
      81                 :            :         /* Run all _REG methods for this address space */
      82                 :            : 
      83                 :          6 :         acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
      84                 :            : 
      85                 :          6 : unlock_and_exit:
      86                 :          6 :         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
      87                 :          6 :         return_ACPI_STATUS(status);
      88                 :            : }
      89                 :            : 
      90                 :            : ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
      91                 :            : 
      92                 :            : /*******************************************************************************
      93                 :            :  *
      94                 :            :  * FUNCTION:    acpi_remove_address_space_handler
      95                 :            :  *
      96                 :            :  * PARAMETERS:  device          - Handle for the device
      97                 :            :  *              space_id        - The address space ID
      98                 :            :  *              handler         - Address of the handler
      99                 :            :  *
     100                 :            :  * RETURN:      Status
     101                 :            :  *
     102                 :            :  * DESCRIPTION: Remove a previously installed handler.
     103                 :            :  *
     104                 :            :  ******************************************************************************/
     105                 :            : acpi_status
     106                 :          0 : acpi_remove_address_space_handler(acpi_handle device,
     107                 :            :                                   acpi_adr_space_type space_id,
     108                 :            :                                   acpi_adr_space_handler handler)
     109                 :            : {
     110                 :          0 :         union acpi_operand_object *obj_desc;
     111                 :          0 :         union acpi_operand_object *handler_obj;
     112                 :          0 :         union acpi_operand_object *region_obj;
     113                 :          0 :         union acpi_operand_object **last_obj_ptr;
     114                 :          0 :         struct acpi_namespace_node *node;
     115                 :          0 :         acpi_status status;
     116                 :            : 
     117                 :          0 :         ACPI_FUNCTION_TRACE(acpi_remove_address_space_handler);
     118                 :            : 
     119                 :            :         /* Parameter validation */
     120                 :            : 
     121         [ #  # ]:          0 :         if (!device) {
     122                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     123                 :            :         }
     124                 :            : 
     125                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
     126         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     127                 :            :                 return_ACPI_STATUS(status);
     128                 :            :         }
     129                 :            : 
     130                 :            :         /* Convert and validate the device handle */
     131                 :            : 
     132                 :          0 :         node = acpi_ns_validate_handle(device);
     133         [ #  # ]:          0 :         if (!node ||
     134         [ #  # ]:          0 :             ((node->type != ACPI_TYPE_DEVICE) &&
     135         [ #  # ]:          0 :              (node->type != ACPI_TYPE_PROCESSOR) &&
     136                 :          0 :              (node->type != ACPI_TYPE_THERMAL) &&
     137         [ #  # ]:          0 :              (node != acpi_gbl_root_node))) {
     138                 :          0 :                 status = AE_BAD_PARAMETER;
     139                 :          0 :                 goto unlock_and_exit;
     140                 :            :         }
     141                 :            : 
     142                 :            :         /* Make sure the internal object exists */
     143                 :            : 
     144                 :          0 :         obj_desc = acpi_ns_get_attached_object(node);
     145         [ #  # ]:          0 :         if (!obj_desc) {
     146                 :          0 :                 status = AE_NOT_EXIST;
     147                 :          0 :                 goto unlock_and_exit;
     148                 :            :         }
     149                 :            : 
     150                 :            :         /* Find the address handler the user requested */
     151                 :            : 
     152                 :          0 :         handler_obj = obj_desc->common_notify.handler;
     153                 :          0 :         last_obj_ptr = &obj_desc->common_notify.handler;
     154         [ #  # ]:          0 :         while (handler_obj) {
     155                 :            : 
     156                 :            :                 /* We have a handler, see if user requested this one */
     157                 :            : 
     158         [ #  # ]:          0 :                 if (handler_obj->address_space.space_id == space_id) {
     159                 :            : 
     160                 :            :                         /* Handler must be the same as the installed handler */
     161                 :            : 
     162         [ #  # ]:          0 :                         if (handler_obj->address_space.handler != handler) {
     163                 :          0 :                                 status = AE_BAD_PARAMETER;
     164                 :          0 :                                 goto unlock_and_exit;
     165                 :            :                         }
     166                 :            : 
     167                 :            :                         /* Matched space_id, first dereference this in the Regions */
     168                 :            : 
     169                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
     170                 :            :                                           "Removing address handler %p(%p) for region %s "
     171                 :            :                                           "on Device %p(%p)\n",
     172                 :            :                                           handler_obj, handler,
     173                 :            :                                           acpi_ut_get_region_name(space_id),
     174                 :          0 :                                           node, obj_desc));
     175                 :            : 
     176                 :          0 :                         region_obj = handler_obj->address_space.region_list;
     177                 :            : 
     178                 :            :                         /* Walk the handler's region list */
     179                 :            : 
     180         [ #  # ]:          0 :                         while (region_obj) {
     181                 :            :                                 /*
     182                 :            :                                  * First disassociate the handler from the region.
     183                 :            :                                  *
     184                 :            :                                  * NOTE: this doesn't mean that the region goes away
     185                 :            :                                  * The region is just inaccessible as indicated to
     186                 :            :                                  * the _REG method
     187                 :            :                                  */
     188                 :          0 :                                 acpi_ev_detach_region(region_obj, TRUE);
     189                 :            : 
     190                 :            :                                 /*
     191                 :            :                                  * Walk the list: Just grab the head because the
     192                 :            :                                  * detach_region removed the previous head.
     193                 :            :                                  */
     194                 :          0 :                                 region_obj =
     195                 :            :                                     handler_obj->address_space.region_list;
     196                 :            :                         }
     197                 :            : 
     198                 :            :                         /* Remove this Handler object from the list */
     199                 :            : 
     200                 :          0 :                         *last_obj_ptr = handler_obj->address_space.next;
     201                 :            : 
     202                 :            :                         /* Now we can delete the handler object */
     203                 :            : 
     204                 :          0 :                         acpi_ut_remove_reference(handler_obj);
     205                 :          0 :                         goto unlock_and_exit;
     206                 :            :                 }
     207                 :            : 
     208                 :            :                 /* Walk the linked list of handlers */
     209                 :            : 
     210                 :          0 :                 last_obj_ptr = &handler_obj->address_space.next;
     211                 :          0 :                 handler_obj = handler_obj->address_space.next;
     212                 :            :         }
     213                 :            : 
     214                 :            :         /* The handler does not exist */
     215                 :            : 
     216                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
     217                 :            :                           "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
     218                 :            :                           handler, acpi_ut_get_region_name(space_id), space_id,
     219                 :            :                           node, obj_desc));
     220                 :            : 
     221                 :            :         status = AE_NOT_EXIST;
     222                 :            : 
     223                 :          0 : unlock_and_exit:
     224                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     225                 :          0 :         return_ACPI_STATUS(status);
     226                 :            : }
     227                 :            : 
     228                 :            : ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)

Generated by: LCOV version 1.14