Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nsobject - Utilities for objects attached to namespace
  4.  *                         table entries
  5.  *
  6.  ******************************************************************************/
  7.  
  8. /*
  9.  * Copyright (C) 2000 - 2015, Intel Corp.
  10.  * All rights reserved.
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions, and the following disclaimer,
  17.  *    without modification.
  18.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19.  *    substantially similar to the "NO WARRANTY" disclaimer below
  20.  *    ("Disclaimer") and any redistribution must be conditioned upon
  21.  *    including a substantially similar Disclaimer requirement for further
  22.  *    binary redistribution.
  23.  * 3. Neither the names of the above-listed copyright holders nor the names
  24.  *    of any contributors may be used to endorse or promote products derived
  25.  *    from this software without specific prior written permission.
  26.  *
  27.  * Alternatively, this software may be distributed under the terms of the
  28.  * GNU General Public License ("GPL") version 2 as published by the Free
  29.  * Software Foundation.
  30.  *
  31.  * NO WARRANTY
  32.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  33.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  34.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  35.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42.  * POSSIBILITY OF SUCH DAMAGES.
  43.  */
  44.  
  45. #include <acpi/acpi.h>
  46. #include "accommon.h"
  47. #include "acnamesp.h"
  48.  
  49. #define _COMPONENT          ACPI_NAMESPACE
  50. ACPI_MODULE_NAME("nsobject")
  51.  
  52. /*******************************************************************************
  53.  *
  54.  * FUNCTION:    acpi_ns_attach_object
  55.  *
  56.  * PARAMETERS:  node                - Parent Node
  57.  *              object              - Object to be attached
  58.  *              type                - Type of object, or ACPI_TYPE_ANY if not
  59.  *                                    known
  60.  *
  61.  * RETURN:      Status
  62.  *
  63.  * DESCRIPTION: Record the given object as the value associated with the
  64.  *              name whose acpi_handle is passed. If Object is NULL
  65.  *              and Type is ACPI_TYPE_ANY, set the name as having no value.
  66.  *              Note: Future may require that the Node->Flags field be passed
  67.  *              as a parameter.
  68.  *
  69.  * MUTEX:       Assumes namespace is locked
  70.  *
  71.  ******************************************************************************/
  72. acpi_status
  73. acpi_ns_attach_object(struct acpi_namespace_node *node,
  74.                       union acpi_operand_object *object, acpi_object_type type)
  75. {
  76.         union acpi_operand_object *obj_desc;
  77.         union acpi_operand_object *last_obj_desc;
  78.         acpi_object_type object_type = ACPI_TYPE_ANY;
  79.  
  80.         ACPI_FUNCTION_TRACE(ns_attach_object);
  81.  
  82.         /*
  83.          * Parameter validation
  84.          */
  85.         if (!node) {
  86.  
  87.                 /* Invalid handle */
  88.  
  89.                 ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
  90.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  91.         }
  92.  
  93.         if (!object && (ACPI_TYPE_ANY != type)) {
  94.  
  95.                 /* Null object */
  96.  
  97.                 ACPI_ERROR((AE_INFO,
  98.                             "Null object, but type not ACPI_TYPE_ANY"));
  99.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  100.         }
  101.  
  102.         if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
  103.  
  104.                 /* Not a name handle */
  105.  
  106.                 ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
  107.                             node, acpi_ut_get_descriptor_name(node)));
  108.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  109.         }
  110.  
  111.         /* Check if this object is already attached */
  112.  
  113.         if (node->object == object) {
  114.                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  115.                                   "Obj %p already installed in NameObj %p\n",
  116.                                   object, node));
  117.  
  118.                 return_ACPI_STATUS(AE_OK);
  119.         }
  120.  
  121.         /* If null object, we will just install it */
  122.  
  123.         if (!object) {
  124.                 obj_desc = NULL;
  125.                 object_type = ACPI_TYPE_ANY;
  126.         }
  127.  
  128.         /*
  129.          * If the source object is a namespace Node with an attached object,
  130.          * we will use that (attached) object
  131.          */
  132.         else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
  133.                  ((struct acpi_namespace_node *)object)->object) {
  134.                 /*
  135.                  * Value passed is a name handle and that name has a
  136.                  * non-null value. Use that name's value and type.
  137.                  */
  138.                 obj_desc = ((struct acpi_namespace_node *)object)->object;
  139.                 object_type = ((struct acpi_namespace_node *)object)->type;
  140.         }
  141.  
  142.         /*
  143.          * Otherwise, we will use the parameter object, but we must type
  144.          * it first
  145.          */
  146.         else {
  147.                 obj_desc = (union acpi_operand_object *)object;
  148.  
  149.                 /* Use the given type */
  150.  
  151.                 object_type = type;
  152.         }
  153.  
  154.         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
  155.                           obj_desc, node, acpi_ut_get_node_name(node)));
  156.  
  157.         /* Detach an existing attached object if present */
  158.  
  159.         if (node->object) {
  160.                 acpi_ns_detach_object(node);
  161.         }
  162.  
  163.         if (obj_desc) {
  164.                 /*
  165.                  * Must increment the new value's reference count
  166.                  * (if it is an internal object)
  167.                  */
  168.                 acpi_ut_add_reference(obj_desc);
  169.  
  170.                 /*
  171.                  * Handle objects with multiple descriptors - walk
  172.                  * to the end of the descriptor list
  173.                  */
  174.                 last_obj_desc = obj_desc;
  175.                 while (last_obj_desc->common.next_object) {
  176.                         last_obj_desc = last_obj_desc->common.next_object;
  177.                 }
  178.  
  179.                 /* Install the object at the front of the object list */
  180.  
  181.                 last_obj_desc->common.next_object = node->object;
  182.         }
  183.  
  184.         node->type = (u8) object_type;
  185.         node->object = obj_desc;
  186.  
  187.         return_ACPI_STATUS(AE_OK);
  188. }
  189.  
  190. /*******************************************************************************
  191.  *
  192.  * FUNCTION:    acpi_ns_detach_object
  193.  *
  194.  * PARAMETERS:  node           - A Namespace node whose object will be detached
  195.  *
  196.  * RETURN:      None.
  197.  *
  198.  * DESCRIPTION: Detach/delete an object associated with a namespace node.
  199.  *              if the object is an allocated object, it is freed.
  200.  *              Otherwise, the field is simply cleared.
  201.  *
  202.  ******************************************************************************/
  203.  
  204. void acpi_ns_detach_object(struct acpi_namespace_node *node)
  205. {
  206.         union acpi_operand_object *obj_desc;
  207.  
  208.         ACPI_FUNCTION_TRACE(ns_detach_object);
  209.  
  210.         obj_desc = node->object;
  211.  
  212.         if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
  213.                 return_VOID;
  214.         }
  215.  
  216.         if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
  217.  
  218.                 /* Free the dynamic aml buffer */
  219.  
  220.                 if (obj_desc->common.type == ACPI_TYPE_METHOD) {
  221.                         ACPI_FREE(obj_desc->method.aml_start);
  222.                 }
  223.         }
  224.  
  225.         /* Clear the Node entry in all cases */
  226.  
  227.         node->object = NULL;
  228.         if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
  229.  
  230.                 /* Unlink object from front of possible object list */
  231.  
  232.                 node->object = obj_desc->common.next_object;
  233.  
  234.                 /* Handle possible 2-descriptor object */
  235.  
  236.                 if (node->object &&
  237.                     (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
  238.                         node->object = node->object->common.next_object;
  239.                 }
  240.  
  241.                 /*
  242.                  * Detach the object from any data objects (which are still held by
  243.                  * the namespace node)
  244.                  */
  245.                 if (obj_desc->common.next_object &&
  246.                     ((obj_desc->common.next_object)->common.type ==
  247.                      ACPI_TYPE_LOCAL_DATA)) {
  248.                         obj_desc->common.next_object = NULL;
  249.                 }
  250.         }
  251.  
  252.         /* Reset the node type to untyped */
  253.  
  254.         node->type = ACPI_TYPE_ANY;
  255.  
  256.         ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
  257.                           node, acpi_ut_get_node_name(node), obj_desc));
  258.  
  259.         /* Remove one reference on the object (and all subobjects) */
  260.  
  261.         acpi_ut_remove_reference(obj_desc);
  262.         return_VOID;
  263. }
  264.  
  265. /*******************************************************************************
  266.  *
  267.  * FUNCTION:    acpi_ns_get_attached_object
  268.  *
  269.  * PARAMETERS:  node             - Namespace node
  270.  *
  271.  * RETURN:      Current value of the object field from the Node whose
  272.  *              handle is passed
  273.  *
  274.  * DESCRIPTION: Obtain the object attached to a namespace node.
  275.  *
  276.  ******************************************************************************/
  277.  
  278. union acpi_operand_object *acpi_ns_get_attached_object(struct
  279.                                                        acpi_namespace_node
  280.                                                        *node)
  281. {
  282.         ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node);
  283.  
  284.         if (!node) {
  285.                 ACPI_WARNING((AE_INFO, "Null Node ptr"));
  286.                 return_PTR(NULL);
  287.         }
  288.  
  289.         if (!node->object ||
  290.             ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
  291.              && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
  292.                  ACPI_DESC_TYPE_NAMED))
  293.             || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
  294.                 return_PTR(NULL);
  295.         }
  296.  
  297.         return_PTR(node->object);
  298. }
  299.  
  300. /*******************************************************************************
  301.  *
  302.  * FUNCTION:    acpi_ns_get_secondary_object
  303.  *
  304.  * PARAMETERS:  node             - Namespace node
  305.  *
  306.  * RETURN:      Current value of the object field from the Node whose
  307.  *              handle is passed.
  308.  *
  309.  * DESCRIPTION: Obtain a secondary object associated with a namespace node.
  310.  *
  311.  ******************************************************************************/
  312.  
  313. union acpi_operand_object *acpi_ns_get_secondary_object(union
  314.                                                         acpi_operand_object
  315.                                                         *obj_desc)
  316. {
  317.         ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
  318.  
  319.         if ((!obj_desc) ||
  320.             (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
  321.             (!obj_desc->common.next_object) ||
  322.             ((obj_desc->common.next_object)->common.type ==
  323.              ACPI_TYPE_LOCAL_DATA)) {
  324.                 return_PTR(NULL);
  325.         }
  326.  
  327.         return_PTR(obj_desc->common.next_object);
  328. }
  329.  
  330. /*******************************************************************************
  331.  *
  332.  * FUNCTION:    acpi_ns_attach_data
  333.  *
  334.  * PARAMETERS:  node            - Namespace node
  335.  *              handler         - Handler to be associated with the data
  336.  *              data            - Data to be attached
  337.  *
  338.  * RETURN:      Status
  339.  *
  340.  * DESCRIPTION: Low-level attach data. Create and attach a Data object.
  341.  *
  342.  ******************************************************************************/
  343.  
  344. acpi_status
  345. acpi_ns_attach_data(struct acpi_namespace_node *node,
  346.                     acpi_object_handler handler, void *data)
  347. {
  348.         union acpi_operand_object *prev_obj_desc;
  349.         union acpi_operand_object *obj_desc;
  350.         union acpi_operand_object *data_desc;
  351.  
  352.         /* We only allow one attachment per handler */
  353.  
  354.         prev_obj_desc = NULL;
  355.         obj_desc = node->object;
  356.         while (obj_desc) {
  357.                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
  358.                     (obj_desc->data.handler == handler)) {
  359.                         return (AE_ALREADY_EXISTS);
  360.                 }
  361.  
  362.                 prev_obj_desc = obj_desc;
  363.                 obj_desc = obj_desc->common.next_object;
  364.         }
  365.  
  366.         /* Create an internal object for the data */
  367.  
  368.         data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
  369.         if (!data_desc) {
  370.                 return (AE_NO_MEMORY);
  371.         }
  372.  
  373.         data_desc->data.handler = handler;
  374.         data_desc->data.pointer = data;
  375.  
  376.         /* Install the data object */
  377.  
  378.         if (prev_obj_desc) {
  379.                 prev_obj_desc->common.next_object = data_desc;
  380.         } else {
  381.                 node->object = data_desc;
  382.         }
  383.  
  384.         return (AE_OK);
  385. }
  386.  
  387. /*******************************************************************************
  388.  *
  389.  * FUNCTION:    acpi_ns_detach_data
  390.  *
  391.  * PARAMETERS:  node            - Namespace node
  392.  *              handler         - Handler associated with the data
  393.  *
  394.  * RETURN:      Status
  395.  *
  396.  * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
  397.  *              is responsible for the actual data.
  398.  *
  399.  ******************************************************************************/
  400.  
  401. acpi_status
  402. acpi_ns_detach_data(struct acpi_namespace_node * node,
  403.                     acpi_object_handler handler)
  404. {
  405.         union acpi_operand_object *obj_desc;
  406.         union acpi_operand_object *prev_obj_desc;
  407.  
  408.         prev_obj_desc = NULL;
  409.         obj_desc = node->object;
  410.         while (obj_desc) {
  411.                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
  412.                     (obj_desc->data.handler == handler)) {
  413.                         if (prev_obj_desc) {
  414.                                 prev_obj_desc->common.next_object =
  415.                                     obj_desc->common.next_object;
  416.                         } else {
  417.                                 node->object = obj_desc->common.next_object;
  418.                         }
  419.  
  420.                         acpi_ut_remove_reference(obj_desc);
  421.                         return (AE_OK);
  422.                 }
  423.  
  424.                 prev_obj_desc = obj_desc;
  425.                 obj_desc = obj_desc->common.next_object;
  426.         }
  427.  
  428.         return (AE_NOT_FOUND);
  429. }
  430.  
  431. /*******************************************************************************
  432.  *
  433.  * FUNCTION:    acpi_ns_get_attached_data
  434.  *
  435.  * PARAMETERS:  node            - Namespace node
  436.  *              handler         - Handler associated with the data
  437.  *              data            - Where the data is returned
  438.  *
  439.  * RETURN:      Status
  440.  *
  441.  * DESCRIPTION: Low level interface to obtain data previously associated with
  442.  *              a namespace node.
  443.  *
  444.  ******************************************************************************/
  445.  
  446. acpi_status
  447. acpi_ns_get_attached_data(struct acpi_namespace_node * node,
  448.                           acpi_object_handler handler, void **data)
  449. {
  450.         union acpi_operand_object *obj_desc;
  451.  
  452.         obj_desc = node->object;
  453.         while (obj_desc) {
  454.                 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
  455.                     (obj_desc->data.handler == handler)) {
  456.                         *data = obj_desc->data.pointer;
  457.                         return (AE_OK);
  458.                 }
  459.  
  460.                 obj_desc = obj_desc->common.next_object;
  461.         }
  462.  
  463.         return (AE_NOT_FOUND);
  464. }
  465.