167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsobject - Utilities for objects attached to namespace 467754Smsmith * table entries 567754Smsmith * 667754Smsmith ******************************************************************************/ 767754Smsmith 8217365Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 1070243Smsmith * All rights reserved. 1167754Smsmith * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 2667754Smsmith * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 3067754Smsmith * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 4467754Smsmith 4567754Smsmith 4667754Smsmith#define __NSOBJECT_C__ 4767754Smsmith 48193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 49193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 50193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 5167754Smsmith 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_NAMESPACE 5491116Smsmith ACPI_MODULE_NAME ("nsobject") 5567754Smsmith 5667754Smsmith 5767754Smsmith/******************************************************************************* 5867754Smsmith * 5967754Smsmith * FUNCTION: AcpiNsAttachObject 6067754Smsmith * 6182367Smsmith * PARAMETERS: Node - Parent Node 6267754Smsmith * Object - Object to be attached 6367754Smsmith * Type - Type of object, or ACPI_TYPE_ANY if not 6482367Smsmith * known 6567754Smsmith * 66151937Sjkim * RETURN: Status 67151937Sjkim * 6867754Smsmith * DESCRIPTION: Record the given object as the value associated with the 69241973Sjkim * name whose ACPI_HANDLE is passed. If Object is NULL 7067754Smsmith * and Type is ACPI_TYPE_ANY, set the name as having no value. 7187031Smsmith * Note: Future may require that the Node->Flags field be passed 7287031Smsmith * as a parameter. 7367754Smsmith * 7467754Smsmith * MUTEX: Assumes namespace is locked 7567754Smsmith * 7667754Smsmith ******************************************************************************/ 7767754Smsmith 7867754SmsmithACPI_STATUS 7967754SmsmithAcpiNsAttachObject ( 8067754Smsmith ACPI_NAMESPACE_NODE *Node, 8167754Smsmith ACPI_OPERAND_OBJECT *Object, 8291116Smsmith ACPI_OBJECT_TYPE Type) 8367754Smsmith{ 8467754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 8587031Smsmith ACPI_OPERAND_OBJECT *LastObjDesc; 8691116Smsmith ACPI_OBJECT_TYPE ObjectType = ACPI_TYPE_ANY; 8767754Smsmith 8867754Smsmith 89167802Sjkim ACPI_FUNCTION_TRACE (NsAttachObject); 9067754Smsmith 9167754Smsmith 9267754Smsmith /* 9367754Smsmith * Parameter validation 9467754Smsmith */ 9567754Smsmith if (!Node) 9667754Smsmith { 9767754Smsmith /* Invalid handle */ 9867754Smsmith 99167802Sjkim ACPI_ERROR ((AE_INFO, "Null NamedObj handle")); 10067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 10167754Smsmith } 10267754Smsmith 10367754Smsmith if (!Object && (ACPI_TYPE_ANY != Type)) 10467754Smsmith { 10567754Smsmith /* Null object */ 10667754Smsmith 107167802Sjkim ACPI_ERROR ((AE_INFO, 108167802Sjkim "Null object, but type not ACPI_TYPE_ANY")); 10967754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 11067754Smsmith } 11167754Smsmith 11291116Smsmith if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 11367754Smsmith { 11467754Smsmith /* Not a name handle */ 11567754Smsmith 116167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid handle %p [%s]", 117167802Sjkim Node, AcpiUtGetDescriptorName (Node))); 11867754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 11967754Smsmith } 12067754Smsmith 12167754Smsmith /* Check if this object is already attached */ 12267754Smsmith 12367754Smsmith if (Node->Object == Object) 12467754Smsmith { 125151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 126151937Sjkim "Obj %p already installed in NameObj %p\n", 12767754Smsmith Object, Node)); 12867754Smsmith 12967754Smsmith return_ACPI_STATUS (AE_OK); 13067754Smsmith } 13167754Smsmith 13267754Smsmith /* If null object, we will just install it */ 13367754Smsmith 13467754Smsmith if (!Object) 13567754Smsmith { 13687031Smsmith ObjDesc = NULL; 13787031Smsmith ObjectType = ACPI_TYPE_ANY; 13867754Smsmith } 13967754Smsmith 14067754Smsmith /* 14184491Smsmith * If the source object is a namespace Node with an attached object, 14267754Smsmith * we will use that (attached) object 14367754Smsmith */ 14491116Smsmith else if ((ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) && 14567754Smsmith ((ACPI_NAMESPACE_NODE *) Object)->Object) 14667754Smsmith { 14767754Smsmith /* 14867754Smsmith * Value passed is a name handle and that name has a 149241973Sjkim * non-null value. Use that name's value and type. 15067754Smsmith */ 15187031Smsmith ObjDesc = ((ACPI_NAMESPACE_NODE *) Object)->Object; 15287031Smsmith ObjectType = ((ACPI_NAMESPACE_NODE *) Object)->Type; 15367754Smsmith } 15467754Smsmith 15567754Smsmith /* 15667754Smsmith * Otherwise, we will use the parameter object, but we must type 15767754Smsmith * it first 15867754Smsmith */ 15967754Smsmith else 16067754Smsmith { 16167754Smsmith ObjDesc = (ACPI_OPERAND_OBJECT *) Object; 16267754Smsmith 163107325Siwasaki /* Use the given type */ 16467754Smsmith 165107325Siwasaki ObjectType = Type; 16667754Smsmith } 16767754Smsmith 16882367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", 169123315Snjl ObjDesc, Node, AcpiUtGetNodeName (Node))); 17067754Smsmith 17187031Smsmith /* Detach an existing attached object if present */ 17267754Smsmith 17387031Smsmith if (Node->Object) 17487031Smsmith { 17587031Smsmith AcpiNsDetachObject (Node); 17687031Smsmith } 17767754Smsmith 17899679Siwasaki if (ObjDesc) 17967754Smsmith { 18099679Siwasaki /* 18199679Siwasaki * Must increment the new value's reference count 18299679Siwasaki * (if it is an internal object) 18399679Siwasaki */ 18499679Siwasaki AcpiUtAddReference (ObjDesc); 18567754Smsmith 18699679Siwasaki /* 18799679Siwasaki * Handle objects with multiple descriptors - walk 18899679Siwasaki * to the end of the descriptor list 18999679Siwasaki */ 19099679Siwasaki LastObjDesc = ObjDesc; 19199679Siwasaki while (LastObjDesc->Common.NextObject) 19299679Siwasaki { 19399679Siwasaki LastObjDesc = LastObjDesc->Common.NextObject; 19499679Siwasaki } 19567754Smsmith 19699679Siwasaki /* Install the object at the front of the object list */ 19767754Smsmith 19899679Siwasaki LastObjDesc->Common.NextObject = Node->Object; 19999679Siwasaki } 20099679Siwasaki 20187031Smsmith Node->Type = (UINT8) ObjectType; 20287031Smsmith Node->Object = ObjDesc; 20367754Smsmith 20467754Smsmith return_ACPI_STATUS (AE_OK); 20567754Smsmith} 20667754Smsmith 20767754Smsmith 20867754Smsmith/******************************************************************************* 20967754Smsmith * 21067754Smsmith * FUNCTION: AcpiNsDetachObject 21167754Smsmith * 212151937Sjkim * PARAMETERS: Node - A Namespace node whose object will be detached 21367754Smsmith * 21467754Smsmith * RETURN: None. 21567754Smsmith * 216114237Snjl * DESCRIPTION: Detach/delete an object associated with a namespace node. 217107325Siwasaki * if the object is an allocated object, it is freed. 218107325Siwasaki * Otherwise, the field is simply cleared. 21967754Smsmith * 22067754Smsmith ******************************************************************************/ 22167754Smsmith 22267754Smsmithvoid 22367754SmsmithAcpiNsDetachObject ( 22467754Smsmith ACPI_NAMESPACE_NODE *Node) 22567754Smsmith{ 22667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 22767754Smsmith 22867754Smsmith 229167802Sjkim ACPI_FUNCTION_TRACE (NsDetachObject); 23067754Smsmith 23183174Smsmith 23267754Smsmith ObjDesc = Node->Object; 23399679Siwasaki 23499679Siwasaki if (!ObjDesc || 235193267Sjkim (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA)) 23667754Smsmith { 23767754Smsmith return_VOID; 23867754Smsmith } 23967754Smsmith 240193267Sjkim if (Node->Flags & ANOBJ_ALLOCATED_BUFFER) 241193267Sjkim { 242193267Sjkim /* Free the dynamic aml buffer */ 243193267Sjkim 244193267Sjkim if (ObjDesc->Common.Type == ACPI_TYPE_METHOD) 245193267Sjkim { 246193267Sjkim ACPI_FREE (ObjDesc->Method.AmlStart); 247193267Sjkim } 248193267Sjkim } 249193267Sjkim 25067754Smsmith /* Clear the entry in all cases */ 25167754Smsmith 25267754Smsmith Node->Object = NULL; 25399679Siwasaki if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND) 25487031Smsmith { 25587031Smsmith Node->Object = ObjDesc->Common.NextObject; 25687031Smsmith if (Node->Object && 257193267Sjkim ((Node->Object)->Common.Type != ACPI_TYPE_LOCAL_DATA)) 25887031Smsmith { 25987031Smsmith Node->Object = Node->Object->Common.NextObject; 26087031Smsmith } 26187031Smsmith } 26267754Smsmith 26387031Smsmith /* Reset the node type to untyped */ 26487031Smsmith 26587031Smsmith Node->Type = ACPI_TYPE_ANY; 26687031Smsmith 26799146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n", 268123315Snjl Node, AcpiUtGetNodeName (Node), ObjDesc)); 26967754Smsmith 27085756Smsmith /* Remove one reference on the object (and all subobjects) */ 27167754Smsmith 27285756Smsmith AcpiUtRemoveReference (ObjDesc); 27367754Smsmith return_VOID; 27467754Smsmith} 27567754Smsmith 27667754Smsmith 27767754Smsmith/******************************************************************************* 27867754Smsmith * 27967754Smsmith * FUNCTION: AcpiNsGetAttachedObject 28067754Smsmith * 281151937Sjkim * PARAMETERS: Node - Namespace node 28267754Smsmith * 28367754Smsmith * RETURN: Current value of the object field from the Node whose 28467754Smsmith * handle is passed 28567754Smsmith * 286107325Siwasaki * DESCRIPTION: Obtain the object attached to a namespace node. 287107325Siwasaki * 28867754Smsmith ******************************************************************************/ 28967754Smsmith 29087031SmsmithACPI_OPERAND_OBJECT * 29167754SmsmithAcpiNsGetAttachedObject ( 29277424Smsmith ACPI_NAMESPACE_NODE *Node) 29367754Smsmith{ 294167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetAttachedObject, Node); 29567754Smsmith 29667754Smsmith 29777424Smsmith if (!Node) 29867754Smsmith { 299167802Sjkim ACPI_WARNING ((AE_INFO, "Null Node ptr")); 30067754Smsmith return_PTR (NULL); 30167754Smsmith } 30267754Smsmith 30387031Smsmith if (!Node->Object || 30499679Siwasaki ((ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_OPERAND) && 30599679Siwasaki (ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_NAMED)) || 306193267Sjkim ((Node->Object)->Common.Type == ACPI_TYPE_LOCAL_DATA)) 30787031Smsmith { 30887031Smsmith return_PTR (NULL); 30987031Smsmith } 31087031Smsmith 31177424Smsmith return_PTR (Node->Object); 31267754Smsmith} 31367754Smsmith 31467754Smsmith 31587031Smsmith/******************************************************************************* 31687031Smsmith * 31787031Smsmith * FUNCTION: AcpiNsGetSecondaryObject 31887031Smsmith * 319151937Sjkim * PARAMETERS: Node - Namespace node 32087031Smsmith * 32187031Smsmith * RETURN: Current value of the object field from the Node whose 322107325Siwasaki * handle is passed. 32387031Smsmith * 324107325Siwasaki * DESCRIPTION: Obtain a secondary object associated with a namespace node. 325107325Siwasaki * 32687031Smsmith ******************************************************************************/ 32787031Smsmith 32887031SmsmithACPI_OPERAND_OBJECT * 32987031SmsmithAcpiNsGetSecondaryObject ( 33087031Smsmith ACPI_OPERAND_OBJECT *ObjDesc) 33187031Smsmith{ 332167802Sjkim ACPI_FUNCTION_TRACE_PTR (NsGetSecondaryObject, ObjDesc); 33387031Smsmith 33487031Smsmith 335193267Sjkim if ((!ObjDesc) || 336193267Sjkim (ObjDesc->Common.Type== ACPI_TYPE_LOCAL_DATA) || 337193267Sjkim (!ObjDesc->Common.NextObject) || 338193267Sjkim ((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA)) 33987031Smsmith { 34087031Smsmith return_PTR (NULL); 34187031Smsmith } 34287031Smsmith 34387031Smsmith return_PTR (ObjDesc->Common.NextObject); 34487031Smsmith} 34587031Smsmith 34687031Smsmith 34787031Smsmith/******************************************************************************* 34887031Smsmith * 34987031Smsmith * FUNCTION: AcpiNsAttachData 35087031Smsmith * 351107325Siwasaki * PARAMETERS: Node - Namespace node 352107325Siwasaki * Handler - Handler to be associated with the data 353107325Siwasaki * Data - Data to be attached 35487031Smsmith * 35587031Smsmith * RETURN: Status 35687031Smsmith * 357241973Sjkim * DESCRIPTION: Low-level attach data. Create and attach a Data object. 35887031Smsmith * 35987031Smsmith ******************************************************************************/ 36087031Smsmith 36187031SmsmithACPI_STATUS 36287031SmsmithAcpiNsAttachData ( 36387031Smsmith ACPI_NAMESPACE_NODE *Node, 36487031Smsmith ACPI_OBJECT_HANDLER Handler, 36587031Smsmith void *Data) 36687031Smsmith{ 36787031Smsmith ACPI_OPERAND_OBJECT *PrevObjDesc; 36887031Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 36987031Smsmith ACPI_OPERAND_OBJECT *DataDesc; 37087031Smsmith 37187031Smsmith 372107325Siwasaki /* We only allow one attachment per handler */ 373107325Siwasaki 37487031Smsmith PrevObjDesc = NULL; 37587031Smsmith ObjDesc = Node->Object; 37687031Smsmith while (ObjDesc) 37787031Smsmith { 378193267Sjkim if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) && 37987031Smsmith (ObjDesc->Data.Handler == Handler)) 38087031Smsmith { 38187031Smsmith return (AE_ALREADY_EXISTS); 38287031Smsmith } 38387031Smsmith 38487031Smsmith PrevObjDesc = ObjDesc; 38587031Smsmith ObjDesc = ObjDesc->Common.NextObject; 38687031Smsmith } 38787031Smsmith 38887031Smsmith /* Create an internal object for the data */ 38987031Smsmith 390107325Siwasaki DataDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_DATA); 39187031Smsmith if (!DataDesc) 39287031Smsmith { 39387031Smsmith return (AE_NO_MEMORY); 39487031Smsmith } 39587031Smsmith 39687031Smsmith DataDesc->Data.Handler = Handler; 39787031Smsmith DataDesc->Data.Pointer = Data; 39887031Smsmith 39987031Smsmith /* Install the data object */ 40087031Smsmith 40187031Smsmith if (PrevObjDesc) 40287031Smsmith { 40387031Smsmith PrevObjDesc->Common.NextObject = DataDesc; 40487031Smsmith } 40587031Smsmith else 40687031Smsmith { 40787031Smsmith Node->Object = DataDesc; 40887031Smsmith } 40987031Smsmith 41087031Smsmith return (AE_OK); 41187031Smsmith} 41287031Smsmith 41387031Smsmith 41487031Smsmith/******************************************************************************* 41587031Smsmith * 41687031Smsmith * FUNCTION: AcpiNsDetachData 41787031Smsmith * 418107325Siwasaki * PARAMETERS: Node - Namespace node 419107325Siwasaki * Handler - Handler associated with the data 42087031Smsmith * 42187031Smsmith * RETURN: Status 42287031Smsmith * 423241973Sjkim * DESCRIPTION: Low-level detach data. Delete the data node, but the caller 424107325Siwasaki * is responsible for the actual data. 42587031Smsmith * 42687031Smsmith ******************************************************************************/ 42787031Smsmith 42887031SmsmithACPI_STATUS 42987031SmsmithAcpiNsDetachData ( 43087031Smsmith ACPI_NAMESPACE_NODE *Node, 43187031Smsmith ACPI_OBJECT_HANDLER Handler) 43287031Smsmith{ 43387031Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 43487031Smsmith ACPI_OPERAND_OBJECT *PrevObjDesc; 43587031Smsmith 43687031Smsmith 43787031Smsmith PrevObjDesc = NULL; 43887031Smsmith ObjDesc = Node->Object; 43987031Smsmith while (ObjDesc) 44087031Smsmith { 441193267Sjkim if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) && 44287031Smsmith (ObjDesc->Data.Handler == Handler)) 44387031Smsmith { 44487031Smsmith if (PrevObjDesc) 44587031Smsmith { 44687031Smsmith PrevObjDesc->Common.NextObject = ObjDesc->Common.NextObject; 44787031Smsmith } 44887031Smsmith else 44987031Smsmith { 45087031Smsmith Node->Object = ObjDesc->Common.NextObject; 45187031Smsmith } 45287031Smsmith 45387031Smsmith AcpiUtRemoveReference (ObjDesc); 45487031Smsmith return (AE_OK); 45587031Smsmith } 45687031Smsmith 45787031Smsmith PrevObjDesc = ObjDesc; 45887031Smsmith ObjDesc = ObjDesc->Common.NextObject; 45987031Smsmith } 46087031Smsmith 46187031Smsmith return (AE_NOT_FOUND); 46287031Smsmith} 46387031Smsmith 46487031Smsmith 46587031Smsmith/******************************************************************************* 46687031Smsmith * 46787031Smsmith * FUNCTION: AcpiNsGetAttachedData 46887031Smsmith * 469107325Siwasaki * PARAMETERS: Node - Namespace node 470107325Siwasaki * Handler - Handler associated with the data 471107325Siwasaki * Data - Where the data is returned 47287031Smsmith * 47387031Smsmith * RETURN: Status 47487031Smsmith * 475107325Siwasaki * DESCRIPTION: Low level interface to obtain data previously associated with 476107325Siwasaki * a namespace node. 47787031Smsmith * 47887031Smsmith ******************************************************************************/ 47987031Smsmith 48087031SmsmithACPI_STATUS 48187031SmsmithAcpiNsGetAttachedData ( 48287031Smsmith ACPI_NAMESPACE_NODE *Node, 48387031Smsmith ACPI_OBJECT_HANDLER Handler, 48487031Smsmith void **Data) 48587031Smsmith{ 48687031Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 48787031Smsmith 48887031Smsmith 48987031Smsmith ObjDesc = Node->Object; 49087031Smsmith while (ObjDesc) 49187031Smsmith { 492193267Sjkim if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) && 49387031Smsmith (ObjDesc->Data.Handler == Handler)) 49487031Smsmith { 49587031Smsmith *Data = ObjDesc->Data.Pointer; 49687031Smsmith return (AE_OK); 49787031Smsmith } 49887031Smsmith 49987031Smsmith ObjDesc = ObjDesc->Common.NextObject; 50087031Smsmith } 50187031Smsmith 50287031Smsmith return (AE_NOT_FOUND); 50387031Smsmith} 504