167754Smsmith/****************************************************************************** 267754Smsmith * 377424Smsmith * Module Name: uteval - Object evaluation 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 4767754Smsmith 4867754Smsmith 4977424Smsmith#define _COMPONENT ACPI_UTILITIES 5091116Smsmith ACPI_MODULE_NAME ("uteval") 5167754Smsmith 5267754Smsmith 5377424Smsmith/******************************************************************************* 5467754Smsmith * 55114237Snjl * FUNCTION: AcpiUtEvaluateObject 5667754Smsmith * 57114237Snjl * PARAMETERS: PrefixNode - Starting node 58114237Snjl * Path - Path to object from starting node 59114237Snjl * ExpectedReturnTypes - Bitmap of allowed return types 60114237Snjl * ReturnDesc - Where a return value is stored 6167754Smsmith * 6267754Smsmith * RETURN: Status 6367754Smsmith * 64114237Snjl * DESCRIPTION: Evaluates a namespace object and verifies the type of the 65197104Sjkim * return object. Common code that simplifies accessing objects 66114237Snjl * that have required return objects of fixed types. 6767754Smsmith * 6867754Smsmith * NOTE: Internal function, no parameter validation 6967754Smsmith * 7077424Smsmith ******************************************************************************/ 7167754Smsmith 7267754SmsmithACPI_STATUS 73114237SnjlAcpiUtEvaluateObject ( 74114237Snjl ACPI_NAMESPACE_NODE *PrefixNode, 75114237Snjl char *Path, 76114237Snjl UINT32 ExpectedReturnBtypes, 77114237Snjl ACPI_OPERAND_OBJECT **ReturnDesc) 7867754Smsmith{ 79167802Sjkim ACPI_EVALUATE_INFO *Info; 8067754Smsmith ACPI_STATUS Status; 81114237Snjl UINT32 ReturnBtype; 8267754Smsmith 8367754Smsmith 84167802Sjkim ACPI_FUNCTION_TRACE (UtEvaluateObject); 8567754Smsmith 8667754Smsmith 87167802Sjkim /* Allocate the evaluation information block */ 88129684Snjl 89167802Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 90167802Sjkim if (!Info) 91167802Sjkim { 92167802Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 93167802Sjkim } 94167802Sjkim 95167802Sjkim Info->PrefixNode = PrefixNode; 96249663Sjkim Info->RelativePathname = Path; 97167802Sjkim 98114237Snjl /* Evaluate the object/method */ 9967754Smsmith 100167802Sjkim Status = AcpiNsEvaluate (Info); 10167754Smsmith if (ACPI_FAILURE (Status)) 10267754Smsmith { 10367754Smsmith if (Status == AE_NOT_FOUND) 10467754Smsmith { 105114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n", 106123315Snjl AcpiUtGetNodeName (PrefixNode), Path)); 10767754Smsmith } 10867754Smsmith else 10967754Smsmith { 110167802Sjkim ACPI_ERROR_METHOD ("Method execution failed", 111114237Snjl PrefixNode, Path, Status); 11267754Smsmith } 11367754Smsmith 114167802Sjkim goto Cleanup; 11567754Smsmith } 11667754Smsmith 11767754Smsmith /* Did we get a return object? */ 11867754Smsmith 119167802Sjkim if (!Info->ReturnObject) 12067754Smsmith { 121114237Snjl if (ExpectedReturnBtypes) 122114237Snjl { 123167802Sjkim ACPI_ERROR_METHOD ("No object was returned from", 124114237Snjl PrefixNode, Path, AE_NOT_EXIST); 125114237Snjl 126167802Sjkim Status = AE_NOT_EXIST; 127114237Snjl } 128114237Snjl 129167802Sjkim goto Cleanup; 13067754Smsmith } 13167754Smsmith 132114237Snjl /* Map the return object type to the bitmapped type */ 13367754Smsmith 134193267Sjkim switch ((Info->ReturnObject)->Common.Type) 13567754Smsmith { 136114237Snjl case ACPI_TYPE_INTEGER: 137250838Sjkim 138114237Snjl ReturnBtype = ACPI_BTYPE_INTEGER; 139114237Snjl break; 140114237Snjl 141114237Snjl case ACPI_TYPE_BUFFER: 142250838Sjkim 143114237Snjl ReturnBtype = ACPI_BTYPE_BUFFER; 144114237Snjl break; 145114237Snjl 146114237Snjl case ACPI_TYPE_STRING: 147250838Sjkim 148114237Snjl ReturnBtype = ACPI_BTYPE_STRING; 149114237Snjl break; 150114237Snjl 151114237Snjl case ACPI_TYPE_PACKAGE: 152250838Sjkim 153114237Snjl ReturnBtype = ACPI_BTYPE_PACKAGE; 154114237Snjl break; 155114237Snjl 156114237Snjl default: 157250838Sjkim 158114237Snjl ReturnBtype = 0; 159114237Snjl break; 160114237Snjl } 161114237Snjl 162151937Sjkim if ((AcpiGbl_EnableInterpreterSlack) && 163151937Sjkim (!ExpectedReturnBtypes)) 164151937Sjkim { 165151937Sjkim /* 166197104Sjkim * We received a return object, but one was not expected. This can 167151937Sjkim * happen frequently if the "implicit return" feature is enabled. 168151937Sjkim * Just delete the return object and return AE_OK. 169151937Sjkim */ 170167802Sjkim AcpiUtRemoveReference (Info->ReturnObject); 171167802Sjkim goto Cleanup; 172151937Sjkim } 173151937Sjkim 174114237Snjl /* Is the return object one of the expected types? */ 175114237Snjl 176114237Snjl if (!(ExpectedReturnBtypes & ReturnBtype)) 177114237Snjl { 178167802Sjkim ACPI_ERROR_METHOD ("Return object type is incorrect", 179114237Snjl PrefixNode, Path, AE_TYPE); 180114237Snjl 181167802Sjkim ACPI_ERROR ((AE_INFO, 182204773Sjkim "Type returned from %s was incorrect: %s, expected Btypes: 0x%X", 183167802Sjkim Path, AcpiUtGetObjectTypeName (Info->ReturnObject), 184151937Sjkim ExpectedReturnBtypes)); 185114237Snjl 186114237Snjl /* On error exit, we must delete the return object */ 187114237Snjl 188167802Sjkim AcpiUtRemoveReference (Info->ReturnObject); 189167802Sjkim Status = AE_TYPE; 190167802Sjkim goto Cleanup; 19167754Smsmith } 192114237Snjl 193114237Snjl /* Object type is OK, return it */ 194114237Snjl 195167802Sjkim *ReturnDesc = Info->ReturnObject; 196167802Sjkim 197167802SjkimCleanup: 198167802Sjkim ACPI_FREE (Info); 199167802Sjkim return_ACPI_STATUS (Status); 200114237Snjl} 201114237Snjl 202114237Snjl 203114237Snjl/******************************************************************************* 204114237Snjl * 205114237Snjl * FUNCTION: AcpiUtEvaluateNumericObject 206114237Snjl * 207151937Sjkim * PARAMETERS: ObjectName - Object name to be evaluated 208114237Snjl * DeviceNode - Node for the device 209197104Sjkim * Value - Where the value is returned 210114237Snjl * 211114237Snjl * RETURN: Status 212114237Snjl * 213114237Snjl * DESCRIPTION: Evaluates a numeric namespace object for a selected device 214197104Sjkim * and stores result in *Value. 215114237Snjl * 216114237Snjl * NOTE: Internal function, no parameter validation 217114237Snjl * 218114237Snjl ******************************************************************************/ 219114237Snjl 220114237SnjlACPI_STATUS 221114237SnjlAcpiUtEvaluateNumericObject ( 222114237Snjl char *ObjectName, 223114237Snjl ACPI_NAMESPACE_NODE *DeviceNode, 224202771Sjkim UINT64 *Value) 225114237Snjl{ 226114237Snjl ACPI_OPERAND_OBJECT *ObjDesc; 227114237Snjl ACPI_STATUS Status; 228114237Snjl 229114237Snjl 230167802Sjkim ACPI_FUNCTION_TRACE (UtEvaluateNumericObject); 231114237Snjl 232114237Snjl 233114237Snjl Status = AcpiUtEvaluateObject (DeviceNode, ObjectName, 234114237Snjl ACPI_BTYPE_INTEGER, &ObjDesc); 235114237Snjl if (ACPI_FAILURE (Status)) 23667754Smsmith { 237114237Snjl return_ACPI_STATUS (Status); 23867754Smsmith } 23967754Smsmith 240114237Snjl /* Get the returned Integer */ 241114237Snjl 242197104Sjkim *Value = ObjDesc->Integer.Value; 243114237Snjl 24467754Smsmith /* On exit, we must delete the return object */ 24567754Smsmith 24677424Smsmith AcpiUtRemoveReference (ObjDesc); 24767754Smsmith return_ACPI_STATUS (Status); 24867754Smsmith} 24967754Smsmith 25067754Smsmith 25177424Smsmith/******************************************************************************* 25267754Smsmith * 25377424Smsmith * FUNCTION: AcpiUtExecute_STA 25467754Smsmith * 25567754Smsmith * PARAMETERS: DeviceNode - Node for the device 256151937Sjkim * Flags - Where the status flags are returned 25767754Smsmith * 25867754Smsmith * RETURN: Status 25967754Smsmith * 26067754Smsmith * DESCRIPTION: Executes _STA for selected device and stores results in 261252279Sjkim * *Flags. If _STA does not exist, then the device is assumed 262252279Sjkim * to be present/functional/enabled (as per the ACPI spec). 26367754Smsmith * 26467754Smsmith * NOTE: Internal function, no parameter validation 26567754Smsmith * 26677424Smsmith ******************************************************************************/ 26767754Smsmith 26867754SmsmithACPI_STATUS 26977424SmsmithAcpiUtExecute_STA ( 27067754Smsmith ACPI_NAMESPACE_NODE *DeviceNode, 27167754Smsmith UINT32 *Flags) 27267754Smsmith{ 27367754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 27467754Smsmith ACPI_STATUS Status; 27567754Smsmith 27667754Smsmith 277167802Sjkim ACPI_FUNCTION_TRACE (UtExecute_STA); 27867754Smsmith 27977424Smsmith 280114237Snjl Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA, 281114237Snjl ACPI_BTYPE_INTEGER, &ObjDesc); 282114237Snjl if (ACPI_FAILURE (Status)) 28367754Smsmith { 284114237Snjl if (AE_NOT_FOUND == Status) 285114237Snjl { 286252279Sjkim /* 287252279Sjkim * if _STA does not exist, then (as per the ACPI specification), 288252279Sjkim * the returned flags will indicate that the device is present, 289252279Sjkim * functional, and enabled. 290252279Sjkim */ 291114237Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 292114237Snjl "_STA on %4.4s was not found, assuming device is present\n", 293123315Snjl AcpiUtGetNodeName (DeviceNode))); 29467754Smsmith 295167802Sjkim *Flags = ACPI_UINT32_MAX; 296114237Snjl Status = AE_OK; 297114237Snjl } 29867754Smsmith 299114237Snjl return_ACPI_STATUS (Status); 30067754Smsmith } 30167754Smsmith 302114237Snjl /* Extract the status flags */ 30367754Smsmith 304114237Snjl *Flags = (UINT32) ObjDesc->Integer.Value; 30567754Smsmith 306114237Snjl /* On exit, we must delete the return object */ 30767754Smsmith 308114237Snjl AcpiUtRemoveReference (ObjDesc); 30967754Smsmith return_ACPI_STATUS (Status); 31067754Smsmith} 311126372Snjl 312126372Snjl 313126372Snjl/******************************************************************************* 314126372Snjl * 315197104Sjkim * FUNCTION: AcpiUtExecutePowerMethods 316126372Snjl * 317126372Snjl * PARAMETERS: DeviceNode - Node for the device 318197104Sjkim * MethodNames - Array of power method names 319197104Sjkim * MethodCount - Number of methods to execute 320197104Sjkim * OutValues - Where the power method values are returned 321126372Snjl * 322197104Sjkim * RETURN: Status, OutValues 323126372Snjl * 324197104Sjkim * DESCRIPTION: Executes the specified power methods for the device and returns 325197104Sjkim * the result(s). 326126372Snjl * 327126372Snjl * NOTE: Internal function, no parameter validation 328126372Snjl * 329126372Snjl ******************************************************************************/ 330126372Snjl 331126372SnjlACPI_STATUS 332197104SjkimAcpiUtExecutePowerMethods ( 333126372Snjl ACPI_NAMESPACE_NODE *DeviceNode, 334197104Sjkim const char **MethodNames, 335197104Sjkim UINT8 MethodCount, 336197104Sjkim UINT8 *OutValues) 337126372Snjl{ 338126372Snjl ACPI_OPERAND_OBJECT *ObjDesc; 339126372Snjl ACPI_STATUS Status; 340197104Sjkim ACPI_STATUS FinalStatus = AE_NOT_FOUND; 341126372Snjl UINT32 i; 342126372Snjl 343126372Snjl 344197104Sjkim ACPI_FUNCTION_TRACE (UtExecutePowerMethods); 345126372Snjl 346126372Snjl 347197104Sjkim for (i = 0; i < MethodCount; i++) 348126372Snjl { 349197104Sjkim /* 350197104Sjkim * Execute the power method (_SxD or _SxW). The only allowable 351197104Sjkim * return type is an Integer. 352197104Sjkim */ 353126372Snjl Status = AcpiUtEvaluateObject (DeviceNode, 354197104Sjkim ACPI_CAST_PTR (char, MethodNames[i]), 355126372Snjl ACPI_BTYPE_INTEGER, &ObjDesc); 356197104Sjkim if (ACPI_SUCCESS (Status)) 357126372Snjl { 358197104Sjkim OutValues[i] = (UINT8) ObjDesc->Integer.Value; 359126372Snjl 360126372Snjl /* Delete the return object */ 361126372Snjl 362126372Snjl AcpiUtRemoveReference (ObjDesc); 363197104Sjkim FinalStatus = AE_OK; /* At least one value is valid */ 364197104Sjkim continue; 365126372Snjl } 366197104Sjkim 367197104Sjkim OutValues[i] = ACPI_UINT8_MAX; 368197104Sjkim if (Status == AE_NOT_FOUND) 369197104Sjkim { 370197104Sjkim continue; /* Ignore if not found */ 371197104Sjkim } 372197104Sjkim 373197104Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Failed %s on Device %4.4s, %s\n", 374197104Sjkim ACPI_CAST_PTR (char, MethodNames[i]), 375197104Sjkim AcpiUtGetNodeName (DeviceNode), AcpiFormatException (Status))); 376126372Snjl } 377126372Snjl 378197104Sjkim return_ACPI_STATUS (FinalStatus); 379126372Snjl} 380