LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nsobject.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 81 114 71.1 %
Date: 2022-04-01 14:58:12 Functions: 6 7 85.7 %
Branches: 45 80 56.2 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: nsobject - Utilities for objects attached to namespace
       5                 :            :  *                         table entries
       6                 :            :  *
       7                 :            :  ******************************************************************************/
       8                 :            : 
       9                 :            : #include <acpi/acpi.h>
      10                 :            : #include "accommon.h"
      11                 :            : #include "acnamesp.h"
      12                 :            : 
      13                 :            : #define _COMPONENT          ACPI_NAMESPACE
      14                 :            : ACPI_MODULE_NAME("nsobject")
      15                 :            : 
      16                 :            : /*******************************************************************************
      17                 :            :  *
      18                 :            :  * FUNCTION:    acpi_ns_attach_object
      19                 :            :  *
      20                 :            :  * PARAMETERS:  node                - Parent Node
      21                 :            :  *              object              - Object to be attached
      22                 :            :  *              type                - Type of object, or ACPI_TYPE_ANY if not
      23                 :            :  *                                    known
      24                 :            :  *
      25                 :            :  * RETURN:      Status
      26                 :            :  *
      27                 :            :  * DESCRIPTION: Record the given object as the value associated with the
      28                 :            :  *              name whose acpi_handle is passed. If Object is NULL
      29                 :            :  *              and Type is ACPI_TYPE_ANY, set the name as having no value.
      30                 :            :  *              Note: Future may require that the Node->Flags field be passed
      31                 :            :  *              as a parameter.
      32                 :            :  *
      33                 :            :  * MUTEX:       Assumes namespace is locked
      34                 :            :  *
      35                 :            :  ******************************************************************************/
      36                 :            : acpi_status
      37                 :        798 : acpi_ns_attach_object(struct acpi_namespace_node *node,
      38                 :            :                       union acpi_operand_object *object, acpi_object_type type)
      39                 :            : {
      40                 :        798 :         union acpi_operand_object *obj_desc;
      41                 :        798 :         union acpi_operand_object *last_obj_desc;
      42                 :        798 :         acpi_object_type object_type = ACPI_TYPE_ANY;
      43                 :            : 
      44                 :        798 :         ACPI_FUNCTION_TRACE(ns_attach_object);
      45                 :            : 
      46                 :            :         /*
      47                 :            :          * Parameter validation
      48                 :            :          */
      49         [ -  + ]:        798 :         if (!node) {
      50                 :            : 
      51                 :            :                 /* Invalid handle */
      52                 :            : 
      53                 :          0 :                 ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
      54                 :          0 :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      55                 :            :         }
      56                 :            : 
      57         [ -  + ]:        798 :         if (!object && (ACPI_TYPE_ANY != type)) {
      58                 :            : 
      59                 :            :                 /* Null object */
      60                 :            : 
      61                 :          0 :                 ACPI_ERROR((AE_INFO,
      62                 :            :                             "Null object, but type not ACPI_TYPE_ANY"));
      63                 :          0 :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      64                 :            :         }
      65                 :            : 
      66         [ -  + ]:        798 :         if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
      67                 :            : 
      68                 :            :                 /* Not a name handle */
      69                 :            : 
      70                 :          0 :                 ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
      71                 :            :                             node, acpi_ut_get_descriptor_name(node)));
      72                 :          0 :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      73                 :            :         }
      74                 :            : 
      75                 :            :         /* Check if this object is already attached */
      76                 :            : 
      77         [ +  - ]:        798 :         if (node->object == object) {
      78                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
      79                 :            :                                   "Obj %p already installed in NameObj %p\n",
      80                 :            :                                   object, node));
      81                 :            : 
      82                 :            :                 return_ACPI_STATUS(AE_OK);
      83                 :            :         }
      84                 :            : 
      85                 :            :         /* If null object, we will just install it */
      86                 :            : 
      87         [ +  - ]:        798 :         if (!object) {
      88                 :            :                 obj_desc = NULL;
      89                 :            :                 object_type = ACPI_TYPE_ANY;
      90                 :            :         }
      91                 :            : 
      92                 :            :         /*
      93                 :            :          * If the source object is a namespace Node with an attached object,
      94                 :            :          * we will use that (attached) object
      95                 :            :          */
      96         [ -  + ]:        798 :         else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
      97         [ #  # ]:          0 :                  ((struct acpi_namespace_node *)object)->object) {
      98                 :            :                 /*
      99                 :            :                  * Value passed is a name handle and that name has a
     100                 :            :                  * non-null value. Use that name's value and type.
     101                 :            :                  */
     102                 :          0 :                 obj_desc = ((struct acpi_namespace_node *)object)->object;
     103                 :          0 :                 object_type = ((struct acpi_namespace_node *)object)->type;
     104                 :            :         }
     105                 :            : 
     106                 :            :         /*
     107                 :            :          * Otherwise, we will use the parameter object, but we must type
     108                 :            :          * it first
     109                 :            :          */
     110                 :            :         else {
     111                 :            :                 obj_desc = (union acpi_operand_object *)object;
     112                 :            : 
     113                 :            :                 /* Use the given type */
     114                 :            : 
     115                 :            :                 object_type = type;
     116                 :            :         }
     117                 :            : 
     118                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
     119                 :        798 :                           obj_desc, node, acpi_ut_get_node_name(node)));
     120                 :            : 
     121                 :            :         /* Detach an existing attached object if present */
     122                 :            : 
     123         [ +  + ]:        798 :         if (node->object) {
     124                 :         27 :                 acpi_ns_detach_object(node);
     125                 :            :         }
     126                 :            : 
     127         [ +  - ]:        798 :         if (obj_desc) {
     128                 :            :                 /*
     129                 :            :                  * Must increment the new value's reference count
     130                 :            :                  * (if it is an internal object)
     131                 :            :                  */
     132                 :        798 :                 acpi_ut_add_reference(obj_desc);
     133                 :            : 
     134                 :            :                 /*
     135                 :            :                  * Handle objects with multiple descriptors - walk
     136                 :            :                  * to the end of the descriptor list
     137                 :            :                  */
     138                 :        798 :                 last_obj_desc = obj_desc;
     139         [ +  + ]:        852 :                 while (last_obj_desc->common.next_object) {
     140                 :            :                         last_obj_desc = last_obj_desc->common.next_object;
     141                 :            :                 }
     142                 :            : 
     143                 :            :                 /* Install the object at the front of the object list */
     144                 :            : 
     145                 :        798 :                 last_obj_desc->common.next_object = node->object;
     146                 :            :         }
     147                 :            : 
     148                 :        798 :         node->type = (u8) object_type;
     149                 :        798 :         node->object = obj_desc;
     150                 :            : 
     151                 :        798 :         return_ACPI_STATUS(AE_OK);
     152                 :            : }
     153                 :            : 
     154                 :            : /*******************************************************************************
     155                 :            :  *
     156                 :            :  * FUNCTION:    acpi_ns_detach_object
     157                 :            :  *
     158                 :            :  * PARAMETERS:  node           - A Namespace node whose object will be detached
     159                 :            :  *
     160                 :            :  * RETURN:      None.
     161                 :            :  *
     162                 :            :  * DESCRIPTION: Detach/delete an object associated with a namespace node.
     163                 :            :  *              if the object is an allocated object, it is freed.
     164                 :            :  *              Otherwise, the field is simply cleared.
     165                 :            :  *
     166                 :            :  ******************************************************************************/
     167                 :            : 
     168                 :        309 : void acpi_ns_detach_object(struct acpi_namespace_node *node)
     169                 :            : {
     170                 :        309 :         union acpi_operand_object *obj_desc;
     171                 :            : 
     172                 :        309 :         ACPI_FUNCTION_TRACE(ns_detach_object);
     173                 :            : 
     174                 :        309 :         obj_desc = node->object;
     175                 :            : 
     176   [ +  +  +  + ]:        309 :         if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
     177                 :            :                 return_VOID;
     178                 :            :         }
     179                 :            : 
     180         [ -  + ]:        225 :         if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
     181                 :            : 
     182                 :            :                 /* Free the dynamic aml buffer */
     183                 :            : 
     184         [ #  # ]:          0 :                 if (obj_desc->common.type == ACPI_TYPE_METHOD) {
     185                 :          0 :                         ACPI_FREE(obj_desc->method.aml_start);
     186                 :            :                 }
     187                 :            :         }
     188                 :            : 
     189         [ -  + ]:        225 :         if (obj_desc->common.type == ACPI_TYPE_REGION) {
     190                 :          0 :                 acpi_ut_remove_address_range(obj_desc->region.space_id, node);
     191                 :            :         }
     192                 :            : 
     193                 :            :         /* Clear the Node entry in all cases */
     194                 :            : 
     195                 :        225 :         node->object = NULL;
     196         [ +  - ]:        225 :         if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
     197                 :            : 
     198                 :            :                 /* Unlink object from front of possible object list */
     199                 :            : 
     200                 :        225 :                 node->object = obj_desc->common.next_object;
     201                 :            : 
     202                 :            :                 /* Handle possible 2-descriptor object */
     203                 :            : 
     204         [ +  + ]:        225 :                 if (node->object &&
     205         [ +  - ]:         30 :                     (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
     206                 :         30 :                         node->object = node->object->common.next_object;
     207                 :            :                 }
     208                 :            : 
     209                 :            :                 /*
     210                 :            :                  * Detach the object from any data objects (which are still held by
     211                 :            :                  * the namespace node)
     212                 :            :                  */
     213         [ +  + ]:        225 :                 if (obj_desc->common.next_object &&
     214         [ -  + ]:         30 :                     ((obj_desc->common.next_object)->common.type ==
     215                 :            :                      ACPI_TYPE_LOCAL_DATA)) {
     216                 :          0 :                         obj_desc->common.next_object = NULL;
     217                 :            :                 }
     218                 :            :         }
     219                 :            : 
     220                 :            :         /* Reset the node type to untyped */
     221                 :            : 
     222                 :        225 :         node->type = ACPI_TYPE_ANY;
     223                 :            : 
     224                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
     225                 :        225 :                           node, acpi_ut_get_node_name(node), obj_desc));
     226                 :            : 
     227                 :            :         /* Remove one reference on the object (and all subobjects) */
     228                 :            : 
     229                 :        225 :         acpi_ut_remove_reference(obj_desc);
     230                 :        225 :         return_VOID;
     231                 :            : }
     232                 :            : 
     233                 :            : /*******************************************************************************
     234                 :            :  *
     235                 :            :  * FUNCTION:    acpi_ns_get_attached_object
     236                 :            :  *
     237                 :            :  * PARAMETERS:  node             - Namespace node
     238                 :            :  *
     239                 :            :  * RETURN:      Current value of the object field from the Node whose
     240                 :            :  *              handle is passed
     241                 :            :  *
     242                 :            :  * DESCRIPTION: Obtain the object attached to a namespace node.
     243                 :            :  *
     244                 :            :  ******************************************************************************/
     245                 :            : 
     246                 :      10686 : union acpi_operand_object *acpi_ns_get_attached_object(struct
     247                 :            :                                                        acpi_namespace_node
     248                 :            :                                                        *node)
     249                 :            : {
     250                 :      10686 :         ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node);
     251                 :            : 
     252         [ -  + ]:      10686 :         if (!node) {
     253                 :          0 :                 ACPI_WARNING((AE_INFO, "Null Node ptr"));
     254                 :          0 :                 return_PTR(NULL);
     255                 :            :         }
     256                 :            : 
     257         [ +  + ]:      10686 :         if (!node->object ||
     258                 :       9492 :             ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
     259         [ +  - ]:       9492 :              && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
     260                 :            :                  ACPI_DESC_TYPE_NAMED))
     261         [ +  + ]:       9492 :             || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
     262                 :       1626 :                 return_PTR(NULL);
     263                 :            :         }
     264                 :            : 
     265                 :            :         return_PTR(node->object);
     266                 :            : }
     267                 :            : 
     268                 :            : /*******************************************************************************
     269                 :            :  *
     270                 :            :  * FUNCTION:    acpi_ns_get_secondary_object
     271                 :            :  *
     272                 :            :  * PARAMETERS:  node             - Namespace node
     273                 :            :  *
     274                 :            :  * RETURN:      Current value of the object field from the Node whose
     275                 :            :  *              handle is passed.
     276                 :            :  *
     277                 :            :  * DESCRIPTION: Obtain a secondary object associated with a namespace node.
     278                 :            :  *
     279                 :            :  ******************************************************************************/
     280                 :            : 
     281                 :        258 : union acpi_operand_object *acpi_ns_get_secondary_object(union
     282                 :            :                                                         acpi_operand_object
     283                 :            :                                                         *obj_desc)
     284                 :            : {
     285                 :        258 :         ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
     286                 :            : 
     287         [ +  - ]:        258 :         if ((!obj_desc) ||
     288         [ +  - ]:        258 :             (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
     289         [ +  - ]:        258 :             (!obj_desc->common.next_object) ||
     290         [ -  + ]:        258 :             ((obj_desc->common.next_object)->common.type ==
     291                 :            :              ACPI_TYPE_LOCAL_DATA)) {
     292                 :          0 :                 return_PTR(NULL);
     293                 :            :         }
     294                 :            : 
     295                 :            :         return_PTR(obj_desc->common.next_object);
     296                 :            : }
     297                 :            : 
     298                 :            : /*******************************************************************************
     299                 :            :  *
     300                 :            :  * FUNCTION:    acpi_ns_attach_data
     301                 :            :  *
     302                 :            :  * PARAMETERS:  node            - Namespace node
     303                 :            :  *              handler         - Handler to be associated with the data
     304                 :            :  *              data            - Data to be attached
     305                 :            :  *
     306                 :            :  * RETURN:      Status
     307                 :            :  *
     308                 :            :  * DESCRIPTION: Low-level attach data. Create and attach a Data object.
     309                 :            :  *
     310                 :            :  ******************************************************************************/
     311                 :            : 
     312                 :            : acpi_status
     313                 :        171 : acpi_ns_attach_data(struct acpi_namespace_node *node,
     314                 :            :                     acpi_object_handler handler, void *data)
     315                 :            : {
     316                 :        171 :         union acpi_operand_object *prev_obj_desc;
     317                 :        171 :         union acpi_operand_object *obj_desc;
     318                 :        171 :         union acpi_operand_object *data_desc;
     319                 :            : 
     320                 :            :         /* We only allow one attachment per handler */
     321                 :            : 
     322                 :        171 :         prev_obj_desc = NULL;
     323                 :        171 :         obj_desc = node->object;
     324         [ +  + ]:        177 :         while (obj_desc) {
     325         [ -  + ]:          6 :                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
     326         [ #  # ]:          0 :                     (obj_desc->data.handler == handler)) {
     327                 :            :                         return (AE_ALREADY_EXISTS);
     328                 :            :                 }
     329                 :            : 
     330                 :          6 :                 prev_obj_desc = obj_desc;
     331                 :          6 :                 obj_desc = obj_desc->common.next_object;
     332                 :            :         }
     333                 :            : 
     334                 :            :         /* Create an internal object for the data */
     335                 :            : 
     336                 :        171 :         data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
     337         [ +  - ]:        171 :         if (!data_desc) {
     338                 :            :                 return (AE_NO_MEMORY);
     339                 :            :         }
     340                 :            : 
     341                 :        171 :         data_desc->data.handler = handler;
     342                 :        171 :         data_desc->data.pointer = data;
     343                 :            : 
     344                 :            :         /* Install the data object */
     345                 :            : 
     346         [ +  + ]:        171 :         if (prev_obj_desc) {
     347                 :          6 :                 prev_obj_desc->common.next_object = data_desc;
     348                 :            :         } else {
     349                 :        165 :                 node->object = data_desc;
     350                 :            :         }
     351                 :            : 
     352                 :            :         return (AE_OK);
     353                 :            : }
     354                 :            : 
     355                 :            : /*******************************************************************************
     356                 :            :  *
     357                 :            :  * FUNCTION:    acpi_ns_detach_data
     358                 :            :  *
     359                 :            :  * PARAMETERS:  node            - Namespace node
     360                 :            :  *              handler         - Handler associated with the data
     361                 :            :  *
     362                 :            :  * RETURN:      Status
     363                 :            :  *
     364                 :            :  * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
     365                 :            :  *              is responsible for the actual data.
     366                 :            :  *
     367                 :            :  ******************************************************************************/
     368                 :            : 
     369                 :            : acpi_status
     370                 :          0 : acpi_ns_detach_data(struct acpi_namespace_node *node,
     371                 :            :                     acpi_object_handler handler)
     372                 :            : {
     373                 :          0 :         union acpi_operand_object *obj_desc;
     374                 :          0 :         union acpi_operand_object *prev_obj_desc;
     375                 :            : 
     376                 :          0 :         prev_obj_desc = NULL;
     377                 :          0 :         obj_desc = node->object;
     378         [ #  # ]:          0 :         while (obj_desc) {
     379         [ #  # ]:          0 :                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
     380         [ #  # ]:          0 :                     (obj_desc->data.handler == handler)) {
     381         [ #  # ]:          0 :                         if (prev_obj_desc) {
     382                 :          0 :                                 prev_obj_desc->common.next_object =
     383                 :          0 :                                     obj_desc->common.next_object;
     384                 :            :                         } else {
     385                 :          0 :                                 node->object = obj_desc->common.next_object;
     386                 :            :                         }
     387                 :            : 
     388                 :          0 :                         acpi_ut_remove_reference(obj_desc);
     389                 :          0 :                         return (AE_OK);
     390                 :            :                 }
     391                 :            : 
     392                 :          0 :                 prev_obj_desc = obj_desc;
     393                 :          0 :                 obj_desc = obj_desc->common.next_object;
     394                 :            :         }
     395                 :            : 
     396                 :            :         return (AE_NOT_FOUND);
     397                 :            : }
     398                 :            : 
     399                 :            : /*******************************************************************************
     400                 :            :  *
     401                 :            :  * FUNCTION:    acpi_ns_get_attached_data
     402                 :            :  *
     403                 :            :  * PARAMETERS:  node            - Namespace node
     404                 :            :  *              handler         - Handler associated with the data
     405                 :            :  *              data            - Where the data is returned
     406                 :            :  *
     407                 :            :  * RETURN:      Status
     408                 :            :  *
     409                 :            :  * DESCRIPTION: Low level interface to obtain data previously associated with
     410                 :            :  *              a namespace node.
     411                 :            :  *
     412                 :            :  ******************************************************************************/
     413                 :            : 
     414                 :            : acpi_status
     415                 :       1362 : acpi_ns_get_attached_data(struct acpi_namespace_node *node,
     416                 :            :                           acpi_object_handler handler, void **data)
     417                 :            : {
     418                 :       1362 :         union acpi_operand_object *obj_desc;
     419                 :            : 
     420                 :       1362 :         obj_desc = node->object;
     421         [ +  + ]:       2265 :         while (obj_desc) {
     422         [ +  + ]:       1377 :                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
     423         [ +  - ]:        474 :                     (obj_desc->data.handler == handler)) {
     424                 :        474 :                         *data = obj_desc->data.pointer;
     425                 :        474 :                         return (AE_OK);
     426                 :            :                 }
     427                 :            : 
     428                 :        903 :                 obj_desc = obj_desc->common.next_object;
     429                 :            :         }
     430                 :            : 
     431                 :            :         return (AE_NOT_FOUND);
     432                 :            : }

Generated by: LCOV version 1.14